aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/pages/api/binaries/version.ts
blob: 339a34d470eb7d99e52ee99ef8d81d540176c98c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import type { NextRequest } from "next/server";

const REGISTRY = "https://registry.npmjs.org";
const DEFAULT_TAG = "latest";
const SUPPORTED_PACKAGES = ["turbo"];
const SUPPORTED_METHODS = ["GET"];
const [DEFAULT_NAME] = SUPPORTED_PACKAGES;

async function fetchDistTags({ name }: { name: string }) {
  const result = await fetch(`${REGISTRY}/${name}`);
  const json = await result.json();
  return json["dist-tags"];
}

function errorResponse({
  status,
  message,
}: {
  status: 400 | 404 | 500;
  message: string;
}) {
  return new Response(
    JSON.stringify({
      error: message,
    }),
    {
      status,
    }
  );
}

/*
This API is called via the turbo rust binary to check for version updates.

Response Schema (200):
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
        },
        "version": {
            "type": "string",
        },
        "tag": {
            "type": "string",
        }
    }
}

Errors (400 | 404 | 500):
{
    "type": "object",
    "properties": {
        "error": {
            "type": "string",
        }
    }
}

*/
export default async function handler(req: NextRequest) {
  if (!SUPPORTED_METHODS.includes(req.method)) {
    return errorResponse({
      status: 404,
      message: `unsupported method - ${req.method}`,
    });
  }

  try {
    const { searchParams } = new URL(req.url);
    const name = searchParams.get("name") || DEFAULT_NAME;
    const tag = searchParams.get("tag") || DEFAULT_TAG;

    if (!SUPPORTED_PACKAGES.includes(name)) {
      return errorResponse({
        status: 400,
        message: `unsupported package - ${name}`,
      });
    }

    const versions = await fetchDistTags({ name });
    if (!versions || !versions[tag]) {
      return errorResponse({
        status: 404,
        message: `unsupported tag - ${tag}`,
      });
    }

    return new Response(
      JSON.stringify({
        name,
        version: versions[tag],
        tag,
      }),
      {
        status: 200,
        headers: {
          "content-type": "application/json",
          // cache for 15 minutes, and allow stale responses for 5 minutes
          "cache-control": "public, s-maxage=900, stale-while-revalidate=300",
        },
      }
    );
  } catch (e) {
    console.error(e);
    return errorResponse({ status: 500, message: e.message });
  }
}

export const config = {
  runtime: "experimental-edge",
};