Feat : Setup cloudflare worker for cloud endpoint
This commit is contained in:
parent
c68b875a36
commit
102c193112
25 changed files with 1739 additions and 82 deletions
27
cloud/src/services/landingPage.js
Normal file
27
cloud/src/services/landingPage.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Landing Page Service
|
||||
* Simple health check page for self-hosted worker
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create landing page response
|
||||
* @returns {Response} HTML response
|
||||
*/
|
||||
export function createLandingPageResponse() {
|
||||
const html = `<!DOCTYPE html>
|
||||
<html><head><title>9Router Worker</title></head>
|
||||
<body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#0a0a0a;color:#fff">
|
||||
<div style="text-align:center">
|
||||
<h1>9Router Worker</h1>
|
||||
<p style="color:#888">Worker is running. Configure this URL in your 9Router dashboard.</p>
|
||||
</div>
|
||||
</body></html>`;
|
||||
|
||||
return new Response(html, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "text/html; charset=utf-8",
|
||||
"Cache-Control": "public, max-age=3600"
|
||||
}
|
||||
});
|
||||
}
|
||||
88
cloud/src/services/storage.js
Normal file
88
cloud/src/services/storage.js
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import * as log from "../utils/logger.js";
|
||||
|
||||
// Request-scoped cache for getMachineData (avoids multiple D1 queries per request)
|
||||
const requestCache = new Map();
|
||||
const CACHE_TTL_MS = 5000;
|
||||
|
||||
/**
|
||||
* Get machine data from D1 (with request-scope caching)
|
||||
* @param {string} machineId
|
||||
* @param {Object} env
|
||||
* @returns {Promise<Object|null>}
|
||||
*/
|
||||
export async function getMachineData(machineId, env) {
|
||||
const cached = requestCache.get(machineId);
|
||||
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
||||
return cached.data;
|
||||
}
|
||||
|
||||
const row = await env.DB.prepare("SELECT data FROM machines WHERE machineId = ?")
|
||||
.bind(machineId)
|
||||
.first();
|
||||
|
||||
if (!row) {
|
||||
log.debug("STORAGE", `Not found: ${machineId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = JSON.parse(row.data);
|
||||
requestCache.set(machineId, { data, timestamp: Date.now() });
|
||||
log.debug("STORAGE", `Retrieved: ${machineId}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save machine data to D1
|
||||
* @param {string} machineId
|
||||
* @param {Object} data
|
||||
* @param {Object} env
|
||||
*/
|
||||
export async function saveMachineData(machineId, data, env) {
|
||||
const now = new Date().toISOString();
|
||||
data.updatedAt = now;
|
||||
|
||||
// Upsert to D1
|
||||
await env.DB.prepare(`
|
||||
INSERT INTO machines (machineId, data, updatedAt)
|
||||
VALUES (?, ?, ?)
|
||||
ON CONFLICT(machineId) DO UPDATE SET data = ?, updatedAt = ?
|
||||
`)
|
||||
.bind(machineId, JSON.stringify(data), now, JSON.stringify(data), now)
|
||||
.run();
|
||||
|
||||
// Update cache after save
|
||||
requestCache.set(machineId, { data, timestamp: Date.now() });
|
||||
log.debug("STORAGE", `Saved: ${machineId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete machine data from D1
|
||||
* @param {string} machineId
|
||||
* @param {Object} env
|
||||
*/
|
||||
export async function deleteMachineData(machineId, env) {
|
||||
await env.DB.prepare("DELETE FROM machines WHERE machineId = ?")
|
||||
.bind(machineId)
|
||||
.run();
|
||||
|
||||
// Clear cache after delete
|
||||
requestCache.delete(machineId);
|
||||
log.debug("STORAGE", `Deleted: ${machineId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update specific fields in machine data (for token refresh, rate limit, etc.)
|
||||
* @param {string} machineId
|
||||
* @param {string} connectionId
|
||||
* @param {Object} updates
|
||||
* @param {Object} env
|
||||
*/
|
||||
export async function updateMachineProvider(machineId, connectionId, updates, env) {
|
||||
const data = await getMachineData(machineId, env);
|
||||
if (!data?.providers?.[connectionId]) return;
|
||||
|
||||
Object.assign(data.providers[connectionId], updates);
|
||||
data.providers[connectionId].updatedAt = new Date().toISOString();
|
||||
|
||||
await saveMachineData(machineId, data, env);
|
||||
}
|
||||
11
cloud/src/services/tokenRefresh.js
Normal file
11
cloud/src/services/tokenRefresh.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Re-export from open-sse with worker logger
|
||||
import * as log from "../utils/logger.js";
|
||||
import {
|
||||
TOKEN_EXPIRY_BUFFER_MS as BUFFER_MS,
|
||||
refreshTokenByProvider as _refreshTokenByProvider
|
||||
} from "open-sse/services/tokenRefresh.js";
|
||||
|
||||
export const TOKEN_EXPIRY_BUFFER_MS = BUFFER_MS;
|
||||
|
||||
export const refreshTokenByProvider = (provider, credentials) =>
|
||||
_refreshTokenByProvider(provider, credentials, log);
|
||||
Loading…
Add table
Add a link
Reference in a new issue