import { GetLicenseStatusRequest, GetLicenseStatusResponse, LICENSE_STATUS_PATH, LicenseActiveRequest, LicenseActiveResponse, LICENSE_ACTIVE_PATH, } from '../server/api-types.js'; import {assertBoolean, assertObject, assertString} from './asserts.js'; import type {SimpleFetch} from './simple-fetch.js'; import type {LogContext} from '@rocicorp/logger'; // licenseActive throws on non-200 and unparsable responses. export async function licenseActive( mustFetch: SimpleFetch, serverURL: URL, key: string, profileID: string, lc: LogContext, ): Promise { lc = lc.withContext('licenseActive'); const url: URL = new URL(LICENSE_ACTIVE_PATH, serverURL); const req: LicenseActiveRequest = { licenseKey: key, profileID, }; // TODO we should probably extract this fetch functionality into a common // call that has uniform error handling across client calls. const reqString = JSON.stringify(req); lc.debug?.(`Sending ${url}`, reqString); // TODO use a sensible timeout const response = await mustFetch('post', url.toString(), reqString, { // eslint-disable-next-line @typescript-eslint/naming-convention 'Content-Type': 'application/json', // eslint-disable-next-line @typescript-eslint/naming-convention 'Accept': 'application/json', }); const responseBody = await response.text(); lc.debug?.(`Got ${url}`, responseBody); const res: LicenseActiveResponse = JSON.parse(responseBody); assertLicenseActiveResponse(res); } export async function getLicenseStatus( mustFetch: SimpleFetch, serverURL: URL, key: string, lc: LogContext, ): Promise { lc = lc.withContext('getLicenseStatus'); const url: URL = new URL(LICENSE_STATUS_PATH, serverURL); const req: GetLicenseStatusRequest = { licenseKey: key, }; // TODO use a sensible timeout // TODO Probably better to pass the key in the url eg /license/:key, // that way this could be a GET. GET can't have a request body. const reqString = JSON.stringify(req); lc.debug?.(`Sending ${url}`, reqString); const response = await mustFetch('post', url.toString(), reqString, { // eslint-disable-next-line @typescript-eslint/naming-convention 'Content-Type': 'application/json', // eslint-disable-next-line @typescript-eslint/naming-convention 'Accept': 'application/json', }); const responseBody = await response.text(); lc.debug?.(`Got ${url}`, responseBody); const res: GetLicenseStatusResponse = JSON.parse(responseBody); assertGetLicenseStatusResponse(res); return res; } function assertLicenseActiveResponse( // eslint-disable-next-line @typescript-eslint/no-explicit-any v: any, ): asserts v is LicenseActiveResponse { assertObject(v); } function assertGetLicenseStatusResponse( // eslint-disable-next-line @typescript-eslint/no-explicit-any v: any, ): asserts v is GetLicenseStatusResponse { assertObject(v); // We don't assert a more specific type because the server could return // enum values that we don't understand. assertString(v.status); assertBoolean(v.disable); assertBoolean(v.pleaseUpdate); }