From 532ed1d3f98e635b65a829957d24548fb5b8ca9e Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 3 Apr 2024 23:18:39 +0300 Subject: [PATCH] server-ts: Port services/setup --- src/becca/entities/boption.ts | 2 +- src/services/api-interface.ts | 17 +++++++++++++++ src/services/options.ts | 2 +- src/services/request.ts | 4 ++-- src/services/request_interface.ts | 4 ++-- src/services/{setup.js => setup.ts} | 33 +++++++++++++++-------------- src/services/sync.ts | 2 +- webpack.config.js | 2 +- 8 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 src/services/api-interface.ts rename src/services/{setup.js => setup.ts} (75%) diff --git a/src/becca/entities/boption.ts b/src/becca/entities/boption.ts index 48abee024..c67d391e1 100644 --- a/src/becca/entities/boption.ts +++ b/src/becca/entities/boption.ts @@ -13,7 +13,7 @@ class BOption extends AbstractBeccaEntity { static get hashedProperties() { return ["name", "value"]; } name!: string; - value!: string; + value!: string | number; isSynced!: boolean; constructor(row?: OptionRow) { diff --git a/src/services/api-interface.ts b/src/services/api-interface.ts new file mode 100644 index 000000000..30c248693 --- /dev/null +++ b/src/services/api-interface.ts @@ -0,0 +1,17 @@ +import { OptionRow } from "../becca/entities/rows"; + +/** + * Response for /api/setup/status. + */ +export interface SetupStatusResponse { + syncVersion: number; + schemaExists: boolean; +} + +/** + * Response for /api/setup/sync-seed. + */ +export interface SetupSyncSeedResponse { + syncVersion: number; + options: OptionRow[] +} \ No newline at end of file diff --git a/src/services/options.ts b/src/services/options.ts index a7b5ad475..d2c413b51 100644 --- a/src/services/options.ts +++ b/src/services/options.ts @@ -51,7 +51,7 @@ function getOptionBool(name: string): boolean { return val === 'true'; } -function setOption(name: string, value: string | boolean) { +function setOption(name: string, value: string | number | boolean) { if (value === true || value === false) { value = value.toString(); } diff --git a/src/services/request.ts b/src/services/request.ts index 9922e4b2d..d4a17ad4e 100644 --- a/src/services/request.ts +++ b/src/services/request.ts @@ -33,7 +33,7 @@ interface Client { request(opts: ClientOpts): Request; } -function exec(opts: ExecOpts) { +function exec(opts: ExecOpts): Promise { const client = getClient(opts); // hack for cases where electron.net does not work, but we don't want to set proxy @@ -129,7 +129,7 @@ function exec(opts: ExecOpts) { : opts.body; } - request.end(payload); + request.end(payload as string); } catch (e: any) { reject(generateError(opts, e.message)); diff --git a/src/services/request_interface.ts b/src/services/request_interface.ts index 4ba1da0a7..45f9defa1 100644 --- a/src/services/request_interface.ts +++ b/src/services/request_interface.ts @@ -3,7 +3,7 @@ export interface CookieJar { } export interface ExecOpts { - proxy: "noproxy" | null; + proxy: "noproxy" | string | null; method: string; url: string; paging?: { @@ -16,5 +16,5 @@ export interface ExecOpts { password?: string; }, timeout: number; - body: string; + body?: string | {}; } \ No newline at end of file diff --git a/src/services/setup.js b/src/services/setup.ts similarity index 75% rename from src/services/setup.js rename to src/services/setup.ts index 9c5d0c0c4..3d7706dba 100644 --- a/src/services/setup.js +++ b/src/services/setup.ts @@ -1,15 +1,16 @@ -const syncService = require('./sync'); -const log = require('./log'); -const sqlInit = require('./sql_init'); -const optionService = require('./options'); -const syncOptions = require('./sync_options'); -const request = require('./request'); -const appInfo = require('./app_info'); -const utils = require('./utils'); -const becca = require('../becca/becca'); +import syncService = require('./sync'); +import log = require('./log'); +import sqlInit = require('./sql_init'); +import optionService = require('./options'); +import syncOptions = require('./sync_options'); +import request = require('./request'); +import appInfo = require('./app_info'); +import utils = require('./utils'); +import becca = require('../becca/becca'); +import { SetupStatusResponse, SetupSyncSeedResponse } from './api-interface'; async function hasSyncServerSchemaAndSeed() { - const response = await requestToSyncServer('GET', '/api/setup/status'); + const response = await requestToSyncServer('GET', '/api/setup/status'); if (response.syncVersion !== appInfo.syncVersion) { throw new Error(`Could not setup sync since local sync protocol version is ${appInfo.syncVersion} while remote is ${response.syncVersion}. To fix this issue, use same Trilium version on all instances.`); @@ -32,7 +33,7 @@ function triggerSync() { async function sendSeedToSyncServer() { log.info("Initiating sync to server"); - await requestToSyncServer('POST', '/api/setup/sync-seed', { + await requestToSyncServer('POST', '/api/setup/sync-seed', { options: getSyncSeedOptions(), syncVersion: appInfo.syncVersion }); @@ -43,7 +44,7 @@ async function sendSeedToSyncServer() { optionService.setOption('lastSyncedPull', 0); } -async function requestToSyncServer(method, path, body = null) { +async function requestToSyncServer(method: string, path: string, body?: string | {}): Promise { const timeout = syncOptions.getSyncTimeout(); return await utils.timeLimit(request.exec({ @@ -52,10 +53,10 @@ async function requestToSyncServer(method, path, body = null) { body, proxy: syncOptions.getSyncProxy(), timeout: timeout - }), timeout); + }), timeout) as T; } -async function setupSyncFromSyncServer(syncServerHost, syncProxy, password) { +async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string, password: string) { if (sqlInit.isDbInitialized()) { return { result: 'failure', @@ -67,7 +68,7 @@ async function setupSyncFromSyncServer(syncServerHost, syncProxy, password) { log.info("Getting document options FROM sync server."); // the response is expected to contain documentId and documentSecret options - const resp = await request.exec({ + const resp = await request.exec({ method: 'get', url: `${syncServerHost}/api/setup/sync-seed`, auth: { password }, @@ -92,7 +93,7 @@ async function setupSyncFromSyncServer(syncServerHost, syncProxy, password) { return { result: 'success' }; } - catch (e) { + catch (e: any) { log.error(`Sync failed: '${e.message}', stack: ${e.stack}`); return { diff --git a/src/services/sync.ts b/src/services/sync.ts index 11978cade..8c8183984 100644 --- a/src/services/sync.ts +++ b/src/services/sync.ts @@ -107,7 +107,7 @@ async function sync() { } async function login() { - const setupService = require('./setup.js'); // circular dependency issue + const setupService = require('./setup'); // circular dependency issue if (!await setupService.hasSyncServerSchemaAndSeed()) { await setupService.sendSeedToSyncServer(); diff --git a/webpack.config.js b/webpack.config.js index 41077c00e..2e3bd7b17 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,7 +4,7 @@ const assetPath = require('./src/services/asset_path'); module.exports = { mode: 'production', entry: { - setup: './src/public/app/setup.js', + setup: './src/public/app/setup.ts', mobile: './src/public/app/mobile.js', desktop: './src/public/app/desktop.js', },