added Schema Bot

This commit is contained in:
makearmy 2025-09-29 11:10:26 -04:00
parent fda015531c
commit 6e3cba4308
2 changed files with 44 additions and 7 deletions

View file

@ -5,4 +5,5 @@ NEXT_PUBLIC_API_BASE_URL=https://forms.lasereverything.net
DIRECTUS_URL=https://forms.lasereverything.net
DIRECTUS_TOKEN_SUBMIT=2uD5w9sFLgPtTtjqfUft8i_pLZRzCSTu
DIRECTUS_TOKEN_ADMIN_REGISTER=l_QqNXKpi--Dt-hHDncHyBX0eiHNYZr7
DIRECTUS_TOKEN_SCHEMA_READ=BCaWlfTkuVIYyEnwBCXujLTIY6lScZbF
DIRECTUS_ROLE_MEMBER_ID=296a28bc-60ab-4251-8bef-27f6dfb67948

View file

@ -4,6 +4,7 @@
const BASE = process.env.DIRECTUS_URL!;
const TOKEN_SUBMIT = process.env.DIRECTUS_TOKEN_SUBMIT!;
const TOKEN_ADMIN_REGISTER = process.env.DIRECTUS_TOKEN_ADMIN_REGISTER || "";
const TOKEN_SCHEMA_READ = process.env.DIRECTUS_TOKEN_SCHEMA_READ || ""; // ← new (schema-bot)
const ROLE_MEMBER_ID_ENV = process.env.DIRECTUS_ROLE_MEMBER_ID || "";
const ROLE_MEMBER_NAME_ENV = process.env.DIRECTUS_ROLE_MEMBER_NAME || "Users";
@ -12,7 +13,14 @@ process.env.DIRECTUS_PROJECTS_COLLECTION || "projects";
if (!BASE) console.warn("[directus] Missing DIRECTUS_URL");
if (!TOKEN_SUBMIT) console.warn("[directus] Missing DIRECTUS_TOKEN_SUBMIT");
if (!TOKEN_ADMIN_REGISTER) console.warn("[directus] Missing DIRECTUS_TOKEN_ADMIN_REGISTER (used for registration)");
if (!TOKEN_ADMIN_REGISTER)
console.warn(
"[directus] Missing DIRECTUS_TOKEN_ADMIN_REGISTER (used for registration)"
);
if (!TOKEN_SCHEMA_READ)
console.warn(
"[directus] Missing DIRECTUS_TOKEN_SCHEMA_READ (used for schema reads)"
);
export function bytesFromMB(mb: number) {
return Math.round(mb * 1024 * 1024);
@ -76,6 +84,30 @@ export async function directusAdminFetch<T = any>(
return (json ?? {}) as T;
}
/** Schema-safe fetch: prefers schema-bot token, falls back to admin-register, then submit */
export async function directusSchemaFetch<T = any>(
path: string,
init?: RequestInit
): Promise<T> {
const token =
TOKEN_SCHEMA_READ || TOKEN_ADMIN_REGISTER || TOKEN_SUBMIT;
const res = await fetch(`${BASE}${path}`, {
...init,
headers: {
Accept: "application/json",
Authorization: `Bearer ${token}`,
...(init?.headers || {}),
},
});
const { json, text } = await parseJsonSafe(res);
if (!res.ok) {
throw new Error(`Directus error ${res.status}: ${text || res.statusText}`);
}
return (json ?? {}) as T;
}
/*
* On-the-fly folder lookup by "path" = "<parent>/<child>"
* Caches results in-memory. If lookup is forbidden (403) or not found,
@ -120,7 +152,10 @@ async function getFolderIdByPath(path: string): Promise<string | undefined> {
return undefined;
}
const parts = path.split("/").map((s) => s.trim()).filter(Boolean);
const parts = path
.split("/")
.map((s) => s.trim())
.filter(Boolean);
const [parentName, childName] = parts;
const eq = (a?: string | null, b?: string | null) =>
@ -179,10 +214,9 @@ export async function uploadFile(
const { json, text } = await parseJsonSafe(res);
if (!res.ok) {
throw new Error(
`File upload failed: status=${res.status} ${res.statusText} body=${(text || "").slice(
0,
400
) || "<empty>"}`
`File upload failed: status=${res.status} ${res.statusText} body=${
(text || "").slice(0, 400) || "<empty>"
}`
);
}
@ -284,7 +318,9 @@ export async function createDirectusUser(input: {
}
/** Find user's email by username (returns null if not found) */
export async function emailForUsername(username: string): Promise<string | null> {
export async function emailForUsername(
username: string
): Promise<string | null> {
const q = `/users?filter[username][_eq]=${encodeURIComponent(
username
)}&fields=email&limit=1`;