Files
abode/src/db/postgres/cast.ts
T
codingetandCodex 1e10391e20
CI / lint (pull_request) Successful in 26s
CI / format (pull_request) Successful in 27s
CI / install-and-build (pull_request) Successful in 50s
CI / typecheck-tests (pull_request) Successful in 33s
CI / typecheck-source (pull_request) Successful in 35s
CI / test (pull_request) Successful in 44s
style: format postgres notes implementation
Co-Authored-By: gpt-5.6-luna <noreply@openai.com>
2026-07-23 20:55:45 +00:00

209 lines
5.4 KiB
TypeScript

import type { Abode } from "../types/Abode.js";
import type { ApikeyPermissions, ClientApikey } from "../types/Apikey.js";
import type { Resident, ResidentFlags } from "../types/Resident.js";
import type {
Note,
NoteProperties,
PartialNote,
PartialNoteProperties,
} from "../types/Note.js";
import type { ClientUser, PartialUser, UserFlags } from "../types/User.js";
export function pgToDate(d: Date | string): string {
return d instanceof Date ? d.toISOString() : new Date(d).toISOString();
}
const defaultUserFlags: UserFlags = {};
export function pgToUserFlags(flags: unknown): UserFlags {
const out = { ...defaultUserFlags };
if (typeof flags !== "object" || !flags || Array.isArray(flags)) return out;
const f = flags as Record<string, unknown>;
if (f.admin === true) out.admin = true;
return out;
}
export function pgToPartialUser(user: {
uid: string;
name: string;
flags: unknown;
created_at: Date | string;
updated_at: Date | string;
}): PartialUser {
return {
uid: user.uid,
name: user.name,
flags: pgToUserFlags(user.flags),
created_at: pgToDate(user.created_at),
updated_at: pgToDate(user.updated_at),
};
}
export function pgToClientUser(user: {
uid: string;
email: string;
name: string;
flags: unknown;
created_at: Date | string;
updated_at: Date | string;
}): ClientUser {
return {
...pgToPartialUser(user),
email: user.email,
};
}
export function pgToAbode(abode: {
aid: string;
name: string;
created_at: Date | string;
created_by: string | null;
updated_at: Date | string;
updated_by: string | null;
}): Abode {
return {
aid: abode.aid,
name: abode.name,
created_at: pgToDate(abode.created_at),
created_by: abode.created_by,
updated_at: pgToDate(abode.updated_at),
updated_by: abode.updated_by,
};
}
const defaultResidentFlags: ResidentFlags = {};
export function pgToResidentFlags(flags: unknown): ResidentFlags {
const out = { ...defaultResidentFlags };
if (typeof flags !== "object" || !flags || Array.isArray(flags)) return out;
const f = flags as Record<string, unknown>;
if (f.admin === true) out.admin = true;
return out;
}
export function pgToResident(resident: {
uid: string;
aid: string;
flags: unknown;
created_at: Date | string;
created_by: string | null;
updated_at: Date | string;
updated_by: string | null;
}): Resident {
return {
uid: resident.uid,
aid: resident.aid,
flags: pgToResidentFlags(resident.flags),
created_at: pgToDate(resident.created_at),
created_by: resident.created_by,
updated_at: pgToDate(resident.updated_at),
updated_by: resident.updated_by,
};
}
const defaultApikeyPermissions: ApikeyPermissions = {};
export function pgToApikeyPermissions(permissions: unknown): ApikeyPermissions {
const out = { ...defaultApikeyPermissions };
if (
typeof permissions !== "object" ||
!permissions ||
Array.isArray(permissions)
)
return out;
const p = permissions as Record<string, unknown>;
if (p.admin === true) out.admin = true;
if (p.all === true) out.all = true;
for (const key of ["users", "residents", "abodes"] as const) {
if (p[key] === "r" || p[key] === "rw") out[key] = p[key] as "r" | "rw";
}
for (const key of ["restrict_users", "restrict_abodes"] as const) {
if (
Array.isArray(p[key]) &&
(p[key] as unknown[]).every((x) => typeof x === "string")
) {
out[key] = p[key] as string[];
}
}
return out;
}
export function pgToClientApikey(apikey: {
uid: string;
kid: string;
name: string;
permissions: unknown;
created_at: Date | string;
expires_at: Date | string | null;
}): ClientApikey {
return {
uid: apikey.uid,
kid: apikey.kid,
name: apikey.name,
permissions: pgToApikeyPermissions(apikey.permissions),
created_at: pgToDate(apikey.created_at),
expires_at: apikey.expires_at ? pgToDate(apikey.expires_at) : null,
};
}
const validNoteTypes = new Set(["note"]);
function pgToNoteProperties(properties: unknown): NoteProperties {
if (
typeof properties !== "object" ||
!properties ||
Array.isArray(properties)
)
return {};
const value = properties as Record<string, unknown>;
return validNoteTypes.has(value.type as string)
? { type: value.type as "note" }
: {};
}
function pgToPartialNoteProperties(properties: unknown): PartialNoteProperties {
return { type: pgToNoteProperties(properties).type ?? "note" };
}
export function pgToNote(note: {
nid: string;
aid: string;
name: string;
content: string;
properties: unknown;
created_at: Date | string;
created_by: string | null;
updated_at: Date | string;
updated_by: string | null;
}): Note {
return {
nid: note.nid,
aid: note.aid,
name: note.name,
content: note.content,
properties: pgToNoteProperties(note.properties),
created_at: pgToDate(note.created_at),
created_by: note.created_by,
updated_at: pgToDate(note.updated_at),
updated_by: note.updated_by,
};
}
export function pgToPartialNote(note: {
nid: string;
aid: string;
name: string;
properties: unknown;
created_at: Date | string;
created_by: string | null;
updated_at: Date | string;
updated_by: string | null;
}): PartialNote {
return {
nid: note.nid,
aid: note.aid,
name: note.name,
properties: pgToPartialNoteProperties(note.properties),
created_at: pgToDate(note.created_at),
created_by: note.created_by,
updated_at: pgToDate(note.updated_at),
updated_by: note.updated_by,
};
}