@updraft-solutions/mcrit-sdk 0.4.0 → 0.6.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.
Files changed (47) hide show
  1. package/dist/chunk-EE4YY3AU.js +2620 -0
  2. package/dist/chunk-H4CJ2YEQ.cjs +2620 -0
  3. package/dist/courses/index.d.cts +2 -2
  4. package/dist/courses/index.d.ts +2 -2
  5. package/dist/index.cjs +201 -5
  6. package/dist/index.d.cts +3 -3
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +207 -11
  9. package/dist/schemas/index.cjs +198 -2
  10. package/dist/schemas/index.d.cts +3157 -128
  11. package/dist/schemas/index.d.ts +3157 -128
  12. package/dist/schemas/index.js +201 -5
  13. package/dist/training-C9rIBUeV.d.cts +101685 -0
  14. package/dist/training-C9rIBUeV.d.ts +101685 -0
  15. package/dist/types/index.cjs +1 -1
  16. package/dist/types/index.d.cts +278 -6
  17. package/dist/types/index.d.ts +278 -6
  18. package/dist/types/index.js +1 -1
  19. package/package.json +1 -1
  20. package/src/courses/index.ts +2 -2
  21. package/src/index.ts +42 -0
  22. package/src/schemas/common.ts +69 -5
  23. package/src/schemas/course-milestone.ts +78 -0
  24. package/src/schemas/equipment.ts +27 -0
  25. package/src/schemas/form-template.ts +416 -0
  26. package/src/schemas/index.ts +7 -1
  27. package/src/schemas/location-map.ts +175 -0
  28. package/src/schemas/models.ts +201 -100
  29. package/src/schemas/newsletter.ts +362 -0
  30. package/src/schemas/todo.ts +46 -0
  31. package/src/schemas/training.ts +500 -0
  32. package/src/types/ai.ts +85 -0
  33. package/src/types/aircraft-block.ts +23 -0
  34. package/src/types/api.ts +3 -1
  35. package/src/types/background-task.ts +28 -0
  36. package/src/types/compliance.ts +27 -3
  37. package/src/types/index.ts +5 -0
  38. package/src/types/landing-fee.ts +92 -0
  39. package/src/types/models.ts +46 -3
  40. package/src/types/roles.ts +26 -0
  41. package/dist/chunk-RC2BBT6H.cjs +0 -1384
  42. package/dist/chunk-WQLDSZNN.js +0 -1384
  43. package/dist/models-Bc5BKYuI.d.cts +0 -36898
  44. package/dist/models-Bc5BKYuI.d.ts +0 -36898
  45. package/src/schemas/fee.ts +0 -37
  46. /package/dist/{chunk-LXNCAKJZ.js → chunk-2WJHTRIE.js} +0 -0
  47. /package/dist/{chunk-MOOGM3DW.cjs → chunk-DCEOET63.cjs} +0 -0
@@ -0,0 +1,362 @@
1
+ import { z } from "zod";
2
+
3
+ /*
4
+ |------------------------------------------------------------------------
5
+ | Block schemas
6
+ |------------------------------------------------------------------------
7
+ |
8
+ | v1 supports heading / paragraph / button / divider. Paragraph content
9
+ | is stored as TipTap JSON on `doc` so variable tokens survive
10
+ | sanitisation. The server converts `variable` nodes to `{{name}}` at
11
+ | render time.
12
+ */
13
+
14
+ export enum NewsletterBlockType {
15
+ Heading = "heading",
16
+ Paragraph = "paragraph",
17
+ Button = "button",
18
+ Divider = "divider",
19
+ }
20
+
21
+ export const TipTapNodeSchema: z.ZodType<TipTapNode> = z.lazy(() =>
22
+ z.object({
23
+ type: z.string(),
24
+ attrs: z.record(z.any()).optional(),
25
+ content: z.array(TipTapNodeSchema).optional(),
26
+ marks: z.array(z.record(z.any())).optional(),
27
+ text: z.string().optional(),
28
+ }),
29
+ );
30
+
31
+ export interface TipTapNode {
32
+ type: string;
33
+ attrs?: Record<string, unknown>;
34
+ content?: TipTapNode[];
35
+ marks?: Array<Record<string, unknown>>;
36
+ text?: string;
37
+ }
38
+
39
+ const Align = z.enum(["left", "center", "right"]).optional();
40
+
41
+ export const HeadingBlockSchema = z.object({
42
+ key: z.string(),
43
+ type: z.literal(NewsletterBlockType.Heading),
44
+ level: z.number().int().min(1).max(3).default(1),
45
+ text: z.string(),
46
+ align: Align,
47
+ });
48
+
49
+ export const ParagraphBlockSchema = z.object({
50
+ key: z.string(),
51
+ type: z.literal(NewsletterBlockType.Paragraph),
52
+ doc: TipTapNodeSchema,
53
+ align: Align,
54
+ });
55
+
56
+ export const ButtonBlockSchema = z.object({
57
+ key: z.string(),
58
+ type: z.literal(NewsletterBlockType.Button),
59
+ label: z.string(),
60
+ url: z.string(),
61
+ align: Align,
62
+ color: z.string().optional(),
63
+ });
64
+
65
+ export const DividerBlockSchema = z.object({
66
+ key: z.string(),
67
+ type: z.literal(NewsletterBlockType.Divider),
68
+ thickness: z.number().int().min(1).max(10).optional(),
69
+ color: z.string().optional(),
70
+ });
71
+
72
+ export const NewsletterBlockSchema = z.discriminatedUnion("type", [
73
+ HeadingBlockSchema,
74
+ ParagraphBlockSchema,
75
+ ButtonBlockSchema,
76
+ DividerBlockSchema,
77
+ ]);
78
+
79
+ export type HeadingBlock = z.infer<typeof HeadingBlockSchema>;
80
+ export type ParagraphBlock = z.infer<typeof ParagraphBlockSchema>;
81
+ export type ButtonBlock = z.infer<typeof ButtonBlockSchema>;
82
+ export type DividerBlock = z.infer<typeof DividerBlockSchema>;
83
+ export type NewsletterBlock = z.infer<typeof NewsletterBlockSchema>;
84
+
85
+ /*
86
+ |------------------------------------------------------------------------
87
+ | Category
88
+ |------------------------------------------------------------------------
89
+ */
90
+
91
+ export const NewsletterCategorySchema = z.object({
92
+ type: z.literal("newsletter_category").optional(),
93
+ id: z.number(),
94
+ key: z.string(),
95
+ name: z.string(),
96
+ description: z.string().nullable().optional(),
97
+ is_mandatory: z.boolean(),
98
+ is_active: z.boolean(),
99
+ sort_order: z.number().int(),
100
+ created_at: z.string().optional(),
101
+ updated_at: z.string().optional(),
102
+ });
103
+
104
+ export type NewsletterCategory = z.infer<typeof NewsletterCategorySchema>;
105
+
106
+ /*
107
+ |------------------------------------------------------------------------
108
+ | Template
109
+ |------------------------------------------------------------------------
110
+ */
111
+
112
+ const UserBasicSchema = z
113
+ .object({
114
+ id: z.number(),
115
+ name: z.string(),
116
+ email: z.string().optional(),
117
+ })
118
+ .nullable();
119
+
120
+ export const NewsletterTemplateSchemaSchema = z.object({
121
+ blocks: z.array(NewsletterBlockSchema),
122
+ variables_used: z.array(z.string()).optional(),
123
+ });
124
+
125
+ export type NewsletterTemplateDoc = z.infer<typeof NewsletterTemplateSchemaSchema>;
126
+
127
+ export const NewsletterTemplateSchema = z.object({
128
+ type: z.literal("newsletter_template").optional(),
129
+ id: z.number(),
130
+ company_id: z.number().nullable(),
131
+ is_system: z.boolean().optional(),
132
+ newsletter_category_id: z.number(),
133
+ category: NewsletterCategorySchema.nullish(),
134
+ name: z.string(),
135
+ slug: z.string(),
136
+ description: z.string().nullable().optional(),
137
+ subject: z.string(),
138
+ preheader: z.string().nullable().optional(),
139
+ schema: NewsletterTemplateSchemaSchema,
140
+ schema_version: z.number().int(),
141
+ is_active: z.boolean(),
142
+ created_by: z.number().nullable().optional(),
143
+ creator: UserBasicSchema.optional(),
144
+ created_at: z.string().optional(),
145
+ updated_at: z.string().optional(),
146
+ });
147
+
148
+ export type NewsletterTemplate = z.infer<typeof NewsletterTemplateSchema>;
149
+
150
+ export const CreateNewsletterTemplateInputSchema = z.object({
151
+ newsletter_category_id: z.number(),
152
+ name: z.string().min(1),
153
+ slug: z.string().optional(),
154
+ description: z.string().nullable().optional(),
155
+ subject: z.string().min(1),
156
+ preheader: z.string().nullable().optional(),
157
+ schema: NewsletterTemplateSchemaSchema,
158
+ is_active: z.boolean().optional(),
159
+ });
160
+
161
+ export type CreateNewsletterTemplateInput = z.infer<typeof CreateNewsletterTemplateInputSchema>;
162
+ export type UpdateNewsletterTemplateInput = Partial<CreateNewsletterTemplateInput>;
163
+
164
+ /*
165
+ |------------------------------------------------------------------------
166
+ | Audience
167
+ |------------------------------------------------------------------------
168
+ */
169
+
170
+ export enum AudienceBucketType {
171
+ AllUsers = "all_users",
172
+ CompanyUsers = "company_users",
173
+ RoleMembers = "role_members",
174
+ }
175
+
176
+ export const AllUsersBucketSchema = z.object({ type: z.literal(AudienceBucketType.AllUsers) });
177
+ export const CompanyUsersBucketSchema = z.object({
178
+ type: z.literal(AudienceBucketType.CompanyUsers),
179
+ company_ids: z.array(z.number()).min(1),
180
+ });
181
+ export const RoleMembersBucketSchema = z.object({
182
+ type: z.literal(AudienceBucketType.RoleMembers),
183
+ role_ids: z.array(z.number()).min(1),
184
+ });
185
+
186
+ export const AudienceBucketSchema = z.discriminatedUnion("type", [
187
+ AllUsersBucketSchema,
188
+ CompanyUsersBucketSchema,
189
+ RoleMembersBucketSchema,
190
+ ]);
191
+
192
+ export const NewsletterAudienceSchema = z.object({
193
+ version: z.literal(1),
194
+ include: z.array(AudienceBucketSchema).min(1),
195
+ exclude: z
196
+ .object({
197
+ emails: z.array(z.string().email()).optional(),
198
+ user_ids: z.array(z.number()).optional(),
199
+ })
200
+ .optional(),
201
+ });
202
+
203
+ export type AudienceBucket = z.infer<typeof AudienceBucketSchema>;
204
+ export type NewsletterAudience = z.infer<typeof NewsletterAudienceSchema>;
205
+
206
+ /**
207
+ * Company-admin audience rule: the role selection is the sole determinant.
208
+ * No roles selected → the whole company (company_users). One or more roles
209
+ * → only those role-holders (role_members), and the company-wide bucket is
210
+ * dropped so the send-time union (ResolveCampaignAudienceAction) cannot
211
+ * widen the audience back to everyone.
212
+ */
213
+ export function companyAudienceInclude(
214
+ companyId: number,
215
+ roleIds: number[],
216
+ ): AudienceBucket[] {
217
+ return roleIds.length > 0
218
+ ? [{ type: AudienceBucketType.RoleMembers, role_ids: roleIds }]
219
+ : [{ type: AudienceBucketType.CompanyUsers, company_ids: [companyId] }];
220
+ }
221
+
222
+ /*
223
+ |------------------------------------------------------------------------
224
+ | Campaign
225
+ |------------------------------------------------------------------------
226
+ */
227
+
228
+ export enum NewsletterCampaignStatus {
229
+ Draft = "draft",
230
+ Scheduled = "scheduled",
231
+ Sending = "sending",
232
+ Sent = "sent",
233
+ Failed = "failed",
234
+ Cancelled = "cancelled",
235
+ }
236
+
237
+ export const NewsletterCampaignSchema = z.object({
238
+ type: z.literal("newsletter_campaign").optional(),
239
+ id: z.number(),
240
+ company_id: z.number().nullable(),
241
+ is_system: z.boolean().optional(),
242
+ newsletter_template_id: z.number().nullable(),
243
+ template: NewsletterTemplateSchema.partial().nullish(),
244
+ newsletter_category_id: z.number(),
245
+ category: NewsletterCategorySchema.nullish(),
246
+ name: z.string(),
247
+ subject: z.string(),
248
+ preheader: z.string().nullable().optional(),
249
+ schema_snapshot: NewsletterTemplateSchemaSchema,
250
+ variables: z.record(z.string()).nullable().optional(),
251
+ audience_definition: NewsletterAudienceSchema,
252
+ status: z.nativeEnum(NewsletterCampaignStatus),
253
+ scheduled_at: z.string().nullable().optional(),
254
+ started_at: z.string().nullable().optional(),
255
+ finished_at: z.string().nullable().optional(),
256
+ cancelled_at: z.string().nullable().optional(),
257
+ counts: z.object({
258
+ queued: z.number().nullable(),
259
+ sent: z.number(),
260
+ failed: z.number(),
261
+ bounced: z.number(),
262
+ complained: z.number(),
263
+ }),
264
+ sent_by_user_id: z.number().nullable().optional(),
265
+ sent_by: UserBasicSchema.optional(),
266
+ can: z
267
+ .object({
268
+ update: z.boolean(),
269
+ schedule: z.boolean(),
270
+ send: z.boolean(),
271
+ cancel: z.boolean(),
272
+ test_send: z.boolean(),
273
+ delete: z.boolean(),
274
+ })
275
+ .partial()
276
+ .optional(),
277
+ created_at: z.string().optional(),
278
+ updated_at: z.string().optional(),
279
+ });
280
+
281
+ export type NewsletterCampaign = z.infer<typeof NewsletterCampaignSchema>;
282
+
283
+ export const CreateNewsletterCampaignInputSchema = z.object({
284
+ newsletter_template_id: z.number().nullable().optional(),
285
+ newsletter_category_id: z.number().optional(),
286
+ name: z.string().min(1),
287
+ subject: z.string().optional(),
288
+ preheader: z.string().nullable().optional(),
289
+ schema_snapshot: NewsletterTemplateSchemaSchema.optional(),
290
+ variables: z.record(z.string()).optional(),
291
+ audience_definition: NewsletterAudienceSchema,
292
+ });
293
+
294
+ export type CreateNewsletterCampaignInput = z.infer<typeof CreateNewsletterCampaignInputSchema>;
295
+ export type UpdateNewsletterCampaignInput = Partial<CreateNewsletterCampaignInput>;
296
+
297
+ /*
298
+ |------------------------------------------------------------------------
299
+ | Recipient
300
+ |------------------------------------------------------------------------
301
+ */
302
+
303
+ export enum NewsletterRecipientStatus {
304
+ Queued = "queued",
305
+ Sent = "sent",
306
+ Failed = "failed",
307
+ Bounced = "bounced",
308
+ Complained = "complained",
309
+ Suppressed = "suppressed",
310
+ OptedOut = "opted_out",
311
+ }
312
+
313
+ export const NewsletterCampaignRecipientSchema = z.object({
314
+ type: z.literal("newsletter_campaign_recipient").optional(),
315
+ id: z.number(),
316
+ newsletter_campaign_id: z.number(),
317
+ user_id: z.number().nullable(),
318
+ user: UserBasicSchema.optional(),
319
+ email: z.string(),
320
+ status: z.nativeEnum(NewsletterRecipientStatus),
321
+ error: z.string().nullable().optional(),
322
+ message_id: z.string().nullable().optional(),
323
+ queued_at: z.string().nullable().optional(),
324
+ sent_at: z.string().nullable().optional(),
325
+ bounced_at: z.string().nullable().optional(),
326
+ complained_at: z.string().nullable().optional(),
327
+ });
328
+
329
+ export type NewsletterCampaignRecipient = z.infer<typeof NewsletterCampaignRecipientSchema>;
330
+
331
+ /*
332
+ |------------------------------------------------------------------------
333
+ | Preference (per-user per-category)
334
+ |------------------------------------------------------------------------
335
+ */
336
+
337
+ export const NewsletterPreferenceRowSchema = z.object({
338
+ category_id: z.number(),
339
+ category_key: z.string(),
340
+ name: z.string(),
341
+ description: z.string().nullable().optional(),
342
+ is_mandatory: z.boolean(),
343
+ opted_in: z.boolean(),
344
+ });
345
+
346
+ export type NewsletterPreferenceRow = z.infer<typeof NewsletterPreferenceRowSchema>;
347
+
348
+ /*
349
+ |------------------------------------------------------------------------
350
+ | Variable allowlist (must mirror backend NewsletterBlocksValidator)
351
+ |------------------------------------------------------------------------
352
+ */
353
+
354
+ export const ALLOWED_NEWSLETTER_VARIABLES = [
355
+ "user.name",
356
+ "user.first_name",
357
+ "user.email",
358
+ "company.name",
359
+ "unsubscribe_url",
360
+ ] as const;
361
+
362
+ export type AllowedNewsletterVariable = (typeof ALLOWED_NEWSLETTER_VARIABLES)[number];
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+
3
+ export const TodoActionSchema = z.object({
4
+ type: z.enum(["open_dialog", "navigate"]),
5
+ target: z.string(),
6
+ params: z.record(z.any()).optional(),
7
+ });
8
+
9
+ export const TodoKey = z.enum([
10
+ "fill_form",
11
+ "sign_form",
12
+ "review_form",
13
+ "log_booking",
14
+ "add_address",
15
+ "add_required_documents",
16
+ "fill_training_record",
17
+ "sign_training_record",
18
+ ]);
19
+
20
+ export const TodoSchema = z.object({
21
+ key: TodoKey,
22
+ ref_type: z.string(),
23
+ ref_id: z.number(),
24
+ title: z.string(),
25
+ subtitle: z.string().nullable().optional(),
26
+ due_date: z.string().nullable().optional(),
27
+ is_overdue: z.boolean().default(false),
28
+ priority: z.enum(["low", "normal", "high"]).default("normal"),
29
+ company_id: z.number().nullable().optional(),
30
+ action: TodoActionSchema,
31
+ meta: z.record(z.any()).optional(),
32
+ });
33
+
34
+ export type Todo = z.infer<typeof TodoSchema>;
35
+ export type TodoAction = z.infer<typeof TodoActionSchema>;
36
+
37
+ /**
38
+ * Shape of one entry in `meta.accepted_alternatives` on
39
+ * `add_required_documents` todos — the other templates of the requirement's
40
+ * OR bucket that would satisfy it equally (backend:
41
+ * MissingDocumentTodoSource::selectOrAlternative()).
42
+ */
43
+ export interface TodoAcceptedAlternative {
44
+ form_template_id: number;
45
+ form_template_name: string | null;
46
+ }