// Import external files first. Eventually this will be broken up in to smaller files.
import { process_permission_checks } from './ae_utils__perm_checks';
import { iso_datetime_formatter } from './ae_utils__datetime_format';
type key_str = {
[key: string]: string;
};
type key_val = {
[key: string]: any;
};
function format_bytes(
bytes: number,
decimals: number = 2
) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
/* This utility function will add commas to a number. */
function number_w_commas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
/* This utility function looks for any form data with the prefixed name passed and returns a new object.
* This function is used heavily! Be very careful making changes!!!
* If rm_empty_id then it will remove/ignore fields matching. This helps with the API and new records/objects
* If rm_empty then it will remove/ignore fields matching. Sometimes this is needed.
* If trim_values then it will trim string values.
* If bool_tf_str then it will convert string values of true/false (case insensitive) to boolean values.
* Updated 2023-12-22
*/
export let extract_prefixed_form_data = function extract_prefixed_form_data({prefix=null, form_data={}, rm_empty_id=true, rm_empty=false, trim_values=false, bool_tf_str=false, log_lvl=0}) {
if (log_lvl) {
console.log('*** extract_prefixed_form_data() ***');
if (prefix) {
console.log(`Looking for prefixed fields: ${prefix}; Removing emptry ID fields: ${rm_empty_id}; Removing empty fields: ${rm_empty}; Trim string values: ${trim_values}; Convert true/false string values to boolean: ${bool_tf_str}`);
} else {
console.log(`No prefix set. Looking at all fields. Removing emptry ID fields: ${rm_empty_id}; Removing empty fields: ${rm_empty}; Trim string values: ${trim_values}; Convert true/false string values to boolean: ${bool_tf_str}`);
}
}
if (log_lvl > 1) {
console.log('Form Data:');
console.log(form_data);
}
// const data_obj: any = {}; // future TS
let data_obj = {};
for (let field of form_data) {
let [obj_prop_name, obj_prop_value] = field;
if (log_lvl > 1) {
console.log(`${obj_prop_name}: ${obj_prop_value} type=${typeof obj_prop_value}`);
}
// Trim string values if needed
if (trim_values && typeof obj_prop_value === 'string') {
if (log_lvl && obj_prop_value.trim() != obj_prop_value) {
console.log('Trimming string value!');
obj_prop_value = obj_prop_value.trim();
}
}
// Convert string to boolean if needed
if (bool_tf_str && typeof obj_prop_value === 'string') {
// console.log('Flag set for converting true/false string values to boolean!');
if (obj_prop_value.toLowerCase() === 'true') {
if (log_lvl) {
console.log('Converting string to boolean value: true');
}
obj_prop_value = true;
} else if (obj_prop_value.toLowerCase() === 'false') {
if (log_lvl) {
console.log('Converting string to boolean value: false');
}
obj_prop_value = false;
}
}
if (prefix && obj_prop_name.startsWith(prefix)) { // Prefix set
// if (obj_prop_name.startsWith(prefix)) {
obj_prop_name = obj_prop_name.replace(prefix, '');
if (log_lvl) {
console.log(`Checking: (${prefix})${obj_prop_name} value=${obj_prop_value}`);
}
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
if (log_lvl) {
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
}
} else if (rm_empty && !obj_prop_value) {
if (log_lvl) {
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
}
} else {
if (log_lvl) {
console.log(`Match: ${prefix})${obj_prop_name} value=${obj_prop_value}`);
}
data_obj[obj_prop_name] = obj_prop_value;
}
} else if (prefix && !obj_prop_name.startsWith(prefix)) { // Prefix set
if (log_lvl > 1) {
console.log('Did not start with prefix. Ignoring');
}
} else { // No prefix set
if (log_lvl) {
console.log(`Checking: ${obj_prop_name} value=${obj_prop_value}`);
}
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
if (log_lvl > 1) {
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
}
} else if (rm_empty && !obj_prop_value) {
if (log_lvl > 1) {
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
}
} else {
if (log_lvl > 1) {
console.log(`Match: ${obj_prop_name} value=${obj_prop_value}`);
}
data_obj[obj_prop_name] = obj_prop_value;
}
}
}
if (log_lvl > 1) {
console.log(data_obj);
}
return data_obj;
}
/* This utility function processes specific data string.
* MECARD
* OBJ = OBJ:ot:example,oi:asdf1234
* ot = Aether object type; oi = Aether object ID random
* KV = KV:"key":"value"
* JS = {"id":123,"name":"example name"}
* http or https?
* Common short keys used:
* bdg: Badge ID Random
* reg: Registration ID Random
* exid: External ID
* gn: Given First Name
* fn: Family Last Name
* em: Email Address
*/
// Updated 2022-02-11
export let process_data_string = function process_data_string(data_string: string) {
console.log('*** process_data_string() ***');
// console.log(data_string);
if (!data_string || data_string.length < 1) {
console.log('No data string found.');
return false;
}
let obj: key_val = {};
let colon_index = data_string.indexOf(':')
if (colon_index) {
let data_string_type = data_string.slice(0, colon_index);
console.log(data_string_type);
obj['qr_type'] = data_string_type;
if (data_string_type == 'MECARD') {
let mecard_str = data_string.slice(colon_index+1);
console.log(mecard_str);
obj['str'] = mecard_str;
} else if (data_string_type == 'OBJ') {
let key_value_str = data_string.slice(colon_index+1);
console.log(key_value_str);
let key_value_array = key_value_str.split(',');
// console.log(key_value_array);
let ot_colon_index = key_value_array[0].indexOf(':')
let obj_type = key_value_array[0].slice(ot_colon_index+1);
// console.log(obj_type);
let oi_colon_index = key_value_array[1].indexOf(':')
let obj_id = key_value_array[1].slice(oi_colon_index+1);
// console.log(obj_id);
obj['type'] = obj_type;
obj['id'] = obj_id;
} else if (data_string_type == 'JSON') {
let partial_json_str = data_string.slice(colon_index+1);
console.log(partial_json_str);
let json_str = `{${partial_json_str}}`;
console.log(json_str);
obj['json'] = JSON.parse(json_str);
} else if (data_string_type == 'STR') {
let str = data_string.slice(colon_index+1);
console.log(str);
obj['str'] = str;
} else if (data_string_type == 'http' || data_string_type == 'https') {
console.log(`http or https: ${data_string}`);
obj['type'] = 'url';
obj['url'] = data_string;
} else {
console.log('The unknown data string type was found. Returning the string part.')
let unknown_str = data_string.slice(colon_index+1);
console.log(unknown_str);
obj['str'] = unknown_str;
}
} else {
console.log('The data string type was not found. Returning the entire string.')
console.log(data_string);
obj['qr_type'] = 'UNKNOWN';
obj['str'] = data_string;
// return false;
}
console.log(obj);
return obj; // Returns an object
}
// This function will update the URL and send a message to the parent window (iframe).
// The name should be something like "example_id".
// Svelte specific:
// WARNING: Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead.
// Updated 2024-03-02
import { pushState, replaceState } from '$app/navigation';
function handle_url_and_message(name: string, value: null|string) {
console.log(`*** handle_url_and_message() *** name=${name} value=${value}`);
let location = window.location.href;
// console.log('location:', location);
const url = new URL(location);
// console.log('url:', url);
if (value) {
url.searchParams.set(name, value);
history.pushState({}, '', url);
// console.log('url:', url);
// pushState(url.href, {});
// pushState(url.search, {});
// replaceState(url.href, {});
let message = {name: value};
window.parent.postMessage(message, "*");
} else {
url.searchParams.delete(name);
history.pushState({}, '', url);
// console.log('url:', url);
// pushState({}, '', url.search);
// pushState(url.href, {});
// replaceState(url.href, {});
let message = {name: null};
window.parent.postMessage(message, "*");
}
// console.log('Message sent to parent (iframe):', message);
}
function create_a_element({account_id, base_url, hosted_file_id, filename=null, extension=null, text="Download", class_li='text-blue-500'}) {
return `${text}`;
}
function create_img_element({account_id, base_url, hosted_file_id, filename=null, extension=null, class_li='max-w-64', style="", inc_link=false}) {
let img_html = '';
if (filename) {
img_html = ``;
} else {
img_html = `
`;
}
if (inc_link) {
let a_html = create_a_element({account_id: account_id, base_url: base_url, hosted_file_id: hosted_file_id, filename: filename, extension: extension});
img_html = `