123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import secrets from 'secrets';
- import browser from 'webextension-polyfill';
- import { parseJSON } from './helper';
- function queryBuilder(obj) {
- let str = '';
- Object.entries(obj).forEach(([key, value], index) => {
- if (index !== 0) str += `&`;
- str += `${key}=${value}`;
- });
- return str;
- }
- export async function fetchApi(path, options) {
- const urlPath = path.startsWith('/') ? path : `/${path}`;
- const headers = {};
- if (urlPath.startsWith('/me')) {
- let { session } = await browser.storage.local.get('session');
- if (!session) throw new Error('Unauthorized');
- const isExpired = Date.now() > session.expires_at * 1000 - 64000;
- if (isExpired) {
- const response = await fetchApi(
- `/session/refresh?token=${session.refresh_token}`
- );
- const result = await response.json();
- if (!response.ok) throw new Error(result.message);
- session = result;
- await browser.storage.local.set({ session });
- }
- headers.Authorization = `Bearer ${session.access_token}`;
- }
- return fetch(`${secrets.baseApiUrl}${urlPath}`, {
- headers: {
- 'Content-Type': 'application/json',
- ...headers,
- },
- ...options,
- });
- }
- export const googleSheets = {
- getUrl(spreadsheetId, range) {
- return `/services/google-sheets?spreadsheetId=${spreadsheetId}&range=${range}`;
- },
- getValues({ spreadsheetId, range }) {
- const url = this.getUrl(spreadsheetId, range);
- return fetchApi(url);
- },
- getRange({ spreadsheetId, range }) {
- return googleSheets.updateValues({
- range,
- append: true,
- spreadsheetId,
- options: {
- body: JSON.stringify({ values: [] }),
- queries: {
- valueInputOption: 'RAW',
- includeValuesInResponse: false,
- insertDataOption: 'INSERT_ROWS',
- },
- },
- });
- },
- updateValues({ spreadsheetId, range, options = {}, append }) {
- const url = `${this.getUrl(spreadsheetId, range)}&${queryBuilder(
- options?.queries || {}
- )}`;
- return fetchApi(url, {
- ...options,
- method: append ? 'POST' : 'PUT',
- });
- },
- };
- export async function cacheApi(key, callback, useCache = true) {
- const tenMinutes = 1000 * 10;
- const tenMinutesAgo = Date.now() - tenMinutes;
- const timerKey = `cache-time:${key}`;
- const cacheResult = parseJSON(sessionStorage.getItem(key), null);
- const cacheTime = +sessionStorage.getItem(timerKey) || Date.now();
- if (useCache && cacheResult && tenMinutesAgo < cacheTime) {
- return cacheResult;
- }
- const result = await callback();
- let cacheData = result;
- if (result?.cacheData) {
- cacheData = result?.cacheData;
- }
- sessionStorage.setItem(timerKey, Date.now());
- sessionStorage.setItem(key, JSON.stringify(cacheData));
- return result;
- }
- export async function getSharedWorkflows(useCache = true) {
- return cacheApi(
- 'shared-workflows',
- async () => {
- try {
- const response = await fetchApi('/me/workflows/shared?data=all');
- if (response.status !== 200) throw new Error(response.statusText);
- const result = await response.json();
- const sharedWorkflows = result.reduce((acc, item) => {
- item.drawflow = JSON.stringify(item.drawflow);
- item.table = item.table || item.dataColumns || [];
- item.createdAt = new Date(item.createdAt || Date.now()).getTime();
- acc[item.id] = item;
- return acc;
- }, {});
- return sharedWorkflows;
- } catch (error) {
- console.error(error);
- return {};
- }
- },
- useCache
- );
- }
- export async function getUserWorkflows(useCache = true) {
- return cacheApi(
- 'user-workflows',
- async () => {
- try {
- const { lastBackup } = await browser.storage.local.get('lastBackup');
- const response = await fetchApi(
- `/me/workflows?lastBackup=${(useCache && lastBackup) || null}`
- );
- if (!response.ok) throw new Error(response.statusText);
- const result = await response.json();
- const workflows = result.reduce(
- (acc, workflow) => {
- if (workflow.isHost) {
- acc.hosted[workflow.id] = {
- id: workflow.id,
- hostId: workflow.hostId,
- };
- }
- acc.backup.push(workflow);
- return acc;
- },
- { hosted: {}, backup: [] }
- );
- workflows.cacheData = {
- backup: [],
- hosted: workflows.hosted,
- };
- return workflows;
- } catch (error) {
- console.error(error);
- return {};
- }
- },
- useCache
- );
- }
|