@kelpie/schemas 0.10.0 → 0.12.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 (81) hide show
  1. package/README.md +16 -0
  2. package/dist/account.d.ts +5 -0
  3. package/dist/account.d.ts.map +1 -1
  4. package/dist/account.js +2 -0
  5. package/dist/account.js.map +1 -1
  6. package/dist/apiKey.d.ts +5 -0
  7. package/dist/apiKey.d.ts.map +1 -1
  8. package/dist/apiKey.js +8 -1
  9. package/dist/apiKey.js.map +1 -1
  10. package/dist/apiKeyScopes.d.ts +36 -0
  11. package/dist/apiKeyScopes.d.ts.map +1 -0
  12. package/dist/apiKeyScopes.js +217 -0
  13. package/dist/apiKeyScopes.js.map +1 -0
  14. package/dist/conversion.d.ts +58 -0
  15. package/dist/conversion.d.ts.map +1 -0
  16. package/dist/conversion.js +63 -0
  17. package/dist/conversion.js.map +1 -0
  18. package/dist/deal.d.ts +3 -0
  19. package/dist/deal.d.ts.map +1 -1
  20. package/dist/deal.js +5 -0
  21. package/dist/deal.js.map +1 -1
  22. package/dist/enquiry.d.ts +3 -0
  23. package/dist/enquiry.d.ts.map +1 -1
  24. package/dist/enquiry.js +5 -0
  25. package/dist/enquiry.js.map +1 -1
  26. package/dist/form.d.ts.map +1 -1
  27. package/dist/form.js +2 -2
  28. package/dist/form.js.map +1 -1
  29. package/dist/formMapTargets.d.ts +72 -0
  30. package/dist/formMapTargets.d.ts.map +1 -0
  31. package/dist/formMapTargets.js +385 -0
  32. package/dist/formMapTargets.js.map +1 -0
  33. package/dist/importExport.d.ts +14 -1
  34. package/dist/importExport.d.ts.map +1 -1
  35. package/dist/importExport.js +161 -1
  36. package/dist/importExport.js.map +1 -1
  37. package/dist/index.d.ts +8 -2
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +4 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/list.d.ts +0 -10
  42. package/dist/list.d.ts.map +1 -1
  43. package/dist/list.js +0 -6
  44. package/dist/list.js.map +1 -1
  45. package/dist/opportunity.d.ts +3 -0
  46. package/dist/opportunity.d.ts.map +1 -1
  47. package/dist/opportunity.js +5 -0
  48. package/dist/opportunity.js.map +1 -1
  49. package/dist/partnership.d.ts +3 -0
  50. package/dist/partnership.d.ts.map +1 -1
  51. package/dist/partnership.js +5 -0
  52. package/dist/partnership.js.map +1 -1
  53. package/dist/raise.d.ts +3 -0
  54. package/dist/raise.d.ts.map +1 -1
  55. package/dist/raise.js +5 -0
  56. package/dist/raise.js.map +1 -1
  57. package/dist/session.d.ts +1 -11
  58. package/dist/session.d.ts.map +1 -1
  59. package/dist/session.js +0 -6
  60. package/dist/session.js.map +1 -1
  61. package/dist/values.d.ts +4 -3
  62. package/dist/values.d.ts.map +1 -1
  63. package/dist/values.js +2 -0
  64. package/dist/values.js.map +1 -1
  65. package/package.json +1 -1
  66. package/src/account.ts +7 -0
  67. package/src/apiKey.ts +13 -1
  68. package/src/apiKeyScopes.ts +264 -0
  69. package/src/conversion.ts +99 -0
  70. package/src/deal.ts +9 -0
  71. package/src/enquiry.ts +9 -0
  72. package/src/form.ts +1 -2
  73. package/src/formMapTargets.ts +548 -0
  74. package/src/importExport.ts +174 -1
  75. package/src/index.ts +61 -0
  76. package/src/list.ts +0 -16
  77. package/src/opportunity.ts +9 -0
  78. package/src/partnership.ts +9 -0
  79. package/src/raise.ts +9 -0
  80. package/src/session.ts +1 -17
  81. package/src/values.ts +7 -2
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import type { CustomFieldObjectType, PipelineKind } from './values.ts'
3
4
  import { idSchema, recordTimestamps } from './wire.ts'
4
5
  import type { RecordTimestamps } from './wire.ts'
5
6
 
@@ -14,7 +15,17 @@ import type { RecordTimestamps } from './wire.ts'
14
15
  */
15
16
 
16
17
  export const IMPORT_SOURCES = ['custom', 'hubspot', 'salesforce', 'attio'] as const
17
- export const IMPORT_OBJECTS = ['companies', 'people', 'positions', 'deals'] as const
18
+ export const IMPORT_OBJECTS = [
19
+ 'companies',
20
+ 'people',
21
+ 'positions',
22
+ 'deals',
23
+ 'opportunities',
24
+ 'enquiries',
25
+ 'partnerships',
26
+ 'raises',
27
+ 'custom_fields',
28
+ ] as const
18
29
  export const IMPORT_CONFLICT_MODES = ['skip', 'update'] as const
19
30
 
20
31
  /**
@@ -88,6 +99,11 @@ export const OBJECT_LABELS: Readonly<Record<ImportObject, string>> = {
88
99
  people: 'People',
89
100
  positions: 'Positions',
90
101
  deals: 'Deals',
102
+ opportunities: 'Opportunities',
103
+ enquiries: 'Enquiries',
104
+ partnerships: 'Partnerships',
105
+ raises: 'Fundraising',
106
+ custom_fields: 'Custom fields',
91
107
  }
92
108
 
93
109
  export const SOURCE_LABELS: Readonly<Record<ImportSource, string>> = {
@@ -215,6 +231,125 @@ export const OBJECT_COLUMNS: Readonly<Record<ImportObject, readonly CsvColumn[]>
215
231
  { key: 'tags', label: 'Tags', required: false },
216
232
  { key: 'external_id', label: 'External id', required: false },
217
233
  ],
234
+ opportunities: [
235
+ { key: 'name', label: 'Name', required: true },
236
+ { key: 'kind', label: 'Kind', required: true },
237
+ { key: 'company_domain', label: 'Company domain', required: false },
238
+ { key: 'stage', label: 'Stage', required: true },
239
+ { key: 'owner_email', label: 'Owner email', required: false },
240
+ { key: 'expected_close', label: 'Expected close', required: false },
241
+ { key: 'person_emails', label: 'Person emails', required: false },
242
+ { key: 'summary', label: 'Summary', required: false },
243
+ { key: 'tags', label: 'Tags', required: false },
244
+ ],
245
+ enquiries: [
246
+ { key: 'name', label: 'Name', required: true },
247
+ { key: 'source', label: 'Source', required: false },
248
+ { key: 'company_domain', label: 'Company domain', required: false },
249
+ { key: 'stage', label: 'Stage', required: true },
250
+ { key: 'owner_email', label: 'Owner email', required: false },
251
+ { key: 'person_emails', label: 'Person emails', required: false },
252
+ { key: 'summary', label: 'Summary', required: false },
253
+ { key: 'tags', label: 'Tags', required: false },
254
+ ],
255
+ partnerships: [
256
+ { key: 'name', label: 'Name', required: true },
257
+ { key: 'company_domain', label: 'Company domain', required: true },
258
+ { key: 'stage', label: 'Stage', required: true },
259
+ { key: 'kind', label: 'Kind', required: true },
260
+ { key: 'next_touchpoint', label: 'Next touchpoint', required: false },
261
+ { key: 'owner_email', label: 'Owner email', required: false },
262
+ { key: 'goals', label: 'Goals', required: false },
263
+ { key: 'success_looks_like', label: 'Success looks like', required: false },
264
+ { key: 'person_emails', label: 'Person emails', required: false },
265
+ { key: 'summary', label: 'Summary', required: false },
266
+ { key: 'tags', label: 'Tags', required: false },
267
+ ],
268
+ raises: [
269
+ { key: 'name', label: 'Name', required: true },
270
+ { key: 'company_domain', label: 'Company domain', required: true },
271
+ { key: 'stage', label: 'Stage', required: true },
272
+ { key: 'check_size', label: 'Check size', required: false },
273
+ { key: 'currency', label: 'Currency', required: false },
274
+ { key: 'thesis_fit', label: 'Thesis fit', required: false },
275
+ { key: 'pass_reason', label: 'Pass reason', required: false },
276
+ { key: 'owner_email', label: 'Owner email', required: false },
277
+ { key: 'expected_close', label: 'Expected close', required: false },
278
+ { key: 'person_emails', label: 'Person emails', required: false },
279
+ { key: 'summary', label: 'Summary', required: false },
280
+ { key: 'tags', label: 'Tags', required: false },
281
+ ],
282
+ custom_fields: [
283
+ { key: 'object_type', label: 'Object type', required: true },
284
+ { key: 'key', label: 'Key', required: true },
285
+ { key: 'label', label: 'Label', required: true },
286
+ { key: 'type', label: 'Type', required: true },
287
+ { key: 'options', label: 'Options', required: false },
288
+ { key: 'description', label: 'Description', required: false },
289
+ { key: 'sort_order', label: 'Sort order', required: true },
290
+ ],
291
+ }
292
+
293
+ /** Every object `GET /v1/export/{object}.csv` and the import wizard accept. */
294
+ export const EXPORT_OBJECTS = IMPORT_OBJECTS
295
+
296
+ export type ExportObject = ImportObject
297
+
298
+ export function isImportObject(object: string): object is ImportObject {
299
+ return (IMPORT_OBJECTS as readonly string[]).includes(object)
300
+ }
301
+
302
+ /** @deprecated Use `OBJECT_LABELS`. Kept for callers that still import this name. */
303
+ export const EXPORT_OBJECT_LABELS: Readonly<Record<ExportObject, string>> = OBJECT_LABELS
304
+
305
+ /** Record exports that carry workspace custom field values as extra columns. */
306
+ export function customFieldObjectTypeForExport(object: ExportObject): CustomFieldObjectType | null {
307
+ switch (object) {
308
+ case 'companies':
309
+ return 'company'
310
+ case 'people':
311
+ return 'person'
312
+ case 'deals':
313
+ return 'deal'
314
+ case 'opportunities':
315
+ return 'opportunity'
316
+ case 'enquiries':
317
+ return 'enquiry'
318
+ case 'partnerships':
319
+ return 'partnership'
320
+ case 'raises':
321
+ return 'raise'
322
+ default:
323
+ return null
324
+ }
325
+ }
326
+
327
+ /** The pipeline kind whose stages a row's `stage` column resolves against. */
328
+ export function pipelineKindForImport(object: ImportObject): PipelineKind | null {
329
+ switch (object) {
330
+ case 'deals':
331
+ return 'deal'
332
+ case 'opportunities':
333
+ return 'opportunity'
334
+ case 'enquiries':
335
+ return 'enquiry'
336
+ case 'partnerships':
337
+ return 'partnership'
338
+ case 'raises':
339
+ return 'raise'
340
+ default:
341
+ return null
342
+ }
343
+ }
344
+
345
+ /** Kelpie column keys a job may map, including workspace custom field definition keys. */
346
+ export function knownImportColumnKeys(
347
+ object: ImportObject,
348
+ customFieldKeys: readonly string[] = [],
349
+ ): readonly string[] {
350
+ const base = OBJECT_COLUMNS[object].map((column) => column.key)
351
+
352
+ return [...new Set([...base, ...customFieldKeys])]
218
353
  }
219
354
 
220
355
  /** Columns whose value is a pipe-separated list (`a|b|c`), per `import-export.md`. */
@@ -224,6 +359,7 @@ export const LIST_COLUMNS: ReadonlySet<string> = new Set([
224
359
  'competitors',
225
360
  'person_emails',
226
361
  'tech_stack',
362
+ 'options',
227
363
  ])
228
364
 
229
365
  export interface MatchKeyOption {
@@ -261,6 +397,43 @@ export const MATCH_KEYS: Readonly<Record<ImportObject, readonly MatchKeyOption[]
261
397
  columns: ['name', 'company_domain'],
262
398
  },
263
399
  ],
400
+ opportunities: [
401
+ {
402
+ id: 'name|company_domain',
403
+ label: 'name + company_domain',
404
+ columns: ['name', 'company_domain'],
405
+ },
406
+ { id: 'name', label: 'name', columns: ['name'] },
407
+ ],
408
+ enquiries: [
409
+ {
410
+ id: 'name|company_domain',
411
+ label: 'name + company_domain',
412
+ columns: ['name', 'company_domain'],
413
+ },
414
+ { id: 'name', label: 'name', columns: ['name'] },
415
+ ],
416
+ partnerships: [
417
+ {
418
+ id: 'name|company_domain',
419
+ label: 'name + company_domain',
420
+ columns: ['name', 'company_domain'],
421
+ },
422
+ ],
423
+ raises: [
424
+ {
425
+ id: 'name|company_domain',
426
+ label: 'name + company_domain',
427
+ columns: ['name', 'company_domain'],
428
+ },
429
+ ],
430
+ custom_fields: [
431
+ {
432
+ id: 'object_type|key',
433
+ label: 'object_type + key',
434
+ columns: ['object_type', 'key'],
435
+ },
436
+ ],
264
437
  }
265
438
 
266
439
  export function defaultMatchKeyId(object: ImportObject): string {
package/src/index.ts CHANGED
@@ -173,6 +173,17 @@ export type { Company, CompanyInput } from './company.ts'
173
173
  export { createPositionBody, positionSchema, updatePositionBody } from './position.ts'
174
174
  export type { CreatePositionInput, Position } from './position.ts'
175
175
 
176
+ export {
177
+ convertEnquiryBody,
178
+ convertPipelineRecordBody,
179
+ convertPipelineRecordRequest,
180
+ convertedToForWire,
181
+ convertedToResponse,
182
+ convertedToSchema,
183
+ convertedToWireSchema,
184
+ } from './conversion.ts'
185
+ export type { ConvertedTo, ConvertPipelineRecordInput } from './conversion.ts'
186
+
176
187
  export { dealBody, dealSchema } from './deal.ts'
177
188
  export type { Deal, DealInput } from './deal.ts'
178
189
 
@@ -247,6 +258,32 @@ export type {
247
258
  FormInput,
248
259
  } from './form.ts'
249
260
 
261
+ export {
262
+ FORM_MAP_OBJECT_TYPES,
263
+ FORM_MAP_OBJECT_TYPE_LABELS,
264
+ FORM_STANDARD_MAP_FIELDS,
265
+ buildCustomMapTarget,
266
+ buildCustomMapTargetEntry,
267
+ isCompatibleFormFieldType,
268
+ isKnownMapTarget,
269
+ isRepeatableMapTarget,
270
+ labelForMapTarget,
271
+ listMapTargetEntries,
272
+ listStandardMapTargetEntries,
273
+ metaForMapTargetEntry,
274
+ parseFormMapTarget,
275
+ resolveMapTargetEntry,
276
+ suggestedFormFieldType,
277
+ } from './formMapTargets.ts'
278
+ export type {
279
+ CustomFieldDefinitionRef,
280
+ FormMapObjectType,
281
+ FormMapStandardField,
282
+ FormMapTargetEntry,
283
+ FormMapValueType,
284
+ ParsedFormMapTarget,
285
+ } from './formMapTargets.ts'
286
+
250
287
  export {
251
288
  FORM_SUBMISSION_LINK_TARGETS,
252
289
  formSubmissionSchema,
@@ -261,6 +298,8 @@ export type {
261
298
 
262
299
  export {
263
300
  CONFLICT_MODE_LABELS,
301
+ EXPORT_OBJECT_LABELS,
302
+ EXPORT_OBJECTS,
264
303
  IMPORT_CONFLICT_MODES,
265
304
  IMPORT_JOB_STATUSES,
266
305
  IMPORT_OBJECTS,
@@ -278,14 +317,19 @@ export {
278
317
  ON_MISSING_COMPANY_LABELS,
279
318
  SOURCE_LABELS,
280
319
  SYNC_IMPORT_ROWS,
320
+ customFieldObjectTypeForExport,
281
321
  defaultMatchKeyId,
282
322
  findMatchKey,
283
323
  importJobSchema,
284
324
  isImportJobSettled,
325
+ isImportObject,
326
+ knownImportColumnKeys,
327
+ pipelineKindForImport,
285
328
  requiredColumns,
286
329
  } from './importExport.ts'
287
330
  export type {
288
331
  CsvColumn,
332
+ ExportObject,
289
333
  ImportColumnMap,
290
334
  ImportConflictMode,
291
335
  ImportCounts,
@@ -321,6 +365,23 @@ export type {
321
365
 
322
366
  export { apiKeySchema, createApiKeyBody, createdApiKeySchema } from './apiKey.ts'
323
367
  export type { ApiKey, CreateApiKeyInput, CreatedApiKey } from './apiKey.ts'
368
+ export {
369
+ API_KEY_ADMIN_RESOURCES,
370
+ API_KEY_GRANULAR_SCOPES,
371
+ API_KEY_OBJECT_CONFIG_RESOURCES,
372
+ API_KEY_OBJECT_DATA_RESOURCES,
373
+ API_KEY_OBJECT_READ_ONLY_RESOURCES,
374
+ API_KEY_PRESET_SCOPES,
375
+ API_KEY_SCOPE_GROUPS,
376
+ API_KEY_SCOPE_LABELS,
377
+ API_KEY_SCOPES,
378
+ dedupeApiKeyScopes,
379
+ expandApiKeyScopes,
380
+ isApiKeyGranularScope,
381
+ isApiKeyPresetScope,
382
+ satisfiesApiKeyScope,
383
+ } from './apiKeyScopes.ts'
384
+ export type { ApiKeyGranularScope, ApiKeyPresetScope, ApiKeyScope } from './apiKeyScopes.ts'
324
385
 
325
386
  export {
326
387
  agentRunSchema,
package/src/list.ts CHANGED
@@ -22,13 +22,6 @@ export interface List extends RecordTimestamps {
22
22
  readonly description: string | null
23
23
  readonly targetType: RecordTargetType
24
24
  readonly memberCount: number
25
- /**
26
- * The consent purpose captured when a form submit adds a person to this
27
- * list. Person lists only. Manual and API list adds capture nothing.
28
- */
29
- readonly consentPurposeId: string | null
30
- /** The named purpose's slug, denormalised so a reader needs no second call. */
31
- readonly consentPurposeSlug: string | null
32
25
  }
33
26
 
34
27
  export const listSchema: z.ZodType<List, unknown> = z
@@ -38,8 +31,6 @@ export const listSchema: z.ZodType<List, unknown> = z
38
31
  description: z.string().nullable(),
39
32
  target_type: z.enum(RECORD_TARGET_TYPES),
40
33
  member_count: z.number().int().nonnegative(),
41
- consent_purpose_id: idSchema.nullable(),
42
- consent_purpose_slug: z.string().nullable(),
43
34
  ...recordTimestamps,
44
35
  })
45
36
  .transform(
@@ -49,8 +40,6 @@ export const listSchema: z.ZodType<List, unknown> = z
49
40
  description: wire.description,
50
41
  targetType: wire.target_type,
51
42
  memberCount: wire.member_count,
52
- consentPurposeId: wire.consent_purpose_id,
53
- consentPurposeSlug: wire.consent_purpose_slug,
54
43
  createdAt: wire.created_at,
55
44
  updatedAt: wire.updated_at,
56
45
  }),
@@ -60,8 +49,6 @@ export interface CreateListInput {
60
49
  readonly name: string
61
50
  readonly targetType: RecordTargetType
62
51
  readonly description?: string | null
63
- /** Person lists only. `null` on a company list is fine; a non-null value is `422`. */
64
- readonly consentPurposeId?: string | null
65
52
  }
66
53
 
67
54
  export function createListBody(input: CreateListInput): Record<string, unknown> {
@@ -69,7 +56,6 @@ export function createListBody(input: CreateListInput): Record<string, unknown>
69
56
  name: input.name,
70
57
  target_type: input.targetType,
71
58
  description: input.description,
72
- consent_purpose_id: input.consentPurposeId,
73
59
  })
74
60
  }
75
61
 
@@ -77,13 +63,11 @@ export function createListBody(input: CreateListInput): Record<string, unknown>
77
63
  export interface ListInput {
78
64
  readonly name?: string
79
65
  readonly description?: string | null
80
- readonly consentPurposeId?: string | null
81
66
  }
82
67
 
83
68
  export function listBody(input: ListInput): Record<string, unknown> {
84
69
  return definedFields({
85
70
  name: input.name,
86
71
  description: input.description,
87
- consent_purpose_id: input.consentPurposeId,
88
72
  })
89
73
  }
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import { convertedToWireSchema } from './conversion.ts'
4
+ import type { ConvertedTo } from './conversion.ts'
3
5
  import { customFieldValuesBody, customFieldValuesSchema } from './customField.ts'
4
6
  import type { CustomFieldValue, CustomFieldValues } from './customField.ts'
5
7
  import { definedFields, idSchema, recordTimestamps } from './wire.ts'
@@ -21,6 +23,8 @@ export interface Opportunity extends RecordTimestamps {
21
23
  readonly personIds: readonly string[]
22
24
  readonly summary: string
23
25
  readonly tags: readonly string[]
26
+ /** Non-null once this record has been converted to another pipeline type. */
27
+ readonly convertedTo: ConvertedTo | null
24
28
  /** Workspace-defined fields, keyed by definition key. Always present (default `{}`). */
25
29
  readonly customFields: CustomFieldValues
26
30
  }
@@ -37,6 +41,7 @@ export const opportunitySchema: z.ZodType<Opportunity, unknown> = z
37
41
  person_ids: z.array(idSchema),
38
42
  summary: z.string(),
39
43
  tags: z.array(z.string()),
44
+ converted_to: convertedToWireSchema,
40
45
  custom_fields: customFieldValuesSchema,
41
46
  ...recordTimestamps,
42
47
  })
@@ -52,6 +57,10 @@ export const opportunitySchema: z.ZodType<Opportunity, unknown> = z
52
57
  personIds: wire.person_ids,
53
58
  summary: wire.summary,
54
59
  tags: wire.tags,
60
+ convertedTo:
61
+ wire.converted_to === null
62
+ ? null
63
+ : { targetType: wire.converted_to.target_type, targetId: wire.converted_to.target_id },
55
64
  customFields: wire.custom_fields,
56
65
  createdAt: wire.created_at,
57
66
  updatedAt: wire.updated_at,
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import { convertedToWireSchema } from './conversion.ts'
4
+ import type { ConvertedTo } from './conversion.ts'
3
5
  import { customFieldValuesBody, customFieldValuesSchema } from './customField.ts'
4
6
  import type { CustomFieldValue, CustomFieldValues } from './customField.ts'
5
7
  import { definedFields, idSchema, recordTimestamps } from './wire.ts'
@@ -23,6 +25,8 @@ export interface Partnership extends RecordTimestamps {
23
25
  readonly personIds: readonly string[]
24
26
  readonly summary: string
25
27
  readonly tags: readonly string[]
28
+ /** Non-null once this record has been converted to another pipeline type. */
29
+ readonly convertedTo: ConvertedTo | null
26
30
  /** Workspace-defined fields, keyed by definition key. Always present (default `{}`). */
27
31
  readonly customFields: CustomFieldValues
28
32
  }
@@ -41,6 +45,7 @@ export const partnershipSchema: z.ZodType<Partnership, unknown> = z
41
45
  person_ids: z.array(idSchema),
42
46
  summary: z.string(),
43
47
  tags: z.array(z.string()),
48
+ converted_to: convertedToWireSchema,
44
49
  custom_fields: customFieldValuesSchema,
45
50
  ...recordTimestamps,
46
51
  })
@@ -58,6 +63,10 @@ export const partnershipSchema: z.ZodType<Partnership, unknown> = z
58
63
  personIds: wire.person_ids,
59
64
  summary: wire.summary,
60
65
  tags: wire.tags,
66
+ convertedTo:
67
+ wire.converted_to === null
68
+ ? null
69
+ : { targetType: wire.converted_to.target_type, targetId: wire.converted_to.target_id },
61
70
  customFields: wire.custom_fields,
62
71
  createdAt: wire.created_at,
63
72
  updatedAt: wire.updated_at,
package/src/raise.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import { convertedToWireSchema } from './conversion.ts'
4
+ import type { ConvertedTo } from './conversion.ts'
3
5
  import { customFieldValuesBody, customFieldValuesSchema } from './customField.ts'
4
6
  import type { CustomFieldValue, CustomFieldValues } from './customField.ts'
5
7
  import { definedFields, idSchema, recordTimestamps } from './wire.ts'
@@ -24,6 +26,8 @@ export interface Raise extends RecordTimestamps {
24
26
  readonly personIds: readonly string[]
25
27
  readonly summary: string
26
28
  readonly tags: readonly string[]
29
+ /** Non-null once this record has been converted to another pipeline type. */
30
+ readonly convertedTo: ConvertedTo | null
27
31
  /** Workspace-defined fields, keyed by definition key. Always present (default `{}`). */
28
32
  readonly customFields: CustomFieldValues
29
33
  }
@@ -43,6 +47,7 @@ export const raiseSchema: z.ZodType<Raise, unknown> = z
43
47
  person_ids: z.array(idSchema),
44
48
  summary: z.string(),
45
49
  tags: z.array(z.string()),
50
+ converted_to: convertedToWireSchema,
46
51
  custom_fields: customFieldValuesSchema,
47
52
  ...recordTimestamps,
48
53
  })
@@ -61,6 +66,10 @@ export const raiseSchema: z.ZodType<Raise, unknown> = z
61
66
  personIds: wire.person_ids,
62
67
  summary: wire.summary,
63
68
  tags: wire.tags,
69
+ convertedTo:
70
+ wire.converted_to === null
71
+ ? null
72
+ : { targetType: wire.converted_to.target_type, targetId: wire.converted_to.target_id },
64
73
  customFields: wire.custom_fields,
65
74
  createdAt: wire.created_at,
66
75
  updatedAt: wire.updated_at,
package/src/session.ts CHANGED
@@ -68,8 +68,6 @@ export interface Workspace {
68
68
  readonly name: string
69
69
  readonly slug: string
70
70
  readonly timezone: string
71
- readonly tagline: string | null
72
- readonly oneLiner: string | null
73
71
  }
74
72
 
75
73
  export const workspaceSchema: z.ZodType<Workspace, unknown> = z
@@ -78,8 +76,6 @@ export const workspaceSchema: z.ZodType<Workspace, unknown> = z
78
76
  name: z.string(),
79
77
  slug: z.string(),
80
78
  timezone: z.string(),
81
- tagline: z.string().nullable(),
82
- one_liner: z.string().nullable(),
83
79
  })
84
80
  .transform(
85
81
  (wire): Workspace => ({
@@ -87,8 +83,6 @@ export const workspaceSchema: z.ZodType<Workspace, unknown> = z
87
83
  name: wire.name,
88
84
  slug: wire.slug,
89
85
  timezone: wire.timezone,
90
- tagline: wire.tagline,
91
- oneLiner: wire.one_liner,
92
86
  }),
93
87
  )
94
88
 
@@ -102,19 +96,11 @@ export function createWorkspaceBody(input: CreateWorkspaceInput): Record<string,
102
96
  return { name: input.name, slug: input.slug, timezone: input.timezone }
103
97
  }
104
98
 
105
- /**
106
- * Settings a workspace admin can change.
107
- *
108
- * `tagline` and `oneLiner` are the two strings an agent reads to say who this
109
- * company is, so `null` clears them and `undefined` leaves them alone, per
110
- * `api.md`. `definedFields` is what keeps those two apart on the wire.
111
- */
99
+ /** Settings a workspace admin can change. */
112
100
  export interface UpdateWorkspaceInput {
113
101
  readonly name?: string
114
102
  readonly slug?: string
115
103
  readonly timezone?: string
116
- readonly tagline?: string | null
117
- readonly oneLiner?: string | null
118
104
  }
119
105
 
120
106
  export function updateWorkspaceBody(input: UpdateWorkspaceInput): Record<string, unknown> {
@@ -122,8 +108,6 @@ export function updateWorkspaceBody(input: UpdateWorkspaceInput): Record<string,
122
108
  name: input.name,
123
109
  slug: input.slug,
124
110
  timezone: input.timezone,
125
- tagline: input.tagline,
126
- one_liner: input.oneLiner,
127
111
  })
128
112
  }
129
113
 
package/src/values.ts CHANGED
@@ -356,6 +356,7 @@ export const FORM_FIELD_MAP_TARGETS = [
356
356
  'person.first_name',
357
357
  'person.last_name',
358
358
  'person.email',
359
+ 'person.phones',
359
360
  'person.consent',
360
361
  'company.name',
361
362
  'company.domain',
@@ -367,13 +368,17 @@ export const FORM_FIELD_MAP_TARGETS = [
367
368
  'submission',
368
369
  ] as const
369
370
 
370
- export type FormFieldMapTarget = (typeof FORM_FIELD_MAP_TARGETS)[number]
371
+ /** Any valid form map target string. See `formMapTargets.ts` for the full catalog. */
372
+ export type FormFieldMapTarget = string
371
373
 
372
- export const FORM_FIELD_MAP_TARGET_LABELS: Readonly<Record<FormFieldMapTarget, string>> = {
374
+ export const FORM_FIELD_MAP_TARGET_LABELS: Readonly<
375
+ Record<(typeof FORM_FIELD_MAP_TARGETS)[number], string>
376
+ > = {
373
377
  'person.name': 'Person · name',
374
378
  'person.first_name': 'Person · first name',
375
379
  'person.last_name': 'Person · last name',
376
380
  'person.email': 'Person · email',
381
+ 'person.phones': 'Person · phone',
377
382
  'person.consent': 'Person · consent',
378
383
  'company.name': 'Company · name',
379
384
  'company.domain': 'Company · domain',