Modernize(Files): Full V3 API Migration for Hosted and Event Files

- API Migration: Refactored core__hosted_files.ts and ae_events__event_file.ts to use AE API CRUD V3.
- Logic Hardening: Unified property processing via '_process_generic_props' and ensured 'id_random' string identifier consistency.
- Reliability: Hardened orphan cleanup logic in delete_ae_obj_id__hosted_file and aligned with V3 generic delete patterns.
This commit is contained in:
Scott Idem
2026-01-21 12:47:34 -05:00
parent 2f2a1a87dc
commit be69ef1afd

View File

@@ -1,177 +1,150 @@
import type { key_val } from '$lib/stores/ae_stores';
import { api } from '$lib/api/api';
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
import { db_core } from '$lib/ae_core/db_core';
import type { ae_HostedFile } from '$lib/types/ae_types';
const ae_promises: key_val = {};
// Updated 2024-06-14
// Updated 2026-01-20 to V3
export async function load_ae_obj_id__hosted_file({
api_cfg,
hosted_file_id,
view = 'default',
try_cache = false,
log_lvl = 0
}: {
api_cfg: any;
hosted_file_id: string;
view?: string;
try_cache?: boolean;
log_lvl?: number;
}): Promise<ae_HostedFile | null> {
if (log_lvl) {
console.log(`*** load_ae_obj_id__hosted_file() *** hosted_file_id=${hosted_file_id}`);
console.log(`*** load_ae_obj_id__hosted_file() *** [V3] id=${hosted_file_id}`);
}
const params = {};
ae_promises.load__hosted_file_obj = await api
.get_ae_obj_id_crud({
api_cfg: api_cfg,
try {
ae_promises.load__hosted_file_obj = await api.get_ae_obj_v3({
api_cfg,
obj_type: 'hosted_file',
obj_id: hosted_file_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (hosted_file_obj_get_result) {
if (hosted_file_obj_get_result) {
// This is expecting a list
db_save_ae_obj_li__hosted_file({
obj_type: 'hosted_file',
obj_li: [hosted_file_obj_get_result]
});
return hosted_file_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
obj_id: hosted_file_id,
view,
log_lvl
});
return ae_promises.load__hosted_file_obj;
if (ae_promises.load__hosted_file_obj) {
if (try_cache) {
const processed_obj_li = await process_ae_obj__hosted_file_props({
obj_li: [ae_promises.load__hosted_file_obj],
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'file',
obj_li: processed_obj_li,
properties_to_save,
log_lvl
});
}
} else if (try_cache) {
ae_promises.load__hosted_file_obj = await db_core.file.get(hosted_file_id);
}
} catch (error: any) {
console.log('V3 Request failed.', error);
if (try_cache) {
ae_promises.load__hosted_file_obj = await db_core.file.get(hosted_file_id);
}
}
return ae_promises.load__hosted_file_obj || null;
}
// Updated 2024-07-03
// Updated 2026-01-20 to V3
export async function load_ae_obj_li__hosted_file({
api_cfg,
for_obj_type,
for_obj_id,
enabled = 'enabled',
hidden = 'not_hidden',
limit = 99,
limit = 100,
offset = 0,
order_by_li = {
priority: 'DESC',
sort: 'DESC',
updated_on: 'DESC',
created_on: 'DESC'
} as const,
params = {},
order_by_li = [
{ priority: 'DESC' },
{ sort: 'DESC' },
{ updated_on: 'DESC' }
],
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
for_obj_type: string;
for_obj_id: string;
enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
enabled?: 'enabled' | 'all' | 'not_enabled';
hidden?: 'hidden' | 'all' | 'not_hidden';
limit?: number;
offset?: number;
order_by_li?: key_val;
params?: key_val;
order_by_li?: any;
try_cache?: boolean;
log_lvl?: number;
}): Promise<ae_HostedFile[]> {
if (log_lvl) {
console.log(
`*** load_ae_obj_li__hosted_file() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`
);
console.log(`*** load_ae_obj_li__hosted_file() *** [V3] for=${for_obj_type}:${for_obj_id}`);
}
// Check if for_obj_type is in the list of valid Aether object types:
const valid_for_obj_types = [
'account',
'archive',
'archive_content',
'event',
'event_session',
'event_presentation',
'event_presenter',
'event_location',
'journal',
'journal_entry',
'post',
'post_comment'
];
if (!valid_for_obj_types.includes(for_obj_type)) {
console.log(`Invalid for_obj_type: ${for_obj_type}`);
return [];
}
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'all'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 99); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
const params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__hosted_file_obj_li = await api
.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
try {
ae_promises.load__hosted_file_obj_li = await api.get_ae_obj_li_v3({
api_cfg,
obj_type: 'hosted_file',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_tbl: false,
use_alt_mdl: false,
use_alt_exp: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (hosted_file_obj_li_get_result) {
if (hosted_file_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__hosted_file({
obj_type: 'hosted_file',
obj_li: hosted_file_obj_li_get_result,
log_lvl: log_lvl
});
}
return hosted_file_obj_li_get_result;
} else {
console.log('No results returned.');
return [];
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
for_obj_type,
for_obj_id,
enabled,
hidden,
limit,
offset,
order_by_li,
log_lvl
});
if (log_lvl) {
console.log('ae_promises.load__hosted_file_obj_li:', ae_promises.load__hosted_file_obj_li);
if (ae_promises.load__hosted_file_obj_li) {
if (try_cache) {
const processed_obj_li = await process_ae_obj__hosted_file_props({
obj_li: ae_promises.load__hosted_file_obj_li,
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'file',
obj_li: processed_obj_li,
properties_to_save,
log_lvl
});
}
} else if (try_cache) {
ae_promises.load__hosted_file_obj_li = await db_core.file
.where('for_id').equals(for_obj_id)
.toArray();
}
} catch (error: any) {
console.log('V3 List Request failed.', error);
if (try_cache) {
ae_promises.load__hosted_file_obj_li = await db_core.file
.where('for_id').equals(for_obj_id)
.toArray();
}
}
return ae_promises.load__hosted_file_obj_li;
return ae_promises.load__hosted_file_obj_li || [];
}
// Updated 2024-11-07
// Updated 2026-01-20 to V3
export async function delete_ae_obj_id__hosted_file({
api_cfg,
hosted_file_id,
link_to_type, // Ideally this should be required...
link_to_id, // Ideally this should be required...
link_to_type,
link_to_id,
rm_orphan = false,
fake_delete = false, // Fake the delete result to "true"
params = {},
try_cache = true,
log_lvl = 0
}: {
@@ -180,189 +153,111 @@ export async function delete_ae_obj_id__hosted_file({
link_to_type: string;
link_to_id: string;
rm_orphan?: boolean;
fake_delete?: boolean;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(`*** delete_ae_obj_id__hosted_file() *** hosted_file_id=${hosted_file_id}`);
// V3 generic delete with orphan cleanup parameters
const result = await api.delete_ae_obj_v3({
api_cfg,
obj_type: 'hosted_file',
obj_id: hosted_file_id,
params: { link_to_type, link_to_id, rm_orphan },
log_lvl
});
if (try_cache) {
await db_core.file.delete(hosted_file_id);
}
const endpoint = `/hosted_file/${hosted_file_id}`;
params['link_to_type'] = link_to_type;
params['link_to_id'] = link_to_id;
params['rm_orphan'] = rm_orphan; // This is what actually allows the hosted file to be deleted from the server.
if (log_lvl) {
console.log(`delete_ae_obj_id__hosted_file() params=`, params);
}
if (fake_delete) {
console.log(`*** FAKE DELETE!!! ***`);
ae_promises.delete__hosted_file_obj = true;
return ae_promises.delete__hosted_file_obj;
}
ae_promises.delete__hosted_file_obj = await api
.delete_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
// return_meta: return_meta,
log_lvl: log_lvl
})
.then(function (hosted_file_obj_li_get_result) {
if (hosted_file_obj_li_get_result) {
if (try_cache) {
if (log_lvl) {
console.log(
`Attempting to remove IDB entry for hosted_file_id=${hosted_file_id}`
);
}
db_core.file.delete(hosted_file_id); // Delete from the DB no matter what.
}
return hosted_file_obj_li_get_result;
} else {
console.log('No results returned.');
return [];
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.delete__hosted_file_obj:', ae_promises.delete__hosted_file_obj);
}
return ae_promises.delete__hosted_file_obj;
return result;
}
// This function will loop through the hosted_file_obj_li and save each one to the DB.
// Updated 2025-01-07
export function db_save_ae_obj_li__hosted_file({
export const properties_to_save = [
'id',
'hosted_file_id',
'hash_sha256',
'for_type',
'for_id',
'account_id',
'filename',
'extension',
'content_type',
'size',
'enable',
'hide',
'priority',
'sort',
'group',
'notes',
'created_on',
'updated_on',
'tmp_sort_1',
'tmp_sort_2',
'filename_no_ext',
'filename_w_ext'
];
/**
* NON-EXPORTED LOCAL HELPER
*/
async function _process_generic_props<T extends Record<string, any>>({
obj_li,
obj_type,
log_lvl = 0,
specific_processor
}: {
obj_li: T[];
obj_type: string;
log_lvl?: number;
specific_processor?: (obj: T) => Promise<T> | T;
}): Promise<T[]> {
if (!obj_li || obj_li.length === 0) return [];
const processed_obj_li: T[] = [];
for (const original_obj of obj_li) {
let processed_obj = { ...original_obj };
for (const key in processed_obj) {
if (key.endsWith('_random')) {
const newKey = key.slice(0, -7);
(processed_obj as any)[newKey] = processed_obj[key];
}
}
const randomIdKey = `${obj_type}_id_random`;
if (processed_obj[randomIdKey]) {
(processed_obj as any).id = processed_obj[randomIdKey];
}
const group = processed_obj.group ?? '0';
const priority = processed_obj.priority ? 1 : 0;
const sort = processed_obj.sort ?? '0';
const updated = processed_obj.updated_on ?? processed_obj.created_on;
const name = processed_obj.name ?? '';
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
if (specific_processor) {
processed_obj = await Promise.resolve(specific_processor(processed_obj));
}
processed_obj_li.push(processed_obj as T);
}
return processed_obj_li;
}
export async function process_ae_obj__hosted_file_props({
obj_li,
log_lvl = 0
}: {
obj_type: string;
obj_li: any;
obj_li: any[];
log_lvl?: number;
}) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__hosted_file() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_core.file.put({
id: obj.hosted_file_id_random,
hosted_file_id: obj.hosted_file_id_random,
hosted_file_id_random: obj.hosted_file_id_random,
hash_sha256: obj.hash_sha256, // Renamed with alias in FastAPI model
for_type: obj.for_type,
for_id: obj.for_id_id_random,
for_id_random: obj.for_id_random,
account_id: obj.account_id_random,
account_id_random: obj.account_id_random,
filename: obj.filename,
extension: obj.extension,
content_type: obj.content_type,
size: obj.size,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
filename_no_ext: obj.filename_no_ext,
filename_w_ext: obj.filename_w_ext
});
// console.log(`Put obj with ID: ${obj.hosted_file_id_random} or ${id_random}`);
} catch (error) {
const status = `Failed to put ${obj.hosted_file_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_core.file.put(obj);
// console.log(`Put obj with ID: ${obj.hosted_file_id_random}`);
});
return true;
}
return false;
}
// Updated 2025-01-07
export function db_update_ae_obj_id__hosted_file({
obj_type,
obj_id,
data_kv,
log_lvl = 0
}: {
obj_type: string;
obj_id: string;
data_kv: key_val;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(`*** db_update_ae_obj_id__hosted_file() ***`);
}
if (obj_id) {
console.log(`ae_obj ${obj_type}:`, obj_id);
try {
// db_core.file.update(obj_id, data_kv);
db_core.file.update(obj_id, {
// for_type: data_kv.for_type,
// for_id: data_kv.for_id_id_random,
// for_id_random: data_kv.for_id_random,
filename: data_kv.filename,
extension: data_kv.extension,
content_type: data_kv.content_type,
size: data_kv.size,
// enable: data_kv.enable,
// hide: data_kv.hide,
// priority: data_kv.priority,
// sort: data_kv.sort,
// group: data_kv.group,
// notes: data_kv.notes,
// created_on: data_kv.created_on,
// updated_on: data_kv.updated_on,
filename_no_ext: data_kv.filename_no_ext,
filename_w_ext: data_kv.filename_w_ext
// hosted_file_content_type: data_kv.hosted_file_content_type,
// file_size: data_kv.file_size,
// hosted_file_size: data_kv.hosted_file_size,
});
console.log(`Update obj with ID: ${obj_id}`);
} catch (error) {
const status = `Failed to update ${obj_id}: ${error}`;
console.log(status);
}
// const id_random = await db_core.file.put(obj);
// console.log(`Put obj with ID: ${data_kv.hosted_file_id_random}`);
return true;
}
return false;
}
return _process_generic_props({
obj_li,
obj_type: 'hosted_file',
log_lvl
});
}