Skip to content

Commit 2f94fba

Browse files
committed
add: urlSlug for s3 bucket
1 parent 08aa216 commit 2f94fba

File tree

6 files changed

+56
-40
lines changed

6 files changed

+56
-40
lines changed

apps/book-server/scripts/createMock.mts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,18 @@ class Seeder {
2424
})
2525
}
2626

27-
async createBook(writer: Writer) {
27+
private escapeForUrl(text: string): string {
28+
return text
29+
.replace(
30+
/[^0-9a-zA-Z-.\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf\u3400-\u4dbf -]/g,
31+
'',
32+
)
33+
.trim()
34+
.replace(/ /g, '-')
35+
.replace(/--+/g, '-')
36+
.replace(/\.+$/, '')
37+
}
38+
public async createBook(writer: Writer) {
2839
const mockPages = getMockPages(100).map((page) => ({
2940
writer_id: writer.id,
3041
...page,
@@ -42,7 +53,7 @@ class Seeder {
4253
is_temp: false,
4354
is_private: false,
4455
is_published: true,
45-
url_slug: urlSlug,
56+
url_slug: this.escapeForUrl(urlSlug),
4657
pages: {
4758
createMany: {
4859
data: mockPages,

apps/book-server/src/graphql/resolvers/bookResolvers.mts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ const bookResolvers: Resolvers = {
2121
},
2222
},
2323
Mutation: {
24-
deploy: async (_, { input }) => {
24+
deploy: async (_, { input }, ctx) => {
2525
const bookDeployService = container.resolve(BookDeployService)
26-
return await bookDeployService.deploy(input.book_id)
26+
return await bookDeployService.deploy(input.book_id, ctx.writer?.id)
2727
},
28-
build: async (_, { input }) => {
28+
build: async (_, { input }, ctx) => {
2929
const bookBuildService = container.resolve(BookBuildService)
30-
return await bookBuildService.build(input.book_id)
30+
return await bookBuildService.build(input.book_id, ctx.writer?.id)
3131
},
3232
},
3333
Subscription: {

apps/book-server/src/services/BookBuildService/index.mts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import { MqService } from '@lib/mq/MqService.mjs'
1313
import { nextConfigTempate } from '@templates/nextConfigTemplate.js'
1414
import { WriterService } from '../WriterService/index.mjs'
1515
import { ENV } from '@env'
16+
import { UnauthorizedError } from '@errors/UnauthorizedError.mjs'
1617

1718
const exec = promisify(execCb)
1819

1920
interface Service {
20-
build(bookId: string): Promise<void>
21+
build(bookId: string, signedWriterId?: string): Promise<void>
2122
}
2223

2324
@injectable()
@@ -29,17 +30,17 @@ export class BookBuildService implements Service {
2930
private readonly pageService: PageService,
3031
private readonly writerService: WriterService,
3132
) {}
32-
public async build(bookId: string): Promise<void> {
33+
public async build(bookId: string, signedWriterId?: string): Promise<void> {
3334
// TODO: ADD authentication
34-
// if (!signedUserId) {
35-
// throw new UnauthorizedError('Not logged in')
36-
// }
35+
if (!signedWriterId) {
36+
throw new UnauthorizedError('Not logged in')
37+
}
3738

38-
// const writer = await this.writerService.findById(signedUserId)
39+
const writer = await this.writerService.findById(signedWriterId)
3940

40-
// if (!writer) {
41-
// throw new NotFoundError('Not found writer')
42-
// }
41+
if (!writer) {
42+
throw new NotFoundError('Not found writer')
43+
}
4344

4445
const book = await this.mongo.book.findUnique({
4546
where: { id: bookId },
@@ -49,9 +50,9 @@ export class BookBuildService implements Service {
4950
throw new NotFoundError('Book not found')
5051
}
5152

52-
// if (book.writer_id !== writer.id) {
53-
// throw new ConfilctError('Not owner of book')
54-
// }
53+
if (book.writer_id !== writer.id) {
54+
throw new ConfilctError('Not owner of book')
55+
}
5556

5657
// create folder
5758
const dest = path.resolve(process.cwd(), 'books', bookId)
@@ -94,7 +95,8 @@ export class BookBuildService implements Service {
9495
`${dest}/next.config.mjs`,
9596
nextConfigTempate({
9697
bucketUrl: ENV.bookBucketUrl,
97-
bookId,
98+
penName: writer.pen_name,
99+
urlSlug: book.url_slug,
98100
}),
99101
)
100102
fs.writeFileSync(`${dest}/theme.config.tsx`, themeConfigTemplate({ title: book.title }))

apps/book-server/src/services/BookDeployService/index.mts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import { WriterService } from '../WriterService/index.mjs'
77
import { AwsS3Service } from '@lib/awsS3/AwsS3Service.mjs'
88
import mime from 'mime'
99
import { ENV } from '@env'
10+
import { UnauthorizedError } from '@errors/UnauthorizedError.mjs'
11+
import { ConfilctError } from '@errors/ConfilctError.mjs'
1012

1113
interface Service {
12-
deploy: (bookId: string) => Promise<void>
14+
deploy: (bookId: string, signedWriterId?: string) => Promise<void>
1315
}
14-
1516
@injectable()
1617
@singleton()
1718
export class BookDeployService implements Service {
@@ -20,27 +21,26 @@ export class BookDeployService implements Service {
2021
private readonly writerService: WriterService,
2122
private readonly bookService: BookService,
2223
) {}
23-
async deploy(bookId: string): Promise<void> {
24-
// TODO: add authentification
25-
// if (!signedUserId) {
26-
// throw new UnauthorizedError('Not logged in')
27-
// }
24+
async deploy(bookId: string, signedWriterId?: string): Promise<void> {
25+
if (!signedWriterId) {
26+
throw new UnauthorizedError('Not logged in')
27+
}
2828

29-
// const writer = await this.writerService.findById(signedUserId)
29+
const writer = await this.writerService.findById(signedWriterId)
3030

31-
// if (!writer) {
32-
// throw new NotFoundError('Not found writer')
33-
// }
31+
if (!writer) {
32+
throw new NotFoundError('Not found writer')
33+
}
3434

3535
const book = await this.bookService.findById(bookId)
3636

3737
if (!book) {
3838
throw new NotFoundError('Not found book')
3939
}
4040

41-
// if (book.writer_id !== writer.id) {
42-
// throw new ConfilctError('Not owner of book')
43-
// }
41+
if (book.writer_id !== writer.id) {
42+
throw new ConfilctError('Not owner of book')
43+
}
4444

4545
const output = path.resolve(process.cwd(), 'books', bookId, 'out')
4646

@@ -70,7 +70,7 @@ export class BookDeployService implements Service {
7070
const contentType = mime.getType(filePath)
7171
await this.awsS3.uploadFile({
7272
bucketName: ENV.bookBucketName,
73-
key: `${bookId}${relativePath}`,
73+
key: `@${writer.pen_name}/${book.url_slug}${relativePath}`,
7474
body: body,
7575
ContentType: contentType ?? 'application/octet-stream',
7676
ACL: 'public-read',
@@ -80,7 +80,9 @@ export class BookDeployService implements Service {
8080
try {
8181
await Promise.all(promises)
8282

83-
console.log(`Deployed URL: , ${ENV.bookBucketUrl}/${bookId}/index.html`)
83+
console.log(
84+
`Deployed URL: , https://books.velog.io/@${writer.pen_name}/${book.url_slug}/index.html`,
85+
)
8486
} catch (error) {
8587
console.error(error)
8688
}

apps/book-server/src/templates/nextConfigTemplate.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
type Props = {
22
bucketUrl: string
3-
bookId: string
3+
penName: string
4+
urlSlug: string
45
}
56

6-
export const nextConfigTempate = ({ bucketUrl, bookId }: Props) => {
7+
export const nextConfigTempate = ({ bucketUrl, penName, urlSlug }: Props) => {
78
return `
89
import nextra from 'nextra'
910
@@ -22,8 +23,8 @@ export const nextConfigTempate = ({ bucketUrl, bookId }: Props) => {
2223
images: {
2324
unoptimized: true,
2425
},
25-
assetPrefix: process.env.NODE_ENV === 'production' ? '${bucketUrl}/${bookId}' : undefined,
26-
basePath: '/${bookId}',
26+
assetPrefix: process.env.NODE_ENV === 'production' ? '${bucketUrl}/@${penName}/${urlSlug}' : undefined,
27+
basePath: '/@${penName}/${urlSlug}',
2728
trailingSlash: false
2829
}
2930

packages/library/src/awsS3/AwsS3Service.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class AwsS3Service implements Service {
2525
const data = await this.client.send(command)
2626
return data.Buckets ?? []
2727
} catch (error: any) {
28-
console.error('get buckets error')
28+
console.error('get buckets error', error)
2929
const { requestId, cfId, extendedRequestId } = error.$metadata
3030
console.log({ requestId, cfId, extendedRequestId })
3131
return []

0 commit comments

Comments
 (0)