@read-frog/api-contract 0.11.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +392 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/contracts/ebook.ts +117 -0
- package/src/index.ts +3 -0
- package/src/public-errors.ts +20 -0
- package/src/schemas/ebook.ts +143 -0
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { betaAccessContract } from "./contracts/beta-access"
|
|
|
3
3
|
import { billingContract } from "./contracts/billing"
|
|
4
4
|
import { cardContract } from "./contracts/card"
|
|
5
5
|
import { cardTemplateContract } from "./contracts/card-template"
|
|
6
|
+
import { ebookContract } from "./contracts/ebook"
|
|
6
7
|
import { hostedAiContract } from "./contracts/hosted-ai"
|
|
7
8
|
import { notebaseContract } from "./contracts/notebase"
|
|
8
9
|
import { notebaseColumnContract } from "./contracts/notebase-column"
|
|
@@ -16,6 +17,7 @@ export const contract = {
|
|
|
16
17
|
billing: billingContract,
|
|
17
18
|
card: cardContract,
|
|
18
19
|
cardTemplate: cardTemplateContract,
|
|
20
|
+
ebook: ebookContract,
|
|
19
21
|
hostedAi: hostedAiContract,
|
|
20
22
|
notebase: notebaseContract,
|
|
21
23
|
notebaseColumn: notebaseColumnContract,
|
|
@@ -31,6 +33,7 @@ export * from "./public-errors"
|
|
|
31
33
|
export * from "./schemas/beta-access"
|
|
32
34
|
export * from "./schemas/billing"
|
|
33
35
|
export * from "./schemas/card"
|
|
36
|
+
export * from "./schemas/ebook"
|
|
34
37
|
export * from "./schemas/hosted-ai"
|
|
35
38
|
export * from "./schemas/notebase"
|
|
36
39
|
export * from "./schemas/notebase-column"
|
package/src/public-errors.ts
CHANGED
|
@@ -157,6 +157,26 @@ export const PUBLIC_APP_ERROR_DEFS = {
|
|
|
157
157
|
message: "Concurrent position conflict, please retry",
|
|
158
158
|
status: 409,
|
|
159
159
|
},
|
|
160
|
+
EBOOK_BETA_RESTRICTED: {
|
|
161
|
+
message: "Ebooks are currently in beta for selected accounts",
|
|
162
|
+
status: 403,
|
|
163
|
+
},
|
|
164
|
+
EBOOK_NOT_FOUND: {
|
|
165
|
+
message: "Ebook not found",
|
|
166
|
+
status: 404,
|
|
167
|
+
},
|
|
168
|
+
EBOOK_LIMIT_EXCEEDED: {
|
|
169
|
+
message: "Upgrade is required to upload more ebooks",
|
|
170
|
+
status: 403,
|
|
171
|
+
},
|
|
172
|
+
EBOOK_FILE_TOO_LARGE: {
|
|
173
|
+
message: "Ebook file exceeds the maximum allowed size",
|
|
174
|
+
status: 413,
|
|
175
|
+
},
|
|
176
|
+
EBOOK_UPLOAD_NOT_COMPLETED: {
|
|
177
|
+
message: "Ebook upload has not been completed",
|
|
178
|
+
status: 409,
|
|
179
|
+
},
|
|
160
180
|
} as const satisfies Record<string, PublicAppErrorDefinition>
|
|
161
181
|
|
|
162
182
|
export type PublicAppErrorCode = keyof typeof PUBLIC_APP_ERROR_DEFS
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { EBOOK_ALLOWED_COVER_CONTENT_TYPES } from "@read-frog/definitions"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
|
|
4
|
+
export const ebookStatusSchema = z.enum(["pending", "ready"])
|
|
5
|
+
export type EbookStatus = z.infer<typeof ebookStatusSchema>
|
|
6
|
+
|
|
7
|
+
export const ebookCoverContentTypeSchema = z.enum(EBOOK_ALLOWED_COVER_CONTENT_TYPES)
|
|
8
|
+
export type EbookCoverContentType = z.infer<typeof ebookCoverContentTypeSchema>
|
|
9
|
+
|
|
10
|
+
export const ebookListItemSchema = z.object({
|
|
11
|
+
id: z.uuid(),
|
|
12
|
+
title: z.string(),
|
|
13
|
+
author: z.string().nullable(),
|
|
14
|
+
language: z.string().nullable(),
|
|
15
|
+
fileByteSize: z.number().int(),
|
|
16
|
+
status: ebookStatusSchema,
|
|
17
|
+
progressFraction: z.number(),
|
|
18
|
+
lastReadAt: z.coerce.date().nullable(),
|
|
19
|
+
coverUrl: z.url().nullable(),
|
|
20
|
+
createdAt: z.coerce.date(),
|
|
21
|
+
updatedAt: z.coerce.date(),
|
|
22
|
+
}).strict()
|
|
23
|
+
export type EbookListItem = z.infer<typeof ebookListItemSchema>
|
|
24
|
+
|
|
25
|
+
export const ebookDetailSchema = ebookListItemSchema.extend({
|
|
26
|
+
progressCfi: z.string().nullable(),
|
|
27
|
+
})
|
|
28
|
+
export type EbookDetail = z.infer<typeof ebookDetailSchema>
|
|
29
|
+
|
|
30
|
+
export const ebookQuotaSchema = z.object({
|
|
31
|
+
count: z.number().int().min(0),
|
|
32
|
+
// 0 is a valid limit: uploading is a paid feature, so free plans get no quota.
|
|
33
|
+
limit: z.number().int().min(0),
|
|
34
|
+
}).strict()
|
|
35
|
+
export type EbookQuota = z.infer<typeof ebookQuotaSchema>
|
|
36
|
+
|
|
37
|
+
export const ebookListInputSchema = z.object({}).strict()
|
|
38
|
+
export type EbookListInput = z.infer<typeof ebookListInputSchema>
|
|
39
|
+
|
|
40
|
+
export const ebookListOutputSchema = z.object({
|
|
41
|
+
items: z.array(ebookListItemSchema),
|
|
42
|
+
quota: ebookQuotaSchema,
|
|
43
|
+
}).strict()
|
|
44
|
+
export type EbookListOutput = z.infer<typeof ebookListOutputSchema>
|
|
45
|
+
|
|
46
|
+
export const ebookGetInputSchema = z.object({
|
|
47
|
+
id: z.uuid(),
|
|
48
|
+
}).strict()
|
|
49
|
+
export type EbookGetInput = z.infer<typeof ebookGetInputSchema>
|
|
50
|
+
|
|
51
|
+
export const ebookGetOutputSchema = z.object({
|
|
52
|
+
ebook: ebookDetailSchema,
|
|
53
|
+
}).strict()
|
|
54
|
+
export type EbookGetOutput = z.infer<typeof ebookGetOutputSchema>
|
|
55
|
+
|
|
56
|
+
export const ebookRequestUploadInputSchema = z.object({
|
|
57
|
+
title: z.string().min(1).max(500),
|
|
58
|
+
author: z.string().max(500).optional(),
|
|
59
|
+
language: z.string().max(35).optional(),
|
|
60
|
+
coverContentType: ebookCoverContentTypeSchema.optional(),
|
|
61
|
+
}).strict()
|
|
62
|
+
export type EbookRequestUploadInput = z.infer<typeof ebookRequestUploadInputSchema>
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* S3 POST form policy. `fields` must be appended to the form in iteration order
|
|
66
|
+
* with the file last; S3 ignores anything sent after the `file` part.
|
|
67
|
+
*/
|
|
68
|
+
export const ebookPresignedPostSchema = z.object({
|
|
69
|
+
url: z.url(),
|
|
70
|
+
fields: z.record(z.string(), z.string()),
|
|
71
|
+
}).strict()
|
|
72
|
+
export type EbookPresignedPost = z.infer<typeof ebookPresignedPostSchema>
|
|
73
|
+
|
|
74
|
+
export const ebookRequestUploadOutputSchema = z.object({
|
|
75
|
+
ebookId: z.uuid(),
|
|
76
|
+
upload: ebookPresignedPostSchema,
|
|
77
|
+
coverUpload: ebookPresignedPostSchema.nullable(),
|
|
78
|
+
expiresAt: z.coerce.date(),
|
|
79
|
+
}).strict()
|
|
80
|
+
export type EbookRequestUploadOutput = z.infer<typeof ebookRequestUploadOutputSchema>
|
|
81
|
+
|
|
82
|
+
export const ebookFinalizeUploadInputSchema = z.object({
|
|
83
|
+
ebookId: z.uuid(),
|
|
84
|
+
}).strict()
|
|
85
|
+
export type EbookFinalizeUploadInput = z.infer<typeof ebookFinalizeUploadInputSchema>
|
|
86
|
+
|
|
87
|
+
export const ebookFinalizeUploadOutputSchema = z.object({
|
|
88
|
+
ebook: ebookListItemSchema,
|
|
89
|
+
}).strict()
|
|
90
|
+
export type EbookFinalizeUploadOutput = z.infer<typeof ebookFinalizeUploadOutputSchema>
|
|
91
|
+
|
|
92
|
+
export const ebookGetDownloadUrlInputSchema = z.object({
|
|
93
|
+
id: z.uuid(),
|
|
94
|
+
}).strict()
|
|
95
|
+
export type EbookGetDownloadUrlInput = z.infer<typeof ebookGetDownloadUrlInputSchema>
|
|
96
|
+
|
|
97
|
+
export const ebookGetDownloadUrlOutputSchema = z.object({
|
|
98
|
+
url: z.url(),
|
|
99
|
+
expiresAt: z.coerce.date(),
|
|
100
|
+
}).strict()
|
|
101
|
+
export type EbookGetDownloadUrlOutput = z.infer<typeof ebookGetDownloadUrlOutputSchema>
|
|
102
|
+
|
|
103
|
+
export const ebookUpdateProgressDataSchema = z.object({
|
|
104
|
+
cfi: z.string().max(2000),
|
|
105
|
+
fraction: z.number().min(0).max(1),
|
|
106
|
+
}).strict()
|
|
107
|
+
export type EbookUpdateProgressData = z.infer<typeof ebookUpdateProgressDataSchema>
|
|
108
|
+
|
|
109
|
+
export const ebookUpdateProgressInputSchema = ebookUpdateProgressDataSchema.extend({
|
|
110
|
+
id: z.uuid(),
|
|
111
|
+
})
|
|
112
|
+
export type EbookUpdateProgressInput = z.infer<typeof ebookUpdateProgressInputSchema>
|
|
113
|
+
|
|
114
|
+
export const ebookUpdateProgressOutputSchema = z.object({
|
|
115
|
+
lastReadAt: z.coerce.date(),
|
|
116
|
+
}).strict()
|
|
117
|
+
export type EbookUpdateProgressOutput = z.infer<typeof ebookUpdateProgressOutputSchema>
|
|
118
|
+
|
|
119
|
+
export const ebookRenameDataSchema = z.object({
|
|
120
|
+
title: z.string().min(1).max(500),
|
|
121
|
+
author: z.string().max(500).nullable().optional(),
|
|
122
|
+
}).strict()
|
|
123
|
+
export type EbookRenameData = z.infer<typeof ebookRenameDataSchema>
|
|
124
|
+
|
|
125
|
+
export const ebookRenameInputSchema = ebookRenameDataSchema.extend({
|
|
126
|
+
id: z.uuid(),
|
|
127
|
+
})
|
|
128
|
+
export type EbookRenameInput = z.infer<typeof ebookRenameInputSchema>
|
|
129
|
+
|
|
130
|
+
export const ebookRenameOutputSchema = z.object({
|
|
131
|
+
ebook: ebookListItemSchema,
|
|
132
|
+
}).strict()
|
|
133
|
+
export type EbookRenameOutput = z.infer<typeof ebookRenameOutputSchema>
|
|
134
|
+
|
|
135
|
+
export const ebookDeleteInputSchema = z.object({
|
|
136
|
+
id: z.uuid(),
|
|
137
|
+
}).strict()
|
|
138
|
+
export type EbookDeleteInput = z.infer<typeof ebookDeleteInputSchema>
|
|
139
|
+
|
|
140
|
+
export const ebookDeleteOutputSchema = z.object({
|
|
141
|
+
id: z.uuid(),
|
|
142
|
+
}).strict()
|
|
143
|
+
export type EbookDeleteOutput = z.infer<typeof ebookDeleteOutputSchema>
|