import { api } from 'boot/api'; import { merge } from 'lodash'; import { CREATE_TABLE, DELETE_TABLE_BY_ID, LIST_TABLES, FETCH_REMOTE_TABLE, SYNC_TABLE_CONTENT, FETCH_TABLE_BY_ID, INITIAL_SETTINGS, SAVE_API_KEY, REMOVE_API_KEY, FETCH_API_KEY, } from './constants'; import mainState from './state'; import { CreateTablePayload, type Table } from './models'; import { parse, ParseResult } from 'papaparse'; import { getJsonFromHeadersHelper } from 'src/helpers/getJsonFromHeadersHelper'; import { isJSON } from 'src/helpers/isJsonHelper'; async function fetchRemoteDataWithApiKey(sheetId: string) { const url = `https://sheets.googleapis.com/v4/spreadsheets/${sheetId}?key=${mainState.apiKey.value}`; const responseInfo = await api.fetchRemoteTable(url); if (responseInfo.error) { return { error: responseInfo.error }; } const isResponseInfoJson = isJSON(responseInfo.response.data); if (!isResponseInfoJson) { return { error: 'Data is not valid JSON' }; } const parsedData = JSON.parse(responseInfo.response.data); if (parsedData.error) { return { error: parsedData.error.message || 'File is not accessible' }; } const sheetTabName = parsedData.sheets[0]?.properties?.title || 'Sheet1'; const outputUrl = `https://sheets.googleapis.com/v4/spreadsheets/${sheetId}/values/${sheetTabName}?key=${mainState.apiKey.value}`; const responseData = await api.fetchRemoteTable(outputUrl); if (responseData.error) { return { error: responseData.error }; } const isResponseDataJson = isJSON(responseData.response.data); if (!isResponseDataJson) { return { error: 'Data is not valid JSON' }; } const parsedRespData = JSON.parse(responseData.response.data); if (parsedRespData.error) { return { error: parsedRespData.error.message }; } responseData.response.data = getJsonFromHeadersHelper(parsedRespData.values); return { response: responseData.response }; } async function fetchRemoteData(sheetId: string) { const url = `https://docs.google.com/spreadsheets/d/${sheetId}/gviz/tq?tqx=out:csv`; const { response, error } = await api.fetchRemoteTable(url); if (error) { return { error }; } const parsedContent: ParseResult = parse(response.data, { header: true, // Use the first row as header keys for JSON dynamicTyping: true, // Automatically convert values to their types }); return { response: parsedContent }; } export default { async [LIST_TABLES]({ search, perPage, page, order, orderby, }: { search: string; perPage: number; page: number; order?: 'ASC' | 'DESC'; orderby?: string; }) { const { response, error } = await api.listTables({ page, perPage, search, order, orderby, }); if (error) { return { error }; } const tables = response.data?.tables.map((el: Table) => { const settingsInStore = JSON.stringify(INITIAL_SETTINGS); const initialSettings = JSON.parse(settingsInStore); const settings = merge(initialSettings, el.settings); return { ...el, shortcode: `[livesheets id=${el.id}]`, settings: { ...settings }, }; }); mainState.tables.value = tables; mainState.totalPerQuery.value = response.data?.total; if (!search) { mainState.totalInDb.value = response.data?.total; } return { response }; }, async [FETCH_TABLE_BY_ID](id: string) { const { response, error } = await api.fetchTableById(id); if (error) { return { error }; } const { content, source, settings } = response.data; const settingsInStore = JSON.stringify(INITIAL_SETTINGS); const initialSettings = JSON.parse(settingsInStore); const mergedSettings = merge(initialSettings, settings); response.data = { ...response.data, shortcode: `[livesheets id=${response.data.id}]`, settings: { ...mergedSettings }, content, source, }; return { response }; }, async [SYNC_TABLE_CONTENT](payload: { id: string; title: string; content: Record; }) { const { response, error } = await api.syncTableContent(payload); if (error) { return { error }; } return { response }; }, async [DELETE_TABLE_BY_ID](id: string) { const { error } = await api.deleteTableById(id); if (error) { return { error }; } mainState.tables.value = mainState.tables.value.filter( (table: Table) => Number(table.id) !== Number(id) ); if (!mainState.tables.value.length) { mainState.totalInDb.value = 0; } }, async [CREATE_TABLE](payload: CreateTablePayload) { const { response, error } = await api.createTable(payload); if (error) { return { error }; } return { response }; }, async [FETCH_REMOTE_TABLE](sheetId: string) { // WITH API KEY if (mainState.apiKey.value) { const resp = await fetchRemoteDataWithApiKey(sheetId); if (resp.error) { return await fetchRemoteData(sheetId); } return resp; } // WITHOUT API KEY return await fetchRemoteData(sheetId); }, async [SAVE_API_KEY](apiKey: string) { const { response, error } = await api.saveApiKey(apiKey); if (error) { return { error }; } return { response }; }, async [FETCH_API_KEY]() { const { response, error } = await api.fetchApiKey(); if (error) { return { error }; } return { response }; }, async [REMOVE_API_KEY]() { const { response, error } = await api.removeApiKey(); if (error) { return { error }; } return { response }; }, };