Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Server upgrade #331

Merged
merged 16 commits into from
Nov 25, 2024
Merged
1 change: 0 additions & 1 deletion apps/lp/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Generated by Shelve CLI
NUXT_PUBLIC_SITE_URL=your_value
NUXT_PRIVATE_VAULT_URL=your_value
NUXT_PRIVATE_ENCRYPTION_KEY=your_value
8 changes: 2 additions & 6 deletions apps/lp/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-04-03',

Expand All @@ -25,11 +24,8 @@ export default defineNuxtConfig({
],

runtimeConfig: {
public: {
siteUrl: process.env.NUXT_PUBLIC_SITE_URL || 'http://localhost:3000',
},
private: {
encryptionKey: process.env.NUXT_PRIVATE_ENCRYPTION_KEY,
encryptionKey: '',
},
},

Expand All @@ -47,7 +43,7 @@ export default defineNuxtConfig({
},

site: {
url: process.env.NUXT_PUBLIC_SITE_URL,
url: 'https://shelve.cloud',
name: 'Shelve',
description: 'Shelve is a project management tool for developers teams',
defaultLocale: 'en',
Expand Down
34 changes: 19 additions & 15 deletions apps/lp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"nuxt": "^3.14.1592",
"vue": "latest",
"vue-router": "latest",
"vue-sonner": "^1.3.0",
"@shelve/types": "*",
"@shelve/crypto": "*",
"@tsparticles/engine": "^3.6.0",
"@tsparticles/slim": "^3.6.0",
"@nuxt/image": "^1.8.1",
"@nuxt/scripts": "^0.9.5",
"nuxt": "3.14.1592",
"vue": "3.5.13",
"vue-router": "4.4.5",
"vue-sonner": "1.3.0",
"@shelve/crypto": "1.2.2",
"@tsparticles/engine": "3.7.0",
"@tsparticles/slim": "3.7.0",
"nuxt-build-cache": "0.1.1",
"@nuxt/image": "1.8.1",
"@nuxt/scripts": "0.9.5",
"@nuxt/ui": "3.0.0-alpha.9",
"@nuxtjs/seo": "^2.0.0-rc.23",
"@iconify-json/heroicons": "^1.2.1",
"@iconify-json/lucide": "^1.2.15",
"@iconify-json/simple-icons": "^1.2.12",
"@nuxt/content": "^2.13.4"
"@nuxtjs/seo": "2.0.0-rc.23",
"@iconify-json/heroicons": "1.2.1",
"@iconify-json/lucide": "1.2.15",
"@iconify-json/simple-icons": "1.2.12",
"@nuxt/content": "2.13.4"
},
"devDependencies": {
"@shelve/types": "*",
"typescript": "5.7.2"
}
}
6 changes: 3 additions & 3 deletions apps/lp/server/api/vault.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { VaultService } from '~~/server/services/vault.service'

export default defineEventHandler(async (event) => {
const vault = new VaultService()
const { id } = await getQuery(event)
const vault = new VaultService(event)
const { id } = getQuery(event)

if (id) return vault.decrypt(id)
if (id) return vault.decrypt(id as string)

const body = await readBody(event)
return vault.encrypt(body)
Expand Down
7 changes: 4 additions & 3 deletions apps/lp/server/services/vault.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { DecryptResponse, EncryptRequest, StoredData, TTLFormat } from '@shelve/types'
import type { Storage, StorageValue } from 'unstorage'
import type { H3Event } from 'h3'

export class VaultService {

Expand All @@ -14,10 +15,10 @@ export class VaultService {
'30d': 30 * 24 * 60 * 60 // 30 days in seconds
}

constructor() {
constructor(event: H3Event) {
const config = useRuntimeConfig()
this.encryptionKey = config.private.encryptionKey
this.siteUrl = config.public.siteUrl
this.siteUrl = event.context.siteConfigNitroOrigin
this.storage = useStorage('vault')
}

Expand Down Expand Up @@ -129,7 +130,7 @@ export class VaultService {
}

private generateShareUrl(id: string): string {
return `${this.siteUrl}/vault?id=${id}`
return `${this.siteUrl}vault?id=${id}`
}

}
1 change: 0 additions & 1 deletion apps/shelve/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ NUXT_PRIVATE_ENCRYPTION_KEY=your_value
NUXT_OAUTH_GITHUB_CLIENT_ID=your_value
NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_value
SHELVE_TOKEN=your_value
NUXT_PUBLIC_APP_URL=your_value
NUXT_SESSION_PASSWORD=your_value
DATABASE_URL=your_value
NUXT_PRIVATE_ADMIN_EMAILS=user@your_domain.com,user2@another_domain.com
2 changes: 1 addition & 1 deletion apps/shelve/app/components/project/variable/Selector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async function deleteVariables() {
loading.value = true
const ids = selectedVariables.value.map((v: Variable) => v.id)
try {
await $fetch(`/api/variable`, {
await $fetch(`/api/variables`, {
method: 'DELETE',
body: {
variables: ids,
Expand Down
10 changes: 5 additions & 5 deletions apps/shelve/app/composables/useProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ export function useProjects() {

async function fetchProjects() {
loading.value = true
projects.value = await $fetch<Project[]>(`/api/teams/projects${teamId.value ? `?teamId=${teamId.value}` : ''}`, {
projects.value = await $fetch<Project[]>(`/api/projects${teamId.value ? `?teamId=${teamId.value}` : ''}`, {
method: 'GET',
})
loading.value = false
}

async function fetchCurrentProject(projectId: number) {
currentLoading.value = true
currentProject.value = await $fetch<Project>(`/api/project/${projectId}`, {
currentProject.value = await $fetch<Project>(`/api/projects/${projectId}`, {
method: 'GET',
})
currentLoading.value = false
}

async function createProject(createProjectInput: Omit<CreateProjectInput, 'teamId'>) {
try {
const response = await $fetch<Project>('/api/project', {
const response = await $fetch<Project>('/api/projects', {
method: 'POST',
body: {
...createProjectInput,
Expand All @@ -50,7 +50,7 @@ export function useProjects() {

async function updateProject(projectId: number, project: Project) {
try {
const response = await $fetch<Project>(`/api/project/${projectId}`, {
const response = await $fetch<Project>(`/api/projects/${projectId}`, {
method: 'PUT',
body: project,
})
Expand All @@ -64,7 +64,7 @@ export function useProjects() {

async function deleteProject(projectId: number) {
try {
await $fetch(`/api/project/${projectId}`, {
await $fetch(`/api/projects/${projectId}`, {
method: 'DELETE',
})
projects.value = projects.value.filter((project) => project.id !== projectId)
Expand Down
6 changes: 3 additions & 3 deletions apps/shelve/app/composables/useVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function useVariables(refresh: () => Promise<void>, projectId: string) {
return
}
try {
await $fetch(`/api/variable`, {
await $fetch(`/api/variables`, {
method: 'POST',
body: variablesInput.value,
})
Expand Down Expand Up @@ -99,7 +99,7 @@ export function useVariables(refresh: () => Promise<void>, projectId: string) {
return
}
try {
await $fetch(`/api/variable/${variable.id}`, {
await $fetch(`/api/variables/${variable.id}`, {
method: 'PUT',
body: {
projectId: +projectId,
Expand All @@ -120,7 +120,7 @@ export function useVariables(refresh: () => Promise<void>, projectId: string) {
async function deleteVariable(varId: number, varEnv: string) {
deleteLoading.value = true
try {
await $fetch(`/api/variable/${varId}/${varEnv}`, {
await $fetch(`/api/variables/${varId}/${varEnv}`, {
method: 'DELETE',
})
toast.success('Your variable has been deleted')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const project = inject('project') as Ref<Project>
const loading = inject('loading') as Ref<boolean>
const route = useRoute()

const { status: updateStatus, error: updateError, execute } = useFetch(`/api/project/${projectId}`, {
const { status: updateStatus, error: updateError, execute } = useFetch(`/api/projects/${projectId}`, {
method: 'PUT',
body: project,
watch: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Variable } from '@shelve/types'

const { projectId } = useRoute().params as { projectId: string }

const { data: variables, status, refresh } = useFetch<Variable[]>(`/api/variable/project/${projectId}`, {
const { data: variables, status, refresh } = useFetch<Variable[]>(`/api/variables/project/${projectId}`, {
method: 'GET',
watch: false,
})
Expand Down
3 changes: 0 additions & 3 deletions apps/shelve/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ export default defineNuxtConfig({
},

runtimeConfig: {
public: {
appUrl: '',
},
private: {
resendApiKey: '',
encryptionKey: '',
Expand Down
44 changes: 22 additions & 22 deletions apps/shelve/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,32 @@
"db:push": "drizzle-kit push"
},
"dependencies": {
"@vueuse/core": "^11.3.0",
"@vueuse/nuxt": "^11.3.0",
"drizzle-kit": "^0.28.1",
"h3-zod": "^0.5.3",
"nuxt": "^3.14.1592",
"nuxt-auth-utils": "^0.5.5",
"nuxt-build-cache": "^0.1.1",
"resend": "^4.0.1",
"@iconify-json/heroicons": "^1.2.1",
"@iconify-json/lucide": "^1.2.15",
"@iconify-json/simple-icons": "^1.2.12",
"@nuxt/devtools": "^1.6.1",
"@nuxt/image": "^1.8.1",
"@vueuse/core": "11.3.0",
"@vueuse/nuxt": "11.3.0",
"drizzle-kit": "0.28.1",
"h3-zod": "0.5.3",
"nuxt": "3.14.1592",
"nuxt-auth-utils": "0.5.5",
"nuxt-build-cache": "0.1.1",
"resend": "4.0.1",
"@iconify-json/heroicons": "1.2.1",
"@iconify-json/lucide": "1.2.15",
"@iconify-json/simple-icons": "1.2.12",
"@nuxt/devtools": "1.6.1",
"@nuxt/image": "1.8.1",
"@nuxt/ui": "3.0.0-alpha.9",
"@shelve/crypto": "*",
"@shelve/crypto": "1.2.2",
"@shelve/utils": "*",
"drizzle-orm": "^0.36.4",
"pg": "^8.13.1",
"vue": "^3.5.13",
"vue-router": "^4.4.5",
"vue-sonner": "^1.3.0",
"zod": "^3.23.8"
"drizzle-orm": "0.36.4",
"pg": "8.13.1",
"vue": "3.5.13",
"vue-router": "4.4.5",
"vue-sonner": "1.3.0",
"zod": "3.23.8"
},
"devDependencies": {
"@shelve/types": "*",
"@types/pg": "^8.11.10",
"typescript": "^5.7.2"
"@types/pg": "8.11.10",
"typescript": "5.7.2"
}
}
3 changes: 1 addition & 2 deletions apps/shelve/server/api/admin/users/[id].delete.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { zh } from 'h3-zod'
import { UserService } from '~~/server/services/user.service'
import { idParamsSchema } from '~~/server/database/zod'

export default eventHandler(async (event) => {
const { user } = await requireUserSession(event)
const { id } = await zh.useValidatedParams(event, idParamsSchema)
if (user.id === id) throw createError({ statusCode: 400, statusMessage: 'you can\'t delete your own account' })
await new UserService().deleteUserById(id)
await useDrizzle().delete(tables.users).where(eq(tables.users.id, id))
return {
statusCode: 200,
message: 'user deleted',
Expand Down
5 changes: 2 additions & 3 deletions apps/shelve/server/api/github/repos.get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { GitHubService } from '~~/server/services/github.service'
import { GithubService } from '~~/server/services/github'

export default defineEventHandler(async (event) => {
const githubService = new GitHubService()
return await githubService.getUserRepos(event)
return await new GithubService().getUserRepos(event)
})
5 changes: 2 additions & 3 deletions apps/shelve/server/api/github/upload.post.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GitHubService } from '~~/server/services/github.service'
import { GithubService } from '~~/server/services/github'

export default defineEventHandler(async (event) => {
const formData = await readMultipartFormData(event)
Expand All @@ -16,10 +16,9 @@ export default defineEventHandler(async (event) => {
statusMessage: 'No file provided'
})
}
const gitHubService = new GitHubService()

const file = new File([fileField.data], fileField.filename, { type: fileField.type })
const repoName = 'astra'

return await gitHubService.uploadFile(event, file, repoName)
return await new GithubService().uploadFile(event, file, repoName)
})
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { zh } from 'h3-zod'
import { ProjectService } from '~~/server/services/project.service'
import { ProjectsService } from '~~/server/services/projects'
import { idParamsSchema } from '~~/server/database/zod'

export default eventHandler(async (event) => {
const { user } = await requireUserSession(event)
const { id } = await zh.useValidatedParams(event, idParamsSchema)
await new ProjectService().deleteProject(id, user.id)
await new ProjectsService().deleteProject(id, user.id)
return {
statusCode: 200,
message: 'Project deleted',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { zh } from 'h3-zod'
import { ProjectService } from '~~/server/services/project.service'
import { ProjectsService } from '~~/server/services/projects'
import { idParamsSchema } from '~~/server/database/zod'

export default eventHandler(async (event) => {
const { user } = await requireUserSession(event)
const { id } = await zh.useValidatedParams(event, idParamsSchema)
return await new ProjectService().getProjectById(id, user.id)
return await new ProjectsService().getProject(id, user.id)
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z, zh } from 'h3-zod'
import { ProjectService } from '~~/server/services/project.service'
import { ProjectsService } from '~~/server/services/projects'
import { idParamsSchema } from '~~/server/database/zod'

export default eventHandler(async (event) => {
Expand All @@ -19,7 +19,7 @@ export default eventHandler(async (event) => {
required_error: 'Team ID is required',
}).positive(),
})
return await new ProjectService().updateProject({
return await new ProjectsService().updateProject({
id,
name: body.name,
description: body.description,
Expand All @@ -29,9 +29,6 @@ export default eventHandler(async (event) => {
repository: body.repository,
logo: body.logo,
teamId: body.teamId,
requester: {
id: user.id,
role: user.role,
}
requester: user
})
})
17 changes: 17 additions & 0 deletions apps/shelve/server/api/projects/index.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { z, zh } from 'h3-zod'
import { TeamsService } from '~~/server/services/teams'
import { ProjectsService } from '~~/server/services/projects'

export default eventHandler(async (event) => {
const { user } = await requireUserSession(event)
let { teamId } = await zh.useValidatedQuery(event, {
teamId: z.string().transform((value) => parseInt(value, 10)).optional()
})

if (!teamId) teamId = await new TeamsService().getPrivateUserTeamId(user.id)

return await new ProjectsService().getProjects(teamId, {
id: user.id,
role: user.role,
})
})
Loading