Skip to content

Commit

Permalink
chore(base): nokia phone 2008
Browse files Browse the repository at this point in the history
  • Loading branch information
antonstjernquist committed Sep 5, 2024
1 parent a1f0d75 commit 6399c5e
Show file tree
Hide file tree
Showing 17 changed files with 3,273 additions and 4,859 deletions.
7,589 changes: 2,860 additions & 4,729 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

191 changes: 90 additions & 101 deletions src/server/database/knex.ts
Original file line number Diff line number Diff line change
@@ -1,114 +1,103 @@
import knex from "knex";
import { ConnectionOptions } from "mysql2";

// https://github.com/overextended/oxmysql/blob/bfe660b9d3419ca6a7b94c465c6d74ae20971c08/src/config.ts
export const mysql_connection_string = GetConvar("mysql_connection_string", "");
import knex from 'knex';
import { ConnectionOptions } from 'mysql2';

function parseUri(connectionString: string) {
const splitMatchGroups = connectionString.match(
new RegExp(
"^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?$",
),
) as RegExpMatchArray;

if (!splitMatchGroups)
throw new Error(
`mysql_connection_string structure was invalid (${connectionString})`,
);

const authTarget = splitMatchGroups[2] ? splitMatchGroups[2].split(":") : [];

const options = {
user: authTarget[0] || undefined,
password: authTarget[1] || undefined,
host: splitMatchGroups[3],
port: parseInt(splitMatchGroups[4]),
database: splitMatchGroups[5]?.replace(/^\/+/, ""),
...(splitMatchGroups[6] &&
splitMatchGroups[6]
.split("&")
.reduce<Record<string, string>>((connectionInfo, parameter) => {
const [key, value] = parameter.split("=");
connectionInfo[key] = value;
return connectionInfo;
}, {})),
};

return options;
const splitMatchGroups = connectionString.match(
new RegExp(
'^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?$',
),
) as RegExpMatchArray;

if (!splitMatchGroups)
throw new Error(`mysql_connection_string structure was invalid (${connectionString})`);

const authTarget = splitMatchGroups[2] ? splitMatchGroups[2].split(':') : [];

const options = {
user: authTarget[0] || undefined,
password: authTarget[1] || undefined,
host: splitMatchGroups[3],
port: parseInt(splitMatchGroups[4]),
database: splitMatchGroups[5]?.replace(/^\/+/, ''),
...(splitMatchGroups[6] &&
splitMatchGroups[6]
.split('&')
.reduce<Record<string, string>>((connectionInfo, parameter) => {
const [key, value] = parameter.split('=');
connectionInfo[key] = value;
return connectionInfo;
}, {})),
};

return options;
}

export let convertNamedPlaceholders:
| null
| ((query: string, parameters: Record<string, any>) => [string, any[]]);
| null
| ((query: string, parameters: Record<string, any>) => [string, any[]]);

export function getConnectionOptions(): ConnectionOptions {
const options: Record<string, any> = mysql_connection_string.includes(
"mysql://",
)
? parseUri(mysql_connection_string)
: mysql_connection_string
.replace(
/(?:host(?:name)|ip|server|data\s?source|addr(?:ess)?)=/gi,
"host=",
)
.replace(/(?:user\s?(?:id|name)?|uid)=/gi, "user=")
.replace(/(?:pwd|pass)=/gi, "password=")
.replace(/(?:db)=/gi, "database=")
.split(";")
.reduce<Record<string, string>>((connectionInfo, parameter) => {
const [key, value] = parameter.split("=");
if (key) connectionInfo[key] = value;
return connectionInfo;
}, {});

convertNamedPlaceholders =
options.namedPlaceholders === "false"
? null
: require("named-placeholders")();

for (const key of ["dateStrings", "flags", "ssl"]) {
const value = options[key];

if (typeof value === "string") {
try {
options[key] = JSON.parse(value);
} catch (err) {
console.log(
`^3Failed to parse property ${key} in configuration (${err})!^0`,
);
}
}
}

const flags: string[] = options.flags || [];
flags.push(options.database ? "CONNECT_WITH_DB" : "-CONNECT_WITH_DB");

return {
connectTimeout: 60000,
trace: false,
supportBigNumbers: true,
jsonStrings: true,
...options,
flags: flags,
};
// https://github.com/overextended/oxmysql/blob/bfe660b9d3419ca6a7b94c465c6d74ae20971c08/src/config.ts
const mysql_connection_string = GetConvar('mysql_connection_string', '');

const options: Record<string, any> = mysql_connection_string.includes('mysql://')
? parseUri(mysql_connection_string)
: mysql_connection_string
.replace(/(?:host(?:name)|ip|server|data\s?source|addr(?:ess)?)=/gi, 'host=')
.replace(/(?:user\s?(?:id|name)?|uid)=/gi, 'user=')
.replace(/(?:pwd|pass)=/gi, 'password=')
.replace(/(?:db)=/gi, 'database=')
.split(';')
.reduce<Record<string, string>>((connectionInfo, parameter) => {
const [key, value] = parameter.split('=');
if (key) connectionInfo[key] = value;
return connectionInfo;
}, {});

convertNamedPlaceholders =
options.namedPlaceholders === 'false' ? null : require('named-placeholders')();

for (const key of ['dateStrings', 'flags', 'ssl']) {
const value = options[key];

if (typeof value === 'string') {
try {
options[key] = JSON.parse(value);
} catch (err) {
console.log(`^3Failed to parse property ${key} in configuration (${err})!^0`);
}
}
}

const flags: string[] = options.flags || [];
flags.push(options.database ? 'CONNECT_WITH_DB' : '-CONNECT_WITH_DB');

return {
connectTimeout: 60000,
trace: false,
supportBigNumbers: true,
jsonStrings: true,
...options,
flags: flags,
};
}

export let DBInstance: knex.Knex;

export function initDB() {
const options = getConnectionOptions();

const conn = knex({
client: "mysql",
connection: {
port: options.port,
host: options.host,
password: options.password,
user: options.user,
db: options.database,
flags: options.flags,
},
});

DBInstance = conn;
const options = getConnectionOptions();

const conn = knex({
client: 'mysql',
connection: {
port: options.port,
host: options.host,
password: options.password,
user: options.user,
db: options.database,
flags: options.flags,
},
});

DBInstance = conn;
}
11 changes: 8 additions & 3 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { initDB } from "./database/knex";
import { initDB } from './database/knex';

function bootstrap() {
initDB();
initDB();
}

bootstrap();
/**
* Just to avoid crashing when running dev in root for now
*/
if (typeof RegisterCommand !== 'undefined') {
bootstrap();
}
2 changes: 1 addition & 1 deletion src/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
4 changes: 3 additions & 1 deletion src/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"react-router": "^6.26.1",
"react-router-dom": "^6.26.1"
},
"devDependencies": {
"@types/react": "^18.3.3",
Expand Down
13 changes: 0 additions & 13 deletions src/ui/src/App.jsx

This file was deleted.

65 changes: 65 additions & 0 deletions src/ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Link, Outlet } from 'react-router-dom';
import { Frame } from './Frame';

import { useEffect } from 'react';
import { setTheme } from './utils/theme';

const lightTheme = {
textColor: {
primary: '#000',
secondary: '#222',
},
backgroundColor: {
primary: '#fff',
secondary: '#eee',
},
};

const darkTheme = {
textColor: {
primary: '#fff',
secondary: '#ddd',
},
backgroundColor: {
primary: '#121212',
secondary: '#222',
},
};

function App() {
const toggleTheme = () => {
const rootElement = document.getElementById('root')!;
const currentTheme =
rootElement.style.getPropertyValue('--bg-primary') === lightTheme.backgroundColor.primary
? darkTheme
: lightTheme;

setTheme(currentTheme);
};

useEffect(() => {
setTheme(lightTheme);
}, []);

return (
<Frame>
<main className="flex flex-col gap-2 flex-1">
<header className="h-8 bg-slate-400 text-secondary px-6 flex gap-4">
(This is the header)
</header>

<Outlet />

<button className="border p-4 rounded-lg m-8" onClick={toggleTheme}>
toggle theme
</button>

<footer className="h-8 bg-slate-400 text-secondary px-6 flex gap-4 items-center mt-auto">
<Link to="/home">Home</Link>
</footer>
</main>
</Frame>
);
}

export default App;
8 changes: 7 additions & 1 deletion src/ui/src/Frame.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export const Frame = ({ children }: { children: React.ReactNode }) => {
return <div className="w-[390px] h-[844px] bg-cyan-950">{children}</div>;
return (
<div className="w-[390px] h-[844px] bg-cyan-600 text-primary flex flex-col">
<div className="bg-primary rounded-[40px] flex-1 flex flex-col overflow-hidden">
{children}
</div>
</div>
);
};
45 changes: 45 additions & 0 deletions src/ui/src/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { createHashRouter, Link } from 'react-router-dom';
import { HomeView } from './views/Home';
import { ContactsApp } from './apps/contacts';
import App from './App';

export const router = createHashRouter([
{
path: '/',
element: <App />,
children: [
{
path: 'home',
element: <HomeView />,
},
{
path: 'apps',
children: [
{
path: 'contacts',
element: <ContactsApp />,
},
],
},
],
},
{
path: 'about',
element: <div>About</div>,
},
{
path: '*',
element: (
<div className="p-8 text-primary h-full w-full bg-black text-slate-50 flex flex-col gap-8">
<span>Not Found</span>
<span>🤷</span>

<Link to="/">
<button className="border px-4 py-2 rounded-sm">
<span>Go Home</span>
</button>
</Link>
</div>
),
},
]);
9 changes: 9 additions & 0 deletions src/ui/src/apps/contacts/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const ContactsApp = () => {
return (
<main className="p-8 flex flex-col gap-2">
<h1 className="text-2xl font-bold">Contacts</h1>

<div className="bg-secondary p-4">Card like component</div>
</main>
);
};
Loading

0 comments on commit 6399c5e

Please sign in to comment.