@purpleschool/gptbot 0.7.80 → 0.7.82

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.
Files changed (65) hide show
  1. package/api/controllers/http/presentation.ts +10 -0
  2. package/build/api/controllers/http/presentation.js +7 -0
  3. package/build/commands/payment/pay.command.js +2 -0
  4. package/build/commands/subscription/downgrade-subscription.command.js +1 -28
  5. package/build/commands/subscription/get-subscriptions-summary.command.js +1 -1
  6. package/build/commands/tools/presentation/build-blank-slide.command.js +21 -0
  7. package/build/commands/tools/presentation/generate-and-insert-slide.command.js +22 -0
  8. package/build/commands/tools/presentation/index.js +7 -0
  9. package/build/commands/tools/presentation/presentation-generate-report.command.js +17 -0
  10. package/build/commands/tools/presentation/presentation-paraphrase.command.js +20 -0
  11. package/build/commands/tools/presentation/update-presentation-slides.command.js +25 -0
  12. package/build/commands/tools/presentation/update-presentation.command.js +4 -3
  13. package/build/commands/tools/presentation/update-slide-image-slot.command.js +34 -0
  14. package/build/commands/tools/presentation/update-slide.command.js +19 -0
  15. package/build/constants/cloud-payments/index.js +2 -1
  16. package/build/constants/errors/errors.js +21 -1
  17. package/build/constants/presentation/enums/index.js +4 -0
  18. package/build/constants/presentation/enums/presentation-ai-action-call-status.enum.js +9 -0
  19. package/build/constants/presentation/enums/presentation-ai-action-pricing-type.enum.js +8 -0
  20. package/build/constants/presentation/enums/presentation-ai-action-type.enum.js +8 -0
  21. package/build/constants/presentation/enums/slide-image-slot-action.enum.js +8 -0
  22. package/build/helpers/index.js +1 -0
  23. package/build/helpers/presentation/calculate-presentation-ai-action-price.util.js +16 -0
  24. package/build/helpers/presentation/index.js +17 -0
  25. package/build/models/tools/index.js +1 -0
  26. package/build/models/tools/presentation/index.js +1 -0
  27. package/build/models/tools/presentation/presentation-ai-action.schema.js +27 -0
  28. package/build/models/tools/presentation/presentation-config.schema.js +3 -0
  29. package/build/models/tools/presentation/presentation.schema.js +2 -0
  30. package/build/models/tools/presentation/slide-content-edit.schema.js +129 -0
  31. package/build/models/tools/presentation/slide-content.schema.js +22 -20
  32. package/build/models/tools/presentation/slide.schema.js +39 -1
  33. package/build/models/user-to-subscription.schema.js +4 -1
  34. package/commands/payment/pay.command.ts +2 -0
  35. package/commands/subscription/downgrade-subscription.command.ts +1 -31
  36. package/commands/subscription/get-subscriptions-summary.command.ts +2 -2
  37. package/commands/tools/presentation/build-blank-slide.command.ts +23 -0
  38. package/commands/tools/presentation/generate-and-insert-slide.command.ts +27 -0
  39. package/commands/tools/presentation/index.ts +7 -0
  40. package/commands/tools/presentation/presentation-generate-report.command.ts +21 -0
  41. package/commands/tools/presentation/presentation-paraphrase.command.ts +26 -0
  42. package/commands/tools/presentation/update-presentation-slides.command.ts +32 -0
  43. package/commands/tools/presentation/update-presentation.command.ts +5 -4
  44. package/commands/tools/presentation/update-slide-image-slot.command.ts +40 -0
  45. package/commands/tools/presentation/update-slide.command.ts +25 -0
  46. package/constants/cloud-payments/index.ts +2 -0
  47. package/constants/errors/errors.ts +21 -1
  48. package/constants/presentation/enums/index.ts +4 -0
  49. package/constants/presentation/enums/presentation-ai-action-call-status.enum.ts +5 -0
  50. package/constants/presentation/enums/presentation-ai-action-pricing-type.enum.ts +4 -0
  51. package/constants/presentation/enums/presentation-ai-action-type.enum.ts +4 -0
  52. package/constants/presentation/enums/slide-image-slot-action.enum.ts +4 -0
  53. package/helpers/index.ts +1 -0
  54. package/helpers/presentation/calculate-presentation-ai-action-price.util.ts +20 -0
  55. package/helpers/presentation/index.ts +1 -0
  56. package/models/tools/index.ts +1 -0
  57. package/models/tools/presentation/index.ts +1 -0
  58. package/models/tools/presentation/presentation-ai-action.schema.ts +33 -0
  59. package/models/tools/presentation/presentation-config.schema.ts +3 -0
  60. package/models/tools/presentation/presentation.schema.ts +2 -0
  61. package/models/tools/presentation/slide-content-edit.schema.ts +154 -0
  62. package/models/tools/presentation/slide-content.schema.ts +119 -32
  63. package/models/tools/presentation/slide.schema.ts +47 -0
  64. package/models/user-to-subscription.schema.ts +7 -0
  65. package/package.json +1 -1
@@ -0,0 +1,4 @@
1
+ export enum PRESENTATION_AI_ACTION_PRICING_TYPE {
2
+ PER_CHARACTER = 'PER_CHARACTER',
3
+ FLAT = 'FLAT',
4
+ }
@@ -0,0 +1,4 @@
1
+ export enum PRESENTATION_AI_ACTION_TYPE {
2
+ PARAPHRASE = 'PARAPHRASE',
3
+ GENERATE_REPORT = 'GENERATE_REPORT',
4
+ }
@@ -0,0 +1,4 @@
1
+ export enum SLIDE_IMAGE_SLOT_ACTION {
2
+ REPLACE = 'REPLACE',
3
+ GENERATE = 'GENERATE',
4
+ }
package/helpers/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './ai-model';
2
+ export * from './presentation';
2
3
  export * from './stt';
3
4
  export * from './subscription';
4
5
  export * from './tts';
@@ -0,0 +1,20 @@
1
+ import { PRESENTATION_AI_ACTION_PRICING_TYPE } from '../../constants';
2
+ import { PresentationAiActionPricingRules } from '../../models/tools/presentation';
3
+
4
+ export function calculatePresentationAiActionPrice(
5
+ pricingRules: PresentationAiActionPricingRules,
6
+ selectionText: string,
7
+ ): number {
8
+ switch (pricingRules.type) {
9
+ case PRESENTATION_AI_ACTION_PRICING_TYPE.PER_CHARACTER:
10
+ const characterCount = selectionText.length;
11
+ const price = characterCount * pricingRules.price;
12
+ return Math.max(1, Math.ceil(price));
13
+
14
+ case PRESENTATION_AI_ACTION_PRICING_TYPE.FLAT:
15
+ return Math.max(1, Math.ceil(pricingRules.price));
16
+
17
+ default:
18
+ throw new Error(`Unknown pricing type`);
19
+ }
20
+ }
@@ -0,0 +1 @@
1
+ export * from './calculate-presentation-ai-action-price.util';
@@ -1,5 +1,6 @@
1
1
  export * from './language';
2
2
  export * from './paraphrase';
3
+ export * from './presentation';
3
4
  export * from './stt';
4
5
  export * from './tts';
5
6
  export * from './video';
@@ -5,3 +5,4 @@ export * from './slide-outline.schema';
5
5
  export * from './slide.schema';
6
6
  export * from './slide-content.schema';
7
7
  export * from './presentation-config.schema';
8
+ export * from './presentation-ai-action.schema';
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import {
3
+ PRESENTATION_AI_ACTION_PRICING_TYPE,
4
+ PRESENTATION_AI_ACTION_TYPE,
5
+ } from '../../../constants';
6
+
7
+ export const PresentationAiActionPricingRulesSchema = z.discriminatedUnion('type', [
8
+ z.object({
9
+ type: z.literal(PRESENTATION_AI_ACTION_PRICING_TYPE.PER_CHARACTER),
10
+ price: z.number(),
11
+ }),
12
+ z.object({
13
+ type: z.literal(PRESENTATION_AI_ACTION_PRICING_TYPE.FLAT),
14
+ price: z.number(),
15
+ }),
16
+ ]);
17
+ export type PresentationAiActionPricingRules = z.infer<
18
+ typeof PresentationAiActionPricingRulesSchema
19
+ >;
20
+
21
+ export const PresentationAiActionSchema = z.object({
22
+ uuid: z.string(),
23
+ type: z.nativeEnum(PRESENTATION_AI_ACTION_TYPE),
24
+ pricingRules: PresentationAiActionPricingRulesSchema,
25
+ maxPromptLength: z.number(),
26
+ aiModel: z.string(),
27
+ title: z.string(),
28
+ icon: z.string(),
29
+ order: z.number(),
30
+ createdAt: z.date(),
31
+ updatedAt: z.date(),
32
+ });
33
+ export type PresentationAiAction = z.infer<typeof PresentationAiActionSchema>;
@@ -2,16 +2,19 @@ import { z } from 'zod';
2
2
  import { SlideContentTypeSchema } from './slide-content-type.schema';
3
3
  import { LanguageSchema } from '../language';
4
4
  import { PresentationTemplateSchema } from './presentation-template.schema';
5
+ import { PresentationAiActionSchema } from './presentation-ai-action.schema';
5
6
 
6
7
  export const PresentationConfigSchema = z.object({
7
8
  slideContentTypes: z.array(SlideContentTypeSchema),
8
9
  languages: z.array(LanguageSchema),
9
10
  templates: z.array(PresentationTemplateSchema),
11
+ aiActions: z.array(PresentationAiActionSchema),
10
12
  slideGenerationPrice: z.number(),
11
13
  maxSlides: z.number(),
12
14
  minSlides: z.number(),
13
15
  maxSlideTitleLength: z.number(),
14
16
  maxSlideOutlineLength: z.number(),
15
17
  maxPromptLength: z.number(),
18
+ imageGenerationPrice: z.number(),
16
19
  });
17
20
  export type PresentationConfig = z.infer<typeof PresentationConfigSchema>;
@@ -13,6 +13,8 @@ export const PresentationSchema = z.object({
13
13
  templateId: z.string(),
14
14
  downloadUrl: z.string().nullable(),
15
15
  slideCount: z.number(),
16
+ lastContentUpdateAt: z.date().nullable(),
17
+ lastPptxExportedAt: z.date().nullable(),
16
18
  createdAt: z.date(),
17
19
  updatedAt: z.date(),
18
20
  });
@@ -0,0 +1,154 @@
1
+ import z from 'zod';
2
+ import {
3
+ ICoverSlideDataStructure,
4
+ IThankYouSlideDataStructure,
5
+ ITextSlideDataStructure,
6
+ IStructuredListSlideDataStructure,
7
+ IContentsSlideDataStructure,
8
+ IImageSlideDataStructure,
9
+ ISectionBreakSlideDataStructure,
10
+ ITableSlideDataStructure,
11
+ SLIDE_CHART_TYPE,
12
+ IBarChartSlideDataStructure,
13
+ IChartSlideDataStructure,
14
+ ImageSlotSchema,
15
+ } from './slide-content.schema';
16
+ import { SLIDE_CONTENT_TYPE } from '../../../constants';
17
+
18
+ export const CoverSlideDataUserEditSchema = z.object({
19
+ contentType: z.literal(SLIDE_CONTENT_TYPE.COVER),
20
+ title: z.string().max(1000),
21
+ author: z.object({
22
+ label: z.string().max(200),
23
+ value: z.string().max(500),
24
+ }),
25
+ date: z.object({
26
+ label: z.string().max(200),
27
+ value: z.string().max(500),
28
+ }),
29
+ email: z.object({
30
+ label: z.string().max(200),
31
+ value: z.string().max(500),
32
+ }),
33
+ version: z.literal(1),
34
+ }) satisfies z.ZodType<ICoverSlideDataStructure>;
35
+
36
+ export const ThankYouSlideDataUserEditSchema = z.object({
37
+ contentType: z.literal(SLIDE_CONTENT_TYPE.THANK_YOU),
38
+ title: z.string().max(1000),
39
+ author: z.object({
40
+ label: z.string().max(200),
41
+ value: z.string().max(500),
42
+ }),
43
+ date: z.object({
44
+ label: z.string().max(200),
45
+ value: z.string().max(500),
46
+ }),
47
+ email: z.object({
48
+ label: z.string().max(200),
49
+ value: z.string().max(500),
50
+ }),
51
+ version: z.literal(1),
52
+ }) satisfies z.ZodType<IThankYouSlideDataStructure>;
53
+
54
+ export const TextSlideDataUserEditSchema = z.object({
55
+ contentType: z.literal(SLIDE_CONTENT_TYPE.TEXT),
56
+ title: z.string().max(1000),
57
+ description: z.string().max(5000),
58
+ version: z.literal(1),
59
+ }) satisfies z.ZodType<ITextSlideDataStructure>;
60
+
61
+ export const StructuredListSlideDataUserEditSchema = z.object({
62
+ contentType: z.literal(SLIDE_CONTENT_TYPE.STRUCTURED_LIST),
63
+ title: z.string().max(1000),
64
+ description: z.string().max(2000),
65
+ list: z
66
+ .array(
67
+ z.object({
68
+ title: z.string().max(500),
69
+ description: z.string().max(1000),
70
+ }),
71
+ )
72
+ .max(15),
73
+ version: z.literal(1),
74
+ }) satisfies z.ZodType<IStructuredListSlideDataStructure>;
75
+
76
+ export const ContentsSlideDataUserEditSchema = z.object({
77
+ contentType: z.literal(SLIDE_CONTENT_TYPE.CONTENTS),
78
+ title: z.string().max(1000),
79
+ items: z
80
+ .array(
81
+ z.object({
82
+ pageNumber: z.number(),
83
+ title: z.string().max(1000),
84
+ }),
85
+ )
86
+ .max(100),
87
+ version: z.literal(1),
88
+ }) satisfies z.ZodType<IContentsSlideDataStructure>;
89
+
90
+ export const ImageSlideDataUserEditSchema = z.object({
91
+ contentType: z.literal(SLIDE_CONTENT_TYPE.TEXT_WITH_IMAGE),
92
+ title: z.string().max(1000),
93
+ description: z.string().max(4000),
94
+ imageSlot: ImageSlotSchema,
95
+ version: z.literal(1),
96
+ }) satisfies z.ZodType<IImageSlideDataStructure>;
97
+
98
+ export const SectionBreakSlideDataUserEditSchema = z.object({
99
+ contentType: z.literal(SLIDE_CONTENT_TYPE.SECTION_BREAK),
100
+ title: z.string().max(1000),
101
+ description: z.string().max(1000),
102
+ version: z.literal(1),
103
+ }) satisfies z.ZodType<ISectionBreakSlideDataStructure>;
104
+
105
+ export const TableSlideDataUserEditSchema = z.object({
106
+ contentType: z.literal(SLIDE_CONTENT_TYPE.TABLE),
107
+ title: z.string().max(1000),
108
+ description: z.string().max(2000),
109
+ table: z.object({
110
+ columnHeaders: z.array(z.string().max(500)).max(30),
111
+ rows: z.array(z.array(z.string().max(1000))).max(50),
112
+ hasRowHeaders: z.boolean(),
113
+ hasSummaryRow: z.boolean(),
114
+ }),
115
+ version: z.literal(1),
116
+ }) satisfies z.ZodType<ITableSlideDataStructure>;
117
+
118
+ export const BarChartSlideDataUserEditSchema = z.object({
119
+ type: z.literal(SLIDE_CHART_TYPE.BAR),
120
+ categories: z.array(z.string().max(500)).max(100),
121
+ series: z
122
+ .array(
123
+ z.object({
124
+ name: z.string().max(500),
125
+ data: z.array(z.number()),
126
+ type: z.number().min(0).max(11),
127
+ }),
128
+ )
129
+ .max(10),
130
+ yAxisLabel: z.string().max(500).optional(),
131
+ unit: z.string().max(100).optional(),
132
+ version: z.literal(1),
133
+ }) satisfies z.ZodType<IBarChartSlideDataStructure>;
134
+
135
+ export const ChartSlideDataUserEditSchema = z.object({
136
+ contentType: z.literal(SLIDE_CONTENT_TYPE.CHART),
137
+ title: z.string().max(1000),
138
+ description: z.string().max(4000),
139
+ chart: z.discriminatedUnion('type', [BarChartSlideDataUserEditSchema]),
140
+ version: z.literal(1),
141
+ }) satisfies z.ZodType<IChartSlideDataStructure>;
142
+
143
+ export const SlideContentUserEditSchema = z.discriminatedUnion('contentType', [
144
+ CoverSlideDataUserEditSchema,
145
+ StructuredListSlideDataUserEditSchema,
146
+ TextSlideDataUserEditSchema,
147
+ ContentsSlideDataUserEditSchema,
148
+ SectionBreakSlideDataUserEditSchema,
149
+ ImageSlideDataUserEditSchema,
150
+ ThankYouSlideDataUserEditSchema,
151
+ TableSlideDataUserEditSchema,
152
+ ChartSlideDataUserEditSchema,
153
+ ]);
154
+ export type SlideContentUserEdit = z.infer<typeof SlideContentUserEditSchema>;
@@ -19,14 +19,95 @@ export const IconSlotSchema = z.object({
19
19
  .string()
20
20
  .uuid()
21
21
  .describe('Generate a valid uuid for icon slot, that will be used for future lookups'),
22
- prompt: z
23
- .string()
24
- .describe(
25
- 'Icons are stored locally. Provide a search query for a fitting icon. MUST BE IN ENGLISH',
26
- ),
22
+ prompt: z.string().describe('Provide a search query for an fitting icon. MUST BE IN ENGLISH'),
27
23
  });
28
24
  export type IconSlot = z.infer<typeof IconSlotSchema>;
29
25
 
26
+ export interface ICoverSlideDataStructure {
27
+ contentType: SLIDE_CONTENT_TYPE.COVER;
28
+ title: string;
29
+ author: { label: string; value: string };
30
+ date: { label: string; value: string };
31
+ email: { label: string; value: string };
32
+ version: 1;
33
+ }
34
+
35
+ export interface IThankYouSlideDataStructure {
36
+ contentType: SLIDE_CONTENT_TYPE.THANK_YOU;
37
+ title: string;
38
+ author: { label: string; value: string };
39
+ date: { label: string; value: string };
40
+ email: { label: string; value: string };
41
+ version: 1;
42
+ }
43
+
44
+ export interface ITextSlideDataStructure {
45
+ contentType: SLIDE_CONTENT_TYPE.TEXT;
46
+ title: string;
47
+ description: string;
48
+ version: 1;
49
+ }
50
+
51
+ export interface IStructuredListSlideDataStructure {
52
+ contentType: SLIDE_CONTENT_TYPE.STRUCTURED_LIST;
53
+ title: string;
54
+ description: string;
55
+ list: Array<{ title: string; description: string }>;
56
+ version: 1;
57
+ }
58
+
59
+ export interface IContentsSlideDataStructure {
60
+ contentType: SLIDE_CONTENT_TYPE.CONTENTS;
61
+ title: string;
62
+ items: Array<{ pageNumber: number; title: string }>;
63
+ version: 1;
64
+ }
65
+
66
+ export interface IImageSlideDataStructure {
67
+ contentType: SLIDE_CONTENT_TYPE.TEXT_WITH_IMAGE;
68
+ title: string;
69
+ description: string;
70
+ imageSlot?: ImageSlot;
71
+ version: 1;
72
+ }
73
+
74
+ export interface ISectionBreakSlideDataStructure {
75
+ contentType: SLIDE_CONTENT_TYPE.SECTION_BREAK;
76
+ title: string;
77
+ description: string;
78
+ version: 1;
79
+ }
80
+
81
+ export interface ITableSlideDataStructure {
82
+ contentType: SLIDE_CONTENT_TYPE.TABLE;
83
+ title: string;
84
+ description: string;
85
+ table: {
86
+ columnHeaders: string[];
87
+ rows: string[][];
88
+ hasRowHeaders: boolean;
89
+ hasSummaryRow: boolean;
90
+ };
91
+ version: 1;
92
+ }
93
+
94
+ export interface IBarChartSlideDataStructure {
95
+ type: SLIDE_CHART_TYPE.BAR;
96
+ categories: string[];
97
+ series: Array<{ name: string; data: number[]; type: number }>;
98
+ yAxisLabel?: string;
99
+ unit?: string;
100
+ version: 1;
101
+ }
102
+
103
+ export interface IChartSlideDataStructure {
104
+ contentType: SLIDE_CONTENT_TYPE.CHART;
105
+ title: string;
106
+ description: string;
107
+ chart: IBarChartSlideDataStructure;
108
+ version: 1;
109
+ }
110
+
30
111
  export const CoverSlideDataSchema = z.object({
31
112
  contentType: z.literal(SLIDE_CONTENT_TYPE.COVER),
32
113
  title: z.string().describe('Slide title in about 6 words').min(10).max(150),
@@ -49,20 +130,22 @@ export const CoverSlideDataSchema = z.object({
49
130
  value: z.string().describe('Just default "email@example.com"'),
50
131
  }),
51
132
  version: z.literal(1),
52
- });
133
+ }) satisfies z.ZodType<ICoverSlideDataStructure>;
53
134
  export type CoverSlideData = z.infer<typeof CoverSlideDataSchema>;
54
135
 
55
136
  export const ThankYouSlideDataSchema = z.object({
56
137
  contentType: z.literal(SLIDE_CONTENT_TYPE.THANK_YOU),
57
- title: z.string().describe('Slide title in about 6 words').min(10).max(150),
138
+ title: z
139
+ .string()
140
+ .describe('"Thank you for your attention" in presentation\'s language')
141
+ .min(10)
142
+ .max(150),
58
143
  author: z.object({
59
- label: z.string().describe('Literal "Author" in presentation\'s language'),
60
- value: z
61
- .string()
62
- .describe('Literal "Author of the presentation" in presentation\'s language'),
144
+ label: z.string().describe('"Author" in presentation\'s language'),
145
+ value: z.string().describe('"Author of the presentation" in presentation\'s language'),
63
146
  }),
64
147
  date: z.object({
65
- label: z.string().describe('Literal "Date" in presentation\'s language'),
148
+ label: z.string().describe('"Date" in presentation\'s language'),
66
149
  value: z
67
150
  .string()
68
151
  .describe(
@@ -74,7 +157,7 @@ export const ThankYouSlideDataSchema = z.object({
74
157
  value: z.string().describe('Just default "email@example.com"'),
75
158
  }),
76
159
  version: z.literal(1),
77
- });
160
+ }) satisfies z.ZodType<IThankYouSlideDataStructure>;
78
161
  export type ThankYouSlideData = z.infer<typeof ThankYouSlideDataSchema>;
79
162
 
80
163
  export const StructuredListSlideDataSchema = z.object({
@@ -90,7 +173,7 @@ export const StructuredListSlideDataSchema = z.object({
90
173
  )
91
174
  .length(4),
92
175
  version: z.literal(1),
93
- });
176
+ }) satisfies z.ZodType<IStructuredListSlideDataStructure>;
94
177
  export type StructuredListSlideData = z.infer<typeof StructuredListSlideDataSchema>;
95
178
 
96
179
  export const TextSlideDataSchema = z.object({
@@ -99,12 +182,12 @@ export const TextSlideDataSchema = z.object({
99
182
  description: z
100
183
  .string()
101
184
  .describe(
102
- 'Fairly long textual description of the point presented in the title. A couple of paragraphs.',
185
+ "Fairly long textual description of the point presented in the title. A couple of paragraphs. Consider maximum amount of text to be 600 characters. Don't cut the text short.",
103
186
  )
104
187
  .min(300)
105
- .max(500),
188
+ .max(600),
106
189
  version: z.literal(1),
107
- });
190
+ }) satisfies z.ZodType<ITextSlideDataStructure>;
108
191
  export type TextSlideData = z.infer<typeof TextSlideDataSchema>;
109
192
 
110
193
  export const ContentsSlideDataSchema = z.object({
@@ -128,7 +211,7 @@ export const ContentsSlideDataSchema = z.object({
128
211
  'List of slide titles. Must be relevant and generated after all the slides are generated',
129
212
  ),
130
213
  version: z.literal(1),
131
- });
214
+ }) satisfies z.ZodType<IContentsSlideDataStructure>;
132
215
  export type ContentsSlideData = z.infer<typeof ContentsSlideDataSchema>;
133
216
 
134
217
  export const ImageSlideDataSchema = z
@@ -143,7 +226,9 @@ export const ImageSlideDataSchema = z
143
226
  imageSlot: ImageSlotSchema,
144
227
  version: z.literal(1),
145
228
  })
146
- .describe('Slide that contains a title, description of the title');
229
+ .describe(
230
+ 'Slide that contains a title, description of the title',
231
+ ) satisfies z.ZodType<IImageSlideDataStructure>;
147
232
  export type ImageSlideData = z.infer<typeof ImageSlideDataSchema>;
148
233
 
149
234
  export const SectionBreakSlideDataSchema = z.object({
@@ -151,7 +236,7 @@ export const SectionBreakSlideDataSchema = z.object({
151
236
  title: z.string().describe('Slide title in about 6 words').min(10).max(200),
152
237
  description: z.string().describe('Description of the slide in about 6 words').min(10).max(200),
153
238
  version: z.literal(1),
154
- });
239
+ }) satisfies z.ZodType<ISectionBreakSlideDataStructure>;
155
240
  export type SectionBreakSlideData = z.infer<typeof SectionBreakSlideDataSchema>;
156
241
 
157
242
  export const TableSlideDataSchema = z.object({
@@ -169,9 +254,9 @@ export const TableSlideDataSchema = z.object({
169
254
  .max(10)
170
255
  .describe('Array of column header labels'),
171
256
  rows: z
172
- .array(z.array(z.string().min(1).max(150)))
173
- .min(2)
174
- .max(10)
257
+ .array(z.array(z.string().min(1).max(75)))
258
+ .min(3)
259
+ .max(4)
175
260
  .describe(
176
261
  'Table rows; each row must have exactly the same number of cells as columnHeaders',
177
262
  ),
@@ -179,21 +264,23 @@ export const TableSlideDataSchema = z.object({
179
264
  hasSummaryRow: z.boolean().describe('If table needs a summary row, set this to true'),
180
265
  }),
181
266
  version: z.literal(1),
182
- });
267
+ }) satisfies z.ZodType<ITableSlideDataStructure>;
183
268
  export type TableSlideData = z.infer<typeof TableSlideDataSchema>;
184
269
 
185
270
  // Charts
186
271
  export const BarChartSlideDataSchema = z.object({
187
272
  type: z.literal(SLIDE_CHART_TYPE.BAR),
188
273
  categories: z
189
- .array(z.string().min(1).max(12))
274
+ .array(z.string())
190
275
  .min(1)
191
276
  .max(12)
192
277
  .describe('Category labels (e.g., months, products, regions)'),
193
278
  series: z
194
279
  .array(
195
280
  z.object({
196
- name: z.string().min(1).max(12).describe('Series name for legend'),
281
+ name: z
282
+ .string()
283
+ .describe('Series name for legend. Try to include measurements if needed'),
197
284
  data: z.array(z.number()).describe('Values corresponding to categories'),
198
285
  type: z
199
286
  .number()
@@ -203,21 +290,21 @@ export const BarChartSlideDataSchema = z.object({
203
290
  }),
204
291
  )
205
292
  .min(1)
206
- .max(12)
207
- .describe('Data series for the chart'),
293
+ .max(1)
294
+ .describe('Data series for the chart. Only one series is supported'),
208
295
  yAxisLabel: z.string().max(40).optional().describe('Y-axis label'),
209
296
  unit: z.string().max(10).optional().describe('Unit symbol (%, $, etc.)'),
210
297
  version: z.literal(1),
211
- });
298
+ }) satisfies z.ZodType<IBarChartSlideDataStructure>;
212
299
  export type BarChartSlideData = z.infer<typeof BarChartSlideDataSchema>;
213
300
 
214
301
  export const ChartSlideDataSchema = z.object({
215
302
  contentType: z.literal(SLIDE_CONTENT_TYPE.CHART),
216
- title: z.string().describe('Slide title in about 6 words').min(10).max(200),
217
- description: z.string().describe("Information on slide's topic").min(10).max(400),
303
+ title: z.string().describe('Slide title in about 2-6 words').max(100),
304
+ description: z.string().describe("Information on slide's topic").max(600),
218
305
  chart: z.discriminatedUnion('type', [BarChartSlideDataSchema]),
219
306
  version: z.literal(1),
220
- });
307
+ }) satisfies z.ZodType<IChartSlideDataStructure>;
221
308
  export type ChartSlideData = z.infer<typeof ChartSlideDataSchema>;
222
309
 
223
310
  export const SlideContentSchema = z.discriminatedUnion('contentType', [
@@ -3,6 +3,7 @@ import { SlideContentSchema } from './slide-content.schema';
3
3
  import { SLIDE_CONTENT_TYPE, SLIDE_LAYOUT } from '../../../constants';
4
4
  import { SlideIconSlotSchema } from './slide-icon-slot.schema';
5
5
  import { SlideImageSlotSchema } from './slide-image-slot.schema';
6
+ import { SlideContentUserEditSchema } from './slide-content-edit.schema';
6
7
 
7
8
  export const SlideSchema = z.object({
8
9
  uuid: z.string().uuid(),
@@ -17,3 +18,49 @@ export const SlideSchema = z.object({
17
18
  updatedAt: z.date(),
18
19
  });
19
20
  export type Slide = z.infer<typeof SlideSchema>;
21
+
22
+ export const SlideUpdateSchema = SlideSchema.pick({
23
+ layoutId: true,
24
+ })
25
+ .extend({
26
+ content: SlideContentUserEditSchema,
27
+ })
28
+ .partial();
29
+ export type SlideUpdate = z.infer<typeof SlideUpdateSchema>;
30
+
31
+ export const SlideBulkUpdateSchema = SlideSchema.pick({
32
+ order: true,
33
+ contentTypeId: true,
34
+ layoutId: true,
35
+ presentationId: true,
36
+ })
37
+ .extend({
38
+ uuid: z.string().uuid().optional(),
39
+ content: SlideContentUserEditSchema,
40
+ })
41
+ .array()
42
+ .min(1, 'Must include at least one slide')
43
+ .refine(
44
+ (arr) => {
45
+ const orders = arr.map((s) => s.order);
46
+ const unique = new Set(orders);
47
+ if (unique.size !== orders.length) return false;
48
+ const sorted = [...orders].sort((a, b) => a - b);
49
+ return sorted.every((val, idx) => val === idx);
50
+ },
51
+ {
52
+ message: 'Slide orders must be unique and sequential starting at 0',
53
+ path: ['order'],
54
+ },
55
+ )
56
+ .refine(
57
+ (arr) => {
58
+ const [firstId, ...rest] = arr.map((s) => s.presentationId);
59
+ return rest.every((id) => id === firstId);
60
+ },
61
+ {
62
+ message: 'All slides must belong to the same presentation',
63
+ path: ['presentationId'],
64
+ },
65
+ );
66
+ export type SlideBulkUpdate = z.infer<typeof SlideBulkUpdateSchema>;
@@ -25,3 +25,10 @@ export const UserToSubscriptionWithSubscriptionSchema = z.intersection(
25
25
  subscription: SubscriptionSchema,
26
26
  }),
27
27
  );
28
+
29
+ export const UserToSubscriptionWithDowngradeSubscriptionSchema = z.intersection(
30
+ UserToSubscriptionWithSubscriptionSchema,
31
+ z.object({
32
+ subscriptionDowngrade: SubscriptionSchema.optional(),
33
+ }),
34
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purpleschool/gptbot",
3
- "version": "0.7.80",
3
+ "version": "0.7.82",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",