@automate.ax/integration-contracts 0.89.2 → 0.91.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.
@@ -0,0 +1,351 @@
1
+ import * as z from "zod"
2
+
3
+ import { JOB_NIMBUS_VALUE_SCHEMA } from "./api"
4
+
5
+ export const JOB_NIMBUS_ID_SCHEMA = z.string().trim().min(1)
6
+
7
+ const NULLABLE_STRING_SCHEMA = z.string().nullable().optional()
8
+ const NULLABLE_NUMBER_SCHEMA = z.number().nullable().optional()
9
+ const DATE_SCHEMA = z.date().nullable().optional()
10
+
11
+ export const JOB_NIMBUS_CUSTOM_FIELDS_SCHEMA = z.record(
12
+ z.string().min(1),
13
+ z.union([z.boolean(), z.number(), z.string(), z.null()]),
14
+ )
15
+
16
+ export const JOB_NIMBUS_REFERENCE_SCHEMA = z
17
+ .object({
18
+ id: JOB_NIMBUS_ID_SCHEMA,
19
+ name: NULLABLE_STRING_SCHEMA,
20
+ number: NULLABLE_STRING_SCHEMA,
21
+ type: NULLABLE_STRING_SCHEMA,
22
+ })
23
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
24
+
25
+ export const JOB_NIMBUS_OWNER_SCHEMA = z
26
+ .object({
27
+ id: JOB_NIMBUS_ID_SCHEMA,
28
+ })
29
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
30
+
31
+ export const JOB_NIMBUS_LOCATION_SCHEMA = z
32
+ .object({
33
+ id: z.number(),
34
+ name: NULLABLE_STRING_SCHEMA,
35
+ parentId: z.number().nullable().optional(),
36
+ })
37
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
38
+
39
+ export const JOB_NIMBUS_GEO_SCHEMA = z.object({
40
+ lat: z.number(),
41
+ lon: z.number(),
42
+ })
43
+
44
+ const CRM_BASE_FIELDS = {
45
+ dateCreated: DATE_SCHEMA,
46
+ createdBy: NULLABLE_STRING_SCHEMA,
47
+ createdByName: NULLABLE_STRING_SCHEMA,
48
+ customer: NULLABLE_STRING_SCHEMA,
49
+ customFields: JOB_NIMBUS_CUSTOM_FIELDS_SCHEMA.optional(),
50
+ id: JOB_NIMBUS_ID_SCHEMA,
51
+ isActive: z.boolean().optional(),
52
+ isArchived: z.boolean().optional(),
53
+ location: JOB_NIMBUS_LOCATION_SCHEMA.nullable().optional(),
54
+ owners: JOB_NIMBUS_OWNER_SCHEMA.array().optional(),
55
+ recordId: z.number().optional(),
56
+ recordType: NULLABLE_NUMBER_SCHEMA,
57
+ recordTypeName: NULLABLE_STRING_SCHEMA,
58
+ related: JOB_NIMBUS_REFERENCE_SCHEMA.array().optional(),
59
+ tags: z.string().array().optional(),
60
+ type: NULLABLE_STRING_SCHEMA,
61
+ dateUpdated: DATE_SCHEMA,
62
+ }
63
+
64
+ const ADDRESS_FIELDS = {
65
+ addressLine1: NULLABLE_STRING_SCHEMA,
66
+ addressLine2: NULLABLE_STRING_SCHEMA,
67
+ city: NULLABLE_STRING_SCHEMA,
68
+ countryName: NULLABLE_STRING_SCHEMA,
69
+ stateText: NULLABLE_STRING_SCHEMA,
70
+ zip: NULLABLE_STRING_SCHEMA,
71
+ }
72
+
73
+ const WORKFLOW_FIELDS = {
74
+ isClosed: z.boolean().optional(),
75
+ isLead: z.boolean().optional(),
76
+ salesRep: NULLABLE_STRING_SCHEMA,
77
+ salesRepName: NULLABLE_STRING_SCHEMA,
78
+ source: NULLABLE_NUMBER_SCHEMA,
79
+ sourceName: NULLABLE_STRING_SCHEMA,
80
+ status: NULLABLE_NUMBER_SCHEMA,
81
+ statusName: NULLABLE_STRING_SCHEMA,
82
+ }
83
+
84
+ export const JOB_NIMBUS_CONTACT_SCHEMA = z
85
+ .object({
86
+ ...CRM_BASE_FIELDS,
87
+ ...ADDRESS_FIELDS,
88
+ ...WORKFLOW_FIELDS,
89
+ company: NULLABLE_STRING_SCHEMA,
90
+ description: NULLABLE_STRING_SCHEMA,
91
+ displayName: NULLABLE_STRING_SCHEMA,
92
+ email: NULLABLE_STRING_SCHEMA,
93
+ faxNumber: NULLABLE_STRING_SCHEMA,
94
+ firstName: NULLABLE_STRING_SCHEMA,
95
+ geo: JOB_NIMBUS_GEO_SCHEMA.nullable().optional(),
96
+ homePhone: NULLABLE_STRING_SCHEMA,
97
+ lastName: NULLABLE_STRING_SCHEMA,
98
+ mobilePhone: NULLABLE_STRING_SCHEMA,
99
+ website: NULLABLE_STRING_SCHEMA,
100
+ workPhone: NULLABLE_STRING_SCHEMA,
101
+ })
102
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
103
+
104
+ export const JOB_NIMBUS_JOB_SCHEMA = z
105
+ .object({
106
+ ...CRM_BASE_FIELDS,
107
+ ...ADDRESS_FIELDS,
108
+ ...WORKFLOW_FIELDS,
109
+ description: NULLABLE_STRING_SCHEMA,
110
+ geo: JOB_NIMBUS_GEO_SCHEMA.nullable().optional(),
111
+ name: z.string(),
112
+ number: NULLABLE_STRING_SCHEMA,
113
+ primary: JOB_NIMBUS_REFERENCE_SCHEMA.nullable().optional(),
114
+ })
115
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
116
+
117
+ export const JOB_NIMBUS_TASK_SCHEMA = z
118
+ .object({
119
+ ...CRM_BASE_FIELDS,
120
+ actualTime: NULLABLE_NUMBER_SCHEMA,
121
+ dateEnd: DATE_SCHEMA,
122
+ dateStart: DATE_SCHEMA,
123
+ description: NULLABLE_STRING_SCHEMA,
124
+ estimatedTime: NULLABLE_NUMBER_SCHEMA,
125
+ isCompleted: z.boolean().optional(),
126
+ number: NULLABLE_STRING_SCHEMA,
127
+ priority: NULLABLE_NUMBER_SCHEMA,
128
+ primary: JOB_NIMBUS_REFERENCE_SCHEMA.nullable().optional(),
129
+ title: z.string(),
130
+ })
131
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
132
+
133
+ export const JOB_NIMBUS_PRODUCT_UOM_SCHEMA = z
134
+ .object({
135
+ labor: z
136
+ .object({ cost: z.number().optional(), price: z.number().optional() })
137
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
138
+ .optional(),
139
+ material: z
140
+ .object({ cost: z.number().optional(), price: z.number().optional() })
141
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
142
+ .optional(),
143
+ uom: z.string(),
144
+ })
145
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
146
+
147
+ export const JOB_NIMBUS_PRODUCT_SCHEMA = z
148
+ .object({
149
+ ...CRM_BASE_FIELDS,
150
+ description: NULLABLE_STRING_SCHEMA,
151
+ externalId: NULLABLE_STRING_SCHEMA,
152
+ itemType: z.enum(["labor", "labor+material", "material"]).optional(),
153
+ locationId: z.number().nullable().optional(),
154
+ name: z.string(),
155
+ suppliers: z.array(JOB_NIMBUS_VALUE_SCHEMA).optional(),
156
+ taxExempt: z.boolean().optional(),
157
+ uoms: JOB_NIMBUS_PRODUCT_UOM_SCHEMA.array().optional(),
158
+ })
159
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
160
+
161
+ export const JOB_NIMBUS_FILE_SCHEMA = z
162
+ .object({
163
+ ...CRM_BASE_FIELDS,
164
+ description: NULLABLE_STRING_SCHEMA,
165
+ filename: NULLABLE_STRING_SCHEMA,
166
+ isPrivate: z.boolean().optional(),
167
+ name: NULLABLE_STRING_SCHEMA,
168
+ size: NULLABLE_NUMBER_SCHEMA,
169
+ })
170
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
171
+
172
+ /**
173
+ * Wraps a legacy item schema in JobNimbus's offset-page response.
174
+ *
175
+ * @param itemSchema - Schema for one legacy result.
176
+ */
177
+ export function jobNimbusPageSchema<TSchema extends z.ZodType>(
178
+ itemSchema: TSchema,
179
+ ) {
180
+ return z
181
+ .object({
182
+ count: z.number().int().nonnegative(),
183
+ results: itemSchema.array(),
184
+ })
185
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
186
+ }
187
+
188
+ export const JOB_NIMBUS_ACTIVITY_RECORD_INPUT_SCHEMA = z.object({
189
+ id: JOB_NIMBUS_ID_SCHEMA,
190
+ type: z.string().trim().min(1),
191
+ })
192
+
193
+ export const JOB_NIMBUS_ACTIVITY_RECORD_SCHEMA = z.object({
194
+ ...JOB_NIMBUS_ACTIVITY_RECORD_INPUT_SCHEMA.shape,
195
+ name: z.string().nullable().optional(),
196
+ })
197
+
198
+ export const JOB_NIMBUS_ACTIVITY_ACTOR_SCHEMA = z
199
+ .object({
200
+ id: JOB_NIMBUS_ID_SCHEMA,
201
+ name: z.string(),
202
+ })
203
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
204
+
205
+ export const JOB_NIMBUS_ACTIVITY_SCHEMA = z
206
+ .object({
207
+ activityAction: z.string(),
208
+ activityTypeId: z.number().int(),
209
+ content: z.string(),
210
+ createdAt: z
211
+ .union([z.date(), z.iso.datetime({ offset: true })])
212
+ .transform((value) => (value instanceof Date ? value : new Date(value))),
213
+ createdBy: JOB_NIMBUS_ACTIVITY_ACTOR_SCHEMA,
214
+ hasFiles: z.boolean(),
215
+ id: JOB_NIMBUS_ID_SCHEMA,
216
+ isEditable: z.boolean(),
217
+ isPrivate: z.boolean(),
218
+ primaryRecord: JOB_NIMBUS_ACTIVITY_RECORD_SCHEMA,
219
+ relatedRecords: JOB_NIMBUS_ACTIVITY_RECORD_SCHEMA.array(),
220
+ updatedAt: z
221
+ .union([z.date(), z.iso.datetime({ offset: true })])
222
+ .transform((value) => (value instanceof Date ? value : new Date(value))),
223
+ })
224
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
225
+
226
+ export const JOB_NIMBUS_ACTIVITY_TYPE_SCHEMA = z.object({
227
+ displayName: z.string(),
228
+ id: z.number().int(),
229
+ isArchived: z.boolean(),
230
+ isSystem: z.boolean(),
231
+ })
232
+
233
+ /**
234
+ * Wraps a Platform response schema in JobNimbus's data envelope.
235
+ *
236
+ * @param dataSchema - Schema for the enveloped data value.
237
+ */
238
+ export function jobNimbusDataSchema<TSchema extends z.ZodType>(
239
+ dataSchema: TSchema,
240
+ ) {
241
+ return z.object({ data: dataSchema }).catchall(JOB_NIMBUS_VALUE_SCHEMA)
242
+ }
243
+
244
+ export const JOB_NIMBUS_ACTIVITY_PAGE_SCHEMA = z
245
+ .object({
246
+ data: JOB_NIMBUS_ACTIVITY_SCHEMA.array(),
247
+ pagination: z.object({
248
+ nextCursor: z.string().nullable(),
249
+ pageSize: z.number().int().positive(),
250
+ }),
251
+ })
252
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
253
+
254
+ export const JOB_NIMBUS_WORKFLOW_STATUS_SCHEMA = z
255
+ .object({
256
+ id: z.number().int(),
257
+ isActive: z.boolean(),
258
+ isArchived: z.boolean(),
259
+ isClosed: z.boolean(),
260
+ isLead: z.boolean(),
261
+ name: z.string(),
262
+ order: z.number().int(),
263
+ })
264
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
265
+
266
+ export const JOB_NIMBUS_WORKFLOW_SCHEMA = z
267
+ .object({
268
+ id: z.number().int(),
269
+ isActive: z.boolean(),
270
+ name: z.string(),
271
+ objectType: z.enum(["contact", "job", "workorder"]),
272
+ order: z.number().int(),
273
+ status: JOB_NIMBUS_WORKFLOW_STATUS_SCHEMA.array(),
274
+ })
275
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
276
+
277
+ export const JOB_NIMBUS_FILE_TYPE_SCHEMA = z.object({
278
+ fileTypeId: z.number().int(),
279
+ isActive: z.boolean(),
280
+ typeName: z.string(),
281
+ })
282
+
283
+ export const JOB_NIMBUS_TASK_TYPE_SCHEMA = z.object({
284
+ defaultName: z.string(),
285
+ hideFromCalendarView: z.boolean(),
286
+ hideFromTaskList: z.boolean(),
287
+ icon: z.string(),
288
+ isActive: z.boolean(),
289
+ taskTypeId: z.number().int(),
290
+ typeName: z.string(),
291
+ })
292
+
293
+ export const JOB_NIMBUS_LEGACY_ACTIVITY_TYPE_SCHEMA = z.object({
294
+ activityTypeId: z.number().int(),
295
+ isActive: z.boolean(),
296
+ showInJobShare: z.boolean(),
297
+ typeName: z.string(),
298
+ })
299
+
300
+ export const JOB_NIMBUS_SOURCE_SCHEMA = z.object({
301
+ isActive: z.boolean(),
302
+ jobSourceId: z.number().int(),
303
+ sourceName: z.string(),
304
+ })
305
+
306
+ export const JOB_NIMBUS_ACCOUNT_SETTINGS_SCHEMA = z
307
+ .object({
308
+ activityTypes: JOB_NIMBUS_LEGACY_ACTIVITY_TYPE_SCHEMA.array().optional(),
309
+ fileTypes: JOB_NIMBUS_FILE_TYPE_SCHEMA.array().optional(),
310
+ sources: JOB_NIMBUS_SOURCE_SCHEMA.array().optional(),
311
+ taskTypes: JOB_NIMBUS_TASK_TYPE_SCHEMA.array().optional(),
312
+ workflows: JOB_NIMBUS_WORKFLOW_SCHEMA.array().optional(),
313
+ })
314
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
315
+
316
+ export const JOB_NIMBUS_GROUP_SCHEMA = z
317
+ .object({
318
+ managers: JOB_NIMBUS_ID_SCHEMA.array(),
319
+ members: JOB_NIMBUS_ID_SCHEMA.array(),
320
+ name: z.string(),
321
+ })
322
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
323
+
324
+ export const JOB_NIMBUS_USER_SCHEMA = z
325
+ .object({
326
+ calendarColor: NULLABLE_STRING_SCHEMA,
327
+ email: z.email(),
328
+ firstName: z.string(),
329
+ id: JOB_NIMBUS_ID_SCHEMA,
330
+ imageUrl: NULLABLE_STRING_SCHEMA,
331
+ isActive: z.boolean(),
332
+ lastName: z.string(),
333
+ })
334
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
335
+
336
+ export const JOB_NIMBUS_USERS_RESPONSE_SCHEMA = z
337
+ .object({
338
+ dateUpdated: z.date().optional(),
339
+ users: JOB_NIMBUS_USER_SCHEMA.array(),
340
+ })
341
+ .catchall(JOB_NIMBUS_VALUE_SCHEMA)
342
+
343
+ export const JOB_NIMBUS_COMPANY_SCHEMA = z.object({
344
+ companyId: JOB_NIMBUS_ID_SCHEMA,
345
+ companyLogoUrl: z.string().nullable(),
346
+ companyName: z.string(),
347
+ isCurrent: z.boolean(),
348
+ isPrimary: z.boolean(),
349
+ lastAccessedAt: z.iso.datetime({ offset: true }).nullable(),
350
+ userAvatarUrl: z.string().nullable(),
351
+ })
@@ -21,9 +21,11 @@ export const NOTION_WEBHOOK_EVENT_TYPES = [
21
21
  "data_source.moved",
22
22
  "data_source.schema_updated",
23
23
  "data_source.undeleted",
24
+ "database.content_updated",
24
25
  "database.created",
25
26
  "database.deleted",
26
27
  "database.moved",
28
+ "database.schema_updated",
27
29
  "database.undeleted",
28
30
  "file_upload.completed",
29
31
  "file_upload.created",
@@ -52,9 +54,11 @@ type NotionSemanticTriggerTypes = {
52
54
  readonly "notion.comment.created": "comment.created"
53
55
  readonly "notion.comment.deleted": "comment.deleted"
54
56
  readonly "notion.comment.updated": "comment.updated"
57
+ readonly "notion.database.contentUpdated": "database.content_updated"
55
58
  readonly "notion.database.created": "database.created"
56
59
  readonly "notion.database.deleted": "database.deleted"
57
60
  readonly "notion.database.moved": "database.moved"
61
+ readonly "notion.database.schemaUpdated": "database.schema_updated"
58
62
  readonly "notion.database.undeleted": "database.undeleted"
59
63
  readonly "notion.dataSource.contentUpdated": "data_source.content_updated"
60
64
  readonly "notion.dataSource.created": "data_source.created"
@@ -98,9 +102,11 @@ export const notionEventTypeMap = {
98
102
  "data_source.moved": "notion.dataSource.moved",
99
103
  "data_source.schema_updated": "notion.dataSource.schemaUpdated",
100
104
  "data_source.undeleted": "notion.dataSource.undeleted",
105
+ "database.content_updated": "notion.database.contentUpdated",
101
106
  "database.created": "notion.database.created",
102
107
  "database.deleted": "notion.database.deleted",
103
108
  "database.moved": "notion.database.moved",
109
+ "database.schema_updated": "notion.database.schemaUpdated",
104
110
  "database.undeleted": "notion.database.undeleted",
105
111
  "file_upload.completed": "notion.fileUpload.completed",
106
112
  "file_upload.created": "notion.fileUpload.created",
@@ -128,9 +134,13 @@ export const notionTriggerContracts: NotionTriggerContracts = {
128
134
  "notion.comment.created": semanticContract("comment.created"),
129
135
  "notion.comment.deleted": semanticContract("comment.deleted"),
130
136
  "notion.comment.updated": semanticContract("comment.updated"),
137
+ "notion.database.contentUpdated": semanticContract(
138
+ "database.content_updated",
139
+ ),
131
140
  "notion.database.created": semanticContract("database.created"),
132
141
  "notion.database.deleted": semanticContract("database.deleted"),
133
142
  "notion.database.moved": semanticContract("database.moved"),
143
+ "notion.database.schemaUpdated": semanticContract("database.schema_updated"),
134
144
  "notion.database.undeleted": semanticContract("database.undeleted"),
135
145
  "notion.dataSource.contentUpdated": semanticContract(
136
146
  "data_source.content_updated",
@@ -8,9 +8,11 @@ import type {
8
8
  DataSourceMovedWebhookPayload,
9
9
  DataSourceSchemaUpdatedWebhookPayload,
10
10
  DataSourceUndeletedWebhookPayload,
11
+ DatabaseContentUpdatedWebhookPayload,
11
12
  DatabaseCreatedWebhookPayload,
12
13
  DatabaseDeletedWebhookPayload,
13
14
  DatabaseMovedWebhookPayload,
15
+ DatabaseSchemaUpdatedWebhookPayload,
14
16
  DatabaseUndeletedWebhookPayload,
15
17
  FileUploadCompletedWebhookPayload,
16
18
  FileUploadCreatedWebhookPayload,
@@ -41,9 +43,11 @@ type OfficialNotionWebhookEvent =
41
43
  | DataSourceMovedWebhookPayload
42
44
  | DataSourceSchemaUpdatedWebhookPayload
43
45
  | DataSourceUndeletedWebhookPayload
46
+ | DatabaseContentUpdatedWebhookPayload
44
47
  | DatabaseCreatedWebhookPayload
45
48
  | DatabaseDeletedWebhookPayload
46
49
  | DatabaseMovedWebhookPayload
50
+ | DatabaseSchemaUpdatedWebhookPayload
47
51
  | DatabaseUndeletedWebhookPayload
48
52
  | FileUploadCompletedWebhookPayload
49
53
  | FileUploadCreatedWebhookPayload
@@ -193,6 +197,14 @@ const RAW_NOTION_EVENT_SCHEMA = z.discriminatedUnion("type", [
193
197
  DATABASE_ENTITY_SCHEMA,
194
198
  PARENT_DATA_SCHEMA,
195
199
  ),
200
+ eventWithDataSchema(
201
+ "database.content_updated",
202
+ DATABASE_ENTITY_SCHEMA,
203
+ z.object({
204
+ parent: PARENT_SCHEMA,
205
+ updated_blocks: UPDATED_BLOCK_SCHEMA.array(),
206
+ }),
207
+ ),
196
208
  eventWithDataSchema(
197
209
  "database.created",
198
210
  DATABASE_ENTITY_SCHEMA,
@@ -208,6 +220,21 @@ const RAW_NOTION_EVENT_SCHEMA = z.discriminatedUnion("type", [
208
220
  DATABASE_ENTITY_SCHEMA,
209
221
  PARENT_DATA_SCHEMA,
210
222
  ),
223
+ eventWithDataSchema(
224
+ "database.schema_updated",
225
+ DATABASE_ENTITY_SCHEMA,
226
+ z.object({
227
+ parent: PARENT_SCHEMA,
228
+ updated_properties: z
229
+ .object({
230
+ action: z.enum(["created", "updated", "deleted"]),
231
+ id: z.string(),
232
+ name: z.string().nullable(),
233
+ })
234
+ .array()
235
+ .optional(),
236
+ }),
237
+ ),
211
238
  eventWithDataSchema(
212
239
  "database.undeleted",
213
240
  DATABASE_ENTITY_SCHEMA,