Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add apiVersion to config and httpd request
Sebastian Martinez committed 2 years ago
commit 2fc03f33129a1319e01a0c6cbefaa2c6991bd221
parent f5a28960bdc73d80ac3bdf007a72c316039c6da8
10 files changed +48 -8
modified httpd-client/index.ts
@@ -103,6 +103,7 @@ const nodeInfoSchema = object({
  message: string(),
  service: string(),
  version: string(),
+
  apiVersion: string(),
  nid: string(),
  path: string(),
  links: array(
modified httpd-client/lib/fetcher.ts
@@ -3,6 +3,9 @@

import type { ZodIssue, ZodType, TypeOf } from "zod";

+
import { config } from "@app/lib/config";
+
import { compare } from "compare-versions";
+

export interface BaseUrl {
  hostname: string;
  port: number;
@@ -40,16 +43,41 @@ export class ResponseError extends Error {
export class ResponseParseError extends Error {
  public method: string;
  public body: unknown;
+
  public description: string;
+
  public apiVersion: string | undefined;
  public zodIssues: ZodIssue[];
  public path?: string;

  public constructor(
    method: string,
    body: unknown,
+
    apiVersion: string | undefined,
    zodIssues: ZodIssue[],
    path?: string,
  ) {
    super("Failed to parse response body");
+

+
    let description: string;
+
    if (
+
      apiVersion === undefined ||
+
      compare(apiVersion, config.nodes.apiVersion, "<")
+
    ) {
+
      description = `The node you are fetching from seems to be outdated, make sure the httpd API version is at least ${config.nodes.apiVersion} currently ${apiVersion ?? "unknown"}.`;
+
    } else if (
+
      config.nodes.apiVersion === undefined ||
+
      compare(apiVersion, config.nodes.apiVersion, ">")
+
    ) {
+
      description = `The web client you are using is outdated, make sure it supports at least ${apiVersion} to interact with this node currently ${config.nodes.apiVersion ?? "unknown"}.`;
+
    } else {
+
      description =
+
        "This is usually due to a version mismatch between the seed and the web interface.";
+
    }
+
    this.apiVersion = apiVersion;
+
    this.description =
+
      "The response received from the seed does not match the expected schema.<br/>".concat(
+
        description,
+
      );
+

    this.method = method;
    this.path = path;
    this.body = body;
@@ -93,8 +121,7 @@ export class Fetcher {
  ): Promise<TypeOf<T>> {
    const response = await this.fetch({
      ...params,
-
      // eslint-disable-next-line @typescript-eslint/naming-convention
-
      query: { ...params.query, bust_cache: "1" },
+
      query: { ...params.query, v: config.nodes.apiVersion },
    });

    if (!response.ok) {
@@ -112,9 +139,12 @@ export class Fetcher {
    if (result.success) {
      return result.data;
    } else {
+
      const response = await this.fetch({ method: "GET" });
+
      const info = await response.json();
      throw new ResponseParseError(
        params.method,
        responseBody,
+
        info.apiVersion,
        result.error.errors,
        params.path,
      );
modified package-lock.json
@@ -15,6 +15,7 @@
        "baconjs": "^3.0.17",
        "bs58": "^5.0.0",
        "buffer": "^6.0.3",
+
        "compare-versions": "^6.1.0",
        "dompurify": "^3.0.11",
        "hast-util-to-dom": "^4.0.0",
        "hast-util-to-html": "^9.0.0",
@@ -1880,6 +1881,11 @@
        "node": ">= 12"
      }
    },
+
    "node_modules/compare-versions": {
+
      "version": "6.1.0",
+
      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz",
+
      "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg=="
+
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
modified package.json
@@ -53,6 +53,7 @@
    "baconjs": "^3.0.17",
    "bs58": "^5.0.0",
    "buffer": "^6.0.3",
+
    "compare-versions": "^6.1.0",
    "dompurify": "^3.0.11",
    "hast-util-to-dom": "^4.0.0",
    "hast-util-to-html": "^9.0.0",
modified src/config.json
@@ -1,6 +1,7 @@
{
  "nodes": {
    "fallbackPublicExplorer": "https://app.radicle.xyz/nodes/$host/$rid$path",
+
    "apiVersion": "0.1.0",
    "defaultHttpdPort": 443,
    "defaultLocalHttpdPort": 8080,
    "defaultHttpdHostname": "seed.radicle.garden",
modified src/lib/config.ts
@@ -4,6 +4,7 @@ import configJson from "@app/config.json";

export interface Config {
  nodes: {
+
    apiVersion: string;
    fallbackPublicExplorer: string;
    defaultHttpdPort: number;
    defaultHttpdHostname: string;
@@ -21,6 +22,7 @@ function getConfig(): Config {
    return {
      nodes: {
        fallbackPublicExplorer: "https://app.radicle.xyz/nodes/$host/$rid$path",
+
        apiVersion: "0.1.0",
        defaultHttpdHostname: "127.0.0.1",
        defaultHttpdPort: 8081,
        defaultLocalHttpdPort: 8081,
modified src/views/home/error.ts
@@ -12,8 +12,7 @@ export function handleError(
    return {
      error,
      title: "Could not parse the request",
-
      description:
-
        "The response received from the seed does not match the expected schema, this is usually due to a version mismatch between the seed and the web interface.",
+
      description: error.description,
    };
  } else if (error instanceof ResponseError) {
    return {
modified src/views/nodes/error.ts
@@ -11,8 +11,7 @@ export function handleError(
      params: {
        error,
        title: "Could not parse the request",
-
        description:
-
          "The response received from the seed does not match the expected schema, this is usually due to a version mismatch between the seed and the web interface.",
+
        description: error.description,
      },
    };
  } else if (error instanceof ResponseError) {
modified src/views/projects/error.ts
@@ -43,8 +43,7 @@ export function handleError(
      params: {
        error,
        title: "Could not parse the request",
-
        description:
-
          "The response received from the seed does not match the expected schema, this is usually due to a version mismatch between the seed and the web interface.",
+
        description: error.description,
      },
    };
  } else if (
modified tests/support/fixtures.ts
@@ -77,6 +77,7 @@ export const test = base.extend<{
            nodes: {
              fallbackPublicExplorer:
                "https://app.radicle.xyz/nodes/$host/$rid$path",
+
              apiVersion: "0.1.0",
              defaultHttpdPort: 8081,
              defaultHttpdHostname: "127.0.0.1",
              defaultLocalHttpdPort: 8081,
@@ -214,6 +215,7 @@ export function appConfigWithFixture(defaultLocalHttpdPort = 8081) {
  window.APP_CONFIG = {
    nodes: {
      fallbackPublicExplorer: "https://app.radicle.xyz/nodes/$host/$rid$path",
+
      apiVersion: "0.1.0",
      defaultHttpdPort: 8081,
      defaultHttpdHostname: "127.0.0.1",
      defaultLocalHttpdPort,