This commit is contained in:
2026-08-20 08:44:42 +01:00
parent e8ef8fbeb7
commit cb43d0616e
18 changed files with 811 additions and 366 deletions
+5
View File
@@ -1,2 +1,7 @@
.git .git
node_modules node_modules
.bunext
/test
.vscode
.data
bun.lock
+8 -2
View File
@@ -39,5 +39,11 @@ yarn-error.log*
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
dsql-schema-to-typedef.json dsql-schema-to-typedef.json
.data .bunext
.bunext
/.data
/test
/.bunext
/db/.backups
/db/.exports
.bun-mariadb
+2 -1
View File
@@ -1,3 +1,4 @@
{ {
"css.lint.unknownAtRules": "ignore" "css.lint.unknownAtRules": "ignore",
"js/ts.tsdk.path": "node_modules/typescript/lib"
} }
+1
View File
@@ -15,6 +15,7 @@ RUN echo 'alias ll="ls -laF"' >/root/.bashrc
COPY . /app/. COPY . /app/.
RUN bun install RUN bun install
# RUN bun db:schema
ENV NODE_ENV=production ENV NODE_ENV=production
+9
View File
@@ -0,0 +1,9 @@
import type { BunMariaDBConfig } from "@moduletrace/bun-mariadb";
const config: BunMariaDBConfig = {
db_name: "tben",
db_dir: "./db",
typedef_file_path: "./db/types/db.ts",
};
export default config;
+273 -281
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
import type { BUN_MARIADB_DatabaseSchemaType } from "@moduletrace/bun-mariadb";
const schema: BUN_MARIADB_DatabaseSchemaType = {
tables: [
{
tableName: "blog_posts",
fields: [
{
fieldName: "title",
dataType: "VARCHAR",
},
{
fieldName: "slug",
dataType: "VARCHAR",
},
{
fieldName: "excerpt",
dataType: "TEXT",
},
{
fieldName: "body",
dataType: "LONGTEXT",
html: true,
},
{
fieldName: "metadata",
dataType: "TEXT",
json: true,
},
{
fieldName: "published",
dataType: "TINYINT",
options: [0, 1],
},
{
fieldName: "meta_title",
dataType: "VARCHAR",
},
{
fieldName: "meta_description",
dataType: "TEXT",
},
],
},
{
tableName: "portfolio",
fields: [],
},
{
tableName: "documents",
fields: [],
},
],
};
export default schema;
+303
View File
@@ -0,0 +1,303 @@
export const BunMariaDBTables = [
"users",
"user_types",
"sso_login_codes",
"media",
"media_paradigms",
"events",
"event_media",
"user_media",
"locations",
"location_types",
"publications",
"publication_types",
"publication_media",
"variables",
] as const
export type BUN_MARIADB_SBF_USERS = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
first_name?: string;
last_name?: string;
email?: string;
sbf_email?: string;
username?: string;
bio_summary?: string;
bio?: string;
archived?: 0 | 1 | "";
date_of_birth?: number | "";
location_id?: number | "";
}
export type BUN_MARIADB_SBF_USER_TYPES = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
user_type?: "super_admin" | "admin" | "auditor" | "chairman" | "founder" | "vice_chairman" | "secretary" | "orphan" | "revoked" | "read_only" | "board_member" | "suspended" | "";
}
export type BUN_MARIADB_SBF_SSO_LOGIN_CODES = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
code?: string;
}
export type BUN_MARIADB_SBF_MEDIA = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
title?: string;
description?: string;
summary?: string;
media_type?: "image" | "video" | "document" | "";
media_write_path?: string;
media_thumbnail_write_path?: string;
mime_type?: string;
text_content?: string;
is_primary?: 0 | 1 | "";
is_rag_ingested?: 0 | 1 | "";
is_private?: 0 | 1 | "";
archived?: 0 | 1 | "";
}
export type BUN_MARIADB_SBF_MEDIA_PARADIGMS = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
media_id?: number | "";
media_paradigm?: "user-profile-image" | "generic" | "event" | "location" | "publication" | "";
}
export type BUN_MARIADB_SBF_EVENTS = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
title?: string;
slug?: string;
short_description?: string;
long_description?: string;
event_date?: number | "";
subsidiary?: "childrens-home" | "youth-development" | "women-empowerment" | "";
}
export type BUN_MARIADB_SBF_EVENT_MEDIA = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
event_id?: number | "";
media_id?: number | "";
is_primary?: 0 | 1 | "";
}
export type BUN_MARIADB_SBF_USER_MEDIA = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
media_id?: number | "";
}
export type BUN_MARIADB_SBF_LOCATIONS = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
name?: string;
slug?: string;
address?: string;
city?: string;
state?: string;
country?: string;
description?: string;
user_id?: number | "";
media_id?: number | "";
subsidiary?: "childrens-home" | "youth-development" | "women-empowerment" | "";
is_primary?: 0 | 1 | "";
archived?: 0 | 1 | "";
}
export type BUN_MARIADB_SBF_LOCATION_TYPES = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
location_id?: number | "";
location_type?: "orphanage" | "office" | "rural_community_branch" | "headquaters" | "";
}
export type BUN_MARIADB_SBF_PUBLICATIONS = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
user_id?: number | "";
title?: string;
slug?: string;
excerpt?: string;
summary?: string;
body?: string;
body_plain?: string;
archived?: 0 | 1 | "";
subsidiary?: "childrens-home" | "youth-development" | "women-empowerment" | "";
}
export type BUN_MARIADB_SBF_PUBLICATION_TYPES = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
publication_id?: number | "";
publication_type?: "blog" | "article" | "case_study" | "";
}
export type BUN_MARIADB_SBF_PUBLICATION_MEDIA = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
publication_id?: number | "";
media_id?: number | "";
is_primary?: 0 | 1 | "";
}
export type BUN_MARIADB_SBF_VARIABLES = {
/**
* The unique identifier of the record.
*/
id?: number | "";
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number | "";
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number | "";
name?: "childrens_home_latest_event" | "";
short_description?: string;
long_description?: string;
media_id?: number | "";
user_id?: number | "";
subsidiary?: "childrens-home" | "youth-development" | "women-empowerment" | "";
}
export type BUN_MARIADB_SBF_ALL_TYPEDEFS = BUN_MARIADB_SBF_USERS & BUN_MARIADB_SBF_USER_TYPES & BUN_MARIADB_SBF_SSO_LOGIN_CODES & BUN_MARIADB_SBF_MEDIA & BUN_MARIADB_SBF_MEDIA_PARADIGMS & BUN_MARIADB_SBF_EVENTS & BUN_MARIADB_SBF_EVENT_MEDIA & BUN_MARIADB_SBF_USER_MEDIA & BUN_MARIADB_SBF_LOCATIONS & BUN_MARIADB_SBF_LOCATION_TYPES & BUN_MARIADB_SBF_PUBLICATIONS & BUN_MARIADB_SBF_PUBLICATION_TYPES & BUN_MARIADB_SBF_PUBLICATION_MEDIA & BUN_MARIADB_SBF_VARIABLES
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
set -e
SOURCE_PATH="/home/archben/Projects/Git/personal/new-personal-site-bunext"
SERVER_IP="65.108.81.79"
SERVER_PATH="/docker/tben-me"
cd $SOURCE_PATH
rsync -avz --exclude-from=.gitignore --delete $SOURCE_PATH/ root@$SERVER_IP:$SERVER_PATH/
ssh -i /home/archben/.ssh/tben root@$SERVER_IP << 'EOF'
cd /docker/tben-me
docker build -t tben-me .
docker kill tben-me || echo "Service already killed"
docker rm tben-me || echo "Container already removed"
docker run --name tben-me -d --network cloudflare --network mariadb tben-me:latest
EOF
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
SERVER_IP="10.1.0.1"
SERVER_PATH="/docker/git/"
+7 -3
View File
@@ -6,17 +6,20 @@
"dev": "NODE_ENV=development bunx bunext dev", "dev": "NODE_ENV=development bunx bunext dev",
"build": "bunx bunext build", "build": "bunx bunext build",
"start": "NODE_ENV=production bunx bunext start", "start": "NODE_ENV=production bunx bunext start",
"schema-to-typedef": "bunx dsql-schema-to-typedef" "schema-to-typedef": "bunx dsql-schema-to-typedef",
"db:schema": "bunx bun-mariadb schema -t",
"deploy": "./deploy/deploy-mail-server.sh"
}, },
"dependencies": { "dependencies": {
"@moduletrace/buncid": "^1.0.7", "@moduletrace/bun-mariadb": "^1.0.19",
"@moduletrace/bunext": "^1.0.61", "@moduletrace/bunext": "^1.0.61",
"@moduletrace/datasquirel": "^5.7.57",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"html-to-react": "^1.7.0", "html-to-react": "^1.7.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lucide-react": "^0.462.0", "lucide-react": "^0.462.0",
"marked": "^17.0.5", "marked": "^17.0.5",
"mdx": "^0.3.1",
"next-mdx-remote": "^6.0.0",
"openai": "^6.21.0", "openai": "^6.21.0",
"prism-react-renderer": "^2.4.1", "prism-react-renderer": "^2.4.1",
"prism-themes": "^1.9.0", "prism-themes": "^1.9.0",
@@ -30,6 +33,7 @@
"@tailwindcss/postcss": "^4.1.11", "@tailwindcss/postcss": "^4.1.11",
"@types/lodash": "^4.17.13", "@types/lodash": "^4.17.13",
"@types/marked": "^6.0.0", "@types/marked": "^6.0.0",
"@types/mdx": "^2.0.14",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
+1 -1
View File
@@ -1,7 +1,7 @@
import React, { MutableRefObject } from "react"; import React, { MutableRefObject } from "react";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import AceEditorModes from "./ace-editor-modes"; import AceEditorModes from "./ace-editor-modes";
import { AceEditorOptions } from "@moduletrace/datasquirel/dist/package-shared/types"; import { AceEditorOptions } from "../types";
export type AceEditorComponentType = { export type AceEditorComponentType = {
editorRef?: MutableRefObject<AceAjax.Editor | undefined>; editorRef?: MutableRefObject<AceAjax.Editor | undefined>;
+71
View File
@@ -66,3 +66,74 @@ export const AutocompleteOptions = [
"on", // Enables autofill (default) "on", // Enables autofill (default)
"off", // Disables autofill "off", // Disables autofill
] as const; ] as const;
export interface AceEditorOptions {
animatedScroll?: boolean;
autoScrollEditorIntoView?: boolean;
behavioursEnabled?: boolean;
copyWithEmptySelection?: boolean;
cursorStyle?: "ace" | "slim" | "smooth" | "wide";
customScrollbar?: boolean;
displayIndentGuides?: boolean;
dragDelay?: number;
dragEnabled?: boolean;
enableAutoIndent?: boolean;
enableBasicAutocompletion?: boolean | any[];
enableKeyboardAccessibility?: boolean;
enableLiveAutocompletion?: boolean | any[];
enableMobileMenu?: boolean;
enableMultiselect?: boolean;
enableSnippets?: boolean;
fadeFoldWidgets?: boolean;
firstLineNumber?: number;
fixedWidthGutter?: boolean;
focusTimeout?: number;
foldStyle?: "markbegin" | "markbeginend" | "manual";
fontFamily?: string;
fontSize?: number;
hScrollBarAlwaysVisible?: boolean;
hasCssTransforms?: boolean;
highlightActiveLine?: boolean;
highlightGutterLine?: boolean;
highlightIndentGuides?: boolean;
highlightSelectedWord?: boolean;
indentedSoftWrap?: boolean;
keyboardHandler?: string;
liveAutocompletionDelay?: number;
liveAutocompletionThreshold?: number;
maxLines?: number;
maxPixelHeight?: number;
mergeUndoDeltas?: boolean | "always";
minLines?: number;
mode?: string;
navigateWithinSoftTabs?: boolean;
newLineMode?: AceAjax.NewLineMode;
overwrite?: boolean;
placeholder?: string;
printMargin?: number | boolean;
printMarginColumn?: number;
readOnly?: boolean;
relativeLineNumbers?: boolean;
scrollPastEnd?: number;
scrollSpeed?: number;
selectionStyle?: string;
session?: any;
showFoldWidgets?: boolean;
showFoldedAnnotations?: boolean;
showGutter?: boolean;
showInvisibles?: boolean;
showLineNumbers?: boolean;
showPrintMargin?: boolean;
tabSize?: number;
textInputAriaLabel?: string;
theme?: string;
tooltipFollowsMouse?: boolean;
useSoftTabs?: boolean;
useSvgGutterIcons?: boolean;
useWorker?: boolean;
vScrollBarAlwaysVisible?: boolean;
value?: string;
wrap?: number | boolean | "off" | "free" | "printmargin";
wrapBehavioursEnabled?: boolean;
wrapMethod?: "code" | "text" | "auto";
}
+2 -1
View File
@@ -7,13 +7,14 @@ import {
BunextHTMLProps, BunextHTMLProps,
BunextRouteConfig, BunextRouteConfig,
BunextPageModuleMeta, BunextPageModuleMeta,
BunextPageModuleServerReturnURLObject,
} from "@moduletrace/bunext/types"; } from "@moduletrace/bunext/types";
import { RootHead } from "./(partials)/root-head"; import { RootHead } from "./(partials)/root-head";
export type AppContextType = { export type AppContextType = {
pageProps: PagePropsType; pageProps: PagePropsType;
query?: any; query?: any;
url?: URL; url?: BunextPageModuleServerReturnURLObject;
}; };
export const AppContext = React.createContext<AppContextType>({ export const AppContext = React.createContext<AppContextType>({
+14 -17
View File
@@ -1,32 +1,29 @@
import { PagePropsType } from "@/src/types"; import { PagePropsType } from "@/src/types";
import matter from "gray-matter";
import { DSQL_TBEN_ME_BLOG_POSTS } from "@/src/types/dsql";
import { BunextPageServerFn } from "@moduletrace/bunext/types"; import { BunextPageServerFn } from "@moduletrace/bunext/types";
import sql from "@/src/utils/db";
export const server: BunextPageServerFn<PagePropsType> = async (ctx) => { export const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
const blog_post_res = await sql` // const blog_post_res = await sql`
SELECT * FROM blog_posts // SELECT * FROM blog_posts
WHERE slug=${ctx.query?.slug} // WHERE slug=${ctx.query?.slug}
`; // `;
const blog_post: DSQL_TBEN_ME_BLOG_POSTS = [...blog_post_res]?.[0]; // const blog_post: DSQL_TBEN_ME_BLOG_POSTS = [...blog_post_res]?.[0];
if (!blog_post?.body) { // if (!blog_post?.body) {
return { // return {
props: {}, // props: {},
}; // };
} // }
const pageMdString = blog_post.body; // const pageMdString = blog_post.body;
const pageGrayMatter = matter(pageMdString); // const pageGrayMatter = matter(pageMdString);
const content = pageGrayMatter.content; // const content = pageGrayMatter.content;
return { return {
props: { props: {
blogPost: blog_post, blogPost: {},
}, },
}; };
}; };
+7 -8
View File
@@ -1,20 +1,19 @@
import { PagePropsType } from "@/src/types"; import { PagePropsType } from "@/src/types";
import { DSQL_TBEN_ME_BLOG_POSTS } from "@/src/types/dsql"; import { DSQL_TBEN_ME_BLOG_POSTS } from "@/src/types/dsql";
import { BunextPageServerFn } from "@moduletrace/bunext/types"; import { BunextPageServerFn } from "@moduletrace/bunext/types";
import sql from "@/src/utils/db";
export const server: BunextPageServerFn<PagePropsType> = async (ctx) => { export const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
const blog_posts_res = await sql` // const blog_posts_res = await sql`
SELECT * FROM blog_posts // SELECT * FROM blog_posts
WHERE published=1 // WHERE published=1
ORDER BY id DESC // ORDER BY id DESC
`; // `;
const blog_posts: DSQL_TBEN_ME_BLOG_POSTS[] = [...blog_posts_res]; // const blog_posts: DSQL_TBEN_ME_BLOG_POSTS[] = [...blog_posts_res];
return { return {
props: { props: {
blogPosts: blog_posts, blogPosts: [],
}, },
}; };
}; };
-24
View File
@@ -1,24 +0,0 @@
import { SQL } from "bun";
let sql_object: any;
const sql = new SQL({
adapter: "mariadb",
hostname: process.env.DSQL_DB_HOST,
database: process.env.DSQL_DB_NAME,
username: process.env.DSQL_DB_USERNAME,
password: process.env.DSQL_DB_PASSWORD,
tls: {
rejectUnauthorized: false,
},
idleTimeout: 30000,
maxLifetime: 60 * 60 * 1000,
onclose(err) {
sql_object?.connect();
},
onconnect(err) {
sql_object = sql;
},
});
export default sql;
+28 -28
View File
@@ -1,29 +1,29 @@
import { DSQL_TBEN_ME_BLOG_POSTS } from "@/src/types/dsql"; // import { DSQL_TBEN_ME_BLOG_POSTS } from "@/src/types/dsql";
import { APIResponseObject } from "@moduletrace/bunext/types"; // import { APIResponseObject } from "@moduletrace/bunext/types";
import datasquirel from "@moduletrace/datasquirel"; // import datasquirel from "@moduletrace/datasquirel";
datasquirel // datasquirel
.crud<DSQL_TBEN_ME_BLOG_POSTS>({ // .crud<DSQL_TBEN_ME_BLOG_POSTS>({
action: "get", // action: "get",
table: "blog_posts", // table: "blog_posts",
query: { // query: {
order: { // order: {
field: "id", // field: "id",
strategy: "DESC", // strategy: "DESC",
}, // },
query: { // query: {
published: { // published: {
value: "1", // value: "1",
}, // },
}, // },
}, // },
}) // })
.then((res) => { // .then((res) => {
console.log("res", res); // console.log("res", res);
}) // })
.catch((err) => { // .catch((err) => {
console.error(err.message); // console.error(err.message);
}) // })
.finally(() => { // .finally(() => {
process.exit(); // process.exit();
}); // });