feat(api): add changelog version routes
This commit is contained in:
parent
14f39f47c7
commit
21dd7a28ec
@ -7,15 +7,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@boring.tools/database": "workspace:*",
|
"@boring.tools/database": "workspace:*",
|
||||||
"@boring.tools/schema": "workspace:*",
|
|
||||||
"@boring.tools/logger": "workspace:*",
|
"@boring.tools/logger": "workspace:*",
|
||||||
|
"@boring.tools/schema": "workspace:*",
|
||||||
"@hono/clerk-auth": "^2.0.0",
|
"@hono/clerk-auth": "^2.0.0",
|
||||||
"@hono/zod-openapi": "^0.16.2",
|
"@hono/zod-openapi": "^0.16.2",
|
||||||
"@scalar/hono-api-reference": "^0.5.149",
|
"@scalar/hono-api-reference": "^0.5.149",
|
||||||
"hono": "^4.6.3",
|
"hono": "^4.6.3",
|
||||||
|
"semver": "^7.6.3",
|
||||||
"svix": "^1.36.0"
|
"svix": "^1.36.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest",
|
||||||
|
"@types/semver": "^7.5.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
66
apps/api/src/changelog/version/byId.ts
Normal file
66
apps/api/src/changelog/version/byId.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { changelog, changelog_version, db } from '@boring.tools/database'
|
||||||
|
import { VersionByIdParams, VersionOutput } from '@boring.tools/schema'
|
||||||
|
import { createRoute } from '@hono/zod-openapi'
|
||||||
|
import { and, eq } from 'drizzle-orm'
|
||||||
|
|
||||||
|
export const byId = createRoute({
|
||||||
|
method: 'get',
|
||||||
|
path: '/:id',
|
||||||
|
request: {
|
||||||
|
params: VersionByIdParams,
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: VersionOutput,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Return version by id',
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: 'Bad Request',
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
description: 'Internal Server Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const byIdFunc = async ({
|
||||||
|
userId,
|
||||||
|
id,
|
||||||
|
}: {
|
||||||
|
userId: string
|
||||||
|
id: string
|
||||||
|
}) => {
|
||||||
|
const versionResult = await db.query.changelog_version.findFirst({
|
||||||
|
where: eq(changelog_version.id, id),
|
||||||
|
with: {
|
||||||
|
commits: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!versionResult) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!versionResult.changelogId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const changelogResult = await db.query.changelog.findMany({
|
||||||
|
where: and(eq(changelog.userId, userId)),
|
||||||
|
columns: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const changelogIds = changelogResult.map((cl) => cl.id)
|
||||||
|
|
||||||
|
if (!changelogIds.includes(versionResult.changelogId)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return versionResult
|
||||||
|
}
|
88
apps/api/src/changelog/version/create.ts
Normal file
88
apps/api/src/changelog/version/create.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import { changelog, changelog_version, db } from '@boring.tools/database'
|
||||||
|
import { VersionCreateInput, VersionCreateOutput } from '@boring.tools/schema'
|
||||||
|
import { createRoute, type z } from '@hono/zod-openapi'
|
||||||
|
import { and, eq } from 'drizzle-orm'
|
||||||
|
import { HTTPException } from 'hono/http-exception'
|
||||||
|
import semver from 'semver'
|
||||||
|
|
||||||
|
export const create = createRoute({
|
||||||
|
method: 'post',
|
||||||
|
path: '/',
|
||||||
|
request: {
|
||||||
|
body: {
|
||||||
|
content: {
|
||||||
|
'application/json': { schema: VersionCreateInput },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
201: {
|
||||||
|
content: {
|
||||||
|
'application/json': { schema: VersionCreateOutput },
|
||||||
|
},
|
||||||
|
description: 'Version created',
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: 'Bad Request',
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
description: 'Internal Server Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const createFunc = async ({
|
||||||
|
userId,
|
||||||
|
payload,
|
||||||
|
}: {
|
||||||
|
userId: string
|
||||||
|
payload: z.infer<typeof VersionCreateInput>
|
||||||
|
}) => {
|
||||||
|
const formattedVersion = semver.coerce(payload.version)
|
||||||
|
const validVersion = semver.valid(formattedVersion)
|
||||||
|
|
||||||
|
const changelogResult = await db.query.changelog.findFirst({
|
||||||
|
where: and(
|
||||||
|
eq(changelog.userId, userId),
|
||||||
|
eq(changelog.id, payload.changelogId),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!changelogResult) {
|
||||||
|
throw new HTTPException(404, {
|
||||||
|
message: 'changelog not found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validVersion === null) {
|
||||||
|
throw new HTTPException(409, {
|
||||||
|
message: 'Version is not semver compatible',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a version with the same version already exists
|
||||||
|
const versionResult = await db.query.version.findFirst({
|
||||||
|
where: and(
|
||||||
|
eq(changelog_version.changelogId, payload.changelogId),
|
||||||
|
eq(changelog_version.version, validVersion),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (versionResult) {
|
||||||
|
throw new HTTPException(409, {
|
||||||
|
message: 'Version exists already',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const [versionCreateResult] = await db
|
||||||
|
.insert(changelog_version)
|
||||||
|
.values({
|
||||||
|
changelogId: payload.changelogId,
|
||||||
|
version: validVersion,
|
||||||
|
status: payload.status,
|
||||||
|
markdown: payload.markdown,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
|
||||||
|
return versionCreateResult
|
||||||
|
}
|
60
apps/api/src/changelog/version/delete.ts
Normal file
60
apps/api/src/changelog/version/delete.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { changelog, changelog_version, db } from '@boring.tools/database'
|
||||||
|
import { GeneralOutput } from '@boring.tools/schema'
|
||||||
|
import { createRoute } from '@hono/zod-openapi'
|
||||||
|
import { and, eq } from 'drizzle-orm'
|
||||||
|
import { HTTPException } from 'hono/http-exception'
|
||||||
|
|
||||||
|
export const remove = createRoute({
|
||||||
|
method: 'delete',
|
||||||
|
path: '/:id',
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: GeneralOutput,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Removes a version by id',
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: GeneralOutput,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Version not found',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const removeFunc = async ({
|
||||||
|
userId,
|
||||||
|
id,
|
||||||
|
}: {
|
||||||
|
userId: string
|
||||||
|
id: string
|
||||||
|
}) => {
|
||||||
|
const changelogResult = await db.query.changelog.findMany({
|
||||||
|
where: and(eq(changelog.userId, userId)),
|
||||||
|
with: {
|
||||||
|
versions: {
|
||||||
|
where: eq(changelog_version.id, id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const findChangelog = changelogResult.find((change) =>
|
||||||
|
change.versions.find((ver) => ver.id === id),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!findChangelog?.versions.length) {
|
||||||
|
throw new HTTPException(404, {
|
||||||
|
message: 'Version not found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return db
|
||||||
|
.delete(changelog_version)
|
||||||
|
.where(and(eq(changelog_version.id, id)))
|
||||||
|
.returning()
|
||||||
|
}
|
101
apps/api/src/changelog/version/index.ts
Normal file
101
apps/api/src/changelog/version/index.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { OpenAPIHono } from '@hono/zod-openapi'
|
||||||
|
|
||||||
|
import { HTTPException } from 'hono/http-exception'
|
||||||
|
import type { Variables } from '../..'
|
||||||
|
import { verifyAuthentication } from '../../utils/authentication'
|
||||||
|
import { byId, byIdFunc } from './byId'
|
||||||
|
import { create, createFunc } from './create'
|
||||||
|
import { remove, removeFunc } from './delete'
|
||||||
|
import { update, updateFunc } from './update'
|
||||||
|
|
||||||
|
const app = new OpenAPIHono<{ Variables: Variables }>()
|
||||||
|
|
||||||
|
app.openapi(create, async (c) => {
|
||||||
|
const userId = verifyAuthentication(c)
|
||||||
|
try {
|
||||||
|
const payload = await c.req.json()
|
||||||
|
const result = await createFunc({ userId, payload })
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return c.json({ message: 'Version not created' }, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json(result, 201)
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HTTPException) {
|
||||||
|
return c.json({ message: error.message }, error.status)
|
||||||
|
}
|
||||||
|
return c.json({ message: 'An unexpected error occurred' }, 500)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.openapi(byId, async (c) => {
|
||||||
|
const userId = verifyAuthentication(c)
|
||||||
|
try {
|
||||||
|
const id = c.req.param('id')
|
||||||
|
const result = await byIdFunc({ userId, id })
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return c.json({ message: 'Version not found' }, 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all required properties are present and non-null
|
||||||
|
return c.json(
|
||||||
|
{
|
||||||
|
...result,
|
||||||
|
changelogId: result.changelogId || '',
|
||||||
|
version: result.version || '',
|
||||||
|
status: result.status || 'draft',
|
||||||
|
releasedAt: result.releasedAt
|
||||||
|
? result.releasedAt.toISOString()
|
||||||
|
: new Date().toISOString(),
|
||||||
|
commits: result.commits || [],
|
||||||
|
markdown: result.markdown || '',
|
||||||
|
},
|
||||||
|
200,
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HTTPException) {
|
||||||
|
return c.json({ message: error.message }, error.status)
|
||||||
|
}
|
||||||
|
return c.json({ message: 'An unexpected error occurred' }, 500)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.openapi(update, async (c) => {
|
||||||
|
const userId = verifyAuthentication(c)
|
||||||
|
try {
|
||||||
|
const id = c.req.param('id')
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return c.json({ message: 'Version not found' }, 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await updateFunc({
|
||||||
|
userId,
|
||||||
|
payload: await c.req.json(),
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
|
||||||
|
return c.json(result)
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HTTPException) {
|
||||||
|
return c.json({ message: error.message }, error.status)
|
||||||
|
}
|
||||||
|
return c.json({ message: 'An unexpected error occurred' }, 500)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.openapi(remove, async (c) => {
|
||||||
|
const userId = verifyAuthentication(c)
|
||||||
|
const id = c.req.param('id')
|
||||||
|
const result = await removeFunc({ userId, id })
|
||||||
|
|
||||||
|
if (result.length === 0) {
|
||||||
|
return c.json({ message: 'Version not found' }, 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json({ message: 'Version removed' })
|
||||||
|
})
|
||||||
|
|
||||||
|
export default app
|
72
apps/api/src/changelog/version/update.ts
Normal file
72
apps/api/src/changelog/version/update.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { changelog, changelog_version, db } from '@boring.tools/database'
|
||||||
|
import { VersionUpdateInput, VersionUpdateOutput } from '@boring.tools/schema'
|
||||||
|
import { createRoute, type z } from '@hono/zod-openapi'
|
||||||
|
import { and, eq } from 'drizzle-orm'
|
||||||
|
import { HTTPException } from 'hono/http-exception'
|
||||||
|
|
||||||
|
export const update = createRoute({
|
||||||
|
method: 'put',
|
||||||
|
path: '/:id',
|
||||||
|
request: {
|
||||||
|
body: {
|
||||||
|
content: {
|
||||||
|
'application/json': { schema: VersionUpdateInput },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
'application/json': { schema: VersionUpdateOutput },
|
||||||
|
},
|
||||||
|
description: 'Return updated version',
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: 'Bad Request',
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
description: 'Internal Server Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateFunc = async ({
|
||||||
|
userId,
|
||||||
|
payload,
|
||||||
|
id,
|
||||||
|
}: {
|
||||||
|
userId: string
|
||||||
|
payload: z.infer<typeof VersionUpdateInput>
|
||||||
|
id: string
|
||||||
|
}) => {
|
||||||
|
const changelogResult = await db.query.changelog.findMany({
|
||||||
|
where: and(eq(changelog.userId, userId)),
|
||||||
|
with: {
|
||||||
|
versions: {
|
||||||
|
where: eq(changelog_version.id, id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const findChangelog = changelogResult.find((change) =>
|
||||||
|
change.versions.find((ver) => ver.id === id),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!findChangelog?.versions.length) {
|
||||||
|
throw new HTTPException(404, {
|
||||||
|
message: 'Version not found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const [versionUpdateResult] = await db
|
||||||
|
.update(changelog_version)
|
||||||
|
.set({
|
||||||
|
status: payload.status,
|
||||||
|
markdown: payload.markdown,
|
||||||
|
releasedAt: payload.status === 'published' ? new Date() : null,
|
||||||
|
})
|
||||||
|
.where(and(eq(changelog_version.id, id)))
|
||||||
|
.returning()
|
||||||
|
|
||||||
|
return versionUpdateResult
|
||||||
|
}
|
200
apps/api/src/changelog/version/version.test.ts
Normal file
200
apps/api/src/changelog/version/version.test.ts
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
import { afterAll, beforeAll, describe, expect, test } from 'bun:test'
|
||||||
|
import {
|
||||||
|
type ChangelogSelect,
|
||||||
|
type CommitSelect,
|
||||||
|
type UserSelect,
|
||||||
|
type VersionSelect,
|
||||||
|
changelog,
|
||||||
|
commit,
|
||||||
|
db,
|
||||||
|
user,
|
||||||
|
} from '@changelog/database'
|
||||||
|
import type {
|
||||||
|
CommitCreateInput,
|
||||||
|
VersionCreateInput,
|
||||||
|
VersionOutput,
|
||||||
|
VersionUpdateInput,
|
||||||
|
} from '@changelog/schemas'
|
||||||
|
import type { z } from '@hono/zod-openapi'
|
||||||
|
import { eq } from 'drizzle-orm'
|
||||||
|
import { fetch } from '../../utils/testing/fetch'
|
||||||
|
|
||||||
|
describe('Version', () => {
|
||||||
|
let testUser: UserSelect
|
||||||
|
let testChangelog: ChangelogSelect
|
||||||
|
let testCommits: CommitSelect[]
|
||||||
|
let testVersion: VersionSelect
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const tUser = await db
|
||||||
|
.insert(user)
|
||||||
|
.values({ email: 'version@test.local' })
|
||||||
|
.returning()
|
||||||
|
const tChangelog = await db
|
||||||
|
.insert(changelog)
|
||||||
|
.values({
|
||||||
|
title: 'test',
|
||||||
|
description: 'some description',
|
||||||
|
userId: tUser[0].id,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
|
||||||
|
const payload: z.infer<typeof CommitCreateInput> = [
|
||||||
|
{
|
||||||
|
changelogId: tChangelog[0].id,
|
||||||
|
date: new Date(),
|
||||||
|
message: 'Some commit',
|
||||||
|
shortHash: '1234567',
|
||||||
|
body: 'some body',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changelogId: tChangelog[0].id,
|
||||||
|
date: new Date(),
|
||||||
|
message: 'Some other commit',
|
||||||
|
shortHash: '1234568',
|
||||||
|
body: 'some body',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
await fetch(
|
||||||
|
{
|
||||||
|
path: '/api/commit',
|
||||||
|
method: 'POST',
|
||||||
|
body: payload,
|
||||||
|
},
|
||||||
|
tUser[0],
|
||||||
|
)
|
||||||
|
|
||||||
|
testCommits = await db.query.commit.findMany({
|
||||||
|
where: eq(commit.changelogId, tChangelog[0].id),
|
||||||
|
})
|
||||||
|
testUser = tUser[0]
|
||||||
|
testChangelog = tChangelog[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await db.delete(user).where(eq(user.email, 'version@test.local'))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Create', () => {
|
||||||
|
test('Success', async () => {
|
||||||
|
const payload: z.infer<typeof VersionCreateInput> = {
|
||||||
|
changelogId: testChangelog.id,
|
||||||
|
releasedAt: new Date(),
|
||||||
|
commits: testCommits.map((c) => c.shortHash),
|
||||||
|
status: 'draft',
|
||||||
|
version: '1.0.0',
|
||||||
|
markdown: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: '/api/version',
|
||||||
|
method: 'POST',
|
||||||
|
body: payload,
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
const json = await res.json()
|
||||||
|
testVersion = json
|
||||||
|
|
||||||
|
expect(res.status).toBe(201)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Duplicate', async () => {
|
||||||
|
const payload: z.infer<typeof VersionCreateInput> = {
|
||||||
|
changelogId: testChangelog.id,
|
||||||
|
releasedAt: new Date(),
|
||||||
|
commits: testCommits.map((c) => c.shortHash),
|
||||||
|
status: 'draft',
|
||||||
|
version: '1.0.0',
|
||||||
|
markdown: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: '/api/version',
|
||||||
|
method: 'POST',
|
||||||
|
body: payload,
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
expect(res.status).toBe(409)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('By Id', () => {
|
||||||
|
test('Success', async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: `/api/version/${testVersion.id}`,
|
||||||
|
method: 'GET',
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
|
||||||
|
const json: z.infer<typeof VersionOutput> = await res.json()
|
||||||
|
expect(json.commits).toHaveLength(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Not found', async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: '/api/version/a7d2a68b-0696-4424-96c9-3629ae37978c',
|
||||||
|
method: 'GET',
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(404)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Update', () => {
|
||||||
|
test('Success', async () => {
|
||||||
|
const payload: z.infer<typeof VersionUpdateInput> = {
|
||||||
|
status: 'published',
|
||||||
|
markdown: '',
|
||||||
|
}
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: `/api/version/${testVersion.id}`,
|
||||||
|
method: 'PUT',
|
||||||
|
body: payload,
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Remove', () => {
|
||||||
|
test('Success', async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: `/api/version/${testVersion.id}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Not Found', async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
{
|
||||||
|
path: `/api/version/${testVersion.id}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
},
|
||||||
|
testUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(404)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -4,6 +4,7 @@ import { apiReference } from '@scalar/hono-api-reference'
|
|||||||
import { cors } from 'hono/cors'
|
import { cors } from 'hono/cors'
|
||||||
|
|
||||||
import changelog from './changelog'
|
import changelog from './changelog'
|
||||||
|
import version from './changelog/version'
|
||||||
import user from './user'
|
import user from './user'
|
||||||
|
|
||||||
import { authentication } from './utils/authentication'
|
import { authentication } from './utils/authentication'
|
||||||
@ -22,6 +23,7 @@ app.use('/v1/*', authentication)
|
|||||||
|
|
||||||
app.route('/v1/user', user)
|
app.route('/v1/user', user)
|
||||||
app.route('/v1/changelog', changelog)
|
app.route('/v1/changelog', changelog)
|
||||||
|
app.route('/v1/changelog/version', version)
|
||||||
|
|
||||||
app.doc('/openapi.json', {
|
app.doc('/openapi.json', {
|
||||||
openapi: '3.0.0',
|
openapi: '3.0.0',
|
||||||
|
Loading…
Reference in New Issue
Block a user