@kelpie/schemas 0.11.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.
Files changed (95) hide show
  1. package/dist/account.d.ts +5 -0
  2. package/dist/account.d.ts.map +1 -1
  3. package/dist/account.js +2 -0
  4. package/dist/account.js.map +1 -1
  5. package/dist/address.d.ts +55 -0
  6. package/dist/address.d.ts.map +1 -0
  7. package/dist/address.js +210 -0
  8. package/dist/address.js.map +1 -0
  9. package/dist/apiKeyScopes.d.ts +3 -3
  10. package/dist/apiKeyScopes.d.ts.map +1 -1
  11. package/dist/apiKeyScopes.js +6 -0
  12. package/dist/apiKeyScopes.js.map +1 -1
  13. package/dist/attendance.d.ts +33 -0
  14. package/dist/attendance.d.ts.map +1 -0
  15. package/dist/attendance.js +35 -0
  16. package/dist/attendance.js.map +1 -0
  17. package/dist/company.d.ts +3 -4
  18. package/dist/company.d.ts.map +1 -1
  19. package/dist/company.js +4 -6
  20. package/dist/company.js.map +1 -1
  21. package/dist/countries.d.ts +30 -0
  22. package/dist/countries.d.ts.map +1 -0
  23. package/dist/countries.js +300 -0
  24. package/dist/countries.js.map +1 -0
  25. package/dist/dashboard.d.ts +11 -0
  26. package/dist/dashboard.d.ts.map +1 -1
  27. package/dist/dashboard.js +23 -0
  28. package/dist/dashboard.js.map +1 -1
  29. package/dist/event.d.ts +54 -0
  30. package/dist/event.d.ts.map +1 -0
  31. package/dist/event.js +85 -0
  32. package/dist/event.js.map +1 -0
  33. package/dist/eventAssociation.d.ts +17 -0
  34. package/dist/eventAssociation.d.ts.map +1 -0
  35. package/dist/eventAssociation.js +17 -0
  36. package/dist/eventAssociation.js.map +1 -0
  37. package/dist/form.d.ts +5 -5
  38. package/dist/form.d.ts.map +1 -1
  39. package/dist/form.js +2 -2
  40. package/dist/form.js.map +1 -1
  41. package/dist/formMapTargets.d.ts +1 -1
  42. package/dist/formMapTargets.d.ts.map +1 -1
  43. package/dist/formMapTargets.js +41 -5
  44. package/dist/formMapTargets.js.map +1 -1
  45. package/dist/importExport.d.ts.map +1 -1
  46. package/dist/importExport.js +3 -3
  47. package/dist/importExport.js.map +1 -1
  48. package/dist/index.d.ts +17 -7
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +8 -3
  51. package/dist/index.js.map +1 -1
  52. package/dist/person.d.ts +3 -2
  53. package/dist/person.d.ts.map +1 -1
  54. package/dist/person.js +4 -3
  55. package/dist/person.js.map +1 -1
  56. package/dist/planItem.d.ts +4 -4
  57. package/dist/planItem.d.ts.map +1 -1
  58. package/dist/planItem.js +2 -2
  59. package/dist/planItem.js.map +1 -1
  60. package/dist/publicConfig.d.ts +42 -3
  61. package/dist/publicConfig.d.ts.map +1 -1
  62. package/dist/publicConfig.js +20 -0
  63. package/dist/publicConfig.js.map +1 -1
  64. package/dist/sampleData.d.ts +7 -2
  65. package/dist/sampleData.d.ts.map +1 -1
  66. package/dist/sampleData.js +4 -0
  67. package/dist/sampleData.js.map +1 -1
  68. package/dist/session.d.ts +28 -0
  69. package/dist/session.d.ts.map +1 -1
  70. package/dist/session.js +39 -0
  71. package/dist/session.js.map +1 -1
  72. package/dist/values.d.ts +35 -5
  73. package/dist/values.d.ts.map +1 -1
  74. package/dist/values.js +90 -0
  75. package/dist/values.js.map +1 -1
  76. package/package.json +1 -1
  77. package/src/account.ts +7 -0
  78. package/src/address.ts +287 -0
  79. package/src/apiKeyScopes.ts +6 -0
  80. package/src/attendance.ts +72 -0
  81. package/src/company.ts +7 -10
  82. package/src/countries.ts +320 -0
  83. package/src/dashboard.ts +36 -0
  84. package/src/event.ts +159 -0
  85. package/src/eventAssociation.ts +36 -0
  86. package/src/form.ts +7 -7
  87. package/src/formMapTargets.ts +43 -4
  88. package/src/importExport.ts +3 -3
  89. package/src/index.ts +80 -2
  90. package/src/person.ts +7 -5
  91. package/src/planItem.ts +6 -6
  92. package/src/publicConfig.ts +44 -3
  93. package/src/sampleData.ts +11 -2
  94. package/src/session.ts +76 -0
  95. package/src/values.ts +119 -0
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 hq: string | null
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
- hq: z.string().nullable(),
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
- hq: wire.hq,
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 hq?: string | null
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
- hq: input.hq,
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,
@@ -0,0 +1,320 @@
1
+ /**
2
+ * ISO 3166-1 alpha-2 country codes, English short names, and common aliases.
3
+ *
4
+ * Import, forms, and the UI picker all resolve a typed name or code to the same
5
+ * two-letter value. The REST body accepts either and stores the code. An unknown
6
+ * string is not a country: the API refuses it, and import leaves `country` null
7
+ * with a row warning rather than guessing.
8
+ *
9
+ * This is the only copy. No extra package: `@kelpie/schemas` depends on Zod
10
+ * alone, so a catalog here stays usable from the browser bundle and the cloud
11
+ * repo.
12
+ */
13
+
14
+ export interface Country {
15
+ readonly code: string
16
+ readonly name: string
17
+ readonly aliases?: readonly string[]
18
+ }
19
+
20
+ /** Officially assigned ISO 3166-1 alpha-2 codes, English short names. */
21
+ export const COUNTRIES: readonly Country[] = [
22
+ { code: 'AD', name: 'Andorra' },
23
+ { code: 'AE', name: 'United Arab Emirates', aliases: ['UAE'] },
24
+ { code: 'AF', name: 'Afghanistan' },
25
+ { code: 'AG', name: 'Antigua and Barbuda' },
26
+ { code: 'AI', name: 'Anguilla' },
27
+ { code: 'AL', name: 'Albania' },
28
+ { code: 'AM', name: 'Armenia' },
29
+ { code: 'AO', name: 'Angola' },
30
+ { code: 'AQ', name: 'Antarctica' },
31
+ { code: 'AR', name: 'Argentina' },
32
+ { code: 'AS', name: 'American Samoa' },
33
+ { code: 'AT', name: 'Austria' },
34
+ { code: 'AU', name: 'Australia' },
35
+ { code: 'AW', name: 'Aruba' },
36
+ { code: 'AX', name: 'Åland Islands', aliases: ['Aland Islands'] },
37
+ { code: 'AZ', name: 'Azerbaijan' },
38
+ { code: 'BA', name: 'Bosnia and Herzegovina' },
39
+ { code: 'BB', name: 'Barbados' },
40
+ { code: 'BD', name: 'Bangladesh' },
41
+ { code: 'BE', name: 'Belgium' },
42
+ { code: 'BF', name: 'Burkina Faso' },
43
+ { code: 'BG', name: 'Bulgaria' },
44
+ { code: 'BH', name: 'Bahrain' },
45
+ { code: 'BI', name: 'Burundi' },
46
+ { code: 'BJ', name: 'Benin' },
47
+ { code: 'BL', name: 'Saint Barthélemy', aliases: ['Saint Barthelemy'] },
48
+ { code: 'BM', name: 'Bermuda' },
49
+ { code: 'BN', name: 'Brunei Darussalam', aliases: ['Brunei'] },
50
+ { code: 'BO', name: 'Bolivia' },
51
+ { code: 'BQ', name: 'Bonaire, Sint Eustatius and Saba' },
52
+ { code: 'BR', name: 'Brazil' },
53
+ { code: 'BS', name: 'Bahamas' },
54
+ { code: 'BT', name: 'Bhutan' },
55
+ { code: 'BV', name: 'Bouvet Island' },
56
+ { code: 'BW', name: 'Botswana' },
57
+ { code: 'BY', name: 'Belarus' },
58
+ { code: 'BZ', name: 'Belize' },
59
+ { code: 'CA', name: 'Canada' },
60
+ { code: 'CC', name: 'Cocos (Keeling) Islands', aliases: ['Cocos Islands'] },
61
+ { code: 'CD', name: 'Congo, Democratic Republic of the', aliases: ['DRC', 'Democratic Republic of the Congo'] },
62
+ { code: 'CF', name: 'Central African Republic' },
63
+ { code: 'CG', name: 'Congo', aliases: ['Republic of the Congo'] },
64
+ { code: 'CH', name: 'Switzerland' },
65
+ { code: 'CI', name: "Côte d'Ivoire", aliases: ['Ivory Coast', "Cote d'Ivoire"] },
66
+ { code: 'CK', name: 'Cook Islands' },
67
+ { code: 'CL', name: 'Chile' },
68
+ { code: 'CM', name: 'Cameroon' },
69
+ { code: 'CN', name: 'China' },
70
+ { code: 'CO', name: 'Colombia' },
71
+ { code: 'CR', name: 'Costa Rica' },
72
+ { code: 'CU', name: 'Cuba' },
73
+ { code: 'CV', name: 'Cabo Verde', aliases: ['Cape Verde'] },
74
+ { code: 'CW', name: 'Curaçao', aliases: ['Curacao'] },
75
+ { code: 'CX', name: 'Christmas Island' },
76
+ { code: 'CY', name: 'Cyprus' },
77
+ { code: 'CZ', name: 'Czechia', aliases: ['Czech Republic'] },
78
+ { code: 'DE', name: 'Germany' },
79
+ { code: 'DJ', name: 'Djibouti' },
80
+ { code: 'DK', name: 'Denmark' },
81
+ { code: 'DM', name: 'Dominica' },
82
+ { code: 'DO', name: 'Dominican Republic' },
83
+ { code: 'DZ', name: 'Algeria' },
84
+ { code: 'EC', name: 'Ecuador' },
85
+ { code: 'EE', name: 'Estonia' },
86
+ { code: 'EG', name: 'Egypt' },
87
+ { code: 'EH', name: 'Western Sahara' },
88
+ { code: 'ER', name: 'Eritrea' },
89
+ { code: 'ES', name: 'Spain' },
90
+ { code: 'ET', name: 'Ethiopia' },
91
+ { code: 'FI', name: 'Finland' },
92
+ { code: 'FJ', name: 'Fiji' },
93
+ { code: 'FK', name: 'Falkland Islands', aliases: ['Falkland Islands (Malvinas)'] },
94
+ { code: 'FM', name: 'Micronesia' },
95
+ { code: 'FO', name: 'Faroe Islands' },
96
+ { code: 'FR', name: 'France' },
97
+ { code: 'GA', name: 'Gabon' },
98
+ { code: 'GB', name: 'United Kingdom', aliases: ['UK', 'Great Britain', 'Britain'] },
99
+ { code: 'GD', name: 'Grenada' },
100
+ { code: 'GE', name: 'Georgia' },
101
+ { code: 'GF', name: 'French Guiana' },
102
+ { code: 'GG', name: 'Guernsey' },
103
+ { code: 'GH', name: 'Ghana' },
104
+ { code: 'GI', name: 'Gibraltar' },
105
+ { code: 'GL', name: 'Greenland' },
106
+ { code: 'GM', name: 'Gambia' },
107
+ { code: 'GN', name: 'Guinea' },
108
+ { code: 'GP', name: 'Guadeloupe' },
109
+ { code: 'GQ', name: 'Equatorial Guinea' },
110
+ { code: 'GR', name: 'Greece' },
111
+ { code: 'GS', name: 'South Georgia and the South Sandwich Islands' },
112
+ { code: 'GT', name: 'Guatemala' },
113
+ { code: 'GU', name: 'Guam' },
114
+ { code: 'GW', name: 'Guinea-Bissau' },
115
+ { code: 'GY', name: 'Guyana' },
116
+ { code: 'HK', name: 'Hong Kong' },
117
+ { code: 'HM', name: 'Heard Island and McDonald Islands' },
118
+ { code: 'HN', name: 'Honduras' },
119
+ { code: 'HR', name: 'Croatia' },
120
+ { code: 'HT', name: 'Haiti' },
121
+ { code: 'HU', name: 'Hungary' },
122
+ { code: 'ID', name: 'Indonesia' },
123
+ { code: 'IE', name: 'Ireland' },
124
+ { code: 'IL', name: 'Israel' },
125
+ { code: 'IM', name: 'Isle of Man' },
126
+ { code: 'IN', name: 'India' },
127
+ { code: 'IO', name: 'British Indian Ocean Territory' },
128
+ { code: 'IQ', name: 'Iraq' },
129
+ { code: 'IR', name: 'Iran' },
130
+ { code: 'IS', name: 'Iceland' },
131
+ { code: 'IT', name: 'Italy' },
132
+ { code: 'JE', name: 'Jersey' },
133
+ { code: 'JM', name: 'Jamaica' },
134
+ { code: 'JO', name: 'Jordan' },
135
+ { code: 'JP', name: 'Japan' },
136
+ { code: 'KE', name: 'Kenya' },
137
+ { code: 'KG', name: 'Kyrgyzstan' },
138
+ { code: 'KH', name: 'Cambodia' },
139
+ { code: 'KI', name: 'Kiribati' },
140
+ { code: 'KM', name: 'Comoros' },
141
+ { code: 'KN', name: 'Saint Kitts and Nevis' },
142
+ { code: 'KP', name: "Korea, Democratic People's Republic of", aliases: ['North Korea'] },
143
+ { code: 'KR', name: 'Korea, Republic of', aliases: ['South Korea'] },
144
+ { code: 'KW', name: 'Kuwait' },
145
+ { code: 'KY', name: 'Cayman Islands' },
146
+ { code: 'KZ', name: 'Kazakhstan' },
147
+ { code: 'LA', name: 'Lao People\'s Democratic Republic', aliases: ['Laos'] },
148
+ { code: 'LB', name: 'Lebanon' },
149
+ { code: 'LC', name: 'Saint Lucia' },
150
+ { code: 'LI', name: 'Liechtenstein' },
151
+ { code: 'LK', name: 'Sri Lanka' },
152
+ { code: 'LR', name: 'Liberia' },
153
+ { code: 'LS', name: 'Lesotho' },
154
+ { code: 'LT', name: 'Lithuania' },
155
+ { code: 'LU', name: 'Luxembourg' },
156
+ { code: 'LV', name: 'Latvia' },
157
+ { code: 'LY', name: 'Libya' },
158
+ { code: 'MA', name: 'Morocco' },
159
+ { code: 'MC', name: 'Monaco' },
160
+ { code: 'MD', name: 'Moldova' },
161
+ { code: 'ME', name: 'Montenegro' },
162
+ { code: 'MF', name: 'Saint Martin' },
163
+ { code: 'MG', name: 'Madagascar' },
164
+ { code: 'MH', name: 'Marshall Islands' },
165
+ { code: 'MK', name: 'North Macedonia' },
166
+ { code: 'ML', name: 'Mali' },
167
+ { code: 'MM', name: 'Myanmar', aliases: ['Burma'] },
168
+ { code: 'MN', name: 'Mongolia' },
169
+ { code: 'MO', name: 'Macao', aliases: ['Macau'] },
170
+ { code: 'MP', name: 'Northern Mariana Islands' },
171
+ { code: 'MQ', name: 'Martinique' },
172
+ { code: 'MR', name: 'Mauritania' },
173
+ { code: 'MS', name: 'Montserrat' },
174
+ { code: 'MT', name: 'Malta' },
175
+ { code: 'MU', name: 'Mauritius' },
176
+ { code: 'MV', name: 'Maldives' },
177
+ { code: 'MW', name: 'Malawi' },
178
+ { code: 'MX', name: 'Mexico' },
179
+ { code: 'MY', name: 'Malaysia' },
180
+ { code: 'MZ', name: 'Mozambique' },
181
+ { code: 'NA', name: 'Namibia' },
182
+ { code: 'NC', name: 'New Caledonia' },
183
+ { code: 'NE', name: 'Niger' },
184
+ { code: 'NF', name: 'Norfolk Island' },
185
+ { code: 'NG', name: 'Nigeria' },
186
+ { code: 'NI', name: 'Nicaragua' },
187
+ { code: 'NL', name: 'Netherlands', aliases: ['Holland'] },
188
+ { code: 'NO', name: 'Norway' },
189
+ { code: 'NP', name: 'Nepal' },
190
+ { code: 'NR', name: 'Nauru' },
191
+ { code: 'NU', name: 'Niue' },
192
+ { code: 'NZ', name: 'New Zealand' },
193
+ { code: 'OM', name: 'Oman' },
194
+ { code: 'PA', name: 'Panama' },
195
+ { code: 'PE', name: 'Peru' },
196
+ { code: 'PF', name: 'French Polynesia' },
197
+ { code: 'PG', name: 'Papua New Guinea' },
198
+ { code: 'PH', name: 'Philippines' },
199
+ { code: 'PK', name: 'Pakistan' },
200
+ { code: 'PL', name: 'Poland' },
201
+ { code: 'PM', name: 'Saint Pierre and Miquelon' },
202
+ { code: 'PN', name: 'Pitcairn' },
203
+ { code: 'PR', name: 'Puerto Rico' },
204
+ { code: 'PS', name: 'Palestine', aliases: ['Palestinian Territory'] },
205
+ { code: 'PT', name: 'Portugal' },
206
+ { code: 'PW', name: 'Palau' },
207
+ { code: 'PY', name: 'Paraguay' },
208
+ { code: 'QA', name: 'Qatar' },
209
+ { code: 'RE', name: 'Réunion', aliases: ['Reunion'] },
210
+ { code: 'RO', name: 'Romania' },
211
+ { code: 'RS', name: 'Serbia' },
212
+ { code: 'RU', name: 'Russian Federation', aliases: ['Russia'] },
213
+ { code: 'RW', name: 'Rwanda' },
214
+ { code: 'SA', name: 'Saudi Arabia' },
215
+ { code: 'SB', name: 'Solomon Islands' },
216
+ { code: 'SC', name: 'Seychelles' },
217
+ { code: 'SD', name: 'Sudan' },
218
+ { code: 'SE', name: 'Sweden' },
219
+ { code: 'SG', name: 'Singapore' },
220
+ { code: 'SH', name: 'Saint Helena, Ascension and Tristan da Cunha', aliases: ['Saint Helena'] },
221
+ { code: 'SI', name: 'Slovenia' },
222
+ { code: 'SJ', name: 'Svalbard and Jan Mayen' },
223
+ { code: 'SK', name: 'Slovakia' },
224
+ { code: 'SL', name: 'Sierra Leone' },
225
+ { code: 'SM', name: 'San Marino' },
226
+ { code: 'SN', name: 'Senegal' },
227
+ { code: 'SO', name: 'Somalia' },
228
+ { code: 'SR', name: 'Suriname' },
229
+ { code: 'SS', name: 'South Sudan' },
230
+ { code: 'ST', name: 'Sao Tome and Principe' },
231
+ { code: 'SV', name: 'El Salvador' },
232
+ { code: 'SX', name: 'Sint Maarten' },
233
+ { code: 'SY', name: 'Syrian Arab Republic', aliases: ['Syria'] },
234
+ { code: 'SZ', name: 'Eswatini', aliases: ['Swaziland'] },
235
+ { code: 'TC', name: 'Turks and Caicos Islands' },
236
+ { code: 'TD', name: 'Chad' },
237
+ { code: 'TF', name: 'French Southern Territories' },
238
+ { code: 'TG', name: 'Togo' },
239
+ { code: 'TH', name: 'Thailand' },
240
+ { code: 'TJ', name: 'Tajikistan' },
241
+ { code: 'TK', name: 'Tokelau' },
242
+ { code: 'TL', name: 'Timor-Leste', aliases: ['East Timor'] },
243
+ { code: 'TM', name: 'Turkmenistan' },
244
+ { code: 'TN', name: 'Tunisia' },
245
+ { code: 'TO', name: 'Tonga' },
246
+ { code: 'TR', name: 'Türkiye', aliases: ['Turkey'] },
247
+ { code: 'TT', name: 'Trinidad and Tobago' },
248
+ { code: 'TV', name: 'Tuvalu' },
249
+ { code: 'TW', name: 'Taiwan' },
250
+ { code: 'TZ', name: 'Tanzania' },
251
+ { code: 'UA', name: 'Ukraine' },
252
+ { code: 'UG', name: 'Uganda' },
253
+ { code: 'UM', name: 'United States Minor Outlying Islands' },
254
+ { code: 'US', name: 'United States', aliases: ['USA', 'United States of America', 'America'] },
255
+ { code: 'UY', name: 'Uruguay' },
256
+ { code: 'UZ', name: 'Uzbekistan' },
257
+ { code: 'VA', name: 'Holy See', aliases: ['Vatican City', 'Vatican'] },
258
+ { code: 'VC', name: 'Saint Vincent and the Grenadines' },
259
+ { code: 'VE', name: 'Venezuela' },
260
+ { code: 'VG', name: 'Virgin Islands (British)', aliases: ['British Virgin Islands'] },
261
+ { code: 'VI', name: 'Virgin Islands (U.S.)', aliases: ['US Virgin Islands', 'U.S. Virgin Islands'] },
262
+ { code: 'VN', name: 'Viet Nam', aliases: ['Vietnam'] },
263
+ { code: 'VU', name: 'Vanuatu' },
264
+ { code: 'WF', name: 'Wallis and Futuna' },
265
+ { code: 'WS', name: 'Samoa' },
266
+ { code: 'YE', name: 'Yemen' },
267
+ { code: 'YT', name: 'Mayotte' },
268
+ { code: 'ZA', name: 'South Africa' },
269
+ { code: 'ZM', name: 'Zambia' },
270
+ { code: 'ZW', name: 'Zimbabwe' },
271
+ ]
272
+
273
+ export const COUNTRY_CODES: readonly string[] = COUNTRIES.map((country) => country.code)
274
+
275
+ const COUNTRY_BY_CODE: ReadonlyMap<string, Country> = new Map(
276
+ COUNTRIES.map((country) => [country.code, country]),
277
+ )
278
+
279
+ function aliasKey(raw: string): string {
280
+ return raw.trim().toLowerCase()
281
+ }
282
+
283
+ const COUNTRY_ALIAS_INDEX: ReadonlyMap<string, string> = ((): ReadonlyMap<string, string> => {
284
+ const index = new Map<string, string>()
285
+
286
+ for (const country of COUNTRIES) {
287
+ index.set(aliasKey(country.code), country.code)
288
+ index.set(aliasKey(country.name), country.code)
289
+
290
+ for (const alias of country.aliases ?? []) {
291
+ index.set(aliasKey(alias), country.code)
292
+ }
293
+ }
294
+
295
+ return index
296
+ })()
297
+
298
+ export function isCountryCode(code: string): boolean {
299
+ return COUNTRY_BY_CODE.has(code)
300
+ }
301
+
302
+ export function countryName(code: string): string | undefined {
303
+ return COUNTRY_BY_CODE.get(code)?.name
304
+ }
305
+
306
+ /**
307
+ * Resolve a typed country to an ISO 3166-1 alpha-2 code.
308
+ *
309
+ * Accepts a code in any case (`au`), an English name (`Australia`), or a listed
310
+ * alias (`USA`). Returns null when the string is empty or not a country we know.
311
+ */
312
+ export function normaliseCountry(raw: string): string | null {
313
+ const trimmed = raw.trim()
314
+
315
+ if (trimmed.length === 0) {
316
+ return null
317
+ }
318
+
319
+ return COUNTRY_ALIAS_INDEX.get(aliasKey(trimmed)) ?? null
320
+ }
package/src/dashboard.ts CHANGED
@@ -252,6 +252,39 @@ const dashboardDecisionSchema: z.ZodType<DashboardDecision, unknown> = z
252
252
  dueAt: wire.due_at,
253
253
  }))
254
254
 
255
+ export interface DashboardUpcomingEvent {
256
+ readonly id: string
257
+ readonly name: string
258
+ readonly startsAt: Date
259
+ readonly endsAt: Date
260
+ readonly format: string
261
+ readonly location: string
262
+ readonly attendeeCount: number
263
+ readonly ownerId: string | null
264
+ }
265
+
266
+ const dashboardUpcomingEventSchema: z.ZodType<DashboardUpcomingEvent, unknown> = z
267
+ .object({
268
+ id: idSchema,
269
+ name: z.string(),
270
+ starts_at: timestampSchema,
271
+ ends_at: timestampSchema,
272
+ format: z.string(),
273
+ location: z.string(),
274
+ attendee_count: z.number().int(),
275
+ owner_id: idSchema.nullable(),
276
+ })
277
+ .transform((wire) => ({
278
+ id: wire.id,
279
+ name: wire.name,
280
+ startsAt: wire.starts_at,
281
+ endsAt: wire.ends_at,
282
+ format: wire.format,
283
+ location: wire.location,
284
+ attendeeCount: wire.attendee_count,
285
+ ownerId: wire.owner_id,
286
+ }))
287
+
255
288
  export interface Dashboard {
256
289
  readonly generatedAt: Date
257
290
  /** The day every signal was measured against, `YYYY-MM-DD`. */
@@ -266,6 +299,7 @@ export interface Dashboard {
266
299
  readonly overduePlanItems: DashboardSignal<DashboardPlanItem>
267
300
  readonly dueSoonPlanItems: DashboardSignal<DashboardPlanItem>
268
301
  readonly partnershipTouchpoints: DashboardSignal<DashboardTouchpoint>
302
+ readonly upcomingEvents: DashboardSignal<DashboardUpcomingEvent>
269
303
  readonly staleContacts: DashboardSignal<DashboardStaleContact>
270
304
  readonly recentActivity: readonly DashboardActivity[]
271
305
  readonly recentNotes: readonly DashboardNote[]
@@ -283,6 +317,7 @@ export const dashboardSchema: z.ZodType<Dashboard, unknown> = z
283
317
  overdue_plan_items: signalSchema(dashboardPlanItemSchema),
284
318
  due_soon_plan_items: signalSchema(dashboardPlanItemSchema),
285
319
  partnership_touchpoints: signalSchema(dashboardTouchpointSchema),
320
+ upcoming_events: signalSchema(dashboardUpcomingEventSchema),
286
321
  stale_contacts: signalSchema(dashboardStaleContactSchema),
287
322
  recent_activity: z.array(dashboardActivitySchema),
288
323
  recent_notes: z.array(dashboardNoteSchema),
@@ -299,6 +334,7 @@ export const dashboardSchema: z.ZodType<Dashboard, unknown> = z
299
334
  overduePlanItems: wire.overdue_plan_items,
300
335
  dueSoonPlanItems: wire.due_soon_plan_items,
301
336
  partnershipTouchpoints: wire.partnership_touchpoints,
337
+ upcomingEvents: wire.upcoming_events,
302
338
  staleContacts: wire.stale_contacts,
303
339
  recentActivity: wire.recent_activity,
304
340
  recentNotes: wire.recent_notes,
package/src/event.ts ADDED
@@ -0,0 +1,159 @@
1
+ import { z } from 'zod'
2
+
3
+ import { customFieldValuesBody, customFieldValuesSchema } from './customField.ts'
4
+ import type { CustomFieldValue, CustomFieldValues } from './customField.ts'
5
+ import {
6
+ EVENT_ASSOCIATION_TARGET_TYPES,
7
+ EVENT_FORMATS,
8
+ EVENT_STATUSES,
9
+ } from './values.ts'
10
+ import type {
11
+ EventAssociationTargetType,
12
+ EventFormat,
13
+ EventStatus,
14
+ } from './values.ts'
15
+ import { definedFields, idSchema, recordTimestamps, timestampSchema } from './wire.ts'
16
+ import type { RecordTimestamps } from './wire.ts'
17
+
18
+ /** Wire and write shapes for `/v1/events`. */
19
+
20
+ export interface EventAssociation {
21
+ readonly targetType: EventAssociationTargetType
22
+ readonly targetId: string
23
+ }
24
+
25
+ export interface Event extends RecordTimestamps {
26
+ readonly id: string
27
+ readonly name: string
28
+ readonly kind: string
29
+ readonly startsAt: Date
30
+ readonly endsAt: Date
31
+ readonly timezone: string
32
+ readonly location: string
33
+ readonly meetingUrl: string | null
34
+ readonly format: EventFormat
35
+ readonly details: string
36
+ readonly status: EventStatus
37
+ readonly ownerId: string | null
38
+ readonly summary: string
39
+ readonly tags: readonly string[]
40
+ readonly associations: readonly EventAssociation[]
41
+ readonly customFields: CustomFieldValues
42
+ }
43
+
44
+ const associationSchema = z
45
+ .object({
46
+ target_type: z.enum(EVENT_ASSOCIATION_TARGET_TYPES),
47
+ target_id: idSchema,
48
+ })
49
+ .transform(
50
+ (wire): EventAssociation => ({
51
+ targetType: wire.target_type,
52
+ targetId: wire.target_id,
53
+ }),
54
+ )
55
+
56
+ export const eventSchema: z.ZodType<Event, unknown> = z
57
+ .object({
58
+ id: idSchema,
59
+ name: z.string(),
60
+ kind: z.string(),
61
+ starts_at: timestampSchema,
62
+ ends_at: timestampSchema,
63
+ timezone: z.string(),
64
+ location: z.string(),
65
+ meeting_url: z.string().nullable(),
66
+ format: z.enum(EVENT_FORMATS),
67
+ details: z.string(),
68
+ status: z.enum(EVENT_STATUSES),
69
+ owner_id: idSchema.nullable(),
70
+ summary: z.string(),
71
+ tags: z.array(z.string()),
72
+ associations: z.array(associationSchema),
73
+ custom_fields: customFieldValuesSchema,
74
+ ...recordTimestamps,
75
+ })
76
+ .transform(
77
+ (wire): Event => ({
78
+ id: wire.id,
79
+ name: wire.name,
80
+ kind: wire.kind,
81
+ startsAt: wire.starts_at,
82
+ endsAt: wire.ends_at,
83
+ timezone: wire.timezone,
84
+ location: wire.location,
85
+ meetingUrl: wire.meeting_url,
86
+ format: wire.format,
87
+ details: wire.details,
88
+ status: wire.status,
89
+ ownerId: wire.owner_id,
90
+ summary: wire.summary,
91
+ tags: wire.tags,
92
+ associations: wire.associations,
93
+ customFields: wire.custom_fields,
94
+ createdAt: wire.created_at,
95
+ updatedAt: wire.updated_at,
96
+ }),
97
+ )
98
+
99
+ function associationBody(association: EventAssociation): Record<string, unknown> {
100
+ return { target_type: association.targetType, target_id: association.targetId }
101
+ }
102
+
103
+ export interface EventInput {
104
+ readonly name?: string
105
+ readonly kind?: string
106
+ readonly startsAt?: Date | string
107
+ readonly endsAt?: Date | string
108
+ readonly timezone?: string
109
+ readonly location?: string
110
+ readonly meetingUrl?: string | null
111
+ readonly format?: EventFormat
112
+ readonly details?: string
113
+ readonly status?: EventStatus
114
+ readonly ownerId?: string | null
115
+ readonly summary?: string
116
+ readonly tags?: readonly string[]
117
+ readonly associations?: readonly EventAssociation[]
118
+ readonly customFields?: Readonly<Record<string, CustomFieldValue | null>>
119
+ }
120
+
121
+ function timestampBody(value: Date | string | undefined): string | undefined {
122
+ if (value === undefined) {
123
+ return undefined
124
+ }
125
+
126
+ return value instanceof Date ? value.toISOString() : value
127
+ }
128
+
129
+ export function eventBody(input: EventInput): Record<string, unknown> {
130
+ return definedFields({
131
+ name: input.name,
132
+ kind: input.kind,
133
+ starts_at: timestampBody(input.startsAt),
134
+ ends_at: timestampBody(input.endsAt),
135
+ timezone: input.timezone,
136
+ location: input.location,
137
+ meeting_url: input.meetingUrl,
138
+ format: input.format,
139
+ details: input.details,
140
+ status: input.status,
141
+ owner_id: input.ownerId,
142
+ summary: input.summary,
143
+ tags: input.tags,
144
+ associations: input.associations?.map(associationBody),
145
+ custom_fields:
146
+ input.customFields === undefined ? undefined : customFieldValuesBody(input.customFields),
147
+ })
148
+ }
149
+
150
+ export interface CreateEventInput extends EventInput {
151
+ readonly name: string
152
+ readonly startsAt: Date | string
153
+ readonly endsAt: Date | string
154
+ readonly format: EventFormat
155
+ }
156
+
157
+ export function createEventBody(input: CreateEventInput): Record<string, unknown> {
158
+ return eventBody(input)
159
+ }
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod'
2
+
3
+ import { EVENT_ASSOCIATION_TARGET_TYPES } from './values.ts'
4
+ import type { EventAssociationTargetType } from './values.ts'
5
+ import { idSchema } from './wire.ts'
6
+
7
+ /**
8
+ * One Event linked to another record, as returned by
9
+ * `GET /v1/event-associations?target_type=&target_id=`.
10
+ *
11
+ * The Event's own `associations` array is the forward view. This is the reverse
12
+ * tab on a Deal, Company, Role, and so on.
13
+ */
14
+
15
+ export interface EventAssociationRow {
16
+ readonly eventId: string
17
+ readonly eventName: string
18
+ readonly targetType: EventAssociationTargetType
19
+ readonly targetId: string
20
+ }
21
+
22
+ export const eventAssociationRowSchema: z.ZodType<EventAssociationRow, unknown> = z
23
+ .object({
24
+ event_id: idSchema,
25
+ event_name: z.string(),
26
+ target_type: z.enum(EVENT_ASSOCIATION_TARGET_TYPES),
27
+ target_id: idSchema,
28
+ })
29
+ .transform(
30
+ (wire): EventAssociationRow => ({
31
+ eventId: wire.event_id,
32
+ eventName: wire.event_name,
33
+ targetType: wire.target_type,
34
+ targetId: wire.target_id,
35
+ }),
36
+ )
package/src/form.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import { z } from 'zod'
2
2
 
3
3
  import {
4
+ FORM_ATTACH_TARGET_TYPES,
4
5
  FORM_FIELD_TYPES,
5
6
  FORM_OPTION_VALUE_TYPES,
6
7
  FORM_STATUSES,
7
- PIPELINE_KINDS,
8
8
  } from './values.ts'
9
9
  import type {
10
+ FormAttachTargetType,
10
11
  FormFieldMapTarget,
11
12
  FormFieldType,
12
13
  FormOptionValueType,
13
14
  FormStatus,
14
- PipelineKind,
15
15
  } from './values.ts'
16
16
  import { definedFields, idSchema, recordTimestamps } from './wire.ts'
17
17
  import type { RecordTimestamps } from './wire.ts'
@@ -69,12 +69,12 @@ export interface FormField {
69
69
  }
70
70
 
71
71
  /**
72
- * One pre-existing pipeline record every submitter is linked into through
73
- * `person_links`. `target_type` is fixed at form-write time; the row itself
74
- * lives in `form_attach_targets` on the server.
72
+ * One pre-existing record every submitter is linked into. Pipeline kinds use
73
+ * `person_links`. `event` creates an Attendance instead. The row itself lives
74
+ * in `form_attach_targets` on the server.
75
75
  */
76
76
  export interface FormAttachTarget {
77
- readonly targetType: PipelineKind
77
+ readonly targetType: FormAttachTargetType
78
78
  readonly targetId: string
79
79
  }
80
80
 
@@ -181,7 +181,7 @@ const formFieldSchema = z
181
181
 
182
182
  const attachTargetSchema = z
183
183
  .object({
184
- target_type: z.enum(PIPELINE_KINDS),
184
+ target_type: z.enum(FORM_ATTACH_TARGET_TYPES),
185
185
  target_id: idSchema,
186
186
  })
187
187
  .transform(