feat:lineage compat, nessa made more similar
This commit is contained in:
65
src/routes/api/lineage/_lib.ts
Normal file
65
src/routes/api/lineage/_lib.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
// Shared REST handler for the Lineage REST shim.
|
||||
//
|
||||
// Each route file calls `rest()` with a function that receives a typed tRPC
|
||||
// caller (scoped to `caller.lineage.*`) and the SolidStart APIEvent. The
|
||||
// handler maps `TRPCError` codes → HTTP status + `{ message }` body (the
|
||||
// legacy client parses `result.message` on non-OK responses), and returns
|
||||
// the procedure's return value as JSON on success.
|
||||
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { createServerCaller } from "~/server/api/root";
|
||||
|
||||
const codeToStatus: Record<string, number> = {
|
||||
BAD_REQUEST: 400,
|
||||
UNAUTHORIZED: 401,
|
||||
FORBIDDEN: 403,
|
||||
NOT_FOUND: 404,
|
||||
CONFLICT: 409,
|
||||
TIMEOUT: 408,
|
||||
PAYLOAD_TOO_LARGE: 413,
|
||||
METHOD_NOT_SUPPORTED: 405,
|
||||
TOO_MANY_REQUESTS: 429,
|
||||
INTERNAL_SERVER_ERROR: 500
|
||||
};
|
||||
|
||||
type Caller = Awaited<ReturnType<typeof createServerCaller>>;
|
||||
|
||||
export async function rest(
|
||||
fn: (caller: Caller, event: APIEvent) => Promise<unknown>,
|
||||
event: APIEvent
|
||||
): Promise<Response> {
|
||||
try {
|
||||
const caller = await createServerCaller(event);
|
||||
const result = await fn(caller, event);
|
||||
return new Response(JSON.stringify(result), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" }
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof TRPCError) {
|
||||
const status = codeToStatus[e.code] ?? 500;
|
||||
return new Response(JSON.stringify({ message: e.message }), {
|
||||
status,
|
||||
headers: { "content-type": "application/json" }
|
||||
});
|
||||
}
|
||||
console.error("Lineage REST shim error:", e);
|
||||
return new Response(JSON.stringify({ message: "Internal server error" }), {
|
||||
status: 500,
|
||||
headers: { "content-type": "application/json" }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Extract the Bearer token from the Authorization header. */
|
||||
export function bearerToken(event: APIEvent): string | null {
|
||||
const auth = event.request.headers.get("authorization") ?? "";
|
||||
const m = auth.match(/^Bearer\s+(.+)$/i);
|
||||
return m?.[1]?.trim() ?? null;
|
||||
}
|
||||
|
||||
/** Parse the JSON request body. */
|
||||
export async function jsonBody<T = any>(event: APIEvent): Promise<T> {
|
||||
return await event.request.json();
|
||||
}
|
||||
8
src/routes/api/lineage/analytics.ts
Normal file
8
src/routes/api/lineage/analytics.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "./_lib";
|
||||
|
||||
export const POST = (event: APIEvent) =>
|
||||
rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.misc.analytics(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/apple/email.ts
Normal file
7
src/routes/api/lineage/apple/email.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.appleGetEmail(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/apple/registration.ts
Normal file
7
src/routes/api/lineage/apple/registration.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.appleRegistration(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/database/creds.ts
Normal file
7
src/routes/api/lineage/database/creds.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.database.databaseCreds(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/database/deletion/cancel.ts
Normal file
7
src/routes/api/lineage/database/deletion/cancel.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.database.deletionCancel(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/database/deletion/check.ts
Normal file
7
src/routes/api/lineage/database/deletion/check.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.database.deletionCheck(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/database/deletion/init.ts
Normal file
7
src/routes/api/lineage/database/deletion/init.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.database.deletionInit(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/email/login.ts
Normal file
7
src/routes/api/lineage/email/login.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.emailLogin(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/email/refresh/token.ts
Normal file
7
src/routes/api/lineage/email/refresh/token.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest, bearerToken } from "../../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
const token = bearerToken(event);
|
||||
return caller.lineage.auth.refreshToken({ token: token ?? "" });
|
||||
}, event);
|
||||
7
src/routes/api/lineage/email/refresh/verification.ts
Normal file
7
src/routes/api/lineage/email/refresh/verification.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.refreshVerification(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/email/registration.ts
Normal file
7
src/routes/api/lineage/email/registration.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.emailRegistration(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/email/verification.ts
Normal file
7
src/routes/api/lineage/email/verification.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.emailVerification(input);
|
||||
}, event);
|
||||
7
src/routes/api/lineage/google/registration.ts
Normal file
7
src/routes/api/lineage/google/registration.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.auth.googleRegistration(input);
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/attacks.ts
Normal file
6
src/routes/api/lineage/json_service/attacks.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.attacks();
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/conditions.ts
Normal file
6
src/routes/api/lineage/json_service/conditions.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.conditions();
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/dungeons.ts
Normal file
6
src/routes/api/lineage/json_service/dungeons.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.dungeons();
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/enemies.ts
Normal file
6
src/routes/api/lineage/json_service/enemies.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.enemies();
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/items.ts
Normal file
6
src/routes/api/lineage/json_service/items.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.items();
|
||||
}, event);
|
||||
6
src/routes/api/lineage/json_service/misc.ts
Normal file
6
src/routes/api/lineage/json_service/misc.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.jsonService.misc();
|
||||
}, event);
|
||||
22
src/routes/api/lineage/offline_secret.ts
Normal file
22
src/routes/api/lineage/offline_secret.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// Plain-text route for the Lineage offline secret.
|
||||
//
|
||||
// `misc.offlineSecret` is a tRPC `.query()` returning `{ secret: "…" }`. But
|
||||
// the Lineage client's `IAPStore.fetchOfflineSecret` does
|
||||
// `await response.text()` and uses the raw string directly as the decryption
|
||||
// key. trpc-openapi always JSON-encodes responses, so exposing it via the openapi
|
||||
// shim would yield `'{"secret":"…"}'` as text and break decryption.
|
||||
//
|
||||
// This dedicated route returns the secret verbatim as `text/plain`, matching
|
||||
// exactly what the legacy endpoint returned. Auth: none (the legacy endpoint
|
||||
// had none either — the secret is a server-side decryption key shared to all
|
||||
// clients; it rotates with `LINEAGE_OFFLINE_SERIALIZATION_SECRET`).
|
||||
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { env } from "~/env/server";
|
||||
|
||||
export const GET = (event: APIEvent) => {
|
||||
return new Response(env.LINEAGE_OFFLINE_SERIALIZATION_SECRET, {
|
||||
status: 200,
|
||||
headers: { "content-type": "text/plain; charset=utf-8" }
|
||||
});
|
||||
};
|
||||
7
src/routes/api/lineage/pvp/battle_result.ts
Normal file
7
src/routes/api/lineage/pvp/battle_result.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.pvp.battleResult(input);
|
||||
}, event);
|
||||
13
src/routes/api/lineage/pvp/index.ts
Normal file
13
src/routes/api/lineage/pvp/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { rest } from "../_lib";
|
||||
|
||||
// GET /api/lineage/pvp — retrieve opponents
|
||||
export const GET = (event: APIEvent) => rest(async (caller) => {
|
||||
return caller.lineage.pvp.getOpponents();
|
||||
}, event);
|
||||
|
||||
// POST /api/lineage/pvp — register/update player character
|
||||
export const POST = (event: APIEvent) => rest(async (caller) => {
|
||||
const input = await event.request.json();
|
||||
return caller.lineage.pvp.registerCharacter(input);
|
||||
}, event);
|
||||
@@ -54,7 +54,8 @@ export default function NessaLanding() {
|
||||
const { isDark } = useDarkMode();
|
||||
|
||||
const iconSrc = () => (isDark() ? ICON_DARK : ICON_DEFAULT);
|
||||
const brandColor = () => site().brandColor;
|
||||
const brandColor = () =>
|
||||
isDark() ? (site().brandColorDark ?? site().brandColor) : site().brandColor;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user