latest
This commit is contained in:
+6
-1
@@ -1,4 +1,9 @@
|
|||||||
import { treaty } from "@elysiajs/eden";
|
import { treaty } from "@elysiajs/eden";
|
||||||
import type { App } from "./server/types";
|
import type { App } from "./server/types";
|
||||||
|
|
||||||
export const api = treaty<App>('http://localhost:5173').api;
|
const baseURL =
|
||||||
|
import.meta.env.PROD
|
||||||
|
? "https://blade-and-brawn.fly.dev"
|
||||||
|
: "http://localhost:5173";
|
||||||
|
|
||||||
|
export const api = treaty<App>(baseURL).api;
|
||||||
|
|||||||
+52
-9
@@ -1,6 +1,6 @@
|
|||||||
import { Elysia, NotFoundError } from "elysia";
|
import { Elysia, NotFoundError } from "elysia";
|
||||||
import { cors } from "@elysiajs/cors";
|
import { cors } from "@elysiajs/cors";
|
||||||
import { LevelCalculator, Standards, type ActivityStandards } from "$lib/services/calculator/main";
|
import { LevelCalculator, Standards, type ActivityStandards, type LevelCalculatorOutput } from "$lib/services/calculator/main";
|
||||||
import type { ActivityPerformance, Player } from "$lib/services/calculator/util";
|
import type { ActivityPerformance, Player } from "$lib/services/calculator/util";
|
||||||
import rawStandards from "$lib/data/standards.json" assert { type: "json" }
|
import rawStandards from "$lib/data/standards.json" assert { type: "json" }
|
||||||
import { Printful, Webflow } from "../services/commerce/util/types";
|
import { Printful, Webflow } from "../services/commerce/util/types";
|
||||||
@@ -9,8 +9,24 @@ import SyncService from "../services/commerce/sync";
|
|||||||
import PrintfulService from "../services/commerce/printful";
|
import PrintfulService from "../services/commerce/printful";
|
||||||
import { FetchError, getStateFromZip } from "../services/commerce/util/misc";
|
import { FetchError, getStateFromZip } from "../services/commerce/util/misc";
|
||||||
|
|
||||||
|
const MAIN_STANDARDS = new Standards(rawStandards as ActivityStandards);
|
||||||
|
const levelCalculator = new LevelCalculator(MAIN_STANDARDS);
|
||||||
|
|
||||||
export const app = new Elysia({ prefix: "/api" })
|
export const app = new Elysia({ prefix: "/api" })
|
||||||
.use(cors({ origin: '*' }))
|
.use(
|
||||||
|
cors({
|
||||||
|
origin: [
|
||||||
|
// bladeandbrawn.com (apex + any subdomain)
|
||||||
|
/^https?:\/\/([a-z0-9-]+\.)?bladeandbrawn\.com$/i,
|
||||||
|
// Webflow preview domains
|
||||||
|
/^https?:\/\/([a-z0-9-]+\.)?bladeandbrawn\.webflow\.io$/i,
|
||||||
|
// Fly app host (this one already works)
|
||||||
|
/^https?:\/\/blade-and-brawn\.fly\.dev$/i,
|
||||||
|
// Local dev
|
||||||
|
"http://localhost:5173",
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
.error({
|
.error({
|
||||||
FetchError
|
FetchError
|
||||||
@@ -24,30 +40,55 @@ export const app = new Elysia({ prefix: "/api" })
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.onAfterHandle(({ request, set }) => {
|
||||||
|
console.log(JSON.stringify({
|
||||||
|
lvl: "info",
|
||||||
|
msg: "req",
|
||||||
|
method: request.method,
|
||||||
|
path: new URL(request.url).pathname,
|
||||||
|
status: set.status ?? 200
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
|
||||||
.get("/", () => "Hello world")
|
.get("/", () => "Hello world")
|
||||||
|
|
||||||
// CALCULATOR
|
// CALCULATOR
|
||||||
|
|
||||||
.post("/calculate", async ({ body }) => {
|
.post("/calculate", async ({ body, query }) => {
|
||||||
const MAIN_STANDARDS = new Standards(rawStandards as ActivityStandards);
|
|
||||||
interface CalcRequest {
|
interface CalcRequest {
|
||||||
player: Player;
|
player: Player;
|
||||||
activityPerformances: ActivityPerformance[];
|
activityPerformances: ActivityPerformance[];
|
||||||
}
|
}
|
||||||
const { player, activityPerformances } = body as CalcRequest;
|
const { player, activityPerformances } = body as CalcRequest;
|
||||||
const levelCalculator = new LevelCalculator(MAIN_STANDARDS);
|
const output = { levels: levelCalculator.calculate(player, activityPerformances) };
|
||||||
return { levels: levelCalculator.calculate(player, activityPerformances) };
|
|
||||||
|
console.log({ log: query?.log });
|
||||||
|
if (query?.log === "true") {
|
||||||
|
void fetch("https://kv-logger.xominus.workers.dev", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({ output, player, activityPerformances })
|
||||||
|
}).catch(e => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
})
|
})
|
||||||
|
|
||||||
// COMMERCE
|
// COMMERCE
|
||||||
|
// TODO: protect with api key/token
|
||||||
.group("/products", app => app
|
.group("/products", app => app
|
||||||
.group("/sync", app => app
|
.group("/sync", app => app
|
||||||
.get("/", async ({ }) => SyncService.state)
|
.get("/", async ({ }) => SyncService.state)
|
||||||
.post("/:printfulProductId?", async ({ params }) => {
|
.post("/:printfulProductId?", async ({ params, set }) => {
|
||||||
|
if (SyncService.state.isSyncing) {
|
||||||
|
set.status = 409;
|
||||||
|
return { error: "Sync already in progress" };
|
||||||
|
}
|
||||||
const printfulProductId = params.printfulProductId ?
|
const printfulProductId = params.printfulProductId ?
|
||||||
+params.printfulProductId :
|
+params.printfulProductId :
|
||||||
undefined;
|
undefined;
|
||||||
await SyncService.sync(printfulProductId);
|
await SyncService.sync(printfulProductId);
|
||||||
|
return { ok: true };
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.get("/:printfulProductId", async ({ params }) => {
|
.get("/:printfulProductId", async ({ params }) => {
|
||||||
@@ -68,8 +109,6 @@ export const app = new Elysia({ prefix: "/api" })
|
|||||||
.post("/webhook/printful", async ({ body }) => {
|
.post("/webhook/printful", async ({ body }) => {
|
||||||
const payload = body as Printful.Webhook.EventPayload;
|
const payload = body as Printful.Webhook.EventPayload;
|
||||||
|
|
||||||
console.log("Hit webhook", payload.type);
|
|
||||||
|
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case Printful.Webhook.Event.ProductUpdated: {
|
case Printful.Webhook.Event.ProductUpdated: {
|
||||||
const printfulProduct = payload.data.sync_product;
|
const printfulProduct = payload.data.sync_product;
|
||||||
@@ -93,6 +132,8 @@ export const app = new Elysia({ prefix: "/api" })
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
})
|
})
|
||||||
.post("/webhook/webflow", async ({ request, body, set }) => {
|
.post("/webhook/webflow", async ({ request, body, set }) => {
|
||||||
if (!WebflowService.Util.verifyWebflowSignature(request, body)) {
|
if (!WebflowService.Util.verifyWebflowSignature(request, body)) {
|
||||||
@@ -130,4 +171,6 @@ export const app = new Elysia({ prefix: "/api" })
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -198,7 +198,9 @@ export class Standards {
|
|||||||
0.1,
|
0.1,
|
||||||
weightSkew: 0,
|
weightSkew: 0,
|
||||||
ageModifier: 0.5,
|
ageModifier: 0.5,
|
||||||
difficultyModifier: 0
|
difficultyModifier: activity === Activity.BroadJump ?
|
||||||
|
0.05 :
|
||||||
|
0
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
) as Record<Activity, StandardsConfig["activity"][Activity]>;
|
) as Record<Activity, StandardsConfig["activity"][Activity]>;
|
||||||
|
|||||||
@@ -101,6 +101,35 @@ export default class PrintfulService {
|
|||||||
throw new FetchError("Failed to create printful order", res);
|
throw new FetchError("Failed to create printful order", res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getAll(offset: number = 0): Promise<Printful.Orders.Order[]> {
|
||||||
|
const allPrintfulOrders: Printful.Orders.Order[] = [];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${env().API_URL}/orders?offset=${offset}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: { ...env().AUTH_HEADERS }
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new FetchError("Failed to get all Printful orders", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload: Printful.Products.MetaDataMulti<Printful.Orders.Order> = await res.json();
|
||||||
|
|
||||||
|
allPrintfulOrders.push(...payload.result);
|
||||||
|
offset = allPrintfulOrders.length;
|
||||||
|
|
||||||
|
if (allPrintfulOrders.length >= payload.paging.total)
|
||||||
|
break;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allPrintfulOrders;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Util = class {
|
static Util = class {
|
||||||
|
|||||||
@@ -46,9 +46,8 @@ const computedPerformances: ActivityPerformance[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const wOrders = await WebflowService.Orders.getAll();
|
const pOrders = await PrintfulService.Orders.getAll();
|
||||||
|
console.log(pOrders);
|
||||||
console.log(wOrders);
|
|
||||||
|
|
||||||
// wProduct.product.fieldData.name = "Rogue Title Hoodie [White] / XS";
|
// wProduct.product.fieldData.name = "Rogue Title Hoodie [White] / XS";
|
||||||
//
|
//
|
||||||
|
|||||||
+1
-1
@@ -3,5 +3,5 @@ import { sveltekit } from '@sveltejs/kit/vite';
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [tailwindcss(), sveltekit()],
|
plugins: [tailwindcss(), sveltekit()]
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user