@read-frog/api-contract 0.6.1 → 0.8.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 +324 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +145 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/contracts/hosted-ai.ts +31 -0
- package/src/contracts/srs.ts +47 -0
- package/src/contracts/user.ts +11 -0
- package/src/index.ts +3 -0
- package/src/public-errors.ts +20 -0
- package/src/schemas/hosted-ai.ts +46 -0
- package/src/schemas/notebase.ts +14 -1
- package/src/schemas/srs.ts +48 -0
- package/src/schemas/user.ts +10 -0
package/src/contracts/srs.ts
CHANGED
|
@@ -4,10 +4,27 @@ import {
|
|
|
4
4
|
srsReviewOutputSchema,
|
|
5
5
|
srsRollbackReviewInputSchema,
|
|
6
6
|
srsRollbackReviewOutputSchema,
|
|
7
|
+
srsScheduleStatusStatsInputSchema,
|
|
8
|
+
srsScheduleStatusStatsOutputSchema,
|
|
9
|
+
srsSetCardBuriedInputSchema,
|
|
10
|
+
srsSetCardBuriedOutputSchema,
|
|
11
|
+
srsSetCardSuspendedInputSchema,
|
|
12
|
+
srsSetCardSuspendedOutputSchema,
|
|
7
13
|
} from "#/schemas/srs"
|
|
8
14
|
import { notebaseProcedure } from "./shared"
|
|
9
15
|
|
|
10
16
|
export const srsContract = {
|
|
17
|
+
scheduleStatusStats: notebaseProcedure
|
|
18
|
+
.errors(pickPublicErrorMap("NOTEBASE_NOT_FOUND"))
|
|
19
|
+
.route({
|
|
20
|
+
method: "GET",
|
|
21
|
+
path: "/srs/schedule-status-stats",
|
|
22
|
+
summary: "List today schedule status stats for notebases",
|
|
23
|
+
tags: ["SRS"],
|
|
24
|
+
})
|
|
25
|
+
.input(srsScheduleStatusStatsInputSchema)
|
|
26
|
+
.output(srsScheduleStatusStatsOutputSchema),
|
|
27
|
+
|
|
11
28
|
review: notebaseProcedure
|
|
12
29
|
.errors(pickPublicErrorMap(
|
|
13
30
|
"CARD_NOT_FOUND",
|
|
@@ -35,4 +52,34 @@ export const srsContract = {
|
|
|
35
52
|
})
|
|
36
53
|
.input(srsRollbackReviewInputSchema)
|
|
37
54
|
.output(srsRollbackReviewOutputSchema),
|
|
55
|
+
setCardBuried: notebaseProcedure
|
|
56
|
+
.errors(pickPublicErrorMap(
|
|
57
|
+
"CARD_NOT_FOUND",
|
|
58
|
+
"CARD_ALREADY_BURIED",
|
|
59
|
+
"CARD_NOT_BURIED",
|
|
60
|
+
"CARD_STATUS_CHANGE_UNAVAILABLE",
|
|
61
|
+
))
|
|
62
|
+
.route({
|
|
63
|
+
method: "POST",
|
|
64
|
+
path: "/srs/card/bury",
|
|
65
|
+
summary: "Manually bury or unbury a card",
|
|
66
|
+
tags: ["SRS"],
|
|
67
|
+
})
|
|
68
|
+
.input(srsSetCardBuriedInputSchema)
|
|
69
|
+
.output(srsSetCardBuriedOutputSchema),
|
|
70
|
+
setCardSuspended: notebaseProcedure
|
|
71
|
+
.errors(pickPublicErrorMap(
|
|
72
|
+
"CARD_NOT_FOUND",
|
|
73
|
+
"CARD_ALREADY_SUSPENDED",
|
|
74
|
+
"CARD_NOT_SUSPENDED",
|
|
75
|
+
"CARD_STATUS_CHANGE_UNAVAILABLE",
|
|
76
|
+
))
|
|
77
|
+
.route({
|
|
78
|
+
method: "POST",
|
|
79
|
+
path: "/srs/card/suspend",
|
|
80
|
+
summary: "Manually suspend or unsuspend a card",
|
|
81
|
+
tags: ["SRS"],
|
|
82
|
+
})
|
|
83
|
+
.input(srsSetCardSuspendedInputSchema)
|
|
84
|
+
.output(srsSetCardSuspendedOutputSchema),
|
|
38
85
|
}
|
package/src/contracts/user.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { oc } from "@orpc/contract"
|
|
|
2
2
|
import {
|
|
3
3
|
userEnsureTimezoneInputSchema,
|
|
4
4
|
userEnsureTimezoneOutputSchema,
|
|
5
|
+
userUpdateTimezoneInputSchema,
|
|
6
|
+
userUpdateTimezoneOutputSchema,
|
|
5
7
|
} from "#/schemas/user"
|
|
6
8
|
|
|
7
9
|
export const userContract = {
|
|
@@ -14,4 +16,13 @@ export const userContract = {
|
|
|
14
16
|
})
|
|
15
17
|
.input(userEnsureTimezoneInputSchema)
|
|
16
18
|
.output(userEnsureTimezoneOutputSchema),
|
|
19
|
+
updateTimezone: oc
|
|
20
|
+
.route({
|
|
21
|
+
method: "PATCH",
|
|
22
|
+
path: "/users/me/timezone",
|
|
23
|
+
summary: "Update the authenticated user's timezone",
|
|
24
|
+
tags: ["Users"],
|
|
25
|
+
})
|
|
26
|
+
.input(userUpdateTimezoneInputSchema)
|
|
27
|
+
.output(userUpdateTimezoneOutputSchema),
|
|
17
28
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ContractRouterClient } from "@orpc/contract"
|
|
|
2
2
|
import { betaAccessContract } from "./contracts/beta-access"
|
|
3
3
|
import { cardContract } from "./contracts/card"
|
|
4
4
|
import { cardTemplateContract } from "./contracts/card-template"
|
|
5
|
+
import { hostedAiContract } from "./contracts/hosted-ai"
|
|
5
6
|
import { notebaseContract } from "./contracts/notebase"
|
|
6
7
|
import { notebaseColumnContract } from "./contracts/notebase-column"
|
|
7
8
|
import { notebaseRowContract } from "./contracts/notebase-row"
|
|
@@ -12,6 +13,7 @@ export const contract = {
|
|
|
12
13
|
betaAccess: betaAccessContract,
|
|
13
14
|
card: cardContract,
|
|
14
15
|
cardTemplate: cardTemplateContract,
|
|
16
|
+
hostedAi: hostedAiContract,
|
|
15
17
|
notebase: notebaseContract,
|
|
16
18
|
notebaseColumn: notebaseColumnContract,
|
|
17
19
|
notebaseRow: notebaseRowContract,
|
|
@@ -24,6 +26,7 @@ export type ORPCRouterClient = ContractRouterClient<typeof contract>
|
|
|
24
26
|
export * from "./public-errors"
|
|
25
27
|
export * from "./schemas/beta-access"
|
|
26
28
|
export * from "./schemas/card"
|
|
29
|
+
export * from "./schemas/hosted-ai"
|
|
27
30
|
export * from "./schemas/notebase"
|
|
28
31
|
export * from "./schemas/notebase-column"
|
|
29
32
|
export * from "./schemas/notebase-row"
|
package/src/public-errors.ts
CHANGED
|
@@ -82,6 +82,26 @@ export const PUBLIC_APP_ERROR_DEFS = {
|
|
|
82
82
|
message: "Card review cannot be rolled back",
|
|
83
83
|
status: 409,
|
|
84
84
|
},
|
|
85
|
+
CARD_ALREADY_BURIED: {
|
|
86
|
+
message: "Card is already buried",
|
|
87
|
+
status: 409,
|
|
88
|
+
},
|
|
89
|
+
CARD_NOT_BURIED: {
|
|
90
|
+
message: "Card is not buried",
|
|
91
|
+
status: 409,
|
|
92
|
+
},
|
|
93
|
+
CARD_ALREADY_SUSPENDED: {
|
|
94
|
+
message: "Card is already suspended",
|
|
95
|
+
status: 409,
|
|
96
|
+
},
|
|
97
|
+
CARD_NOT_SUSPENDED: {
|
|
98
|
+
message: "Card is not suspended",
|
|
99
|
+
status: 409,
|
|
100
|
+
},
|
|
101
|
+
CARD_STATUS_CHANGE_UNAVAILABLE: {
|
|
102
|
+
message: "Card status change is unavailable",
|
|
103
|
+
status: 409,
|
|
104
|
+
},
|
|
85
105
|
NOTEBASE_VIEW_NOT_FOUND: {
|
|
86
106
|
message: "Notebase view not found",
|
|
87
107
|
status: 404,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
export const HostedAiOutputFieldTypeSchema = z.enum(["string", "number"])
|
|
4
|
+
|
|
5
|
+
export const HostedAiOutputFieldSchema = z.strictObject({
|
|
6
|
+
name: z.string().trim().min(1).max(80),
|
|
7
|
+
type: HostedAiOutputFieldTypeSchema,
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export const HostedAiStreamTextInputSchema = z.strictObject({
|
|
11
|
+
system: z.string().trim().min(1).max(16000),
|
|
12
|
+
prompt: z.string().trim().min(1).max(32000),
|
|
13
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const HostedAiStreamStructuredObjectInputSchema = z.strictObject({
|
|
17
|
+
system: z.string().trim().min(1).max(16000),
|
|
18
|
+
prompt: z.string().trim().min(1).max(32000),
|
|
19
|
+
outputSchema: z.array(HostedAiOutputFieldSchema).min(1).max(32),
|
|
20
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
21
|
+
}).superRefine((input, ctx) => {
|
|
22
|
+
const fieldNames = new Set<string>()
|
|
23
|
+
|
|
24
|
+
input.outputSchema.forEach((field, index) => {
|
|
25
|
+
if (fieldNames.has(field.name)) {
|
|
26
|
+
ctx.addIssue({
|
|
27
|
+
code: "custom",
|
|
28
|
+
message: `Duplicate output schema name "${field.name}".`,
|
|
29
|
+
path: ["outputSchema", index, "name"],
|
|
30
|
+
})
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fieldNames.add(field.name)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export const HostedAiStreamPartSchema = z.looseObject({
|
|
39
|
+
type: z.string().trim().min(1),
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
export type HostedAiOutputFieldType = z.infer<typeof HostedAiOutputFieldTypeSchema>
|
|
43
|
+
export type HostedAiOutputField = z.infer<typeof HostedAiOutputFieldSchema>
|
|
44
|
+
export type HostedAiStreamTextInput = z.infer<typeof HostedAiStreamTextInputSchema>
|
|
45
|
+
export type HostedAiStreamStructuredObjectInput = z.infer<typeof HostedAiStreamStructuredObjectInputSchema>
|
|
46
|
+
export type HostedAiStreamPart = z.infer<typeof HostedAiStreamPartSchema>
|
package/src/schemas/notebase.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schedulingParamsShape, srsWeightsSchema } from "@read-frog/definitions"
|
|
1
|
+
import { notebaseColumnConfigSchema, schedulingParamsShape, srsWeightsSchema } from "@read-frog/definitions"
|
|
2
2
|
import { z } from "zod"
|
|
3
3
|
import { notebaseColumnSchema } from "./notebase-column"
|
|
4
4
|
import { notebaseRowSchema } from "./notebase-row"
|
|
@@ -38,6 +38,17 @@ export type Notebase = z.infer<typeof notebaseSchema>
|
|
|
38
38
|
export const notebaseCreateDataSchema = z.object({
|
|
39
39
|
id: z.uuid().optional(),
|
|
40
40
|
name: z.string().min(1),
|
|
41
|
+
options: z.object({
|
|
42
|
+
initialColumns: z.array(z.object({
|
|
43
|
+
id: z.uuid(),
|
|
44
|
+
name: z.string().min(1),
|
|
45
|
+
config: notebaseColumnConfigSchema,
|
|
46
|
+
}).strict()).min(1),
|
|
47
|
+
initialRow: z.object({
|
|
48
|
+
id: z.uuid().optional(),
|
|
49
|
+
cells: z.record(z.string(), z.unknown()),
|
|
50
|
+
}).strict().optional(),
|
|
51
|
+
}).strict().optional(),
|
|
41
52
|
}).strict()
|
|
42
53
|
export type NotebaseCreateData = z.infer<typeof notebaseCreateDataSchema>
|
|
43
54
|
|
|
@@ -51,6 +62,8 @@ export type NotebaseCreateOutput = z.infer<typeof NotebaseCreateOutputSchema>
|
|
|
51
62
|
|
|
52
63
|
export const notebaseUpdateDataSchema = z.object({
|
|
53
64
|
name: z.string().min(1).optional(),
|
|
65
|
+
srsNewPerDay: schedulingParamsShape.newPerDay.optional(),
|
|
66
|
+
srsReviewsPerDay: schedulingParamsShape.reviewsPerDay.optional(),
|
|
54
67
|
}).strict()
|
|
55
68
|
export type NotebaseUpdateData = z.infer<typeof notebaseUpdateDataSchema>
|
|
56
69
|
|
package/src/schemas/srs.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
activeScheduleStatusSchema,
|
|
2
3
|
cardStateSchema,
|
|
3
4
|
fsrsReviewLogSnapshotSchema,
|
|
4
5
|
reviewRatingSchema,
|
|
@@ -53,6 +54,36 @@ export const srsRollbackReviewInputSchema = z.object({
|
|
|
53
54
|
}).strict()
|
|
54
55
|
export type SrsRollbackReviewInput = z.infer<typeof srsRollbackReviewInputSchema>
|
|
55
56
|
|
|
57
|
+
export const srsScheduleStatusStatsSchema = z.record(
|
|
58
|
+
activeScheduleStatusSchema,
|
|
59
|
+
z.number().int().min(0),
|
|
60
|
+
)
|
|
61
|
+
export type SrsScheduleStatusStats = z.infer<typeof srsScheduleStatusStatsSchema>
|
|
62
|
+
|
|
63
|
+
export const srsScheduleStatusStatsInputSchema = z.object({
|
|
64
|
+
notebaseIds: z.array(z.uuid()).optional(),
|
|
65
|
+
timezone: timezoneSchema,
|
|
66
|
+
}).strict()
|
|
67
|
+
export type SrsScheduleStatusStatsInput = z.infer<typeof srsScheduleStatusStatsInputSchema>
|
|
68
|
+
|
|
69
|
+
export const srsScheduleStatusStatsOutputSchema = z.record(
|
|
70
|
+
z.uuid(),
|
|
71
|
+
srsScheduleStatusStatsSchema,
|
|
72
|
+
)
|
|
73
|
+
export type SrsScheduleStatusStatsOutput = z.infer<typeof srsScheduleStatusStatsOutputSchema>
|
|
74
|
+
|
|
75
|
+
export const srsManualCardStatusInputSchema = z.object({
|
|
76
|
+
cardId: z.uuid(),
|
|
77
|
+
enabled: z.boolean(),
|
|
78
|
+
}).strict()
|
|
79
|
+
export type SrsManualCardStatusInput = z.infer<typeof srsManualCardStatusInputSchema>
|
|
80
|
+
|
|
81
|
+
export const srsSetCardBuriedInputSchema = srsManualCardStatusInputSchema
|
|
82
|
+
export type SrsSetCardBuriedInput = SrsManualCardStatusInput
|
|
83
|
+
|
|
84
|
+
export const srsSetCardSuspendedInputSchema = srsManualCardStatusInputSchema
|
|
85
|
+
export type SrsSetCardSuspendedInput = SrsManualCardStatusInput
|
|
86
|
+
|
|
56
87
|
export const srsRevlogSchema = z.object({
|
|
57
88
|
id: z.uuid(),
|
|
58
89
|
notebaseId: z.uuid(),
|
|
@@ -67,6 +98,11 @@ export const srsRevlogSchema = z.object({
|
|
|
67
98
|
})
|
|
68
99
|
export type SrsRevlog = z.infer<typeof srsRevlogSchema>
|
|
69
100
|
|
|
101
|
+
export const srsRevlogWithoutSnapshotSchema = srsRevlogSchema.omit({
|
|
102
|
+
fsrsReviewLogSnapshot: true,
|
|
103
|
+
})
|
|
104
|
+
export type SrsRevlogWithoutSnapshot = z.infer<typeof srsRevlogWithoutSnapshotSchema>
|
|
105
|
+
|
|
70
106
|
export const srsReviewOutputSchema = z.object({
|
|
71
107
|
card: cardSchema,
|
|
72
108
|
revlog: srsRevlogSchema,
|
|
@@ -81,6 +117,17 @@ export const srsRollbackReviewOutputSchema = z.object({
|
|
|
81
117
|
})
|
|
82
118
|
export type SrsRollbackReviewOutput = z.infer<typeof srsRollbackReviewOutputSchema>
|
|
83
119
|
|
|
120
|
+
export const srsTxidOutputSchema = z.object({
|
|
121
|
+
txid: z.number(),
|
|
122
|
+
})
|
|
123
|
+
export type SrsTxidOutput = z.infer<typeof srsTxidOutputSchema>
|
|
124
|
+
|
|
125
|
+
export const srsSetCardBuriedOutputSchema = srsTxidOutputSchema
|
|
126
|
+
export type SrsSetCardBuriedOutput = SrsTxidOutput
|
|
127
|
+
|
|
128
|
+
export const srsSetCardSuspendedOutputSchema = srsTxidOutputSchema
|
|
129
|
+
export type SrsSetCardSuspendedOutput = SrsTxidOutput
|
|
130
|
+
|
|
84
131
|
function formatLastReviewTime(lastReviewTime: Date | string | null) {
|
|
85
132
|
return lastReviewTime ? new Date(lastReviewTime).toISOString() : nullLastReviewTimeSentinel
|
|
86
133
|
}
|
|
@@ -107,6 +154,7 @@ async function uuidV5(name: string, namespace: string) {
|
|
|
107
154
|
|
|
108
155
|
function uuidToBytes(uuid: string) {
|
|
109
156
|
const hex = uuid.replaceAll("-", "").toLowerCase()
|
|
157
|
+
/* v8 ignore next 3 -- SRS_REVIEW_CLIENT_ID_NAMESPACE is a fixed valid UUID. */
|
|
110
158
|
if (!/^[0-9a-f]{32}$/.test(hex)) {
|
|
111
159
|
throw new Error("Invalid UUID namespace")
|
|
112
160
|
}
|
package/src/schemas/user.ts
CHANGED
|
@@ -11,3 +11,13 @@ export const userEnsureTimezoneOutputSchema = z.object({
|
|
|
11
11
|
updated: z.boolean(),
|
|
12
12
|
}).strict()
|
|
13
13
|
export type UserEnsureTimezoneOutput = z.infer<typeof userEnsureTimezoneOutputSchema>
|
|
14
|
+
|
|
15
|
+
export const userUpdateTimezoneInputSchema = z.object({
|
|
16
|
+
timezone: timezoneSchema,
|
|
17
|
+
}).strict()
|
|
18
|
+
export type UserUpdateTimezoneInput = z.infer<typeof userUpdateTimezoneInputSchema>
|
|
19
|
+
|
|
20
|
+
export const userUpdateTimezoneOutputSchema = z.object({
|
|
21
|
+
timezone: timezoneSchema,
|
|
22
|
+
}).strict()
|
|
23
|
+
export type UserUpdateTimezoneOutput = z.infer<typeof userUpdateTimezoneOutputSchema>
|