@kelpie/schemas 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/address.d.ts +55 -0
- package/dist/address.d.ts.map +1 -0
- package/dist/address.js +210 -0
- package/dist/address.js.map +1 -0
- package/dist/apiKeyScopes.d.ts +3 -3
- package/dist/apiKeyScopes.d.ts.map +1 -1
- package/dist/apiKeyScopes.js +6 -0
- package/dist/apiKeyScopes.js.map +1 -1
- package/dist/attendance.d.ts +33 -0
- package/dist/attendance.d.ts.map +1 -0
- package/dist/attendance.js +35 -0
- package/dist/attendance.js.map +1 -0
- package/dist/company.d.ts +3 -4
- package/dist/company.d.ts.map +1 -1
- package/dist/company.js +4 -6
- package/dist/company.js.map +1 -1
- package/dist/countries.d.ts +30 -0
- package/dist/countries.d.ts.map +1 -0
- package/dist/countries.js +300 -0
- package/dist/countries.js.map +1 -0
- package/dist/dashboard.d.ts +11 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +23 -0
- package/dist/dashboard.js.map +1 -1
- package/dist/event.d.ts +54 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +85 -0
- package/dist/event.js.map +1 -0
- package/dist/eventAssociation.d.ts +17 -0
- package/dist/eventAssociation.d.ts.map +1 -0
- package/dist/eventAssociation.js +17 -0
- package/dist/eventAssociation.js.map +1 -0
- package/dist/form.d.ts +5 -5
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +2 -2
- package/dist/form.js.map +1 -1
- package/dist/formMapTargets.d.ts +1 -1
- package/dist/formMapTargets.d.ts.map +1 -1
- package/dist/formMapTargets.js +41 -5
- package/dist/formMapTargets.js.map +1 -1
- package/dist/importExport.d.ts.map +1 -1
- package/dist/importExport.js +3 -3
- package/dist/importExport.js.map +1 -1
- package/dist/index.d.ts +17 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/person.d.ts +3 -2
- package/dist/person.d.ts.map +1 -1
- package/dist/person.js +4 -3
- package/dist/person.js.map +1 -1
- package/dist/planItem.d.ts +4 -4
- package/dist/planItem.d.ts.map +1 -1
- package/dist/planItem.js +2 -2
- package/dist/planItem.js.map +1 -1
- package/dist/publicConfig.d.ts +42 -3
- package/dist/publicConfig.d.ts.map +1 -1
- package/dist/publicConfig.js +20 -0
- package/dist/publicConfig.js.map +1 -1
- package/dist/sampleData.d.ts +7 -2
- package/dist/sampleData.d.ts.map +1 -1
- package/dist/sampleData.js +4 -0
- package/dist/sampleData.js.map +1 -1
- package/dist/session.d.ts +28 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +39 -0
- package/dist/session.js.map +1 -1
- package/dist/values.d.ts +35 -5
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +90 -0
- package/dist/values.js.map +1 -1
- package/package.json +1 -1
- package/src/address.ts +287 -0
- package/src/apiKeyScopes.ts +6 -0
- package/src/attendance.ts +72 -0
- package/src/company.ts +7 -10
- package/src/countries.ts +320 -0
- package/src/dashboard.ts +36 -0
- package/src/event.ts +159 -0
- package/src/eventAssociation.ts +36 -0
- package/src/form.ts +7 -7
- package/src/formMapTargets.ts +43 -4
- package/src/importExport.ts +3 -3
- package/src/index.ts +80 -2
- package/src/person.ts +7 -5
- package/src/planItem.ts +6 -6
- package/src/publicConfig.ts +44 -3
- package/src/sampleData.ts +11 -2
- package/src/session.ts +76 -0
- package/src/values.ts +119 -0
package/dist/values.js
CHANGED
|
@@ -75,8 +75,10 @@ export const EXTENSIBLE_RECORD_TYPES = [
|
|
|
75
75
|
'partnership',
|
|
76
76
|
'raise',
|
|
77
77
|
'enquiry',
|
|
78
|
+
'event',
|
|
78
79
|
'role',
|
|
79
80
|
'candidate',
|
|
81
|
+
'attendance',
|
|
80
82
|
];
|
|
81
83
|
/**
|
|
82
84
|
* The record types a note, activity, decision, or plan item attaches to.
|
|
@@ -94,6 +96,8 @@ export const RECORD_TARGET_TYPES = [
|
|
|
94
96
|
'raise',
|
|
95
97
|
'enquiry',
|
|
96
98
|
'candidate',
|
|
99
|
+
'event',
|
|
100
|
+
'attendance',
|
|
97
101
|
];
|
|
98
102
|
/** Human labels for `RECORD_TARGET_TYPES`. Used by any picker that names a type. */
|
|
99
103
|
export const RECORD_TARGET_TYPE_LABELS = {
|
|
@@ -105,6 +109,8 @@ export const RECORD_TARGET_TYPE_LABELS = {
|
|
|
105
109
|
raise: 'Raise',
|
|
106
110
|
enquiry: 'Enquiry',
|
|
107
111
|
candidate: 'Candidate',
|
|
112
|
+
event: 'Event',
|
|
113
|
+
attendance: 'Attendance',
|
|
108
114
|
};
|
|
109
115
|
/**
|
|
110
116
|
* What `GET /v1/search` looks through, and the order its groups come back in.
|
|
@@ -127,6 +133,7 @@ export const SEARCH_COLLECTIONS = [
|
|
|
127
133
|
'opportunity',
|
|
128
134
|
'raise',
|
|
129
135
|
'partnership',
|
|
136
|
+
'event',
|
|
130
137
|
'decision',
|
|
131
138
|
];
|
|
132
139
|
/** Whether a Role is still being hired for. */
|
|
@@ -190,6 +197,86 @@ export const PIPELINE_KIND_LABELS = {
|
|
|
190
197
|
raise: 'Fundraising',
|
|
191
198
|
partnership: 'Partnership',
|
|
192
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* What a Plan item may attach to: the five pipelines plus Event.
|
|
202
|
+
*
|
|
203
|
+
* Event is a calendar object, not a pipeline, but prep work ("send reminder",
|
|
204
|
+
* "record the session") still needs a dated action on the Event itself.
|
|
205
|
+
*/
|
|
206
|
+
export const PLAN_ITEM_TARGET_TYPES = [
|
|
207
|
+
'enquiry',
|
|
208
|
+
'deal',
|
|
209
|
+
'opportunity',
|
|
210
|
+
'raise',
|
|
211
|
+
'partnership',
|
|
212
|
+
'event',
|
|
213
|
+
];
|
|
214
|
+
export const PLAN_ITEM_TARGET_TYPE_LABELS = {
|
|
215
|
+
enquiry: 'Enquiry',
|
|
216
|
+
deal: 'Deal',
|
|
217
|
+
opportunity: 'Opportunity',
|
|
218
|
+
raise: 'Fundraising',
|
|
219
|
+
partnership: 'Partnership',
|
|
220
|
+
event: 'Event',
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Form attach targets: pipeline records (person_links) plus Event (Attendance).
|
|
224
|
+
*/
|
|
225
|
+
export const FORM_ATTACH_TARGET_TYPES = [
|
|
226
|
+
'enquiry',
|
|
227
|
+
'deal',
|
|
228
|
+
'opportunity',
|
|
229
|
+
'raise',
|
|
230
|
+
'partnership',
|
|
231
|
+
'event',
|
|
232
|
+
];
|
|
233
|
+
/** Where an Event may point besides its own Attendances. */
|
|
234
|
+
export const EVENT_ASSOCIATION_TARGET_TYPES = [
|
|
235
|
+
'person',
|
|
236
|
+
'company',
|
|
237
|
+
'deal',
|
|
238
|
+
'opportunity',
|
|
239
|
+
'partnership',
|
|
240
|
+
'raise',
|
|
241
|
+
'enquiry',
|
|
242
|
+
'role',
|
|
243
|
+
'candidate',
|
|
244
|
+
];
|
|
245
|
+
export const EVENT_ASSOCIATION_TARGET_TYPE_LABELS = {
|
|
246
|
+
person: 'Person',
|
|
247
|
+
company: 'Company',
|
|
248
|
+
deal: 'Deal',
|
|
249
|
+
opportunity: 'Opportunity',
|
|
250
|
+
partnership: 'Partnership',
|
|
251
|
+
raise: 'Raise',
|
|
252
|
+
enquiry: 'Enquiry',
|
|
253
|
+
role: 'Role',
|
|
254
|
+
candidate: 'Candidate',
|
|
255
|
+
};
|
|
256
|
+
export const EVENT_FORMATS = ['in_person', 'virtual', 'hybrid'];
|
|
257
|
+
export const EVENT_FORMAT_LABELS = {
|
|
258
|
+
in_person: 'In person',
|
|
259
|
+
virtual: 'Virtual',
|
|
260
|
+
hybrid: 'Hybrid',
|
|
261
|
+
};
|
|
262
|
+
export const EVENT_STATUSES = ['draft', 'scheduled', 'cancelled'];
|
|
263
|
+
export const EVENT_STATUS_LABELS = {
|
|
264
|
+
draft: 'Draft',
|
|
265
|
+
scheduled: 'Scheduled',
|
|
266
|
+
cancelled: 'Cancelled',
|
|
267
|
+
};
|
|
268
|
+
export const ATTENDANCE_STATUSES = ['registered', 'attended', 'no_show', 'cancelled'];
|
|
269
|
+
export const ATTENDANCE_STATUS_LABELS = {
|
|
270
|
+
registered: 'Registered',
|
|
271
|
+
attended: 'Attended',
|
|
272
|
+
no_show: 'No-show',
|
|
273
|
+
cancelled: 'Cancelled',
|
|
274
|
+
};
|
|
275
|
+
export const ATTENDANCE_SOURCES = ['manual', 'form'];
|
|
276
|
+
export const ATTENDANCE_SOURCE_LABELS = {
|
|
277
|
+
manual: 'Manual',
|
|
278
|
+
form: 'Form',
|
|
279
|
+
};
|
|
193
280
|
/**
|
|
194
281
|
* How far along a plan item is. Stored, never derived: whether something is
|
|
195
282
|
* overdue is a question about its date, and whether it is finished is a question
|
|
@@ -369,6 +456,7 @@ export const AGENT_TASK_TARGET_TYPES = [
|
|
|
369
456
|
'partnership',
|
|
370
457
|
'raise',
|
|
371
458
|
'enquiry',
|
|
459
|
+
'event',
|
|
372
460
|
'candidate',
|
|
373
461
|
'role',
|
|
374
462
|
'handbook',
|
|
@@ -407,6 +495,7 @@ export const CUSTOM_FIELD_OBJECT_TYPES = [
|
|
|
407
495
|
'partnership',
|
|
408
496
|
'raise',
|
|
409
497
|
'enquiry',
|
|
498
|
+
'event',
|
|
410
499
|
];
|
|
411
500
|
export const CUSTOM_FIELD_OBJECT_TYPE_LABELS = {
|
|
412
501
|
person: 'Person',
|
|
@@ -416,6 +505,7 @@ export const CUSTOM_FIELD_OBJECT_TYPE_LABELS = {
|
|
|
416
505
|
partnership: 'Partnership',
|
|
417
506
|
raise: 'Raise',
|
|
418
507
|
enquiry: 'Enquiry',
|
|
508
|
+
event: 'Event',
|
|
419
509
|
};
|
|
420
510
|
/**
|
|
421
511
|
* The nine editor types a custom field can carry.
|
package/dist/values.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAU,CAAA;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,UAAU;CACF,CAAA;AACV,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAA;AAMtE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAU,CAAA;AACnF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAA;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAU,CAAA;AAC9F,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAU,CAAA;AAOrE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,WAAW;IACX,SAAS;IACT,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,WAAW;IACX,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,SAAS;IACT,QAAQ;IACR,SAAS;IACT,SAAS;IACT,OAAO;CACC,CAAA;AAIV,iEAAiE;AACjE,MAAM,CAAC,MAAM,qBAAqB,GAA8C;IAC9E,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACf,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ;IACR,SAAS;IACT,MAAM;IACN,aAAa;IACb,aAAa;IACb,OAAO;IACP,SAAS;IACT,MAAM;IACN,WAAW;
|
|
1
|
+
{"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/address.ts
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import { countryName, isCountryCode, normaliseCountry } from './countries.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Labelled postal addresses on Person and Company.
|
|
7
|
+
*
|
|
8
|
+
* Stored as jsonb arrays, like `phones` and `social_profiles`. They are not a
|
|
9
|
+
* CRM object and have no id. One entry per kind on a record. Wire keys are
|
|
10
|
+
* snake_case; TypeScript is camelCase, mapped at this boundary.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const PERSON_ADDRESS_KINDS = ['mailing', 'home', 'work', 'other'] as const
|
|
14
|
+
export const COMPANY_ADDRESS_KINDS = ['hq', 'billing', 'shipping', 'other'] as const
|
|
15
|
+
export const ADDRESS_PARTS = [
|
|
16
|
+
'line1',
|
|
17
|
+
'line2',
|
|
18
|
+
'city',
|
|
19
|
+
'region',
|
|
20
|
+
'postal_code',
|
|
21
|
+
'country',
|
|
22
|
+
] as const
|
|
23
|
+
|
|
24
|
+
export type PersonAddressKind = (typeof PERSON_ADDRESS_KINDS)[number]
|
|
25
|
+
export type CompanyAddressKind = (typeof COMPANY_ADDRESS_KINDS)[number]
|
|
26
|
+
export type AddressPart = (typeof ADDRESS_PARTS)[number]
|
|
27
|
+
|
|
28
|
+
export const PERSON_ADDRESS_KIND_LABELS: Readonly<Record<PersonAddressKind, string>> = {
|
|
29
|
+
mailing: 'Mailing',
|
|
30
|
+
home: 'Home',
|
|
31
|
+
work: 'Work',
|
|
32
|
+
other: 'Other',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const COMPANY_ADDRESS_KIND_LABELS: Readonly<Record<CompanyAddressKind, string>> = {
|
|
36
|
+
hq: 'Headquarters',
|
|
37
|
+
billing: 'Billing',
|
|
38
|
+
shipping: 'Shipping',
|
|
39
|
+
other: 'Other',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PostalAddress<Kind extends string = string> {
|
|
43
|
+
readonly kind: Kind
|
|
44
|
+
readonly line1: string | null
|
|
45
|
+
readonly line2: string | null
|
|
46
|
+
readonly city: string | null
|
|
47
|
+
readonly region: string | null
|
|
48
|
+
readonly postalCode: string | null
|
|
49
|
+
readonly country: string | null
|
|
50
|
+
readonly primary: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type PersonAddress = PostalAddress<PersonAddressKind>
|
|
54
|
+
export type CompanyAddress = PostalAddress<CompanyAddressKind>
|
|
55
|
+
|
|
56
|
+
/** The parts that hold postal text. `kind` and `primary` are labels, not location. */
|
|
57
|
+
const LOCATION_KEYS = ['line1', 'line2', 'city', 'region', 'postalCode', 'country'] as const
|
|
58
|
+
|
|
59
|
+
function blankToNull(value: string | null): string | null {
|
|
60
|
+
if (value === null) {
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const trimmed = value.trim()
|
|
65
|
+
|
|
66
|
+
return trimmed.length === 0 ? null : trimmed
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function hasLocation(address: {
|
|
70
|
+
readonly line1: string | null
|
|
71
|
+
readonly line2: string | null
|
|
72
|
+
readonly city: string | null
|
|
73
|
+
readonly region: string | null
|
|
74
|
+
readonly postalCode: string | null
|
|
75
|
+
readonly country: string | null
|
|
76
|
+
}): boolean {
|
|
77
|
+
return LOCATION_KEYS.some((key) => address[key] !== null)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const nullablePart = z
|
|
81
|
+
.string()
|
|
82
|
+
.nullable()
|
|
83
|
+
.transform((value): string | null => blankToNull(value))
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A country on the wire: ISO 3166-1 alpha-2, or an English name / alias that
|
|
87
|
+
* resolves to one. Empty becomes null. An unknown string is refused in the
|
|
88
|
+
* address superRefine, after this maps a known name onto its code.
|
|
89
|
+
*/
|
|
90
|
+
const countryPart = z
|
|
91
|
+
.string()
|
|
92
|
+
.nullable()
|
|
93
|
+
.transform((value): string | null => {
|
|
94
|
+
const trimmed = blankToNull(value)
|
|
95
|
+
|
|
96
|
+
if (trimmed === null) {
|
|
97
|
+
return null
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return normaliseCountry(trimmed) ?? trimmed
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
function postalAddressObjectSchema<const K extends readonly [string, ...string[]]>(kinds: K) {
|
|
104
|
+
return z
|
|
105
|
+
.object({
|
|
106
|
+
kind: z.enum(kinds),
|
|
107
|
+
line1: nullablePart,
|
|
108
|
+
line2: nullablePart,
|
|
109
|
+
city: nullablePart,
|
|
110
|
+
region: nullablePart,
|
|
111
|
+
postal_code: nullablePart,
|
|
112
|
+
country: countryPart,
|
|
113
|
+
primary: z.boolean(),
|
|
114
|
+
})
|
|
115
|
+
.transform(
|
|
116
|
+
(wire): PostalAddress<K[number]> => ({
|
|
117
|
+
kind: wire.kind,
|
|
118
|
+
line1: wire.line1,
|
|
119
|
+
line2: wire.line2,
|
|
120
|
+
city: wire.city,
|
|
121
|
+
region: wire.region,
|
|
122
|
+
postalCode: wire.postal_code,
|
|
123
|
+
country: wire.country,
|
|
124
|
+
primary: wire.primary,
|
|
125
|
+
}),
|
|
126
|
+
)
|
|
127
|
+
.superRefine((address, context) => {
|
|
128
|
+
if (address.country !== null && !isCountryCode(address.country)) {
|
|
129
|
+
context.addIssue({
|
|
130
|
+
code: 'custom',
|
|
131
|
+
message: 'Must be an ISO 3166-1 alpha-2 country code',
|
|
132
|
+
path: ['country'],
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!hasLocation(address)) {
|
|
137
|
+
context.addIssue({
|
|
138
|
+
code: 'custom',
|
|
139
|
+
message: 'An address needs at least one of line1, line2, city, region, postal_code, or country',
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function uniqueKindsAndOnePrimary<Kind extends string>(
|
|
146
|
+
addresses: readonly PostalAddress<Kind>[],
|
|
147
|
+
context: z.RefinementCtx,
|
|
148
|
+
): void {
|
|
149
|
+
const seen = new Set<string>()
|
|
150
|
+
let primaries = 0
|
|
151
|
+
|
|
152
|
+
for (const [index, address] of addresses.entries()) {
|
|
153
|
+
if (seen.has(address.kind)) {
|
|
154
|
+
context.addIssue({
|
|
155
|
+
code: 'custom',
|
|
156
|
+
message: 'Each kind may appear only once',
|
|
157
|
+
path: [index, 'kind'],
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
seen.add(address.kind)
|
|
162
|
+
|
|
163
|
+
if (address.primary) {
|
|
164
|
+
primaries += 1
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (addresses.length > 0 && primaries !== 1) {
|
|
169
|
+
context.addIssue({
|
|
170
|
+
code: 'custom',
|
|
171
|
+
message: 'A non-empty address list must mark exactly one entry primary',
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export const personAddressSchema: z.ZodType<PersonAddress, unknown> =
|
|
177
|
+
postalAddressObjectSchema(PERSON_ADDRESS_KINDS)
|
|
178
|
+
|
|
179
|
+
export const companyAddressSchema: z.ZodType<CompanyAddress, unknown> =
|
|
180
|
+
postalAddressObjectSchema(COMPANY_ADDRESS_KINDS)
|
|
181
|
+
|
|
182
|
+
export const personAddressesSchema: z.ZodType<readonly PersonAddress[], unknown> = z
|
|
183
|
+
.array(personAddressSchema)
|
|
184
|
+
.superRefine((addresses, context) => {
|
|
185
|
+
uniqueKindsAndOnePrimary(addresses, context)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
export const companyAddressesSchema: z.ZodType<readonly CompanyAddress[], unknown> = z
|
|
189
|
+
.array(companyAddressSchema)
|
|
190
|
+
.superRefine((addresses, context) => {
|
|
191
|
+
uniqueKindsAndOnePrimary(addresses, context)
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
/** The write body for one address. Same keys the response uses. */
|
|
195
|
+
export function addressBody(address: PostalAddress): Record<string, unknown> {
|
|
196
|
+
return {
|
|
197
|
+
kind: address.kind,
|
|
198
|
+
line1: address.line1,
|
|
199
|
+
line2: address.line2,
|
|
200
|
+
city: address.city,
|
|
201
|
+
region: address.region,
|
|
202
|
+
postal_code: address.postalCode,
|
|
203
|
+
country: address.country,
|
|
204
|
+
primary: address.primary,
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function primaryAddress<Kind extends string>(
|
|
209
|
+
addresses: readonly PostalAddress<Kind>[],
|
|
210
|
+
): PostalAddress<Kind> | undefined {
|
|
211
|
+
return addresses.find((address) => address.primary) ?? addresses[0]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* One-line display for lists, export, and agents. Country is shown as its
|
|
216
|
+
* English name when we know it, otherwise the stored code. Empty parts are
|
|
217
|
+
* skipped. An empty address (should not reach here) returns an empty string.
|
|
218
|
+
*/
|
|
219
|
+
export function formatAddress(address: PostalAddress): string {
|
|
220
|
+
const country =
|
|
221
|
+
address.country === null ? null : (countryName(address.country) ?? address.country)
|
|
222
|
+
const parts = [
|
|
223
|
+
address.line1,
|
|
224
|
+
address.line2,
|
|
225
|
+
address.city,
|
|
226
|
+
address.region,
|
|
227
|
+
address.postalCode,
|
|
228
|
+
country,
|
|
229
|
+
].filter((part): part is string => part !== null && part.length > 0)
|
|
230
|
+
|
|
231
|
+
return parts.join(', ')
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function addressColumnKey(kind: string, part: AddressPart): string {
|
|
235
|
+
return `${kind}_${part}`
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function personAddressColumnKeys(): readonly string[] {
|
|
239
|
+
return PERSON_ADDRESS_KINDS.flatMap((kind) => ADDRESS_PARTS.map((part) => addressColumnKey(kind, part)))
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function companyAddressColumnKeys(): readonly string[] {
|
|
243
|
+
return COMPANY_ADDRESS_KINDS.flatMap((kind) => ADDRESS_PARTS.map((part) => addressColumnKey(kind, part)))
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function titleCaseKind(kind: string): string {
|
|
247
|
+
if (kind === 'hq') {
|
|
248
|
+
return 'HQ'
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return kind.charAt(0).toUpperCase() + kind.slice(1)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function partLabel(part: AddressPart): string {
|
|
255
|
+
switch (part) {
|
|
256
|
+
case 'line1':
|
|
257
|
+
return 'line 1'
|
|
258
|
+
case 'line2':
|
|
259
|
+
return 'line 2'
|
|
260
|
+
case 'postal_code':
|
|
261
|
+
return 'postal code'
|
|
262
|
+
default:
|
|
263
|
+
return part
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function addressColumnLabel(kind: string, part: AddressPart): string {
|
|
268
|
+
return `${titleCaseKind(kind)} ${partLabel(part)}`
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Build address-part CSV columns for one object's kinds, in kind then part
|
|
273
|
+
* order. Used by `OBJECT_COLUMNS` so import and export share one header list.
|
|
274
|
+
*/
|
|
275
|
+
export function addressCsvColumns(kinds: readonly string[]): readonly {
|
|
276
|
+
readonly key: string
|
|
277
|
+
readonly label: string
|
|
278
|
+
readonly required: false
|
|
279
|
+
}[] {
|
|
280
|
+
return kinds.flatMap((kind) =>
|
|
281
|
+
ADDRESS_PARTS.map((part) => ({
|
|
282
|
+
key: addressColumnKey(kind, part),
|
|
283
|
+
label: addressColumnLabel(kind, part),
|
|
284
|
+
required: false as const,
|
|
285
|
+
})),
|
|
286
|
+
)
|
|
287
|
+
}
|
package/src/apiKeyScopes.ts
CHANGED
|
@@ -31,6 +31,8 @@ export const API_KEY_OBJECT_DATA_RESOURCES = [
|
|
|
31
31
|
'raises',
|
|
32
32
|
'roles',
|
|
33
33
|
'candidates',
|
|
34
|
+
'events',
|
|
35
|
+
'attendances',
|
|
34
36
|
'decisions',
|
|
35
37
|
'plan_items',
|
|
36
38
|
'notes',
|
|
@@ -137,6 +139,10 @@ export const API_KEY_SCOPE_LABELS: Readonly<Record<ApiKeyScope, string>> = {
|
|
|
137
139
|
'roles:write': 'Roles (write)',
|
|
138
140
|
'candidates:read': 'Candidates (read)',
|
|
139
141
|
'candidates:write': 'Candidates (write)',
|
|
142
|
+
'events:read': 'Events (read)',
|
|
143
|
+
'events:write': 'Events (write)',
|
|
144
|
+
'attendances:read': 'Attendances (read)',
|
|
145
|
+
'attendances:write': 'Attendances (write)',
|
|
140
146
|
'decisions:read': 'Decisions (read)',
|
|
141
147
|
'decisions:write': 'Decisions (write)',
|
|
142
148
|
'plan_items:read': 'Plan items (read)',
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import { ATTENDANCE_SOURCES, ATTENDANCE_STATUSES } from './values.ts'
|
|
4
|
+
import type { AttendanceSource, AttendanceStatus } from './values.ts'
|
|
5
|
+
import { definedFields, idSchema, recordTimestamps } from './wire.ts'
|
|
6
|
+
import type { RecordTimestamps } from './wire.ts'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Wire and write shapes for `/v1/attendances`, the Person↔Event link.
|
|
10
|
+
*
|
|
11
|
+
* RSVP state sits here rather than on Person, so the same person can attend one
|
|
12
|
+
* webinar and cancel another. Notes attach to the attendance, not to the person
|
|
13
|
+
* or the event in general.
|
|
14
|
+
*
|
|
15
|
+
* Neither end is updatable: moving an attendance to a different event or person
|
|
16
|
+
* is a delete and a create, the rule Candidate already follows.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export interface Attendance extends RecordTimestamps {
|
|
20
|
+
readonly id: string
|
|
21
|
+
readonly eventId: string
|
|
22
|
+
readonly personId: string
|
|
23
|
+
readonly status: AttendanceStatus
|
|
24
|
+
readonly source: AttendanceSource
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const attendanceSchema: z.ZodType<Attendance, unknown> = z
|
|
28
|
+
.object({
|
|
29
|
+
id: idSchema,
|
|
30
|
+
event_id: idSchema,
|
|
31
|
+
person_id: idSchema,
|
|
32
|
+
status: z.enum(ATTENDANCE_STATUSES),
|
|
33
|
+
source: z.enum(ATTENDANCE_SOURCES),
|
|
34
|
+
...recordTimestamps,
|
|
35
|
+
})
|
|
36
|
+
.transform(
|
|
37
|
+
(wire): Attendance => ({
|
|
38
|
+
id: wire.id,
|
|
39
|
+
eventId: wire.event_id,
|
|
40
|
+
personId: wire.person_id,
|
|
41
|
+
status: wire.status,
|
|
42
|
+
source: wire.source,
|
|
43
|
+
createdAt: wire.created_at,
|
|
44
|
+
updatedAt: wire.updated_at,
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
export interface CreateAttendanceInput {
|
|
49
|
+
readonly eventId: string
|
|
50
|
+
readonly personId: string
|
|
51
|
+
readonly status?: AttendanceStatus
|
|
52
|
+
readonly source?: AttendanceSource
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function createAttendanceBody(input: CreateAttendanceInput): Record<string, unknown> {
|
|
56
|
+
return definedFields({
|
|
57
|
+
event_id: input.eventId,
|
|
58
|
+
person_id: input.personId,
|
|
59
|
+
status: input.status,
|
|
60
|
+
source: input.source,
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface AttendanceInput {
|
|
65
|
+
readonly status?: AttendanceStatus
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function attendanceBody(input: AttendanceInput): Record<string, unknown> {
|
|
69
|
+
return definedFields({
|
|
70
|
+
status: input.status,
|
|
71
|
+
})
|
|
72
|
+
}
|
package/src/company.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
|
|
3
|
+
import { addressBody, companyAddressesSchema } from './address.ts'
|
|
4
|
+
import type { CompanyAddress } from './address.ts'
|
|
3
5
|
import { customFieldValuesBody, customFieldValuesSchema } from './customField.ts'
|
|
4
6
|
import type { CustomFieldValue, CustomFieldValues } from './customField.ts'
|
|
5
7
|
import { ACCOUNT_TYPES, COMPANY_STAGES, ICP_FITS, SIZE_BANDS } from './values.ts'
|
|
@@ -17,8 +19,7 @@ export interface Company extends RecordTimestamps {
|
|
|
17
19
|
readonly description: string
|
|
18
20
|
readonly stage: CompanyStage
|
|
19
21
|
readonly sizeBand: SizeBand
|
|
20
|
-
readonly
|
|
21
|
-
readonly website: string | null
|
|
22
|
+
readonly addresses: readonly CompanyAddress[]
|
|
22
23
|
readonly accountType: AccountType
|
|
23
24
|
readonly icpFit: IcpFit
|
|
24
25
|
readonly techStack: readonly string[]
|
|
@@ -39,8 +40,7 @@ export const companySchema: z.ZodType<Company, unknown> = z
|
|
|
39
40
|
description: z.string(),
|
|
40
41
|
stage: z.enum(COMPANY_STAGES),
|
|
41
42
|
size_band: z.enum(SIZE_BANDS),
|
|
42
|
-
|
|
43
|
-
website: z.string().nullable(),
|
|
43
|
+
addresses: companyAddressesSchema,
|
|
44
44
|
account_type: z.enum(ACCOUNT_TYPES),
|
|
45
45
|
icp_fit: z.enum(ICP_FITS),
|
|
46
46
|
tech_stack: z.array(z.string()),
|
|
@@ -59,8 +59,7 @@ export const companySchema: z.ZodType<Company, unknown> = z
|
|
|
59
59
|
description: wire.description,
|
|
60
60
|
stage: wire.stage,
|
|
61
61
|
sizeBand: wire.size_band,
|
|
62
|
-
|
|
63
|
-
website: wire.website,
|
|
62
|
+
addresses: wire.addresses,
|
|
64
63
|
accountType: wire.account_type,
|
|
65
64
|
icpFit: wire.icp_fit,
|
|
66
65
|
techStack: wire.tech_stack,
|
|
@@ -80,8 +79,7 @@ export interface CompanyInput {
|
|
|
80
79
|
readonly description?: string
|
|
81
80
|
readonly stage?: CompanyStage
|
|
82
81
|
readonly sizeBand?: SizeBand
|
|
83
|
-
readonly
|
|
84
|
-
readonly website?: string | null
|
|
82
|
+
readonly addresses?: readonly CompanyAddress[]
|
|
85
83
|
readonly accountType?: AccountType
|
|
86
84
|
readonly icpFit?: IcpFit
|
|
87
85
|
readonly techStack?: readonly string[]
|
|
@@ -103,8 +101,7 @@ export function companyBody(input: CompanyInput): Record<string, unknown> {
|
|
|
103
101
|
description: input.description,
|
|
104
102
|
stage: input.stage,
|
|
105
103
|
size_band: input.sizeBand,
|
|
106
|
-
|
|
107
|
-
website: input.website,
|
|
104
|
+
addresses: input.addresses?.map(addressBody),
|
|
108
105
|
account_type: input.accountType,
|
|
109
106
|
icp_fit: input.icpFit,
|
|
110
107
|
tech_stack: input.techStack,
|