@purpleschool/gptbot-tools 0.0.77-ai-proxy → 0.0.78-ai-proxy
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/ai-vendor/index.ts +1 -0
- package/ai-vendor/models/ai-vendor.schema.ts +13 -0
- package/ai-vendor/models/index.ts +1 -0
- package/build/ai-vendor/index.js +17 -0
- package/build/ai-vendor/models/ai-vendor.schema.js +13 -0
- package/build/ai-vendor/models/index.js +17 -0
- package/build/common/errors/errors.js +163 -0
- package/build/common/models/attached-file.schema.js +13 -0
- package/build/common/models/index.js +1 -0
- package/build/image-editor/commands/image-editor-model/get-image-editor-model-by-uuid.command.js +13 -0
- package/build/image-editor/commands/image-editor-model/index.js +17 -0
- package/build/image-editor/commands/image-editor.command.js +3 -1
- package/build/image-editor/commands/index.js +1 -0
- package/build/image-editor/commands/retry-image-editor-job.command.js +4 -0
- package/build/image-editor/commands/set-reaction-to-image-editor-job.command.js +12 -2
- package/build/image-editor/enums/image-editor-model-type.enum.js +2 -0
- package/build/image-editor/enums/image-editor-strategy.enum.js +4 -0
- package/build/image-editor/models/image-editor-config.schema.js +1 -0
- package/build/image-editor/models/image-editor-job.schema.js +2 -0
- package/build/image-editor/models/image-editor-model.schema.js +9 -1
- package/build/image-editor/routes/image-editor-model.amqp.routes.js +6 -0
- package/build/image-editor/routes/image-editor.http.routes.js +1 -0
- package/build/image-editor/routes/index.js +1 -0
- package/build/image-generation/commands/execute-image-generation.command.js +20 -0
- package/build/image-generation/commands/forward-image-generation-job.command.js +32 -0
- package/build/image-generation/commands/index.js +23 -0
- package/build/image-generation/commands/save-image-generation-job.command.js +17 -0
- package/build/image-generation/commands/set-reaction-to-image-generation-job.command.js +27 -0
- package/build/image-generation/commands/soft-delete-image-generation-job-by-uuid.command.js +14 -0
- package/build/image-generation/commands/soft-delete-image-generation-jobs-by-criteria.command.js +13 -0
- package/build/image-generation/commands/update-image-generation-job-title.command.js +16 -0
- package/build/image-generation/enums/image-generation-model-strategy.enum.js +23 -0
- package/build/image-generation/enums/image-generation-models.enum.js +8 -0
- package/build/image-generation/enums/image-generation-resolution.enum.js +9 -0
- package/build/image-generation/enums/index.js +19 -0
- package/build/image-generation/index.js +21 -0
- package/build/image-generation/models/image-generation-config.schema.js +12 -0
- package/build/image-generation/models/image-generation-job.schema.js +35 -0
- package/build/image-generation/models/image-generation-model.schema.js +51 -0
- package/build/image-generation/models/image-generation-preset.schema.js +13 -0
- package/build/image-generation/models/index.js +20 -0
- package/build/image-generation/queries/find-image-generation-job-by-id.query.js +19 -0
- package/build/image-generation/queries/find-image-generation-jobs.query.js +28 -0
- package/build/image-generation/queries/get-image-generation-config.query.js +11 -0
- package/build/image-generation/queries/index.js +19 -0
- package/build/image-generation/routes/image-generation.amqp.routes.js +14 -0
- package/build/image-generation/routes/image-generation.http.routes.js +9 -0
- package/build/image-generation/routes/index.js +18 -0
- package/build/index.js +6 -0
- package/build/music/commands/index.js +1 -0
- package/build/music/commands/music-model/get-music-model-by-uuid.command.js +13 -0
- package/build/music/commands/music-model/index.js +17 -0
- package/build/music/commands/retry-music-job.command.js +2 -0
- package/build/music/commands/set-reaction-to-music-job.command.js +12 -2
- package/build/music/models/music-job.schema.js +1 -0
- package/build/music/models/music-track.schema.js +1 -0
- package/build/music/routes/index.js +1 -0
- package/build/music/routes/music-model.amqp.routes.js +6 -0
- package/build/paraphrase/commands/delete-all-paraphrase-jobs.command.js +13 -0
- package/build/paraphrase/commands/delete-paraphrase-job-by-uuid.command.js +14 -0
- package/build/paraphrase/commands/index.js +5 -0
- package/build/paraphrase/commands/retry-paraphrase-job.command.js +16 -0
- package/build/paraphrase/commands/set-reaction-to-paraphrase-job.command.js +27 -0
- package/build/paraphrase/commands/update-paraphrase-job-title.command.js +16 -0
- package/build/paraphrase/models/paraphrase-job.schema.js +7 -0
- package/build/paraphrase/queries/find-paraphrase-jobs.query.js +28 -0
- package/build/paraphrase/queries/index.js +1 -0
- package/build/paraphrase/routes/paraphrase.amqp.routes.js +6 -0
- package/build/presentation/commands/index.js +1 -0
- package/build/presentation/commands/set-reaction-to-presentation.command.js +26 -0
- package/build/presentation/constants/slide-layout-map.constant.js +1 -0
- package/build/presentation/enums/slide-content-type.enum.js +1 -0
- package/build/presentation/models/pptx-export-payload.js +19 -1
- package/build/presentation/models/presentation.schema.js +3 -0
- package/build/presentation/models/slide-content-edit.schema.js +18 -1
- package/build/presentation/models/slide-content.schema.js +30 -1
- package/build/presentation/routes/presentation.routes.js +1 -0
- package/build/stt/commands/set-reaction-to-stt-job.command.js +12 -2
- package/build/stt/models/stt-job.schema.js +2 -0
- package/build/tools/enums/tool-content-type.enum.js +1 -0
- package/build/tools/enums/tool-type.enum.js +1 -0
- package/build/tools/models/global-tools-config.schema.js +2 -0
- package/build/tools/models/tool.schema.js +3 -0
- package/build/tools/models/tools-with-configs.schema.js +5 -0
- package/build/tts/commands/set-reaction-to-tts-job.command.js +12 -2
- package/build/tts/models/tts-job.schema.js +2 -0
- package/build/video/commands/index.js +1 -0
- package/build/video/commands/retry-video-job.command.js +4 -0
- package/build/video/commands/set-reaction-to-video-job.command.js +12 -2
- package/build/video/commands/video-model/get-video-model-by-uuid.command.js +13 -0
- package/build/video/commands/video-model/index.js +17 -0
- package/build/video/enums/video-pricing-rule-type.enum.js +1 -0
- package/build/video/enums/video-strategy.enum.js +1 -0
- package/build/video/models/video-job.schema.js +3 -0
- package/build/video/models/video-model.schema.js +9 -1
- package/build/video/routes/index.js +1 -0
- package/build/video/routes/video-model.amqp.routes.js +6 -0
- package/build/video/routes/video.http.routes.js +1 -0
- package/build/video/utils/calculate-video-generation-price.util.js +5 -1
- package/build/video-editor/commands/edit-video.command.js +2 -1
- package/build/video-editor/commands/index.js +1 -0
- package/build/video-editor/commands/retry-video-editor-job.command.js +5 -0
- package/build/video-editor/commands/set-reaction-to-video-editor-job.command.js +12 -2
- package/build/video-editor/commands/video-editor-model/get-video-editor-model.command.js +13 -0
- package/build/video-editor/commands/video-editor-model/index.js +17 -0
- package/build/video-editor/models/video-editor-job.schema.js +3 -0
- package/build/video-editor/routes/index.js +1 -0
- package/build/video-editor/routes/video-editor-model.amqp.routes.js +6 -0
- package/build/writer/commands/set-reaction-writer-document.command.js +11 -1
- package/build/writer/models/writer-document.schema.js +1 -0
- package/common/errors/errors.ts +163 -0
- package/common/models/attached-file.schema.ts +11 -0
- package/common/models/index.ts +1 -0
- package/image-editor/commands/image-editor-model/get-image-editor-model-by-uuid.command.ts +13 -0
- package/image-editor/commands/image-editor-model/index.ts +1 -0
- package/image-editor/commands/image-editor.command.ts +3 -1
- package/image-editor/commands/index.ts +1 -0
- package/image-editor/commands/retry-image-editor-job.command.ts +5 -1
- package/image-editor/commands/set-reaction-to-image-editor-job.command.ts +19 -6
- package/image-editor/enums/image-editor-model-type.enum.ts +2 -0
- package/image-editor/enums/image-editor-strategy.enum.ts +4 -0
- package/image-editor/models/image-editor-config.schema.ts +1 -0
- package/image-editor/models/image-editor-job.schema.ts +3 -1
- package/image-editor/models/image-editor-model.schema.ts +16 -0
- package/image-editor/routes/image-editor-model.amqp.routes.ts +3 -0
- package/image-editor/routes/image-editor.http.routes.ts +1 -0
- package/image-editor/routes/index.ts +1 -0
- package/image-generation/commands/execute-image-generation.command.ts +20 -0
- package/image-generation/commands/forward-image-generation-job.command.ts +32 -0
- package/image-generation/commands/index.ts +7 -0
- package/image-generation/commands/save-image-generation-job.command.ts +17 -0
- package/image-generation/commands/set-reaction-to-image-generation-job.command.ts +30 -0
- package/image-generation/commands/soft-delete-image-generation-job-by-uuid.command.ts +14 -0
- package/image-generation/commands/soft-delete-image-generation-jobs-by-criteria.command.ts +13 -0
- package/image-generation/commands/update-image-generation-job-title.command.ts +16 -0
- package/image-generation/enums/image-generation-model-strategy.enum.ts +24 -0
- package/image-generation/enums/image-generation-models.enum.ts +4 -0
- package/image-generation/enums/image-generation-resolution.enum.ts +5 -0
- package/image-generation/enums/index.ts +3 -0
- package/image-generation/index.ts +5 -0
- package/image-generation/models/image-generation-config.schema.ts +11 -0
- package/image-generation/models/image-generation-job.schema.ts +37 -0
- package/image-generation/models/image-generation-model.schema.ts +64 -0
- package/image-generation/models/image-generation-preset.schema.ts +13 -0
- package/image-generation/models/index.ts +4 -0
- package/image-generation/queries/find-image-generation-job-by-id.query.ts +19 -0
- package/image-generation/queries/find-image-generation-jobs.query.ts +33 -0
- package/image-generation/queries/get-image-generation-config.query.ts +11 -0
- package/image-generation/queries/index.ts +3 -0
- package/image-generation/routes/image-generation.amqp.routes.ts +11 -0
- package/image-generation/routes/image-generation.http.routes.ts +7 -0
- package/image-generation/routes/index.ts +2 -0
- package/index.ts +6 -0
- package/music/commands/index.ts +1 -0
- package/music/commands/music-model/get-music-model-by-uuid.command.ts +13 -0
- package/music/commands/music-model/index.ts +1 -0
- package/music/commands/retry-music-job.command.ts +3 -1
- package/music/commands/set-reaction-to-music-job.command.ts +19 -6
- package/music/models/music-job.schema.ts +1 -0
- package/music/models/music-track.schema.ts +1 -0
- package/music/routes/index.ts +1 -0
- package/music/routes/music-model.amqp.routes.ts +3 -0
- package/package.json +1 -1
- package/paraphrase/commands/delete-all-paraphrase-jobs.command.ts +13 -0
- package/paraphrase/commands/delete-paraphrase-job-by-uuid.command.ts +14 -0
- package/paraphrase/commands/index.ts +5 -0
- package/paraphrase/commands/retry-paraphrase-job.command.ts +16 -0
- package/paraphrase/commands/set-reaction-to-paraphrase-job.command.ts +30 -0
- package/paraphrase/commands/update-paraphrase-job-title.command.ts +16 -0
- package/paraphrase/models/paraphrase-job.schema.ts +7 -0
- package/paraphrase/queries/find-paraphrase-jobs.query.ts +33 -0
- package/paraphrase/queries/index.ts +1 -0
- package/paraphrase/routes/paraphrase.amqp.routes.ts +6 -0
- package/presentation/commands/index.ts +1 -0
- package/presentation/commands/set-reaction-to-presentation.command.ts +29 -0
- package/presentation/constants/slide-layout-map.constant.ts +1 -0
- package/presentation/enums/slide-content-type.enum.ts +1 -0
- package/presentation/models/pptx-export-payload.ts +20 -0
- package/presentation/models/presentation.schema.ts +3 -0
- package/presentation/models/slide-content-edit.schema.ts +21 -0
- package/presentation/models/slide-content.schema.ts +51 -0
- package/presentation/routes/presentation.routes.ts +1 -0
- package/stt/commands/set-reaction-to-stt-job.command.ts +19 -6
- package/stt/models/stt-job.schema.ts +2 -0
- package/tools/enums/tool-content-type.enum.ts +1 -0
- package/tools/enums/tool-type.enum.ts +1 -0
- package/tools/models/global-tools-config.schema.ts +2 -0
- package/tools/models/tool.schema.ts +3 -0
- package/tools/models/tools-with-configs.schema.ts +7 -0
- package/tts/commands/set-reaction-to-tts-job.command.ts +19 -6
- package/tts/models/tts-job.schema.ts +2 -0
- package/video/commands/index.ts +1 -0
- package/video/commands/retry-video-job.command.ts +4 -0
- package/video/commands/set-reaction-to-video-job.command.ts +19 -6
- package/video/commands/video-model/get-video-model-by-uuid.command.ts +13 -0
- package/video/commands/video-model/index.ts +1 -0
- package/video/enums/video-pricing-rule-type.enum.ts +1 -0
- package/video/enums/video-strategy.enum.ts +1 -0
- package/video/models/video-job.schema.ts +3 -0
- package/video/models/video-model.schema.ts +9 -1
- package/video/routes/index.ts +1 -0
- package/video/routes/video-model.amqp.routes.ts +3 -0
- package/video/routes/video.http.routes.ts +1 -0
- package/video/utils/calculate-video-generation-price.util.ts +7 -1
- package/video-editor/commands/edit-video.command.ts +2 -1
- package/video-editor/commands/index.ts +1 -0
- package/video-editor/commands/retry-video-editor-job.command.ts +5 -0
- package/video-editor/commands/set-reaction-to-video-editor-job.command.ts +19 -6
- package/video-editor/commands/video-editor-model/get-video-editor-model.command.ts +13 -0
- package/video-editor/commands/video-editor-model/index.ts +1 -0
- package/video-editor/models/video-editor-job.schema.ts +3 -0
- package/video-editor/routes/index.ts +1 -0
- package/video-editor/routes/video-editor-model.amqp.routes.ts +3 -0
- package/writer/commands/set-reaction-writer-document.command.ts +19 -6
- package/writer/models/writer-document.schema.ts +1 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ICommandResponseSchema } from '../../common/models/command-response.schema';
|
|
3
|
+
import { ParaphraseJobSchema } from '../models/paraphrase-job.schema';
|
|
4
|
+
|
|
5
|
+
export namespace FindParaphraseJobsQuery {
|
|
6
|
+
export const RequestSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
userId: z.string().uuid().optional(),
|
|
9
|
+
unregisteredUserId: z.string().uuid().optional(),
|
|
10
|
+
title: z.string().optional(),
|
|
11
|
+
limit: z.coerce.number().min(1).optional(),
|
|
12
|
+
offset: z.coerce.number().min(0).default(0).optional(),
|
|
13
|
+
})
|
|
14
|
+
.refine(
|
|
15
|
+
(data) => {
|
|
16
|
+
return Boolean(data.userId) !== Boolean(data.unregisteredUserId);
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
message: 'At least userId or unregisteredUserId must be present',
|
|
20
|
+
path: ['userId', 'unregisteredUserId'],
|
|
21
|
+
},
|
|
22
|
+
);
|
|
23
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
24
|
+
|
|
25
|
+
export const ResponseSchema = ICommandResponseSchema(
|
|
26
|
+
z.object({
|
|
27
|
+
data: z.array(ParaphraseJobSchema),
|
|
28
|
+
page: z.number(),
|
|
29
|
+
totalPages: z.number(),
|
|
30
|
+
}),
|
|
31
|
+
);
|
|
32
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
33
|
+
}
|
|
@@ -2,4 +2,10 @@ export const PARAPHRASE_AMQP_ROUTES = {
|
|
|
2
2
|
EXECUTE: 'tools.paraphrase.execute.rpc',
|
|
3
3
|
CONFIG: 'tools.paraphrase.config.rpc',
|
|
4
4
|
GET_JOB: 'tools.paraphrase.jobs.get.rpc',
|
|
5
|
+
LIST_JOBS: 'tools.paraphrase.jobs.list.rpc',
|
|
6
|
+
SET_REACTION: 'tools.paraphrase.jobs.set-reaction.rpc',
|
|
7
|
+
UPDATE_TITLE: 'tools.paraphrase.jobs.update-title.rpc',
|
|
8
|
+
SOFT_DELETE: 'tools.paraphrase.jobs.soft-delete.rpc',
|
|
9
|
+
SOFT_DELETE_ALL: 'tools.paraphrase.jobs.soft-delete-all.rpc',
|
|
10
|
+
RETRY: 'tools.paraphrase.jobs.retry.rpc',
|
|
5
11
|
} as const;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ICommandResponseSchema, USER_REACTION } from '../../common';
|
|
3
|
+
import { PresentationSchema } from '../models';
|
|
4
|
+
|
|
5
|
+
export namespace SetReactionToPresentationCommand {
|
|
6
|
+
export const RequestSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
userId: z.string().uuid().nullable().optional(),
|
|
9
|
+
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
10
|
+
uuid: z.string().uuid(),
|
|
11
|
+
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
12
|
+
dislikeReason: z.string().nullable().default(null),
|
|
13
|
+
})
|
|
14
|
+
.refine(
|
|
15
|
+
(data) => {
|
|
16
|
+
if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
message: 'Dislike reason is not allowed when reaction is not disliked',
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
26
|
+
|
|
27
|
+
export const ResponseSchema = ICommandResponseSchema(PresentationSchema);
|
|
28
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
29
|
+
}
|
|
@@ -11,4 +11,5 @@ export const SLIDE_LAYOUT_MAP = new Map<SLIDE_CONTENT_TYPE, SLIDE_LAYOUT[]>([
|
|
|
11
11
|
[SLIDE_CONTENT_TYPE.THANK_YOU, [SLIDE_LAYOUT.TYPE_1]],
|
|
12
12
|
[SLIDE_CONTENT_TYPE.TABLE, [SLIDE_LAYOUT.TYPE_1]],
|
|
13
13
|
[SLIDE_CONTENT_TYPE.CHART, [SLIDE_LAYOUT.TYPE_1]],
|
|
14
|
+
[SLIDE_CONTENT_TYPE.TIMELINE, [SLIDE_LAYOUT.TYPE_1]],
|
|
14
15
|
]);
|
|
@@ -5,6 +5,7 @@ export enum PPTX_SHAPE_TYPE {
|
|
|
5
5
|
PICTURE_BOX = 'picture_box',
|
|
6
6
|
CUSTOM_SHAPE = 'custom_shape',
|
|
7
7
|
TABLE = 'table',
|
|
8
|
+
CHEVRON = 'chevron',
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export enum PPTX_H_ALIGN {
|
|
@@ -47,6 +48,13 @@ export enum PPTX_CUSTOM_SHAPE_TYPE {
|
|
|
47
48
|
ROUND_RECT = 'roundRect',
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
export enum PPTX_CHEVRON_DIRECTION {
|
|
52
|
+
RIGHT = 'right',
|
|
53
|
+
LEFT = 'left',
|
|
54
|
+
UP = 'up',
|
|
55
|
+
DOWN = 'down',
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
export const PPTXShadowSchema = z.object({
|
|
51
59
|
type: z.nativeEnum(PPTX_SHADOW_TYPE),
|
|
52
60
|
opacity: z.number().min(0).max(100).optional().describe('percents, range 0-100'),
|
|
@@ -182,6 +190,17 @@ export const PPTXTableShapeSchema = z.object({
|
|
|
182
190
|
});
|
|
183
191
|
export type PPTXTableShape = z.infer<typeof PPTXTableShapeSchema>;
|
|
184
192
|
|
|
193
|
+
// Chevron
|
|
194
|
+
export const PPTXChevronShapeSchema = z.object({
|
|
195
|
+
type: z.literal(PPTX_SHAPE_TYPE.CHEVRON),
|
|
196
|
+
direction: z.nativeEnum(PPTX_CHEVRON_DIRECTION).default(PPTX_CHEVRON_DIRECTION.RIGHT),
|
|
197
|
+
position: PPTXPositionSchema,
|
|
198
|
+
fill: PPTXFillSchema.optional(),
|
|
199
|
+
align: z.nativeEnum(PPTX_H_ALIGN).optional().default(PPTX_H_ALIGN.CENTER),
|
|
200
|
+
valign: z.nativeEnum(PPTX_V_ALIGN).optional().default(PPTX_V_ALIGN.MIDDLE),
|
|
201
|
+
});
|
|
202
|
+
export type PPTXChevronShape = z.infer<typeof PPTXChevronShapeSchema>;
|
|
203
|
+
|
|
185
204
|
// Overview
|
|
186
205
|
|
|
187
206
|
export const PPTXShapeSchema = z.discriminatedUnion('type', [
|
|
@@ -189,6 +208,7 @@ export const PPTXShapeSchema = z.discriminatedUnion('type', [
|
|
|
189
208
|
PPTXPictureBoxSchema,
|
|
190
209
|
PPTXCustomShapeSchema,
|
|
191
210
|
PPTXTableShapeSchema,
|
|
211
|
+
PPTXChevronShapeSchema,
|
|
192
212
|
]);
|
|
193
213
|
export type PPTXShape = z.infer<typeof PPTXShapeSchema>;
|
|
194
214
|
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { PRESENTATION_STAGE } from '../enums';
|
|
3
3
|
import { SlideOutlineSchema } from './slide-outline.schema';
|
|
4
4
|
import { SlideSchema } from './slide.schema';
|
|
5
|
+
import { USER_REACTION } from '../../common';
|
|
5
6
|
|
|
6
7
|
export const PresentationSchema = z.object({
|
|
7
8
|
uuid: z.string().uuid(),
|
|
@@ -12,6 +13,8 @@ export const PresentationSchema = z.object({
|
|
|
12
13
|
languageId: z.string(),
|
|
13
14
|
templateId: z.string(),
|
|
14
15
|
downloadUrl: z.string().nullable(),
|
|
16
|
+
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
17
|
+
dislikeReason: z.string().nullable(),
|
|
15
18
|
userId: z.string().uuid().nullable().optional(),
|
|
16
19
|
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
17
20
|
slideCount: z.number(),
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
IBarChartSlideDataStructure,
|
|
14
14
|
IChartSlideDataStructure,
|
|
15
15
|
ImageSlotSchema,
|
|
16
|
+
ITimelineSlideDataStructure,
|
|
16
17
|
} from './slide-content.schema';
|
|
17
18
|
|
|
18
19
|
export const CoverSlideDataUserEditSchema = z.object({
|
|
@@ -146,6 +147,25 @@ export const ChartSlideDataUserEditSchema = z.object({
|
|
|
146
147
|
version: z.literal(1),
|
|
147
148
|
}) satisfies z.ZodType<IChartSlideDataStructure>;
|
|
148
149
|
|
|
150
|
+
export const TimelineSlideDataUserEditSchema = z.object({
|
|
151
|
+
contentType: z.literal(SLIDE_CONTENT_TYPE.TIMELINE),
|
|
152
|
+
title: z.string().min(1).max(500),
|
|
153
|
+
description: z.string().min(1).max(1000),
|
|
154
|
+
timeline: z.object({
|
|
155
|
+
events: z
|
|
156
|
+
.array(
|
|
157
|
+
z.object({
|
|
158
|
+
date: z.string().min(1).max(100),
|
|
159
|
+
title: z.string().min(1).max(200),
|
|
160
|
+
description: z.string().min(1).max(500),
|
|
161
|
+
}),
|
|
162
|
+
)
|
|
163
|
+
.min(2)
|
|
164
|
+
.max(10),
|
|
165
|
+
}),
|
|
166
|
+
version: z.literal(1),
|
|
167
|
+
}) satisfies z.ZodType<ITimelineSlideDataStructure>;
|
|
168
|
+
|
|
149
169
|
export const SlideContentUserEditSchema = z.discriminatedUnion('contentType', [
|
|
150
170
|
CoverSlideDataUserEditSchema,
|
|
151
171
|
StructuredListSlideDataUserEditSchema,
|
|
@@ -156,5 +176,6 @@ export const SlideContentUserEditSchema = z.discriminatedUnion('contentType', [
|
|
|
156
176
|
ThankYouSlideDataUserEditSchema,
|
|
157
177
|
TableSlideDataUserEditSchema,
|
|
158
178
|
ChartSlideDataUserEditSchema,
|
|
179
|
+
TimelineSlideDataUserEditSchema,
|
|
159
180
|
]);
|
|
160
181
|
export type SlideContentUserEdit = z.infer<typeof SlideContentUserEditSchema>;
|
|
@@ -108,6 +108,20 @@ export interface IChartSlideDataStructure {
|
|
|
108
108
|
version: 1;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
export interface ITimelineSlideDataStructure {
|
|
112
|
+
contentType: SLIDE_CONTENT_TYPE.TIMELINE;
|
|
113
|
+
title: string;
|
|
114
|
+
description: string;
|
|
115
|
+
timeline: {
|
|
116
|
+
events: Array<{
|
|
117
|
+
date: string;
|
|
118
|
+
title: string;
|
|
119
|
+
description: string;
|
|
120
|
+
}>;
|
|
121
|
+
};
|
|
122
|
+
version: 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
111
125
|
export const CoverSlideDataSchema = z.object({
|
|
112
126
|
contentType: z.literal(SLIDE_CONTENT_TYPE.COVER),
|
|
113
127
|
title: z.string().describe('Slide title in about 6 words').min(10).max(150),
|
|
@@ -313,6 +327,42 @@ export const ChartSlideDataSchema = z.object({
|
|
|
313
327
|
}) satisfies z.ZodType<IChartSlideDataStructure>;
|
|
314
328
|
export type ChartSlideData = z.infer<typeof ChartSlideDataSchema>;
|
|
315
329
|
|
|
330
|
+
export const TimelineSlideDataSchema = z.object({
|
|
331
|
+
contentType: z.literal(SLIDE_CONTENT_TYPE.TIMELINE),
|
|
332
|
+
title: z.string().describe('Slide title in about 6 words').min(10).max(150),
|
|
333
|
+
description: z.string().describe('Brief context for the timeline').min(10).max(200),
|
|
334
|
+
timeline: z.object({
|
|
335
|
+
events: z
|
|
336
|
+
.array(
|
|
337
|
+
z.object({
|
|
338
|
+
date: z
|
|
339
|
+
.string()
|
|
340
|
+
.describe(
|
|
341
|
+
'Date or time period label. MUST be general/approximate if exact date unknown (e.g., "Early 2020s", "Mid-1990s", "Recent years")',
|
|
342
|
+
)
|
|
343
|
+
.min(2)
|
|
344
|
+
.max(50),
|
|
345
|
+
title: z
|
|
346
|
+
.string()
|
|
347
|
+
.describe(
|
|
348
|
+
'Event title. Prefer 2 words, max 3 words. Keep it short and punchy.',
|
|
349
|
+
)
|
|
350
|
+
.min(5)
|
|
351
|
+
.max(60),
|
|
352
|
+
description: z
|
|
353
|
+
.string()
|
|
354
|
+
.describe('Brief description of the event or milestone')
|
|
355
|
+
.min(20)
|
|
356
|
+
.max(150),
|
|
357
|
+
}),
|
|
358
|
+
)
|
|
359
|
+
.length(4)
|
|
360
|
+
.describe('Timeline must contain exactly 4 chronological events'),
|
|
361
|
+
}),
|
|
362
|
+
version: z.literal(1),
|
|
363
|
+
}) satisfies z.ZodType<ITimelineSlideDataStructure>;
|
|
364
|
+
export type TimelineSlideData = z.infer<typeof TimelineSlideDataSchema>;
|
|
365
|
+
|
|
316
366
|
export const SlideContentSchema = z.discriminatedUnion('contentType', [
|
|
317
367
|
CoverSlideDataSchema,
|
|
318
368
|
StructuredListSlideDataSchema,
|
|
@@ -323,5 +373,6 @@ export const SlideContentSchema = z.discriminatedUnion('contentType', [
|
|
|
323
373
|
ThankYouSlideDataSchema,
|
|
324
374
|
TableSlideDataSchema,
|
|
325
375
|
ChartSlideDataSchema,
|
|
376
|
+
TimelineSlideDataSchema,
|
|
326
377
|
]);
|
|
327
378
|
export type SlideContent = z.infer<typeof SlideContentSchema>;
|
|
@@ -18,6 +18,7 @@ export const PRESENTATION_AMQP_ROUTES = {
|
|
|
18
18
|
UPDATE_SLIDE: 'tools.presentation.update-slide.rpc',
|
|
19
19
|
PARAPHRASE: 'tools.presentation.actions.paraphrase.rpc',
|
|
20
20
|
GENERATE_REPORT: 'tools.presentation.actions.generate-report.rpc',
|
|
21
|
+
SET_REACTION: 'tools.presentation.set-reaction.rpc',
|
|
21
22
|
} as const;
|
|
22
23
|
|
|
23
24
|
export const PRESENTATION_SLIDE_OUTLINE_AMQP_ROUTES = {
|
|
@@ -4,12 +4,25 @@ import { USER_REACTION } from '../../common';
|
|
|
4
4
|
import { STTJobSchema } from '../models';
|
|
5
5
|
|
|
6
6
|
export namespace SetReactionToSTTJobCommand {
|
|
7
|
-
export const RequestSchema = z
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export const RequestSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
userId: z.string().uuid().nullable().optional(),
|
|
10
|
+
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
11
|
+
uuid: z.string().uuid(),
|
|
12
|
+
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
13
|
+
dislikeReason: z.string().nullable().default(null),
|
|
14
|
+
})
|
|
15
|
+
.refine(
|
|
16
|
+
(data) => {
|
|
17
|
+
if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
message: 'Dislike reason is not allowed when reaction is not disliked',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
13
26
|
export type Request = z.infer<typeof RequestSchema>;
|
|
14
27
|
|
|
15
28
|
export const ResponseSchema = ICommandResponseSchema(STTJobSchema);
|
|
@@ -12,7 +12,9 @@ export const STTJobSchema = z.object({
|
|
|
12
12
|
fileUrl: z.string(),
|
|
13
13
|
aiResponse: STTResponseSchema.nullable(),
|
|
14
14
|
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
15
|
+
dislikeReason: z.string().nullable(),
|
|
15
16
|
status: z.nativeEnum(JOB_STATUS),
|
|
17
|
+
duration: z.number(),
|
|
16
18
|
error: z.string().nullable(),
|
|
17
19
|
userId: z.string().nullable(),
|
|
18
20
|
unregisteredUserId: z.string().nullable(),
|
|
@@ -4,6 +4,7 @@ import { VideoConfigSchema } from '../../video';
|
|
|
4
4
|
import { MusicConfigSchema } from '../../music';
|
|
5
5
|
import { WriterConfigSchema } from '../../writer';
|
|
6
6
|
import { ImageEditorConfigSchema } from '../../image-editor';
|
|
7
|
+
import { ImageGenerationConfigSchema } from '../../image-generation';
|
|
7
8
|
import { ParaphraseToolConfigSchema } from '../../paraphrase';
|
|
8
9
|
import { PresentationConfigSchema } from '../../presentation';
|
|
9
10
|
import { VideoEditorConfigSchema } from '../../video-editor';
|
|
@@ -15,6 +16,7 @@ export const GlobalToolsConfigSchema = z.object({
|
|
|
15
16
|
[TOOL_CONTENT_TYPE.MUSIC]: MusicConfigSchema,
|
|
16
17
|
[TOOL_CONTENT_TYPE.WRITER]: WriterConfigSchema,
|
|
17
18
|
[TOOL_CONTENT_TYPE.IMAGE_EDITOR]: ImageEditorConfigSchema,
|
|
19
|
+
[TOOL_CONTENT_TYPE.IMAGE_GENERATION]: ImageGenerationConfigSchema,
|
|
18
20
|
[TOOL_CONTENT_TYPE.REPHRASE]: ParaphraseToolConfigSchema,
|
|
19
21
|
[TOOL_CONTENT_TYPE.PRESENTATION]: PresentationConfigSchema,
|
|
20
22
|
[TOOL_CONTENT_TYPE.VIDEO_EDITOR]: VideoEditorConfigSchema,
|
|
@@ -6,6 +6,9 @@ export const ToolSchema = z.object({
|
|
|
6
6
|
title: z.string(),
|
|
7
7
|
description: z.string(),
|
|
8
8
|
icon: z.string(),
|
|
9
|
+
alias: z.string(),
|
|
10
|
+
bgColor: z.string(),
|
|
11
|
+
iconColor: z.string(),
|
|
9
12
|
order: z.number(),
|
|
10
13
|
contentType: z.nativeEnum(TOOL_CONTENT_TYPE),
|
|
11
14
|
createdAt: z.date(),
|
|
@@ -4,6 +4,7 @@ import { VideoConfigSchema } from '../../video';
|
|
|
4
4
|
import { MusicConfigSchema } from '../../music';
|
|
5
5
|
import { WriterConfigSchema } from '../../writer';
|
|
6
6
|
import { ImageEditorConfigSchema } from '../../image-editor';
|
|
7
|
+
import { ImageGenerationConfigSchema } from '../../image-generation';
|
|
7
8
|
import { ParaphraseToolConfigSchema } from '../../paraphrase';
|
|
8
9
|
import { PresentationConfigSchema } from '../../presentation';
|
|
9
10
|
import { VideoEditorConfigSchema } from '../../video-editor';
|
|
@@ -37,6 +38,12 @@ export const ToolWithConfigSchema = z.discriminatedUnion('contentType', [
|
|
|
37
38
|
config: ImageEditorConfigSchema,
|
|
38
39
|
}),
|
|
39
40
|
),
|
|
41
|
+
ToolSchema.merge(
|
|
42
|
+
z.object({
|
|
43
|
+
contentType: z.literal(TOOL_CONTENT_TYPE.IMAGE_GENERATION),
|
|
44
|
+
config: ImageGenerationConfigSchema,
|
|
45
|
+
}),
|
|
46
|
+
),
|
|
40
47
|
ToolSchema.merge(
|
|
41
48
|
z.object({
|
|
42
49
|
contentType: z.literal(TOOL_CONTENT_TYPE.REPHRASE),
|
|
@@ -4,12 +4,25 @@ import { TTSJobSchema } from '../models/tts-job.schema';
|
|
|
4
4
|
import { USER_REACTION } from '../../common';
|
|
5
5
|
|
|
6
6
|
export namespace SetReactionToTTSJobCommand {
|
|
7
|
-
export const RequestSchema = z
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export const RequestSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
userId: z.string().uuid().nullable().optional(),
|
|
10
|
+
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
11
|
+
uuid: z.string().uuid(),
|
|
12
|
+
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
13
|
+
dislikeReason: z.string().nullable().default(null),
|
|
14
|
+
})
|
|
15
|
+
.refine(
|
|
16
|
+
(data) => {
|
|
17
|
+
if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
message: 'Dislike reason is not allowed when reaction is not disliked',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
13
26
|
export type Request = z.infer<typeof RequestSchema>;
|
|
14
27
|
|
|
15
28
|
export const ResponseSchema = ICommandResponseSchema(TTSJobSchema);
|
|
@@ -15,12 +15,14 @@ export const TTSJobSchema = z.object({
|
|
|
15
15
|
userInput: z.string(),
|
|
16
16
|
aiResponse: z.string().nullable(),
|
|
17
17
|
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
18
|
+
dislikeReason: z.string().nullable(),
|
|
18
19
|
title: z.string(),
|
|
19
20
|
status: z.nativeEnum(JOB_STATUS),
|
|
20
21
|
error: z.string().nullable(),
|
|
21
22
|
modelId: z.string(),
|
|
22
23
|
voiceId: z.string(),
|
|
23
24
|
price: z.number(),
|
|
25
|
+
duration: z.number(),
|
|
24
26
|
userId: z.string().nullable(),
|
|
25
27
|
unregisteredUserId: z.string().nullable(),
|
|
26
28
|
isDeleted: z.boolean(),
|
package/video/commands/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ICommandResponseSchema } from '../../common/models/command-response.schema';
|
|
3
3
|
import { VideoJobSchema } from '../models/video-job.schema';
|
|
4
|
+
import { VideoGenerationRequestParamsSchema } from '../models';
|
|
4
5
|
|
|
5
6
|
export namespace RetryVideoJobCommand {
|
|
6
7
|
export const RequestSchema = z.object({
|
|
@@ -8,6 +9,9 @@ export namespace RetryVideoJobCommand {
|
|
|
8
9
|
userBalance: z.number(),
|
|
9
10
|
userId: z.string().uuid().nullable().optional(),
|
|
10
11
|
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
12
|
+
prompt: z.string().optional(),
|
|
13
|
+
modelId: z.string().uuid().optional(),
|
|
14
|
+
params: VideoGenerationRequestParamsSchema.optional(),
|
|
11
15
|
});
|
|
12
16
|
export type Request = z.infer<typeof RequestSchema>;
|
|
13
17
|
|
|
@@ -4,12 +4,25 @@ import { VideoJobSchema } from '../models/video-job.schema';
|
|
|
4
4
|
import { USER_REACTION } from '../../common';
|
|
5
5
|
|
|
6
6
|
export namespace SetReactionToVideoJobCommand {
|
|
7
|
-
export const RequestSchema = z
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export const RequestSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
userId: z.string().uuid().nullable().optional(),
|
|
10
|
+
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
11
|
+
uuid: z.string().uuid(),
|
|
12
|
+
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
13
|
+
dislikeReason: z.string().nullable().default(null),
|
|
14
|
+
})
|
|
15
|
+
.refine(
|
|
16
|
+
(data) => {
|
|
17
|
+
if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
message: 'Dislike reason is not allowed when reaction is not disliked',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
13
26
|
export type Request = z.infer<typeof RequestSchema>;
|
|
14
27
|
|
|
15
28
|
export const ResponseSchema = ICommandResponseSchema(VideoJobSchema);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { VideoModelSchema } from '../../models';
|
|
3
|
+
import { ICommandResponseSchema } from '../../../common';
|
|
4
|
+
|
|
5
|
+
export namespace GetVideoModelByUuidCommand {
|
|
6
|
+
export const RequestSchema = z.object({
|
|
7
|
+
uuid: z.string().uuid(),
|
|
8
|
+
});
|
|
9
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
10
|
+
|
|
11
|
+
export const ResponseSchema = ICommandResponseSchema(VideoModelSchema);
|
|
12
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './get-video-model-by-uuid.command';
|
|
@@ -5,4 +5,5 @@ export enum VIDEO_GENERATION_STRATEGY {
|
|
|
5
5
|
RUNWAY_CALLBACK = 'RUNWAY_CALLBACK',
|
|
6
6
|
SORA_2_VIDEO_GENERATION_POLLING = 'SORA_2_VIDEO_GENERATION_POLLING',
|
|
7
7
|
SORA_2_VIDEO_GENERATION_CALLBACK = 'SORA_2_VIDEO_GENERATION_CALLBACK',
|
|
8
|
+
SEEDANCE_VIDEO_GENERATION_CALLBACK = 'SEEDANCE_VIDEO_GENERATION_CALLBACK',
|
|
8
9
|
}
|
|
@@ -4,8 +4,10 @@ import { USER_REACTION } from '../../common';
|
|
|
4
4
|
|
|
5
5
|
export const VideoJobParamsSchema = z.object({
|
|
6
6
|
imageUrls: z.string().array().optional(),
|
|
7
|
+
imageIds: z.array(z.string()).optional(),
|
|
7
8
|
duration: z.number().optional(),
|
|
8
9
|
aspectRatio: z.string().optional(),
|
|
10
|
+
resolution: z.string().optional(),
|
|
9
11
|
});
|
|
10
12
|
|
|
11
13
|
export type VideoJobParams = z.infer<typeof VideoJobParamsSchema>;
|
|
@@ -14,6 +16,7 @@ export const VideoJobSchema = z.object({
|
|
|
14
16
|
uuid: z.string(),
|
|
15
17
|
prompt: z.string(),
|
|
16
18
|
reaction: z.nativeEnum(USER_REACTION).nullable(),
|
|
19
|
+
dislikeReason: z.string().nullable(),
|
|
17
20
|
externalId: z.string().nullable(),
|
|
18
21
|
title: z.string(),
|
|
19
22
|
status: z.nativeEnum(JOB_STATUS),
|
|
@@ -20,20 +20,28 @@ export const VideoModelParamsSchema = z.object({
|
|
|
20
20
|
})
|
|
21
21
|
.optional(),
|
|
22
22
|
quality: z.string().optional(),
|
|
23
|
+
resolution: z
|
|
24
|
+
.object({
|
|
25
|
+
options: z.array(z.string()),
|
|
26
|
+
})
|
|
27
|
+
.optional(),
|
|
23
28
|
});
|
|
24
29
|
|
|
25
30
|
export type VideoModelParams = z.infer<typeof VideoModelParamsSchema>;
|
|
26
31
|
|
|
27
32
|
export const VideoGenerationRequestParamsSchema = z.object({
|
|
28
33
|
imageUrls: z.string().array().optional(),
|
|
34
|
+
imageIds: z.array(z.string()).optional(),
|
|
29
35
|
duration: z.number(),
|
|
30
36
|
aspectRatio: z.string().optional(),
|
|
31
37
|
quality: z.string().optional(),
|
|
38
|
+
resolution: z.string().optional(),
|
|
32
39
|
});
|
|
33
40
|
export type VideoGenerationRequestParams = z.infer<typeof VideoGenerationRequestParamsSchema>;
|
|
34
41
|
|
|
35
42
|
export const VideoModelPricingRuleConditionSchema = z.object({
|
|
36
|
-
aspectRatio: z.string(),
|
|
43
|
+
aspectRatio: z.string().optional(),
|
|
44
|
+
resolution: z.string().optional(),
|
|
37
45
|
});
|
|
38
46
|
export type VideoModelPricingRuleCondition = z.infer<typeof VideoModelPricingRuleConditionSchema>;
|
|
39
47
|
|
package/video/routes/index.ts
CHANGED
|
@@ -36,7 +36,13 @@ export function calculateVideoGenerationPrice({
|
|
|
36
36
|
params: VideoGenerationRequestParams;
|
|
37
37
|
rules: VideoModelPricingRules;
|
|
38
38
|
}) {
|
|
39
|
-
const
|
|
39
|
+
const perSecondRule = rules
|
|
40
|
+
.filter((r) => r.type === VIDEO_PRICING_RULE_TYPE.PER_SECOND)
|
|
41
|
+
.find((r) => matchesCondition(r.condition, params));
|
|
42
|
+
|
|
43
|
+
const effectivePricePerSecond = perSecondRule ? perSecondRule.value : pricePerSecond;
|
|
44
|
+
|
|
45
|
+
const base = effectivePricePerSecond * params.duration;
|
|
40
46
|
|
|
41
47
|
const flatMarkup = rules.reduce((sum, r) => {
|
|
42
48
|
if (r.type !== VIDEO_PRICING_RULE_TYPE.FLAT) {
|
|
@@ -7,10 +7,11 @@ export namespace EditVideoCommand {
|
|
|
7
7
|
userId: z.string().uuid().nullable().optional(),
|
|
8
8
|
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
9
9
|
prompt: z.string(),
|
|
10
|
+
inputVideoId: z.string().uuid(),
|
|
10
11
|
inputVideoUrl: z.string(),
|
|
11
12
|
duration: z.number(),
|
|
12
13
|
userBalance: z.number(),
|
|
13
|
-
modelId: z.string(),
|
|
14
|
+
modelId: z.string().uuid(),
|
|
14
15
|
});
|
|
15
16
|
export type Request = z.infer<typeof RequestSchema>;
|
|
16
17
|
|
|
@@ -8,6 +8,11 @@ export namespace RetryVideoEditorJobCommand {
|
|
|
8
8
|
userBalance: z.number(),
|
|
9
9
|
userId: z.string().uuid().nullable().optional(),
|
|
10
10
|
unregisteredUserId: z.string().uuid().nullable().optional(),
|
|
11
|
+
prompt: z.string().optional(),
|
|
12
|
+
inputVideoId: z.string().uuid().optional(),
|
|
13
|
+
inputVideoUrl: z.string().optional(),
|
|
14
|
+
duration: z.number().optional(),
|
|
15
|
+
modelId: z.string().uuid().optional(),
|
|
11
16
|
});
|
|
12
17
|
export type Request = z.infer<typeof RequestSchema>;
|
|
13
18
|
|