import dayjs from 'dayjs'; type key_val = { [key: string]: any; }; export let iso_datetime_formatter = function iso_datetime_formatter(raw_datetime: string|Date, named_format: string) { // console.log('*** iso_datetime_formatter() ***'); // https://en.wikipedia.org/wiki/ISO_8601 // https://day.js.org/docs/en/display/format // ISO 8601-1:2019 includes the T before the time portion // ISO 8601-1:2019 midnight may only be referred to as "00:00", corresponding to the beginning of a calendar day // and "24:00" is no longer allowed corresponding to the end of a day // 60 is only used to denote an added leap second // ISO 8601 UTC: 2021-03-04T19:04:44+00:00 // ISO 8601 UTC: 2021-03-04T19:04:44Z // ISO 8601 UTC: 20210304T190444Z //datetime_iso 'YYYY-MM-DD HH:mm:ss' //datetime_iso_12 'YYYY-MM-DD hh:mm:ss A' //datetime_iso_12_short 'YY-MM-DD hh:mm A' //datetime_iso_tz 'YYYY-MM-DD HH:mm:ss' //datetime_long 'dddd, MMMM D, YYYY hh:mm:ss A' //datetime_medium 'ddd, MMM D, YYYY hh:mm:ss A' //datetime_short 'MMM D, YY hh:mm A' //date_iso 'YYYY-MM-DD' //date_long 'dddd, MMMM D, YYYY' //date_medium 'ddd, MMM D, YYYY' //date_short 'MMM D, YY' //time_iso 'HH:mm:ss' //time_iso_12 'hh:mm:ss A' //time_long 'hh:mm:ss A' //time_medium 'h:m:s A' //time_short 'hh:mm A' //dayjs(raw_datetime).format('dddd, MMMM D, YYYY hh:mm:ss A'); if (!raw_datetime) { raw_datetime = new Date(); // Get the current datetime if one was not passed. } let datetime_string = null; switch (named_format) { case 'datetime_iso': datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm:ss'); break; case 'datetime_iso_no_seconds': datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm'); break; case 'datetime_iso_12_short': datetime_string = dayjs(raw_datetime).format('YY-MM-DD hh:mm A'); break; case 'datetime_iso_12_short_month': datetime_string = dayjs(raw_datetime).format('MM-DD hh:mm A'); break; case 'datetime_short': datetime_string = dayjs(raw_datetime).format('MMM D, YY hh:mm A'); break; case 'datetime_medium': datetime_string = dayjs(raw_datetime).format('MMM D, YYYY h:mm A'); break; case 'datetime_long': datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY hh:mm A'); break; case 'datetime_short_month': datetime_string = dayjs(raw_datetime).format('MMM D hh:mm A'); break; case 'datetime_long_month': datetime_string = dayjs(raw_datetime).format('MMMM D hh:mm A'); break; case 'datetime_short_day': datetime_string = dayjs(raw_datetime).format('D hh:mm A'); break; case 'date_iso': datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD'); break; case 'date_long_month_day': datetime_string = dayjs(raw_datetime).format('MMMM D'); break; case 'date_short': datetime_string = dayjs(raw_datetime).format('MMM D, YY'); break; case 'date_short_no_year': datetime_string = dayjs(raw_datetime).format('MMM D'); break; case 'date_long': datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY'); break; case 'date_full': datetime_string = dayjs(raw_datetime).format('dddd, MMMM D, YYYY'); break; case 'date_full_no_year': datetime_string = dayjs(raw_datetime).format('dddd, MMMM D'); break; case 'time_iso': datetime_string = dayjs(raw_datetime).format('HH:mm:ss'); break; case 'time_long': datetime_string = dayjs(raw_datetime).format('hh:mm:ss A'); break; case 'time_short': datetime_string = dayjs(raw_datetime).format('hh:mm A'); break; case 'time_short_no_leading': datetime_string = dayjs(raw_datetime).format('h:mm A'); break; case 'week_long': datetime_string = dayjs(raw_datetime).format('dddd'); break; case 'week_medium': datetime_string = dayjs(raw_datetime).format('ddd'); break; case 'week_short': datetime_string = dayjs(raw_datetime).format('dd'); break; default: console.log(`The named format passed (${named_format}) did not match a common name. Trying to format with the named format value.`); datetime_string = dayjs(raw_datetime).format(named_format); // datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm:ss'); } return datetime_string; } /* 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) { console.log('*** process_data_string() ***'); // console.log(data_string); let obj = {}; 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 } // NOTE: I know there is a better more efficient way to do this, but I don't have time for that right now. export let process_permission_checks = function process_permission_checks(access_type: string) { // let access_checks = { 'access_type': null, 'super_check': null }; let access_checks: key_val = {}; if (access_type == 'super') { access_checks.access_type = 'super'; access_checks.super_check = true; access_checks.manager_check = false; access_checks.administrator_check = false; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = false; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = true; access_checks.anonymous_check = false; access_checks.super_access = true; access_checks.manager_access = true; access_checks.administrator_access = true; access_checks.support_access = true; access_checks.assistant_access = true; access_checks.trusted_access = true; access_checks.verified_access = true; access_checks.provisional_access = true; access_checks.public_access = true; access_checks.authenticated_access = true; access_checks.anonymous_access = true; } else if (access_type == 'manager') { access_checks.access_type = 'manager'; access_checks.super_check = false; access_checks.manager_check = true; access_checks.administrator_check = false; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = false; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = true; access_checks.anonymous_check = false; access_checks.super_access = false; access_checks.manager_access = true; access_checks.administrator_access = true; access_checks.support_access = true; access_checks.assistant_access = true; access_checks.trusted_access = true; access_checks.verified_access = true; access_checks.provisional_access = true; access_checks.public_access = true; access_checks.authenticated_access = true; access_checks.anonymous_access = true; } else if (access_type == 'administrator') { access_checks.access_type = 'administrator'; access_checks.super_check = false; access_checks.manager_check = false; access_checks.administrator_check = true; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = false; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = false; access_checks.anonymous_check = false; access_checks.super_access = false; access_checks.manager_access = false; access_checks.administrator_access = true; access_checks.support_access = true; access_checks.assistant_access = true; access_checks.trusted_access = true; access_checks.verified_access = true; access_checks.provisional_access = true; access_checks.public_access = true; access_checks.authenticated_access = true; access_checks.anonymous_access = true; } else if (access_type == 'trusted') { access_checks.access_type = 'trusted'; access_checks.super_check = false; access_checks.manager_check = false; access_checks.administrator_check = false; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = true; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = true; access_checks.anonymous_check = false; access_checks.super_access = false; access_checks.manager_access = false; access_checks.administrator_access = false; access_checks.support_access = false; access_checks.assistant_access = false; access_checks.trusted_access = true; access_checks.verified_access = true; access_checks.provisional_access = true; access_checks.public_access = true; access_checks.authenticated_access = true; access_checks.anonymous_access = true; } else if (access_type == 'authenticated') { access_checks.access_type = 'authenticated'; access_checks.super_check = false; access_checks.manager_check = false; access_checks.administrator_check = false; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = false; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = true; access_checks.anonymous_check = false; access_checks.super_access = false; access_checks.manager_access = false; access_checks.administrator_access = false; access_checks.support_access = false; access_checks.assistant_access = false; access_checks.trusted_access = false; access_checks.verified_access = false; access_checks.provisional_access = false; access_checks.public_access = false; access_checks.authenticated_access = true; access_checks.anonymous_access = true; } else { access_checks.access_type = 'anonymous'; access_checks.super_check = false; access_checks.manager_check = false; access_checks.administrator_check = false; access_checks.support_check = false; access_checks.assistant_check = false; access_checks.trusted_check = false; access_checks.verified_check = false; access_checks.provisional_check = false; access_checks.public_check = false; access_checks.authenticated_check = false; access_checks.anonymous_check = true; access_checks.super_access = false; access_checks.manager_access = false; access_checks.administrator_access = false; access_checks.support_access = false; access_checks.assistant_access = false; access_checks.trusted_access = false; access_checks.verified_access = false; access_checks.provisional_access = false; access_checks.public_access = false; access_checks.authenticated_access = false; access_checks.anonymous_access = true; } return access_checks; } // 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 = `
${img_html}${a_html}
`; } return img_html; } function create_video_element({account_id, base_url, hosted_file_id, filename=null, extension=null, class_li='max-w-64', inc_link=false}) { let video_html = ''; if (filename) { video_html = ``; } else { video_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}); video_html = `
${video_html}${a_html}
`; } return video_html; } // // Clear the quick access type // function clear_access_type() { // // NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar. // window.localStorage.setItem('access_type', 'anonymous'); // // $ae_loc.access_type = null; // 'anonymous'; // $ae_loc.access_type = 'anonymous'; // trigger = 'process_permission_check'; // show_passcode_input = false; // // $ae_loc = $ae_loc; // Trigger Svelte just in case // // ae_loc.set($ae_loc); // // console.log($ae_loc); // return true; // } // This function will take a long string (sentences or paraghraphs) of text and return an estimated number of words. function count_words(text: string) { if (!text && text.length < 1) { return false; } let count = text.trim().split(/\s+/).length; return count; } export let ae_util = { iso_datetime_formatter: iso_datetime_formatter, number_w_commas: number_w_commas, extract_prefixed_form_data: extract_prefixed_form_data, process_data_string: process_data_string, process_permission_checks: process_permission_checks, handle_url_and_message: handle_url_and_message, create_a_element: create_a_element, create_img_element: create_img_element, create_video_element: create_video_element, count_words: count_words, }; // export default ae_util;