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"