save to db
This commit is contained in:
parent
8b987bc589
commit
7874167582
@ -1,5 +1,4 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { Center, Cover, Stack } from "@firebox/components";
|
||||
import { Pico8Console } from "./pico8-client/Pico8Console";
|
||||
import testcarts from "./testcarts";
|
||||
|
||||
|
@ -4,10 +4,11 @@ DROP TABLE releases;
|
||||
|
||||
CREATE TABLE releases (
|
||||
id text,
|
||||
picobook_version int,
|
||||
repo text,
|
||||
author text,
|
||||
slug text,
|
||||
version text,
|
||||
carts json,
|
||||
title text,
|
||||
manifest json,
|
||||
created_at time
|
||||
);
|
42
src/server/api/getRelease.ts
Normal file
42
src/server/api/getRelease.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { FirRouteInput, FirRouteOptions } from "../util/routewrap.ts";
|
||||
import { getRelease, getReleases } from "../dbal/dbal.ts";
|
||||
|
||||
const method = "GET";
|
||||
const url = "/api/release";
|
||||
|
||||
const payloadT = Type.Any();
|
||||
|
||||
const handler = async ({payload}: FirRouteInput<typeof payloadT>) => {
|
||||
const {author, slug, version} = payload;
|
||||
|
||||
if (typeof author !== "string") {
|
||||
return {
|
||||
release: null,
|
||||
versions: [],
|
||||
};
|
||||
}
|
||||
if (typeof slug !== "string") {
|
||||
return {
|
||||
release: null,
|
||||
versions: [],
|
||||
};
|
||||
}
|
||||
|
||||
const release = await getRelease({author, slug, version});
|
||||
const releases = await getReleases({author, slug});
|
||||
|
||||
const versions = releases.map(r => r.version);
|
||||
|
||||
return {
|
||||
release,
|
||||
versions,
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
method,
|
||||
url,
|
||||
payloadT,
|
||||
handler,
|
||||
} as const satisfies FirRouteOptions<typeof payloadT>;
|
@ -1,11 +1,12 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
||||
import { FirRouteInput, FirRouteOptions } from "../util/routewrap";
|
||||
import {git} from "../util/git.ts";
|
||||
import { randomUUID } from "crypto";
|
||||
import path from "path";
|
||||
import {fileURLToPath} from 'url';
|
||||
import { getCarts } from "../util/carts.ts";
|
||||
import { getRelease, insertRelease } from "../dbal/dbal.ts";
|
||||
import { ManifestType } from "../types.ts";
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const reposPath = path.resolve(__dirname, "..", "..", "..", "repos");
|
||||
|
||||
@ -14,19 +15,6 @@ const url = "/api/release";
|
||||
|
||||
const payloadT = Type.Any();
|
||||
|
||||
const manifestT = Type.Object({
|
||||
picobook_version: Type.Number(),
|
||||
id: Type.String(),
|
||||
version: Type.String(),
|
||||
carts: Type.Array(Type.String()),
|
||||
repo: Type.String(),
|
||||
title: Type.Optional(Type.String()),
|
||||
author: Type.Optional(Type.String()),
|
||||
readme: Type.Optional(Type.String()),
|
||||
});
|
||||
|
||||
const ManifestType = TypeCompiler.Compile(manifestT)
|
||||
|
||||
const handler = async ({payload}: FirRouteInput<typeof payloadT>) => {
|
||||
const {manifest, token} = payload;
|
||||
|
||||
@ -34,6 +22,11 @@ const handler = async ({payload}: FirRouteInput<typeof payloadT>) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
const release = await getRelease({author: manifest.author, slug: manifest.id, version: manifest.version});
|
||||
if (release) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uuid = randomUUID();
|
||||
const repoPath = path.join(reposPath, uuid);
|
||||
|
||||
@ -45,6 +38,11 @@ const handler = async ({payload}: FirRouteInput<typeof payloadT>) => {
|
||||
|
||||
const carts = await getCarts(repoPath, manifest.carts);
|
||||
|
||||
insertRelease({
|
||||
manifest,
|
||||
carts,
|
||||
});
|
||||
|
||||
console.log({
|
||||
manifest,
|
||||
carts,
|
||||
|
@ -1 +1,89 @@
|
||||
// Database Access Layer stuff goes here
|
||||
// Database Access Layer stuff goes here
|
||||
|
||||
// Database Access Layer stuff goes here
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { db, sql } from "../../database/db"
|
||||
import { JsonValue } from '@firebox/tsutil';
|
||||
import { PicobookManifest } from '../types';
|
||||
|
||||
export type DbRelease = {
|
||||
id: string;
|
||||
slug: string;
|
||||
repo: string;
|
||||
version: string;
|
||||
carts: {name: string; rom: number[]}[];
|
||||
author: string;
|
||||
manifest: PicobookManifest;
|
||||
}
|
||||
|
||||
const compareVersions = (a: string, b: string) => {
|
||||
const [a1, a2] = a.split(".").map(x => Number(x));
|
||||
const [b1, b2] = b.split(".").map(x => Number(x));
|
||||
if (a1 !== b1) {
|
||||
return a1 - b1;
|
||||
} else {
|
||||
return a2 - b2;
|
||||
}
|
||||
}
|
||||
|
||||
const compareByVersion = (a: DbRelease, b: DbRelease) => compareVersions(a.version, b.version);
|
||||
|
||||
export const getReleases = async (where: {
|
||||
author: string;
|
||||
slug: string;
|
||||
version?: string;
|
||||
}): Promise<DbRelease[]> => {
|
||||
const {author, slug, version} = where;
|
||||
if (!version) {
|
||||
const rows = await db.query(sql`
|
||||
SELECT * from releases
|
||||
WHERE
|
||||
slug = ${slug} AND
|
||||
author = ${author}
|
||||
`);
|
||||
return rows;
|
||||
} else {
|
||||
const rows = await db.query(sql`
|
||||
SELECT * from releases
|
||||
WHERE
|
||||
slug = ${slug} AND
|
||||
author = ${author} AND
|
||||
version = ${version}
|
||||
`);
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
||||
export const getRelease = async (where: {
|
||||
author: string;
|
||||
slug: string;
|
||||
version?: string;
|
||||
}) => {
|
||||
const {version} = where;
|
||||
const releases = await getReleases(where);
|
||||
if (version) {
|
||||
if (releases.length === 1) {
|
||||
return releases[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (releases.length < 1) {
|
||||
return null;
|
||||
}
|
||||
releases.sort(compareByVersion);
|
||||
return releases[releases.length-1];
|
||||
}
|
||||
}
|
||||
|
||||
export const insertRelease = async (props: {manifest: PicobookManifest, carts: {name: string; rom: number[]}[]}) => {
|
||||
const {manifest, carts} = props;
|
||||
const {id: slug, author, repo, version} = manifest;
|
||||
const id = uuidv4();
|
||||
const now = new Date();
|
||||
await db.query(sql`
|
||||
INSERT INTO chats (id, slug, repo, version, author, carts, manifest, created_at)
|
||||
VALUES (${id}, ${slug}, ${repo}, ${version}, ${author} ${carts}, ${manifest}, ${now})
|
||||
`);
|
||||
return id;
|
||||
}
|
||||
|
17
src/server/types.ts
Normal file
17
src/server/types.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { Static, Type } from "@sinclair/typebox";
|
||||
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
||||
|
||||
export const manifestT = Type.Object({
|
||||
picobook_version: Type.Number(),
|
||||
id: Type.String(),
|
||||
version: Type.String(),
|
||||
carts: Type.Array(Type.String()),
|
||||
repo: Type.String(),
|
||||
author: Type.String(),
|
||||
title: Type.Optional(Type.String()),
|
||||
readme: Type.Optional(Type.String()),
|
||||
});
|
||||
|
||||
export const ManifestType = TypeCompiler.Compile(manifestT);
|
||||
|
||||
export type PicobookManifest = Static<typeof manifestT>;
|
Loading…
x
Reference in New Issue
Block a user