This commit is contained in:
2025-03-26 19:54:15 +05:00
parent f2de9827ff
commit 68650f7109
37 changed files with 365 additions and 270 deletions
+3 -6
View File
@@ -1,9 +1,6 @@
POSTGRES_URI=postgres://postgres:admin@192.168.1.250:5432/postgres # POSTGRES_URI=postgres://postgres:admin@192.168.1.250:5432/postgres
DB_HOST=192.168.1.250:5432 POSTGRES_URI=postgres://postgres:v1sq3vD5faXL@194.26.138.94:5432/estate
DB_USER=postgres PORT=3003
DB_PASSWORD=admin
DB_DATABASE=postgres
PORT=3001
JWT_ACCESS_SECRET=aboba JWT_ACCESS_SECRET=aboba
JWT_REFRESH_SECRET=aboba JWT_REFRESH_SECRET=aboba
JWT_ACCESS_EXP_TIME=30d JWT_ACCESS_EXP_TIME=30d
+12
View File
@@ -0,0 +1,12 @@
POSTGRES_URI=postgres://postgres:v1sq3vD5faXL@194.26.138.94:5432/estate
PORT=3003
JWT_ACCESS_SECRET=aboba
JWT_REFRESH_SECRET=aboba
JWT_ACCESS_EXP_TIME=30d
JWT_REFRESH_EXP_TIME=30d
NODE_ENV=development
S3_REGION=ru-central1
S3_ENDPOINT=https://storage.yandexcloud.net
S3_ACCESS_KEY_ID=YCAJE7XefUV51hyi9GEdld8S3
S3_ACCESS_KEY=YCPY__ni1vs95aDjhutAlF8xX0kg3XP6Lbj9PifZ
S3_BUCKET=dult-faib-knac-fint
+3
View File
@@ -33,6 +33,9 @@ yarn-error.log*
# vercel # vercel
.vercel .vercel
dist
.vscode
**/*.trace **/*.trace
**/*.zip **/*.zip
**/*.tar.gz **/*.tar.gz
+31
View File
@@ -0,0 +1,31 @@
import { $, Glob } from 'bun';
import path from 'path';
// Cross-platform directory removal
if (process.platform === 'win32') {
// await $`cmd /c "rmdir /s /q dist"`;
} else {
await $`rm -rf ./dist`;
}
// await Bun.build({
// entrypoints: ["./src/index.ts"],
// env: "inline",
// target: "bun",
// outdir: `./dist`,
// minify: true,
// });
// Build all files in src
for (const entrypoint of new Glob('./src/**/*.ts').scanSync()) {
const parts = entrypoint.split(path.sep);
const entrypointPath = path.join(...parts.slice(2, -1));
await Bun.build({
entrypoints: [entrypoint],
target: 'bun',
outdir: path.join('dist', entrypointPath),
env: 'inline',
minify: true,
});
}
-8
View File
@@ -1,8 +0,0 @@
import { Glob } from 'bun';
for (const entrypoint of new Glob('src/**/*.ts').scanSync())
await Bun.build({
entrypoints: [entrypoint],
target: 'bun',
outdir: './dist/' + entrypoint.split('\\').slice(1, -1).join('\\'),
});
+2
View File
@@ -1,5 +1,7 @@
import { defineConfig } from 'drizzle-kit'; import { defineConfig } from 'drizzle-kit';
console.log('POSTGRES_URI!', process.env.POSTGRES_URI!);
export default defineConfig({ export default defineConfig({
dialect: 'postgresql', dialect: 'postgresql',
schema: './src/db/schema/index.ts', schema: './src/db/schema/index.ts',
+2 -1
View File
@@ -4,7 +4,8 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "bun --hot ./src", "dev": "bun --hot ./src",
"push": "drizzle-kit push" "push": "drizzle-kit push",
"build": "bun ./bun.build.ts"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.709.0", "@aws-sdk/client-s3": "^3.709.0",
+11 -6
View File
@@ -1,11 +1,16 @@
import Elysia, { t } from 'elysia'; import Elysia, { t } from 'elysia';
import { authMiddleware } from '../middlewares/auth'; import { authMiddleware } from '../middlewares/auth.ts';
import { getAll, getOne, create, remove, update } from '../services/articles'; import {
import { Block } from '../types/article'; getAll,
import { getCount } from '../services/articles/getCount'; getOne,
create,
remove,
update,
} from '../services/articles/index.ts';
import { getCount } from '../services/articles/getCount.ts';
import { createInsertSchema, createSelectSchema } from 'drizzle-typebox'; import { createInsertSchema, createSelectSchema } from 'drizzle-typebox';
import { articlesTable } from '../db/schema'; import { articlesTable } from '../db/schema/index.ts';
import { getDrafted } from '../services/articles/getDrafted'; import { getDrafted } from '../services/articles/getDrafted.ts';
const getArticle = createSelectSchema(articlesTable); const getArticle = createSelectSchema(articlesTable);
+10 -8
View File
@@ -3,7 +3,7 @@ import { authMiddleware } from '../middlewares/auth';
import { login, logout, refresh } from '../services/auth'; import { login, logout, refresh } from '../services/auth';
export const authController = new Elysia({ prefix: '/auth' }) export const authController = new Elysia({ prefix: '/auth' })
.post('/login', async ({ body, cookie }) => await login(body, cookie), { .post('/login', async ({ body }) => await login(body), {
body: t.Object({ body: t.Object({
username: t.String(), username: t.String(),
password: t.String({ minLength: 6 }), password: t.String({ minLength: 6 }),
@@ -16,16 +16,15 @@ export const authController = new Elysia({ prefix: '/auth' })
}, },
}) })
.use(authMiddleware) .use(authMiddleware)
.get('/check', async (context) => { .get('/check', async (context) => ({
return { auth: !!('adminId' in context && context.adminId),
auth: 'adminId' in context && context.adminId, }))
};
})
.get( .get(
'/logout', '/logout',
async ({ cookie, adminId }) => await logout(cookie, adminId), async ({ adminId, headers }) =>
await logout(adminId, headers.authorization),
{ {
cookie: t.Cookie({ accessToken: t.String(), refreshToken: t.String() }), // cookie: t.Cookie({ accessToken: t.String(), refreshToken: t.String() }),
adminId: t.String(), adminId: t.String(),
response: { response: {
200: t.Object({ success: t.Boolean() }), 200: t.Object({ success: t.Boolean() }),
@@ -33,6 +32,9 @@ export const authController = new Elysia({ prefix: '/auth' })
401: t.ObjectString({}), 401: t.ObjectString({}),
500: t.ObjectString({}), 500: t.ObjectString({}),
}, },
headers: t.Object({
authorization: t.String(),
}),
} }
) )
.get( .get(
+4 -4
View File
@@ -5,11 +5,11 @@ import {
create, create,
update, update,
remove, remove,
} from '../services/companies'; } from '../services/companies/index.ts';
import { authMiddleware } from '../middlewares/auth'; import { authMiddleware } from '../middlewares/auth.ts';
import { createInsertSchema, createSelectSchema } from 'drizzle-typebox'; import { createInsertSchema, createSelectSchema } from 'drizzle-typebox';
import { companiesTable } from '../db/schema'; import { companiesTable } from '../db/schema/index.ts';
import { getByCity } from '../services/companies/getByCity'; import { getByCity } from '../services/companies/getByCity.ts';
const createCompany = createInsertSchema(companiesTable); const createCompany = createInsertSchema(companiesTable);
+53 -35
View File
@@ -1,51 +1,69 @@
import Elysia, { t } from 'elysia'; import Elysia, { error, t } from 'elysia';
import nodemailer from 'nodemailer'; import nodemailer from 'nodemailer';
import { db } from '../db';
import { mailTable } from '../db/schema/mail';
import { createInsertSchema } from 'drizzle-typebox';
const createMailSchema = createInsertSchema(mailTable);
export const mailController = new Elysia({ prefix: '/mail' }).post( export const mailController = new Elysia({ prefix: '/mail' }).post(
'/', '/',
async ({ async ({
headers: { referer }, headers: { referer },
body: { email, fullname, phone, products }, body: { email, fullname, phone, products = [], request = '' },
}) => { }) => {
const url = new URL(referer); const url = new URL(referer);
let transporter = nodemailer.createTransport({ try {
host: 'mail.netangels.ru', await db
port: 587, .insert(mailTable)
secure: false, // true for 465, false for other ports .values({ email, fullname, phone, products, request, from: url.host });
auth: {
user: 'test@graff.tech', // generated ethereal user
pass: 'ZmL0pKiDFWUyCDMq', // generated ethereal password
},
});
let info = await transporter.sendMail({ let transporter = nodemailer.createTransport({
from: email, // sender address host: 'mail.netangels.ru',
to: 'info@graff.tech', // list of receivers port: 587,
subject: `Заявка с сайта ${url.host}`, // Subject line secure: false, // true for 465, false for other ports
text: ` auth: {
Имя Фамилия: ${fullname} user: 'test@graff.tech', // generated ethereal user
Email: ${email} pass: 'ZmL0pKiDFWUyCDMq', // generated ethereal password
Телефон: ${phone} },
Продукты: ${products.join(', ')} });
`, // plain text body
html: `<div>
<p>Имя: ${fullname}</p>
<p>Email: ${email}</p>
<p>Телефон: ${phone}</p>
<p>Продукты: ${products.join(', ')}</p>
</div>`, // html body
});
return info; let info = await transporter.sendMail({
from: email, // sender address
to: 'info@graff.tech', // list of receivers
subject: `Заявка с сайта ${url.host}`, // Subject line
text: `
Имя Фамилия: ${fullname}
Email: ${email}
${phone ? `Телефон: ${phone}` : ''}
${
products && products.length > 0
? 'Продукты: ' + products.join(', ')
: ''
}
`, // plain text body
html: `<div>
<p>Имя: ${fullname}</p>
<p>Email: ${email}</p>
${phone ? `<p>Телефон: ${phone}</p>` : ''}
${
products && products.length > 0
? '<p>Продукты: ' + products.join(', ') + '</p>'
: ''
}
${request ? '<p>Текст заявки: ' + request + '</p>' : ''}
</div>`, // html body
});
return info;
} catch (err) {
console.log((err as Error).message);
return error(500, { error: 'Internal Server Error' });
}
}, },
{ {
headers: t.Object({ referer: t.String() }), headers: t.Object({ referer: t.String() }),
body: t.Object({ body: createMailSchema,
fullname: t.String(),
email: t.String({ format: 'email' }),
phone: t.String(),
products: t.Array(t.String()),
}),
} }
); );
+52
View File
@@ -0,0 +1,52 @@
import { createInsertSchema, createSelectSchema } from 'drizzle-typebox';
import Elysia, { t } from 'elysia';
import { mapTable } from '../db/schema';
import { getByCity } from '../services/map/getByCity';
import { authMiddleware } from '../middlewares/auth';
import { createMapPoint } from '../services/map/createMapPoint';
import { updateMapPoint } from '../services/map/updateMapPoint';
import { deleteMapPoint } from '../services/map/deleteMapPoint';
const getMapPointsSchema = createSelectSchema(mapTable);
const createMapPointSchema = createInsertSchema(mapTable);
export const mapController = new Elysia({
prefix: '/map',
})
.get('/', async ({ query: { city } }) => await getByCity(city), {
response: {
200: t.Array(getMapPointsSchema),
404: t.ObjectString({}),
500: t.ObjectString({}),
},
query: t.Object({
city: t.String(),
}),
})
.use(authMiddleware)
.post('/', async ({ body }) => await createMapPoint(body), {
response: { 200: getMapPointsSchema, 500: t.ObjectString({}) },
body: createMapPointSchema,
})
.put(
'/:id',
async ({ body, params: { id } }) => await updateMapPoint(id, body),
{
response: {
200: getMapPointsSchema,
404: t.ObjectString({}),
500: t.ObjectString({}),
},
params: t.Object({ id: t.String({ format: 'uuid' }) }),
body: createMapPointSchema,
}
)
.delete('/:id', async ({ params: { id } }) => await deleteMapPoint(id), {
response: {
200: getMapPointsSchema,
404: t.ObjectString({}),
500: t.ObjectString({}),
},
params: t.Object({ id: t.String({ format: 'uuid' }) }),
});
-49
View File
@@ -1,49 +0,0 @@
import { getAll } from '../services/mapVideos/getAll';
import { createInsertSchema, createSelectSchema } from 'drizzle-typebox';
import Elysia, { t } from 'elysia';
import { mapVideosTable } from '../db/schema';
import { authMiddleware } from '../middlewares/auth';
import { createMapVideo } from '../services/mapVideos/create';
import { updateMapVideo } from '../services/mapVideos/update';
import { deleteMapVideo } from '../services/mapVideos/delete';
const getMapVideosSchema = createSelectSchema(mapVideosTable);
const createMapVideoSchema = createInsertSchema(mapVideosTable);
export const mapVideosController = new Elysia({ prefix: '/mapVideos' })
.get('/', async () => await getAll(), {
response: {
200: t.Array(getMapVideosSchema),
500: t.ObjectString({}),
},
})
.use(authMiddleware)
.post('/', async ({ body }) => await createMapVideo(body), {
body: createMapVideoSchema,
response: {
200: getMapVideosSchema,
500: t.ObjectString({}),
},
})
.put(
'/:id',
async ({ body, params: { id } }) => await updateMapVideo(id, body),
{
params: t.Object({ id: t.String({ format: 'uuid' }) }),
body: createMapVideoSchema,
response: {
200: getMapVideosSchema,
404: t.ObjectString({}),
500: t.ObjectString({}),
},
}
)
.delete('/:id', async ({ params: { id } }) => await deleteMapVideo(id), {
params: t.Object({ id: t.String({ format: 'uuid' }) }),
response: {
200: getMapVideosSchema,
404: t.ObjectString({}),
500: t.ObjectString({}),
},
});
+2 -2
View File
@@ -1,6 +1,6 @@
import Elysia, { error, t } from 'elysia'; import Elysia, { error, t } from 'elysia';
import { authMiddleware } from '../middlewares/auth'; import { authMiddleware } from '../middlewares/auth.ts';
import { s3client } from '../config/s3client'; import { s3client } from '../config/s3client.ts';
import { PutObjectCommand } from '@aws-sdk/client-s3'; import { PutObjectCommand } from '@aws-sdk/client-s3';
import { randomUUIDv7 } from 'bun'; import { randomUUIDv7 } from 'bun';
+2 -1
View File
@@ -4,4 +4,5 @@ export * from './projects.ts';
export * from './tokens.ts'; export * from './tokens.ts';
export * from './companies.ts'; export * from './companies.ts';
export * from './stories.ts'; export * from './stories.ts';
export * from './mapVideos.ts'; export * from './map.ts';
export * from './mail.ts';
+20
View File
@@ -0,0 +1,20 @@
import { text } from 'drizzle-orm/pg-core';
import { pgTable, uuid } from 'drizzle-orm/pg-core';
export const mailTable = pgTable('mail', {
id: uuid('id').defaultRandom().primaryKey(),
fullname: text('fullname').notNull(),
email: text('email').notNull(),
phone: text('phone'),
request: text('request'),
products: text('products', {
enum: [
'Интерактивная презентация',
'Удаленная демонстрация',
'Архитектурная визуализация',
'Создание сайтов',
'Web-тур по 360 сферам',
],
}).array(),
from: text('from').notNull(),
});
+27
View File
@@ -0,0 +1,27 @@
import { pgTable, text, uuid, varchar } from 'drizzle-orm/pg-core';
import { companiesTable } from './companies';
import { projectsTable } from './projects';
import { relations } from 'drizzle-orm';
export const mapTable = pgTable('map', {
id: uuid('id').defaultRandom().primaryKey(),
city: varchar('city', { length: 50 }).notNull(),
src: text('src'),
companyId: uuid('company_id')
.notNull()
.references(() => companiesTable.id),
projectId: uuid('project_id')
.notNull()
.references(() => projectsTable.id),
});
export const mapRelations = relations(mapTable, ({ one }) => ({
company: one(companiesTable, {
fields: [mapTable.companyId],
references: [companiesTable.id],
}),
project: one(projectsTable, {
fields: [mapTable.projectId],
references: [projectsTable.id],
}),
}));
-17
View File
@@ -1,17 +0,0 @@
import { pgTable, text, uuid, varchar } from 'drizzle-orm/pg-core';
import { companiesTable } from './companies';
import { relations } from 'drizzle-orm';
export const mapVideosTable = pgTable('map_videos', {
id: uuid('id').defaultRandom().primaryKey(),
city: varchar('city', { length: 50 }).notNull(),
video: text('video').notNull(),
companyId: uuid('company_id').references(() => companiesTable.id),
});
export const videosRelations = relations(mapVideosTable, ({ one }) => ({
company: one(companiesTable, {
fields: [mapVideosTable.companyId],
references: [companiesTable.id],
}),
}));
+2 -5
View File
@@ -10,10 +10,7 @@ import { companiesController } from './controllers/companies';
import { mailController } from './controllers/mail'; import { mailController } from './controllers/mail';
import { getReionNameController } from './controllers/getRegionName'; import { getReionNameController } from './controllers/getRegionName';
import { storiesController } from './controllers/stories'; import { storiesController } from './controllers/stories';
import { mapVideosController } from './controllers/mapVideos'; import { mapController } from './controllers/map';
import { db } from './db';
import { projectsTable } from './db/schema';
import { eq, ne } from 'drizzle-orm';
try { try {
const app = new Elysia(); const app = new Elysia();
@@ -30,7 +27,7 @@ try {
.use(uploadController) .use(uploadController)
.use(companiesController) .use(companiesController)
.use(storiesController) .use(storiesController)
.use(mapVideosController) .use(mapController)
.use(mailController) .use(mailController)
.use(getReionNameController) .use(getReionNameController)
.listen(process.env.PORT); .listen(process.env.PORT);
+5 -16
View File
@@ -5,16 +5,10 @@ import { verifyToken } from '../utils/verifyToken';
import { adminsTable } from '../db/schema'; import { adminsTable } from '../db/schema';
export const authMiddleware = new Elysia() export const authMiddleware = new Elysia()
.derive({ as: 'scoped' }, async ({ headers, cookie, path }: Context) => { .derive({ as: 'scoped' }, async ({ headers, path }: Context) => {
const token = const token = headers['authorization'];
(path === '/auth/refresh'
? cookie.refreshToken.value
: cookie.accessToken.value) || headers.authorization;
const payload = await verifyToken( const payload = await verifyToken('access', token);
path === '/auth/refresh' ? 'refresh' : 'access',
token
);
if (!token || !payload) if (!token || !payload)
return path === '/auth/check' return path === '/auth/check'
@@ -32,14 +26,9 @@ export const authMiddleware = new Elysia()
if ( if (
!user || !user ||
user.tokens.every( user.tokens.every(({ accessToken }) => token !== accessToken)
({ accessToken, refreshToken }) => )
token !== (path === '/auth/refresh' ? refreshToken : accessToken)
)
) {
console.log("attempt to login with someone else's token");
return error(401, { error: 'Not authorized' }); return error(401, { error: 'Not authorized' });
}
} catch (err) { } catch (err) {
console.log((err as Error).message); console.log((err as Error).message);
return error(500, { return error(500, {
+2 -2
View File
@@ -1,6 +1,6 @@
import { error } from 'elysia'; import { error } from 'elysia';
import { db } from '../../db'; import { db } from '../../db/index.ts';
import { articlesTable } from '../../db/schema'; import { articlesTable } from '../../db/schema/index.ts';
import { slugify } from 'transliteration'; import { slugify } from 'transliteration';
export async function create(input: typeof articlesTable.$inferInsert) { export async function create(input: typeof articlesTable.$inferInsert) {
+3 -2
View File
@@ -1,4 +1,4 @@
import { and, arrayContains, not } from 'drizzle-orm'; import { and, arrayContains, arrayOverlaps, desc, not } from 'drizzle-orm';
import { db } from '../../db'; import { db } from '../../db';
import { articlesTable } from '../../db/schema'; import { articlesTable } from '../../db/schema';
import { error } from 'elysia'; import { error } from 'elysia';
@@ -10,8 +10,9 @@ export async function getAll(tags: string[] = [], offset = 0, limit = 10) {
limit, limit,
where: and( where: and(
not(articlesTable.drafted), not(articlesTable.drafted),
tags.length > 0 ? arrayContains(articlesTable.tags, tags) : undefined tags.length > 0 ? arrayOverlaps(articlesTable.tags, tags) : undefined
), ),
orderBy: desc(articlesTable.createdAt),
}); });
} catch (err) { } catch (err) {
console.log((err as Error).message); console.log((err as Error).message);
+5 -5
View File
@@ -1,5 +1,5 @@
export * from './getAll'; export * from './getAll.ts';
export * from './getOne'; export * from './getOne.ts';
export * from './create'; export * from './create.ts';
export * from './remove'; export * from './remove.ts';
export * from './update'; export * from './update.ts';
+2 -2
View File
@@ -1,6 +1,6 @@
import { eq } from 'drizzle-orm'; import { eq } from 'drizzle-orm';
import { db } from '../../db'; import { db } from '../../db/index.ts';
import { articlesTable } from '../../db/schema'; import { articlesTable } from '../../db/schema/index.ts';
import { error } from 'elysia'; import { error } from 'elysia';
import { slugify } from 'transliteration'; import { slugify } from 'transliteration';
+7 -18
View File
@@ -3,10 +3,13 @@ import { generateToken } from '../../utils/generateToken';
import { db } from '../../db'; import { db } from '../../db';
import { tokensTable } from '../../db/schema'; import { tokensTable } from '../../db/schema';
export async function generateTokens( export async function generateTokens(adminId: string): Promise<
adminId: string, | {
cookie: Record<string, Cookie<string | undefined>> accessToken: string;
) { refreshToken: string;
}
| ReturnType<typeof error>
> {
const accessToken = await generateToken(adminId, 'access'); const accessToken = await generateToken(adminId, 'access');
const refreshToken = await generateToken(adminId, 'refresh'); const refreshToken = await generateToken(adminId, 'refresh');
@@ -23,20 +26,6 @@ export async function generateTokens(
return error(500, { error: 'Something went wrong (Postgres insert)' }); return error(500, { error: 'Something went wrong (Postgres insert)' });
} }
cookie.accessToken.set({
value: accessToken,
httpOnly: true,
// secure: true,
maxAge: 3600 * 24 * 30,
});
cookie.refreshToken.set({
value: refreshToken,
httpOnly: true,
// secure: true,
maxAge: 3600 * 24 * 30,
});
return { return {
accessToken, accessToken,
refreshToken, refreshToken,
+24 -8
View File
@@ -4,8 +4,8 @@ import { getUserByUsername } from '../admins/getByUsername';
import { generateTokens } from './generateTokens'; import { generateTokens } from './generateTokens';
export async function login( export async function login(
body: { username: string; password: string }, body: { username: string; password: string }
cookie: Record<string, Cookie<string | undefined>> // cookie: Record<string, Cookie<string | undefined>>
) { ) {
const { username, password } = body; const { username, password } = body;
@@ -14,12 +14,28 @@ export async function login(
if (user instanceof ElysiaCustomStatusResponse) if (user instanceof ElysiaCustomStatusResponse)
return error(user.code, user.response.error); return error(user.code, user.response.error);
const passwordMatches = user if (!user || !Bun.password.verifySync(password, user.hashedPassword))
? Bun.password.verifySync(password, user.hashedPassword)
: false;
if (!user || !passwordMatches)
return error(401, { error: 'Wrong credentials' }); return error(401, { error: 'Wrong credentials' });
return await generateTokens(user.id, cookie); const res = await generateTokens(user.id);
// if ('accessToken' in res && 'refreshToken' in res) {
// cookie.accessToken.set({
// value: res.accessToken,
// httpOnly: true,
// sameSite: 'lax',
// // secure: true,
// maxAge: 3600 * 24 * 30,
// });
// cookie.refreshToken.set({
// value: res.refreshToken,
// httpOnly: true,
// sameSite: 'lax',
// // secure: true,
// maxAge: 3600 * 24 * 30,
// });
// }
return res;
} }
+9 -8
View File
@@ -4,11 +4,12 @@ import { tokensTable } from '../../db/schema';
import { and, eq } from 'drizzle-orm'; import { and, eq } from 'drizzle-orm';
export async function logout( export async function logout(
cookie: Record<string, Cookie<string | undefined>> & { adminId: string,
accessToken: Cookie<string>; authorizatoin: string
refreshToken: Cookie<string>; // cookie: Record<string, Cookie<string | undefined>> & {
}, // accessToken: Cookie<string>;
adminId: string // refreshToken: Cookie<string>;
// }
) { ) {
try { try {
const result = await db const result = await db
@@ -16,7 +17,7 @@ export async function logout(
.where( .where(
and( and(
eq(tokensTable.adminId, adminId), eq(tokensTable.adminId, adminId),
eq(tokensTable.accessToken, cookie.accessToken.value!) eq(tokensTable.accessToken, authorizatoin)
) )
) )
.returning(); .returning();
@@ -29,8 +30,8 @@ export async function logout(
}); });
} }
cookie.accessToken.remove(); // cookie.accessToken.remove();
cookie.refreshToken.remove(); // cookie.refreshToken.remove();
return { return {
success: true, success: true,
+5 -5
View File
@@ -1,5 +1,5 @@
export * from './getMany'; export * from './getMany.ts';
export * from './getCount'; export * from './getCount.ts';
export * from './create'; export * from './create.ts';
export * from './update'; export * from './update.ts';
export * from './remove'; export * from './remove.ts';
+14
View File
@@ -0,0 +1,14 @@
import { error } from 'elysia';
import { db } from '../../db';
import { mapTable } from '../../db/schema';
export async function createMapPoint(payload: typeof mapTable.$inferInsert) {
try {
const res = await db.insert(mapTable).values(payload).returning();
if (res.length) return res[0];
return error(500, 'Internal Server Error');
} catch (err) {
console.log((err as Error).message);
return error(500, 'Internal Server Error');
}
}
@@ -1,15 +1,15 @@
import { eq } from 'drizzle-orm';
import { db } from '../../db';
import { mapVideosTable } from '../../db/schema';
import { error } from 'elysia'; import { error } from 'elysia';
import { db } from '../../db';
import { mapTable } from '../../db/schema';
import { eq } from 'drizzle-orm';
export async function deleteMapVideo(id: string) { export async function deleteMapPoint(id: string) {
try { try {
const res = await db const res = await db
.delete(mapVideosTable) .delete(mapTable)
.where(eq(mapVideosTable.id, id)) .where(eq(mapTable.id, id))
.returning(); .returning();
if (!res.length) return error(404, 'Not Found'); if (!res.length) return error(404, 'Map not found');
return res[0]; return res[0];
} catch (err) { } catch (err) {
console.log((err as Error).message); console.log((err as Error).message);
+21
View File
@@ -0,0 +1,21 @@
import { eq } from 'drizzle-orm';
import { db } from '../../db';
import { mapTable } from '../../db/schema';
import { error } from 'elysia';
export async function getByCity(city: string) {
try {
const res = await db.query.mapTable.findMany({
where: eq(mapTable.city, city),
with: {
company: true,
project: true,
},
});
if (!res) return error(404, { error: 'Map point not found' });
return res;
} catch (err) {
console.log((err as Error).message);
return error(500, 'Internal Server Error');
}
}
+22
View File
@@ -0,0 +1,22 @@
import { error } from 'elysia';
import { mapTable } from '../../db/schema';
import { db } from '../../db';
import { eq } from 'drizzle-orm';
export async function updateMapPoint(
id: string,
payload: Partial<typeof mapTable.$inferInsert>
) {
try {
const res = await db
.update(mapTable)
.set(payload)
.where(eq(mapTable.id, id))
.returning();
if (!res.length) return error(404, 'Map not found');
return res[0];
} catch (err) {
console.log((err as Error).message);
return error(500, 'Internal Server Error');
}
}
-16
View File
@@ -1,16 +0,0 @@
import { error } from 'elysia';
import { db } from '../../db';
import { mapVideosTable } from '../../db/schema';
export async function createMapVideo(
paylaod: typeof mapVideosTable.$inferInsert
) {
try {
const res = await db.insert(mapVideosTable).values(paylaod).returning();
if (!res) return error(500, 'Internal Server Error');
return res[0];
} catch (err) {
console.log((err as Error).message);
return error(500, 'Internal Server Error');
}
}
-11
View File
@@ -1,11 +0,0 @@
import { error } from 'elysia';
import { db } from '../../db';
export async function getAll() {
try {
return await db.query.mapVideosTable.findMany({ with: { company: true } });
} catch (err) {
console.log((err as Error).message);
return error(500, { error: 'Internal Server Error' });
}
}
-24
View File
@@ -1,24 +0,0 @@
import { error } from 'elysia';
import { db } from '../../db';
import { mapVideosTable } from '../../db/schema';
import { eq } from 'drizzle-orm';
export async function updateMapVideo(
id: string,
payload: typeof mapVideosTable.$inferInsert
) {
try {
const candidate = await db.query.mapVideosTable.findFirst();
if (!candidate) return error(404, 'Not Found');
const res = await db
.update(mapVideosTable)
.set(payload)
.where(eq(mapVideosTable.id, id))
.returning();
if (!res) return error(500, 'Internal Server Error');
return res[0];
} catch (err) {
console.log((err as Error).message);
return error(500, 'Internal Server Error');
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { and, arrayContains, desc, eq } from 'drizzle-orm'; import { and, arrayContains, arrayOverlaps, desc, eq } from 'drizzle-orm';
import { db } from '../../db'; import { db } from '../../db';
import { projectsTable } from '../../db/schema'; import { projectsTable } from '../../db/schema';
import { error } from 'elysia'; import { error } from 'elysia';
@@ -12,7 +12,7 @@ export async function getMany(
try { try {
return await db.query.projectsTable.findMany({ return await db.query.projectsTable.findMany({
where: and( where: and(
tags.length > 0 ? arrayContains(projectsTable.tags, tags) : undefined, tags.length > 0 ? arrayOverlaps(projectsTable.tags, tags) : undefined,
city ? eq(projectsTable.city, city) : undefined, city ? eq(projectsTable.city, city) : undefined,
companyId ? eq(projectsTable.companyId, companyId) : undefined companyId ? eq(projectsTable.companyId, companyId) : undefined
), ),
+1 -2
View File
@@ -107,8 +107,7 @@
"./drizzle.config.ts", "./drizzle.config.ts",
"./env.d.ts", "./env.d.ts",
"./src/**/*.ts", "./src/**/*.ts",
"./bun.config.ts" "./bun.build.ts"
// "src/controllers/getRegionName.ts"
], ],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }