diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..ff30c44
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "editor.tabSize": 2
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 27f5778..5b65544 100644
--- a/package.json
+++ b/package.json
@@ -18,5 +18,10 @@
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
- "type": "module"
+ "type": "module",
+ "dependencies": {
+ "dotenv": "^16.4.5",
+ "postgres": "^3.4.4",
+ "ssh2": "^1.15.0"
+ }
}
diff --git a/src/app.d.ts b/src/app.d.ts
index 743f07b..288a2b9 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -1,9 +1,13 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
+import type { Sql } from "postgres";
+
declare global {
namespace App {
// interface Error {}
- // interface Locals {}
+ interface Locals {
+ sql: Sql
+ }
// interface PageData {}
// interface PageState {}
// interface Platform {}
diff --git a/src/comp/post.svelte b/src/comp/post.svelte
new file mode 100644
index 0000000..b3ababa
--- /dev/null
+++ b/src/comp/post.svelte
@@ -0,0 +1,12 @@
+
+
+
+
{post.name}
+
+
{post.content}
+
diff --git a/src/comp/postlist.svelte b/src/comp/postlist.svelte
new file mode 100644
index 0000000..0528ad9
--- /dev/null
+++ b/src/comp/postlist.svelte
@@ -0,0 +1,14 @@
+
+
+
+ {#each posts as post}
+
+ {/each}
+
diff --git a/src/hooks.server.js b/src/hooks.server.js
new file mode 100644
index 0000000..7e337ad
--- /dev/null
+++ b/src/hooks.server.js
@@ -0,0 +1,41 @@
+// @ts-nocheck
+import { env } from '$lib/env';
+import postgres from 'postgres';
+import ssh2 from 'ssh2';
+
+export const handle = async ({event, resolve}) => {
+ const sql = postgres(
+ // 'postgres://doki8902:ChangeItN8w@pgsql3.mif:5432/studentu',
+ {
+ host: env.PG_HOST,
+ port: parseInt(env.PG_PORT),
+ database: env.PG_DATABASE,
+ username: env.PG_USERNAME,
+ password: env.PG_PASSWORD,
+ socket: ({ host: [host], port: [port] }) => new Promise((resolve, reject) => {
+ const ssh = new ssh2.Client();
+ ssh
+ .on('error', reject)
+ .on('ready', () =>
+ ssh.forwardOut('127.0.0.1', 12345, host, port,
+ (err, socket) => err ? reject(err) : resolve(socket)
+ )
+ )
+ .connect({
+ host: env.SSH_HOST,
+ port: parseInt(env.SSH_PORT),
+ username: env.SSH_USERNAME,
+ password: env.SSH_PASSWORD
+ })
+ })
+ }
+ );
+
+ // https://github.com/porsager/postgres/issues/762
+
+ event.locals = {
+ sql: sql
+ };
+ const response = await resolve(event);
+ return response;
+};
diff --git a/src/lib/db/post.js b/src/lib/db/post.js
new file mode 100644
index 0000000..b300649
--- /dev/null
+++ b/src/lib/db/post.js
@@ -0,0 +1,41 @@
+/**
+ * @param {import('postgres').Sql} sql
+ * @param {number | undefined} category
+ * @param {number} limit
+ * @param {number} offset
+ * @returns {Promise}
+ */
+export async function getPosts(sql, category = undefined, limit = 10, offset = 0) {
+ let query;
+
+ if (category === undefined) {
+ query = sql`
+ SELECT name, latest_content
+ FROM doki8902.message_post
+ FETCH FIRST ${limit} ROWS ONLY
+ OFFSET ${offset};`;
+ } else {
+ query = sql`
+ SELECT name, latest_content
+ FROM doki8902.message_post
+ WHERE category_id = ${category}
+ FETCH FIRST ${limit} ROWS ONLY
+ OFFSET ${offset};`;
+ }
+
+ let posts = await query;
+
+ /**
+ * @type {import('$types/base').Post[]}
+ */
+ let result = [];
+
+ posts.forEach(row => {
+ result.push({
+ name: row['name'],
+ content: row['latest_content']
+ });
+ });
+
+ return result;
+}
diff --git a/src/lib/db/root.js b/src/lib/db/root.js
new file mode 100644
index 0000000..ce29d4f
--- /dev/null
+++ b/src/lib/db/root.js
@@ -0,0 +1,6 @@
+// export function runQuery(
+// /** @type {import('postgres').Sql} */ sql,
+// /** @type {string} */ query,
+// /** @type {any[]} */ args = []) {
+// sql`${query}`
+// }
\ No newline at end of file
diff --git a/src/lib/env.js b/src/lib/env.js
new file mode 100644
index 0000000..1bbb1b7
--- /dev/null
+++ b/src/lib/env.js
@@ -0,0 +1,8 @@
+import dotenv from 'dotenv';
+
+dotenv.config();
+
+/**
+ * @type {import('$types/env').Env}
+ */
+export const env = process.env;
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
new file mode 100644
index 0000000..0385342
--- /dev/null
+++ b/src/routes/(app)/+layout.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/routes/(app)/posts/+page.server.js b/src/routes/(app)/posts/+page.server.js
new file mode 100644
index 0000000..83104e1
--- /dev/null
+++ b/src/routes/(app)/posts/+page.server.js
@@ -0,0 +1,15 @@
+import { getPosts } from '$lib/db/post';
+import { env } from '$lib/env';
+
+/** @type {import('./$types').PageServerLoad} */
+export async function load({ locals }) {
+ let result = await getPosts(locals.sql);
+
+ // console.log();
+
+ console.log(result);
+
+ return {
+ posts: result
+ };
+}
diff --git a/src/routes/(app)/posts/+page.svelte b/src/routes/(app)/posts/+page.svelte
new file mode 100644
index 0000000..9c3220d
--- /dev/null
+++ b/src/routes/(app)/posts/+page.svelte
@@ -0,0 +1,11 @@
+
+
+Posts
+
diff --git a/src/routes/register/+page.server.js b/src/routes/register/+page.server.js
new file mode 100644
index 0000000..ceb2893
--- /dev/null
+++ b/src/routes/register/+page.server.js
@@ -0,0 +1,8 @@
+/** @type {import('./$types').PageServerLoad} */
+export function load({ cookies }) {
+ // coo
+
+ return {
+
+ };
+}
\ No newline at end of file
diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte
new file mode 100644
index 0000000..e69de29
diff --git a/src/types/base.ts b/src/types/base.ts
new file mode 100644
index 0000000..c87f1e3
--- /dev/null
+++ b/src/types/base.ts
@@ -0,0 +1,21 @@
+export type User = {
+ name: string
+};
+
+export type Rating = {
+ likes: number,
+ dislikes: number
+}
+
+export type Category = {
+ name: string
+}
+
+export type Post = {
+ // author: User,
+ name: string,
+ // category: Category,
+ content: string,
+ // post_date: Date,
+ // rating: Rating
+};
diff --git a/src/types/env.ts b/src/types/env.ts
new file mode 100644
index 0000000..86dcf69
--- /dev/null
+++ b/src/types/env.ts
@@ -0,0 +1,12 @@
+export type Env = {
+ PG_USERNAME: string,
+ PG_PASSWORD: string,
+ PG_HOST: string,
+ PG_PORT: string,
+ PG_DATABASE: string,
+
+ SSH_HOST: string,
+ SSH_PORT: string,
+ SSH_USERNAME: string,
+ SSH_PASSWORD: string
+};
diff --git a/svelte.config.js b/svelte.config.js
index 2ca5922..d68dc86 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -1,12 +1,18 @@
import adapter from '@sveltejs/adapter-auto';
+import preprocess from 'svelte-preprocess';
/** @type {import('@sveltejs/kit').Config} */
const config = {
+ preprocess: preprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
- adapter: adapter()
+ adapter: adapter(),
+ alias: {
+ '$types/*': './src/types',
+ '$comp/*': './src/comp'
+ }
}
};
diff --git a/yarn.lock b/yarn.lock
index c9fdbf9..9132936 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -343,6 +343,13 @@ aria-query@^5.3.0:
dependencies:
dequal "^2.0.3"
+asn1@^0.2.6:
+ version "0.2.6"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
+ integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
+ dependencies:
+ safer-buffer "~2.1.0"
+
axobject-query@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.0.0.tgz#04a4c90dce33cc5d606c76d6216e3b250ff70dab"
@@ -355,6 +362,13 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+bcrypt-pbkdf@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+ integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
+ dependencies:
+ tweetnacl "^0.14.3"
+
binary-extensions@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
@@ -380,6 +394,11 @@ buffer-crc32@^0.2.5:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
+buildcheck@~0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238"
+ integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==
+
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -421,6 +440,14 @@ cookie@^0.6.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
+cpu-features@~0.0.9:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.10.tgz#9aae536db2710c7254d7ed67cb3cbc7d29ad79c5"
+ integrity sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==
+ dependencies:
+ buildcheck "~0.0.6"
+ nan "^2.19.0"
+
css-tree@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
@@ -456,6 +483,11 @@ devalue@^5.0.0:
resolved "https://registry.yarnpkg.com/devalue/-/devalue-5.0.0.tgz#1ca0099a7d715b4d6cac3924e770ccbbc584ad98"
integrity sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==
+dotenv@^16.4.5:
+ version "16.4.5"
+ resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
+ integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
+
es6-promise@^3.1.2:
version "3.3.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
@@ -702,6 +734,11 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+nan@^2.18.0, nan@^2.19.0:
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0"
+ integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==
+
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
@@ -759,6 +796,11 @@ postcss@^8.4.38:
picocolors "^1.0.0"
source-map-js "^1.2.0"
+postgres@^3.4.4:
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/postgres/-/postgres-3.4.4.tgz#adbe08dc1fff0dea3559aa4f83ded70a289a6cb8"
+ integrity sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -827,6 +869,11 @@ sade@^1.7.4, sade@^1.8.1:
dependencies:
mri "^1.1.0"
+safer-buffer@~2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
sander@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/sander/-/sander-0.5.1.tgz#741e245e231f07cafb6fdf0f133adfa216a502ad"
@@ -866,6 +913,17 @@ source-map-js@^1.0.1, source-map-js@^1.2.0:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
+ssh2@^1.15.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.15.0.tgz#2f998455036a7f89e0df5847efb5421748d9871b"
+ integrity sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==
+ dependencies:
+ asn1 "^0.2.6"
+ bcrypt-pbkdf "^1.0.2"
+ optionalDependencies:
+ cpu-features "~0.0.9"
+ nan "^2.18.0"
+
strip-indent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
@@ -943,6 +1001,11 @@ totalist@^3.0.0:
resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8"
integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==
+tweetnacl@^0.14.3:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+ integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
+
typescript@^5.0.0, typescript@^5.0.3:
version "5.4.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"