Implement geo backend, TS client, frontend, and CI tests.
Add a Go HTTP API with Ed25519 auth and invitation onboarding, user-scoped GeoJSON Point management, a Bun-tested @noble/ed25519 TypeScript client, static Vue/Vuetify frontend integration, and a Gitea CI workflow running both Go and Bun test suites. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
export function bytesToBase64Url(bytes: Uint8Array): string {
|
||||
const bin = Array.from(bytes)
|
||||
.map((b) => String.fromCharCode(b))
|
||||
.join("");
|
||||
|
||||
if (typeof btoa !== "undefined") {
|
||||
return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
||||
}
|
||||
|
||||
// Bun/Node fallback
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const b64 = (globalThis as any).Buffer.from(bytes).toString("base64");
|
||||
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
||||
}
|
||||
|
||||
export function base64UrlToBytes(input: string): Uint8Array {
|
||||
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
||||
const padLen = (4 - (normalized.length % 4)) % 4;
|
||||
const b64 = normalized + "=".repeat(padLen);
|
||||
|
||||
if (typeof atob !== "undefined") {
|
||||
const bin = atob(b64);
|
||||
const out = new Uint8Array(bin.length);
|
||||
for (let i = 0; i < bin.length; i++) {
|
||||
out[i] = bin.charCodeAt(i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Bun/Node fallback
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return new Uint8Array((globalThis as any).Buffer.from(b64, "base64"));
|
||||
}
|
||||
|
||||
export function textToBytes(value: string): Uint8Array {
|
||||
return new TextEncoder().encode(value);
|
||||
}
|
||||
Reference in New Issue
Block a user