Fix type-check after bun-sqlite 1.2.0 upgrade
Import types from @moduletrace/bun-sqlite/types now that the package has an exports map, and guard optional ctx.props in signup server fn. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import type { BunSQLiteConfig } from "@moduletrace/bun-sqlite/dist/types";
|
import type { BunSQLiteConfig } from "@moduletrace/bun-sqlite/types";
|
||||||
|
|
||||||
const config: BunSQLiteConfig = {
|
const config: BunSQLiteConfig = {
|
||||||
db_name: "wgui",
|
db_name: "wgui",
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
|||||||
import { MediaParadigms, MediaTypes } from "@/src/dict/media-dict";
|
import { MediaParadigms, MediaTypes } from "@/src/dict/media-dict";
|
||||||
import { UserTypes } from "@/src/dict/user-types-dict";
|
import { UserTypes } from "@/src/dict/user-types-dict";
|
||||||
import { Variables } from "@/src/dict/variables-dict";
|
import { Variables } from "@/src/dict/variables-dict";
|
||||||
import type { BUN_SQLITE_DatabaseSchemaType } from "@moduletrace/bun-sqlite/dist/types";
|
import type { BUN_SQLITE_DatabaseSchemaType } from "@moduletrace/bun-sqlite/types";
|
||||||
|
|
||||||
const schema: BUN_SQLITE_DatabaseSchemaType = {
|
const schema: BUN_SQLITE_DatabaseSchemaType = {
|
||||||
tables: [
|
tables: [
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import type { PropsWithChildren } from "react";
|
|
||||||
|
|
||||||
type Props = PropsWithChildren & {};
|
|
||||||
|
|
||||||
export default function EmailRoot({ children }: Props) {
|
|
||||||
const divider = (
|
|
||||||
<hr
|
|
||||||
style={{
|
|
||||||
opacity: 0.4,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: "14px",
|
|
||||||
fontWeight: "600",
|
|
||||||
opacity: 0.5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Wireguard UI Mailer
|
|
||||||
</span>
|
|
||||||
{divider}
|
|
||||||
<div>{children}</div>
|
|
||||||
{divider}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { BUN_SQLITE_WGUI_ALL_TYPEDEFS } from "@/db/types/db";
|
import type { BUN_SQLITE_WGUI_ALL_TYPEDEFS } from "@/db/types/db";
|
||||||
import type { TableType } from "@/src/types";
|
import type { TableType } from "@/src/types";
|
||||||
import uniqueStringArr from "@/src/utils/unique-string-arr";
|
import uniqueStringArr from "@/src/utils/unique-string-arr";
|
||||||
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/dist/types";
|
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/types";
|
||||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||||
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { AppData } from "@/src/data/app-data";
|
import { AppData } from "@/src/data/app-data";
|
||||||
import type { ApiReqParams, SQLInsertGenValueType } from "@/src/types";
|
import type { ApiReqParams, SQLInsertGenValueType } from "@/src/types";
|
||||||
import type { BUN_SQLITE_WGUI_CLIENTS_JOIN } from "@/src/types/sql-joins";
|
import type { BUN_SQLITE_WGUI_CLIENTS_JOIN } from "@/src/types/sql-joins";
|
||||||
import type { ServerQueryParamOrder } from "@moduletrace/bun-sqlite/dist/types";
|
import type { ServerQueryParamOrder } from "@moduletrace/bun-sqlite/types";
|
||||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||||
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
import TurndownService from "turndown";
|
|
||||||
import { extractText, getDocumentProxy } from "unpdf";
|
|
||||||
import mammoth from "mammoth";
|
|
||||||
import * as XLSX from "xlsx";
|
|
||||||
import type { FileType } from "onnxruntime-node";
|
|
||||||
import bufferFromUrl from "@/src/utils/buffer-from-url";
|
|
||||||
|
|
||||||
const turndownService = new TurndownService({
|
|
||||||
headingStyle: "atx",
|
|
||||||
codeBlockStyle: "fenced",
|
|
||||||
});
|
|
||||||
|
|
||||||
type Params = {
|
|
||||||
file_stream?: Buffer<ArrayBuffer>;
|
|
||||||
file_path?: string;
|
|
||||||
file_type?: FileType;
|
|
||||||
url?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function fileToText({
|
|
||||||
file_type,
|
|
||||||
file_stream,
|
|
||||||
file_path,
|
|
||||||
url,
|
|
||||||
}: Params): Promise<string | undefined> {
|
|
||||||
let buffer: Buffer | undefined;
|
|
||||||
let ext: string;
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
const result = await bufferFromUrl(url);
|
|
||||||
buffer = result.buffer;
|
|
||||||
ext = result.ext;
|
|
||||||
} else {
|
|
||||||
buffer = file_path
|
|
||||||
? Buffer.from(await Bun.file(file_path).arrayBuffer())
|
|
||||||
: file_stream;
|
|
||||||
ext = (file_type || file_path?.split(".").pop() || "txt")
|
|
||||||
.toString()
|
|
||||||
.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!buffer) return undefined;
|
|
||||||
|
|
||||||
switch (ext) {
|
|
||||||
case "docx": {
|
|
||||||
const { value: html } = await mammoth.convertToHtml({ buffer });
|
|
||||||
return turndownService.turndown(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
case "pdf": {
|
|
||||||
try {
|
|
||||||
const pdfUintBuffer = new Uint8Array(buffer);
|
|
||||||
const pdfDocProxy = await getDocumentProxy(pdfUintBuffer);
|
|
||||||
const { text } = await extractText(pdfDocProxy, {
|
|
||||||
mergePages: true,
|
|
||||||
});
|
|
||||||
return text;
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error(
|
|
||||||
`PDF text extraction failed: ${err?.message ?? err}`,
|
|
||||||
);
|
|
||||||
throw new Error(
|
|
||||||
`Failed to extract text from PDF: ${err?.message ?? "unknown error"}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "xlsx":
|
|
||||||
case "csv": {
|
|
||||||
const workbook = XLSX.read(buffer, { type: "buffer" });
|
|
||||||
return workbook.SheetNames.map((name) => {
|
|
||||||
const sheet = workbook.Sheets[name];
|
|
||||||
return `### Sheet: ${name}\n\n${XLSX.utils.sheet_to_csv(sheet!)}`;
|
|
||||||
}).join("\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
case "md":
|
|
||||||
case "txt":
|
|
||||||
default:
|
|
||||||
return buffer.toString("utf-8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import nodemailer from "nodemailer";
|
|
||||||
|
|
||||||
const EmailClient = nodemailer.createTransport({
|
|
||||||
host: process.env.EMAIL_DOMAIN,
|
|
||||||
port: 465,
|
|
||||||
secure: true,
|
|
||||||
auth: {
|
|
||||||
user: process.env.EMAIL_USER,
|
|
||||||
pass: process.env.EMAIL_PASS,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default EmailClient;
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { renderToString } from "react-dom/server";
|
|
||||||
import path from "path";
|
|
||||||
import type Mail from "nodemailer/lib/mailer";
|
|
||||||
import type SMTPTransport from "nodemailer/lib/smtp-transport";
|
|
||||||
import type { FC, ReactNode } from "react";
|
|
||||||
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
|
||||||
import EmailClient from "./email-client";
|
|
||||||
|
|
||||||
type Params = {
|
|
||||||
options?: Mail.Options & Partial<SMTPTransport.Options>;
|
|
||||||
to: string;
|
|
||||||
content: ReactNode;
|
|
||||||
subject: string;
|
|
||||||
text: string;
|
|
||||||
title?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function sendEmail({
|
|
||||||
options,
|
|
||||||
to,
|
|
||||||
content,
|
|
||||||
subject,
|
|
||||||
text,
|
|
||||||
title,
|
|
||||||
}: Params): Promise<APIResponseObject> {
|
|
||||||
try {
|
|
||||||
const now = Date.now();
|
|
||||||
const EmailRoot = (
|
|
||||||
await import(path.join(process.cwd(), `src/email/root?t=${now}`))
|
|
||||||
).default as FC<any>;
|
|
||||||
const final_component = <EmailRoot>{content}</EmailRoot>;
|
|
||||||
|
|
||||||
const html = renderToString(final_component);
|
|
||||||
|
|
||||||
const mail = await EmailClient.sendMail({
|
|
||||||
from: `"${title || "SBF Mailer"}" <${process.env.EMAIL_USER}>`,
|
|
||||||
to,
|
|
||||||
subject,
|
|
||||||
text,
|
|
||||||
html,
|
|
||||||
sender: `${process.env.EMAIL_USER}`,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: Boolean(mail.accepted?.[0]),
|
|
||||||
singleRes: mail,
|
|
||||||
};
|
|
||||||
} catch (error: any) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
msg: error.message,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ import { AppData } from "../data/app-data";
|
|||||||
import useStatus from "../components/twui/hooks/useStatus";
|
import useStatus from "../components/twui/hooks/useStatus";
|
||||||
import type { BUN_SQLITE_WGUI_ALL_TYPEDEFS } from "@/db/types/db";
|
import type { BUN_SQLITE_WGUI_ALL_TYPEDEFS } from "@/db/types/db";
|
||||||
import type { ApiReqParams, ClientAdminCrudParams, TableType } from "../types";
|
import type { ApiReqParams, ClientAdminCrudParams, TableType } from "../types";
|
||||||
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/dist/types";
|
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/types";
|
||||||
import EJSON from "../utils/ejson";
|
import EJSON from "../utils/ejson";
|
||||||
|
|
||||||
type Params<T extends {} = BUN_SQLITE_WGUI_ALL_TYPEDEFS> = Pick<
|
type Params<T extends {} = BUN_SQLITE_WGUI_ALL_TYPEDEFS> = Pick<
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type {
|
|||||||
} from "@/db/types/db";
|
} from "@/db/types/db";
|
||||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||||
import { rmSync } from "fs";
|
import { rmSync } from "fs";
|
||||||
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/dist/types";
|
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/types";
|
||||||
|
|
||||||
export default async function (
|
export default async function (
|
||||||
params: AdminCrudAPIParams,
|
params: AdminCrudAPIParams,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { PagePropsType } from "@/src/types";
|
|||||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||||
|
|
||||||
export const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
|
export const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
|
||||||
if (ctx.props.user?.id) {
|
if (ctx.props?.user?.id) {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
destination: `/admin`,
|
destination: `/admin`,
|
||||||
|
|||||||
+1
-2
@@ -23,7 +23,7 @@ import type {
|
|||||||
BUN_SQLITE_WGUI_CLIENTS_JOIN,
|
BUN_SQLITE_WGUI_CLIENTS_JOIN,
|
||||||
} from "./sql-joins";
|
} from "./sql-joins";
|
||||||
import type { ImageInputToBase64FunctionReturn } from "../components/twui/utils/form/imageInputToBase64";
|
import type { ImageInputToBase64FunctionReturn } from "../components/twui/utils/form/imageInputToBase64";
|
||||||
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/dist/types";
|
import type { ServerQueryParam } from "@moduletrace/bun-sqlite/types";
|
||||||
import type grabHostDirnames from "../functions/backend/setup/grab-host-dir-names";
|
import type grabHostDirnames from "../functions/backend/setup/grab-host-dir-names";
|
||||||
import type grabSystemSetupStatus from "../functions/backend/setup/grab-system-setup-status";
|
import type grabSystemSetupStatus from "../functions/backend/setup/grab-system-setup-status";
|
||||||
|
|
||||||
@@ -264,7 +264,6 @@ export type ApiReqParams<
|
|||||||
search_term_user_type?: string | string[];
|
search_term_user_type?: string | string[];
|
||||||
|
|
||||||
text?: string;
|
text?: string;
|
||||||
return_media_text_content?: boolean;
|
|
||||||
media?: BUN_SQLITE_WGUI_MEDIA;
|
media?: BUN_SQLITE_WGUI_MEDIA;
|
||||||
|
|
||||||
ip_address?: string;
|
ip_address?: string;
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
export default async function bufferFromUrl(
|
|
||||||
url: string,
|
|
||||||
): Promise<{ buffer: Buffer; ext: string }> {
|
|
||||||
const res = await fetch(url);
|
|
||||||
if (!res.ok) throw new Error(`Failed to fetch ${url}: ${res.status}`);
|
|
||||||
|
|
||||||
const contentType = res.headers.get("content-type") ?? "";
|
|
||||||
const arrayBuffer = await res.arrayBuffer();
|
|
||||||
const buffer = Buffer.from(arrayBuffer);
|
|
||||||
|
|
||||||
// Derive ext from content-type first, fall back to URL path
|
|
||||||
let ext = "txt";
|
|
||||||
if (contentType.includes("application/pdf")) ext = "pdf";
|
|
||||||
else if (
|
|
||||||
contentType.includes(
|
|
||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ext = "docx";
|
|
||||||
else if (
|
|
||||||
contentType.includes(
|
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ext = "xlsx";
|
|
||||||
else if (contentType.includes("text/csv")) ext = "csv";
|
|
||||||
else if (contentType.includes("text/markdown")) ext = "md";
|
|
||||||
else {
|
|
||||||
const urlPath = new URL(url).pathname;
|
|
||||||
ext = urlPath.split(".").pop()?.toLowerCase() ?? "txt";
|
|
||||||
}
|
|
||||||
|
|
||||||
return { buffer, ext };
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user