@kelpie/schemas 0.1.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/LICENSE +661 -0
- package/README.md +33 -0
- package/dist/account.d.ts +79 -0
- package/dist/account.d.ts.map +1 -0
- package/dist/account.js +66 -0
- package/dist/account.js.map +1 -0
- package/dist/activity.d.ts +23 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +27 -0
- package/dist/activity.js.map +1 -0
- package/dist/agentTask.d.ts +97 -0
- package/dist/agentTask.d.ts.map +1 -0
- package/dist/agentTask.js +127 -0
- package/dist/agentTask.js.map +1 -0
- package/dist/candidate.d.ts +39 -0
- package/dist/candidate.d.ts.map +1 -0
- package/dist/candidate.js +40 -0
- package/dist/candidate.js.map +1 -0
- package/dist/company.d.ts +38 -0
- package/dist/company.d.ts.map +1 -0
- package/dist/company.js +57 -0
- package/dist/company.js.map +1 -0
- package/dist/dashboard.d.ts +112 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +165 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/deal.d.ts +40 -0
- package/dist/deal.d.ts.map +1 -0
- package/dist/deal.js +59 -0
- package/dist/deal.js.map +1 -0
- package/dist/decision.d.ts +46 -0
- package/dist/decision.d.ts.map +1 -0
- package/dist/decision.js +48 -0
- package/dist/decision.js.map +1 -0
- package/dist/form.d.ts +97 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +98 -0
- package/dist/form.js.map +1 -0
- package/dist/formSubmission.d.ts +47 -0
- package/dist/formSubmission.d.ts.map +1 -0
- package/dist/formSubmission.js +47 -0
- package/dist/formSubmission.js.map +1 -0
- package/dist/handbookPage.d.ts +52 -0
- package/dist/handbookPage.d.ts.map +1 -0
- package/dist/handbookPage.js +56 -0
- package/dist/handbookPage.js.map +1 -0
- package/dist/importExport.d.ts +143 -0
- package/dist/importExport.d.ts.map +1 -0
- package/dist/importExport.js +239 -0
- package/dist/importExport.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/invite.d.ts +35 -0
- package/dist/invite.d.ts.map +1 -0
- package/dist/invite.js +31 -0
- package/dist/invite.js.map +1 -0
- package/dist/mcpTool.d.ts +26 -0
- package/dist/mcpTool.d.ts.map +1 -0
- package/dist/mcpTool.js +13 -0
- package/dist/mcpTool.js.map +1 -0
- package/dist/member.d.ts +26 -0
- package/dist/member.d.ts.map +1 -0
- package/dist/member.js +24 -0
- package/dist/member.js.map +1 -0
- package/dist/moduleSetting.d.ts +19 -0
- package/dist/moduleSetting.d.ts.map +1 -0
- package/dist/moduleSetting.js +16 -0
- package/dist/moduleSetting.js.map +1 -0
- package/dist/note.d.ts +34 -0
- package/dist/note.d.ts.map +1 -0
- package/dist/note.js +35 -0
- package/dist/note.js.map +1 -0
- package/dist/opportunity.d.ts +30 -0
- package/dist/opportunity.d.ts.map +1 -0
- package/dist/opportunity.js +41 -0
- package/dist/opportunity.js.map +1 -0
- package/dist/partnership.d.ts +36 -0
- package/dist/partnership.d.ts.map +1 -0
- package/dist/partnership.js +50 -0
- package/dist/partnership.js.map +1 -0
- package/dist/person.d.ts +45 -0
- package/dist/person.d.ts.map +1 -0
- package/dist/person.js +60 -0
- package/dist/person.js.map +1 -0
- package/dist/pipelineStage.d.ts +29 -0
- package/dist/pipelineStage.d.ts.map +1 -0
- package/dist/pipelineStage.js +38 -0
- package/dist/pipelineStage.js.map +1 -0
- package/dist/planItem.d.ts +43 -0
- package/dist/planItem.d.ts.map +1 -0
- package/dist/planItem.js +44 -0
- package/dist/planItem.js.map +1 -0
- package/dist/position.d.ts +22 -0
- package/dist/position.d.ts.map +1 -0
- package/dist/position.js +25 -0
- package/dist/position.js.map +1 -0
- package/dist/raise.d.ts +38 -0
- package/dist/raise.d.ts.map +1 -0
- package/dist/raise.js +53 -0
- package/dist/raise.js.map +1 -0
- package/dist/role.d.ts +21 -0
- package/dist/role.d.ts.map +1 -0
- package/dist/role.js +21 -0
- package/dist/role.js.map +1 -0
- package/dist/search.d.ts +41 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +41 -0
- package/dist/search.js.map +1 -0
- package/dist/session.d.ts +92 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +67 -0
- package/dist/session.js.map +1 -0
- package/dist/values.d.ts +216 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +329 -0
- package/dist/values.js.map +1 -0
- package/dist/webhook.d.ts +85 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +75 -0
- package/dist/webhook.js.map +1 -0
- package/dist/wire.d.ts +40 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +40 -0
- package/dist/wire.js.map +1 -0
- package/package.json +51 -0
- package/src/account.ts +149 -0
- package/src/activity.ts +52 -0
- package/src/agentTask.ts +254 -0
- package/src/candidate.ts +83 -0
- package/src/company.ts +98 -0
- package/src/dashboard.ts +307 -0
- package/src/deal.ts +102 -0
- package/src/decision.ts +106 -0
- package/src/form.ts +217 -0
- package/src/formSubmission.ts +99 -0
- package/src/handbookPage.ts +99 -0
- package/src/importExport.ts +339 -0
- package/src/index.ts +324 -0
- package/src/invite.ts +69 -0
- package/src/mcpTool.ts +32 -0
- package/src/member.ts +53 -0
- package/src/moduleSetting.ts +37 -0
- package/src/note.ts +73 -0
- package/src/opportunity.ts +74 -0
- package/src/partnership.ts +89 -0
- package/src/person.ts +116 -0
- package/src/pipelineStage.ts +71 -0
- package/src/planItem.ts +91 -0
- package/src/position.ts +50 -0
- package/src/raise.ts +94 -0
- package/src/role.ts +45 -0
- package/src/search.ts +86 -0
- package/src/session.ts +177 -0
- package/src/values.ts +427 -0
- package/src/webhook.ts +164 -0
- package/src/wire.ts +51 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import { idSchema, recordTimestamps } from './wire.ts'
|
|
4
|
+
import type { RecordTimestamps } from './wire.ts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Wire shapes and shared catalogues for `/v1/import` and `/v1/export`, per
|
|
8
|
+
* `import-export.md`.
|
|
9
|
+
*
|
|
10
|
+
* The column catalogue lives here rather than in the server module because both
|
|
11
|
+
* ends need it: the server validates a row against it, and the browser renders
|
|
12
|
+
* the mapping table from it. The source presets do not, so they stay server-side
|
|
13
|
+
* — a caller sends a `column_map` and never has to know how one was derived.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const IMPORT_SOURCES = ['custom', 'hubspot', 'salesforce'] as const
|
|
17
|
+
export const IMPORT_OBJECTS = ['companies', 'people', 'positions', 'deals'] as const
|
|
18
|
+
export const IMPORT_CONFLICT_MODES = ['skip', 'update'] as const
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* `pending → validating → ready | failed → committing → completed | failed`.
|
|
22
|
+
*
|
|
23
|
+
* `pending` is the moment between the row insert and the dry run starting. A
|
|
24
|
+
* synchronous job passes through it inside one request and is never observed
|
|
25
|
+
* there; an asynchronous one can be.
|
|
26
|
+
*/
|
|
27
|
+
export const IMPORT_JOB_STATUSES = [
|
|
28
|
+
'pending',
|
|
29
|
+
'validating',
|
|
30
|
+
'ready',
|
|
31
|
+
'committing',
|
|
32
|
+
'completed',
|
|
33
|
+
'failed',
|
|
34
|
+
] as const
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* What a dry run forecasts for a row, and what a commit records against it.
|
|
38
|
+
*
|
|
39
|
+
* `pending` is a row that has been stored but not yet planned, which is what
|
|
40
|
+
* every row of an asynchronous job is until its validation pass reaches it. The
|
|
41
|
+
* counts only ever hold the four settled actions.
|
|
42
|
+
*/
|
|
43
|
+
export const IMPORT_ROW_ACTIONS = ['pending', 'create', 'update', 'skip', 'error'] as const
|
|
44
|
+
|
|
45
|
+
export type ImportSource = (typeof IMPORT_SOURCES)[number]
|
|
46
|
+
export type ImportObject = (typeof IMPORT_OBJECTS)[number]
|
|
47
|
+
export type ImportConflictMode = (typeof IMPORT_CONFLICT_MODES)[number]
|
|
48
|
+
export type ImportJobStatus = (typeof IMPORT_JOB_STATUSES)[number]
|
|
49
|
+
export type ImportRowAction = (typeof IMPORT_ROW_ACTIONS)[number]
|
|
50
|
+
|
|
51
|
+
/** A row that has been planned. What a dry run and a commit both write back. */
|
|
52
|
+
export type SettledRowAction = Exclude<ImportRowAction, 'pending'>
|
|
53
|
+
|
|
54
|
+
/** Limits from `import-export.md`. Placeholders until billing exists. */
|
|
55
|
+
export const MAX_IMPORT_FILE_BYTES = 10 * 1024 * 1024
|
|
56
|
+
export const MAX_IMPORT_ROWS = 10_000
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Above this many rows a job validates and commits in the background, and the
|
|
60
|
+
* request answers `202` with the job in a transient status. The caller polls
|
|
61
|
+
* `GET /v1/import/jobs/{id}`.
|
|
62
|
+
*/
|
|
63
|
+
export const SYNC_IMPORT_ROWS = 500
|
|
64
|
+
|
|
65
|
+
/** Mapped rows returned with a job, so a caller can check the mapping before committing. */
|
|
66
|
+
export const IMPORT_PREVIEW_ROWS = 5
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Row errors carried on the job body. `counts.error` is the true total, so a
|
|
70
|
+
* truncated list is visible rather than mistaken for the whole story.
|
|
71
|
+
*/
|
|
72
|
+
export const IMPORT_REPORTED_ERRORS = 50
|
|
73
|
+
|
|
74
|
+
export const OBJECT_LABELS: Readonly<Record<ImportObject, string>> = {
|
|
75
|
+
companies: 'Companies',
|
|
76
|
+
people: 'People',
|
|
77
|
+
positions: 'Positions',
|
|
78
|
+
deals: 'Deals',
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const SOURCE_LABELS: Readonly<Record<ImportSource, string>> = {
|
|
82
|
+
custom: 'Custom CSV',
|
|
83
|
+
hubspot: 'HubSpot CSV pack',
|
|
84
|
+
salesforce: 'Salesforce CSV pack',
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const CONFLICT_MODE_LABELS: Readonly<Record<ImportConflictMode, string>> = {
|
|
88
|
+
skip: 'Skip existing',
|
|
89
|
+
update: 'Update existing',
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface CsvColumn {
|
|
93
|
+
/** The Kelpie CSV header, and the key a `column_map` is keyed by. */
|
|
94
|
+
readonly key: string
|
|
95
|
+
readonly label: string
|
|
96
|
+
readonly required: boolean
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The canonical Kelpie CSV columns per object (`import-export.md`).
|
|
101
|
+
*
|
|
102
|
+
* Order is the header order of an export and of a template, so a file Kelpie
|
|
103
|
+
* wrote maps onto itself by exact header match with no preset involved.
|
|
104
|
+
*
|
|
105
|
+
* Job title is absent from Person on purpose: it lives on Position, which is
|
|
106
|
+
* what the contact title in a HubSpot or Salesforce export maps to.
|
|
107
|
+
*/
|
|
108
|
+
export const OBJECT_COLUMNS: Readonly<Record<ImportObject, readonly CsvColumn[]>> = {
|
|
109
|
+
companies: [
|
|
110
|
+
{ key: 'name', label: 'Name', required: true },
|
|
111
|
+
{ key: 'domain', label: 'Domain', required: true },
|
|
112
|
+
{ key: 'industry', label: 'Industry', required: false },
|
|
113
|
+
{ key: 'stage', label: 'Stage', required: false },
|
|
114
|
+
{ key: 'size_band', label: 'Size band', required: false },
|
|
115
|
+
{ key: 'account_type', label: 'Account type', required: false },
|
|
116
|
+
{ key: 'icp_fit', label: 'ICP fit', required: false },
|
|
117
|
+
{ key: 'description', label: 'Description', required: false },
|
|
118
|
+
{ key: 'summary', label: 'Summary', required: false },
|
|
119
|
+
{ key: 'tags', label: 'Tags', required: false },
|
|
120
|
+
{ key: 'website', label: 'Website', required: false },
|
|
121
|
+
{ key: 'hq', label: 'HQ', required: false },
|
|
122
|
+
],
|
|
123
|
+
people: [
|
|
124
|
+
{ key: 'name', label: 'Name', required: true },
|
|
125
|
+
{ key: 'email', label: 'Email', required: true },
|
|
126
|
+
{ key: 'timezone', label: 'Timezone', required: false },
|
|
127
|
+
{ key: 'location', label: 'Location', required: false },
|
|
128
|
+
{ key: 'preferred_channel', label: 'Preferred channel', required: false },
|
|
129
|
+
{ key: 'influence', label: 'Influence', required: false },
|
|
130
|
+
{ key: 'relationship', label: 'Relationship', required: false },
|
|
131
|
+
{ key: 'summary', label: 'Summary', required: false },
|
|
132
|
+
{ key: 'tags', label: 'Tags', required: false },
|
|
133
|
+
{ key: 'phones', label: 'Phones', required: false },
|
|
134
|
+
],
|
|
135
|
+
positions: [
|
|
136
|
+
{ key: 'person_email', label: 'Person email', required: true },
|
|
137
|
+
{ key: 'company_domain', label: 'Company domain', required: true },
|
|
138
|
+
{ key: 'title', label: 'Title', required: true },
|
|
139
|
+
],
|
|
140
|
+
deals: [
|
|
141
|
+
{ key: 'name', label: 'Name', required: true },
|
|
142
|
+
{ key: 'company_domain', label: 'Company domain', required: true },
|
|
143
|
+
{ key: 'stage', label: 'Stage', required: true },
|
|
144
|
+
{ key: 'value', label: 'Value', required: true },
|
|
145
|
+
{ key: 'owner_email', label: 'Owner email', required: false },
|
|
146
|
+
{ key: 'expected_close', label: 'Expected close', required: false },
|
|
147
|
+
{ key: 'person_emails', label: 'Person emails', required: false },
|
|
148
|
+
{ key: 'competitors', label: 'Competitors', required: false },
|
|
149
|
+
{ key: 'risks', label: 'Risks', required: false },
|
|
150
|
+
{ key: 'why_win', label: 'Why we win', required: false },
|
|
151
|
+
{ key: 'summary', label: 'Summary', required: false },
|
|
152
|
+
{ key: 'tags', label: 'Tags', required: false },
|
|
153
|
+
{ key: 'external_id', label: 'External id', required: false },
|
|
154
|
+
],
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Columns whose value is a pipe-separated list (`a|b|c`), per `import-export.md`. */
|
|
158
|
+
export const LIST_COLUMNS: ReadonlySet<string> = new Set([
|
|
159
|
+
'tags',
|
|
160
|
+
'phones',
|
|
161
|
+
'competitors',
|
|
162
|
+
'person_emails',
|
|
163
|
+
'tech_stack',
|
|
164
|
+
])
|
|
165
|
+
|
|
166
|
+
export interface MatchKeyOption {
|
|
167
|
+
/** The `match_key` a request sends. Composite keys join their columns with `|`. */
|
|
168
|
+
readonly id: string
|
|
169
|
+
readonly label: string
|
|
170
|
+
/** Kelpie columns the key is built from. Every one must be mapped and non-empty. */
|
|
171
|
+
readonly columns: readonly string[]
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Selectable match keys per object. The first of each list is the default. */
|
|
175
|
+
export const MATCH_KEYS: Readonly<Record<ImportObject, readonly MatchKeyOption[]>> = {
|
|
176
|
+
companies: [
|
|
177
|
+
{ id: 'domain', label: 'domain', columns: ['domain'] },
|
|
178
|
+
{ id: 'name', label: 'name', columns: ['name'] },
|
|
179
|
+
],
|
|
180
|
+
people: [{ id: 'email', label: 'email', columns: ['email'] }],
|
|
181
|
+
positions: [
|
|
182
|
+
{
|
|
183
|
+
id: 'person_email|company_domain|title',
|
|
184
|
+
label: 'person_email + company_domain + title',
|
|
185
|
+
columns: ['person_email', 'company_domain', 'title'],
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'person_email|company_domain',
|
|
189
|
+
label: 'person_email + company_domain',
|
|
190
|
+
columns: ['person_email', 'company_domain'],
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
deals: [
|
|
194
|
+
{ id: 'external_id', label: 'external_id', columns: ['external_id'] },
|
|
195
|
+
{
|
|
196
|
+
id: 'name|company_domain',
|
|
197
|
+
label: 'name + company_domain',
|
|
198
|
+
columns: ['name', 'company_domain'],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function defaultMatchKeyId(object: ImportObject): string {
|
|
204
|
+
const [first] = MATCH_KEYS[object]
|
|
205
|
+
|
|
206
|
+
if (first === undefined) {
|
|
207
|
+
throw new Error(`No match keys declared for ${object}`)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return first.id
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** @returns The named key, or undefined when no such key exists for this object. */
|
|
214
|
+
export function findMatchKey(object: ImportObject, matchKeyId: string): MatchKeyOption | undefined {
|
|
215
|
+
return MATCH_KEYS[object].find((key) => key.id === matchKeyId)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Kelpie columns a job must have mapped: the object's required ones plus every
|
|
220
|
+
* column the chosen match key is built from.
|
|
221
|
+
*/
|
|
222
|
+
export function requiredColumns(object: ImportObject, matchKey: MatchKeyOption): readonly string[] {
|
|
223
|
+
const required = OBJECT_COLUMNS[object].filter((column) => column.required).map((c) => c.key)
|
|
224
|
+
|
|
225
|
+
return [...new Set([...required, ...matchKey.columns])]
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface ImportRowError {
|
|
229
|
+
/** The line in the file, counting the header as line 1. */
|
|
230
|
+
readonly row: number
|
|
231
|
+
readonly field: string
|
|
232
|
+
readonly message: string
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export interface ImportCounts {
|
|
236
|
+
readonly total: number
|
|
237
|
+
readonly create: number
|
|
238
|
+
readonly update: number
|
|
239
|
+
readonly skip: number
|
|
240
|
+
readonly error: number
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** A mapped row as Kelpie read it, for checking a column map before committing. */
|
|
244
|
+
export interface ImportPreviewRow {
|
|
245
|
+
readonly row: number
|
|
246
|
+
readonly action: ImportRowAction
|
|
247
|
+
/** Kelpie column → value, for the mapped columns only. */
|
|
248
|
+
readonly values: Readonly<Record<string, string>>
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* A `column_map`: Kelpie column → source header, or null to ignore the column.
|
|
253
|
+
*
|
|
254
|
+
* A key absent from the map means the same as null. Both are the ordinary way to
|
|
255
|
+
* say a file has no such column.
|
|
256
|
+
*/
|
|
257
|
+
export type ImportColumnMap = Readonly<Record<string, string | null>>
|
|
258
|
+
|
|
259
|
+
export interface ImportJob extends RecordTimestamps {
|
|
260
|
+
readonly id: string
|
|
261
|
+
readonly source: ImportSource
|
|
262
|
+
readonly object: ImportObject
|
|
263
|
+
readonly status: ImportJobStatus
|
|
264
|
+
readonly conflictMode: ImportConflictMode
|
|
265
|
+
readonly matchKey: string
|
|
266
|
+
readonly columnMap: ImportColumnMap
|
|
267
|
+
/** The headers as they appeared in the uploaded file, in file order. */
|
|
268
|
+
readonly sourceHeaders: readonly string[]
|
|
269
|
+
readonly fileName: string | null
|
|
270
|
+
readonly counts: ImportCounts
|
|
271
|
+
/** At most `IMPORT_REPORTED_ERRORS`. `counts.error` is the true number of failing rows. */
|
|
272
|
+
readonly errors: readonly ImportRowError[]
|
|
273
|
+
readonly preview: readonly ImportPreviewRow[]
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const countsSchema = z.object({
|
|
277
|
+
total: z.number().int(),
|
|
278
|
+
create: z.number().int(),
|
|
279
|
+
update: z.number().int(),
|
|
280
|
+
skip: z.number().int(),
|
|
281
|
+
error: z.number().int(),
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
const rowErrorSchema = z.object({
|
|
285
|
+
row: z.number().int(),
|
|
286
|
+
field: z.string(),
|
|
287
|
+
message: z.string(),
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
const previewRowSchema = z.object({
|
|
291
|
+
row: z.number().int(),
|
|
292
|
+
action: z.enum(IMPORT_ROW_ACTIONS),
|
|
293
|
+
values: z.record(z.string(), z.string()),
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* `workspace_id` is not on this body, unlike the sample in `import-export.md`.
|
|
298
|
+
* `api.md` makes the workspace implicit on every endpoint and no other resource
|
|
299
|
+
* returns it; one that did would be the odd one out for no gain.
|
|
300
|
+
*/
|
|
301
|
+
export const importJobSchema: z.ZodType<ImportJob, unknown> = z
|
|
302
|
+
.object({
|
|
303
|
+
id: idSchema,
|
|
304
|
+
source: z.enum(IMPORT_SOURCES),
|
|
305
|
+
object: z.enum(IMPORT_OBJECTS),
|
|
306
|
+
status: z.enum(IMPORT_JOB_STATUSES),
|
|
307
|
+
conflict_mode: z.enum(IMPORT_CONFLICT_MODES),
|
|
308
|
+
match_key: z.string(),
|
|
309
|
+
column_map: z.record(z.string(), z.string().nullable()),
|
|
310
|
+
source_headers: z.array(z.string()),
|
|
311
|
+
file_name: z.string().nullable(),
|
|
312
|
+
counts: countsSchema,
|
|
313
|
+
errors: z.array(rowErrorSchema),
|
|
314
|
+
preview: z.array(previewRowSchema),
|
|
315
|
+
...recordTimestamps,
|
|
316
|
+
})
|
|
317
|
+
.transform(
|
|
318
|
+
(wire): ImportJob => ({
|
|
319
|
+
id: wire.id,
|
|
320
|
+
source: wire.source,
|
|
321
|
+
object: wire.object,
|
|
322
|
+
status: wire.status,
|
|
323
|
+
conflictMode: wire.conflict_mode,
|
|
324
|
+
matchKey: wire.match_key,
|
|
325
|
+
columnMap: wire.column_map,
|
|
326
|
+
sourceHeaders: wire.source_headers,
|
|
327
|
+
fileName: wire.file_name,
|
|
328
|
+
counts: wire.counts,
|
|
329
|
+
errors: wire.errors,
|
|
330
|
+
preview: wire.preview,
|
|
331
|
+
createdAt: wire.created_at,
|
|
332
|
+
updatedAt: wire.updated_at,
|
|
333
|
+
}),
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
/** Statuses a job will not move on from without another request. */
|
|
337
|
+
export function isImportJobSettled(status: ImportJobStatus): boolean {
|
|
338
|
+
return status === 'ready' || status === 'completed' || status === 'failed'
|
|
339
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@kelpie/schemas` — the wire contract for `/v1`, as Zod schemas.
|
|
3
|
+
*
|
|
4
|
+
* Roadmap decision 8: the UI decodes API responses with Zod, and a schema's
|
|
5
|
+
* `.parse` is already the `Decoder<T>` the API client takes. These schemas live
|
|
6
|
+
* in their own package because `@kelpie/ui` must not import `@kelpie/server`;
|
|
7
|
+
* that would put Drizzle, postgres.js, and Node built-ins in the browser bundle.
|
|
8
|
+
* The dependency list here is Zod and nothing else, which is also what makes the
|
|
9
|
+
* package usable from the cloud repo.
|
|
10
|
+
*
|
|
11
|
+
* Each resource module holds three things: the record the UI works with, a
|
|
12
|
+
* schema that parses the `snake_case` response into it, and a function that
|
|
13
|
+
* builds a request body back out of it.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
ACCOUNT_TYPES,
|
|
18
|
+
ACTIVITY_KINDS,
|
|
19
|
+
AGENT_RUN_STATUS_LABELS,
|
|
20
|
+
AGENT_RUN_STATUSES,
|
|
21
|
+
AGENT_TASK_PLACEMENTS,
|
|
22
|
+
AGENT_TASK_TARGET_TYPES,
|
|
23
|
+
CANDIDATE_STATUS_LABELS,
|
|
24
|
+
CANDIDATE_STATUSES,
|
|
25
|
+
COMPANY_STAGES,
|
|
26
|
+
EXTENSIBLE_RECORD_TYPES,
|
|
27
|
+
FIRST_INTERVIEW_STAGE,
|
|
28
|
+
FORM_FIELD_MAP_TARGET_LABELS,
|
|
29
|
+
FORM_FIELD_MAP_TARGETS,
|
|
30
|
+
FORM_FIELD_TYPES,
|
|
31
|
+
FORM_OPTION_VALUE_TYPES,
|
|
32
|
+
FORM_STATUSES,
|
|
33
|
+
ICP_FITS,
|
|
34
|
+
IN_PROCESS,
|
|
35
|
+
INFLUENCE_LEVELS,
|
|
36
|
+
INTERVIEW_STAGE_LABELS,
|
|
37
|
+
INTERVIEW_STAGES,
|
|
38
|
+
INVITABLE_ROLES,
|
|
39
|
+
INVITE_STATUSES,
|
|
40
|
+
MEMBER_ROLES,
|
|
41
|
+
OPEN_PLAN_ITEM_STATUSES,
|
|
42
|
+
PERSON_EMAIL_TARGET,
|
|
43
|
+
PIPELINE_KIND_LABELS,
|
|
44
|
+
PIPELINE_KINDS,
|
|
45
|
+
PLAN_ITEM_STATUS_LABELS,
|
|
46
|
+
PLAN_ITEM_STATUSES,
|
|
47
|
+
PREFERRED_CHANNELS,
|
|
48
|
+
RECORD_TARGET_TYPES,
|
|
49
|
+
RELATIONSHIP_LEVELS,
|
|
50
|
+
ROLE_STATUS_LABELS,
|
|
51
|
+
ROLE_STATUSES,
|
|
52
|
+
SEARCH_COLLECTIONS,
|
|
53
|
+
SIZE_BANDS,
|
|
54
|
+
SOCIAL_NETWORK_IDS,
|
|
55
|
+
SOCIAL_NETWORK_LABELS,
|
|
56
|
+
THEME_PREFERENCES,
|
|
57
|
+
WEBHOOK_DELIVERY_STATUSES,
|
|
58
|
+
WEBHOOK_EVENTS,
|
|
59
|
+
WEBHOOK_SETTABLE_STATUSES,
|
|
60
|
+
WEBHOOK_STATUS_LABELS,
|
|
61
|
+
WEBHOOK_STATUSES,
|
|
62
|
+
} from './values.ts'
|
|
63
|
+
export type {
|
|
64
|
+
AccountType,
|
|
65
|
+
ActivityKind,
|
|
66
|
+
AgentRunStatus,
|
|
67
|
+
AgentTaskPlacement,
|
|
68
|
+
AgentTaskTargetType,
|
|
69
|
+
CandidateStatus,
|
|
70
|
+
CompanyStage,
|
|
71
|
+
ExtensibleRecordType,
|
|
72
|
+
FormFieldMapTarget,
|
|
73
|
+
FormFieldType,
|
|
74
|
+
FormOptionValueType,
|
|
75
|
+
FormStatus,
|
|
76
|
+
IcpFit,
|
|
77
|
+
Influence,
|
|
78
|
+
InterviewStage,
|
|
79
|
+
InvitableRole,
|
|
80
|
+
InviteStatus,
|
|
81
|
+
MemberRole,
|
|
82
|
+
PipelineKind,
|
|
83
|
+
PlanItemStatus,
|
|
84
|
+
PreferredChannel,
|
|
85
|
+
RecordTargetType,
|
|
86
|
+
Relationship,
|
|
87
|
+
RoleStatus,
|
|
88
|
+
SearchCollection,
|
|
89
|
+
SizeBand,
|
|
90
|
+
SocialNetworkId,
|
|
91
|
+
ThemePreference,
|
|
92
|
+
WebhookDeliveryStatus,
|
|
93
|
+
WebhookEvent,
|
|
94
|
+
WebhookSettableStatus,
|
|
95
|
+
WebhookStatus,
|
|
96
|
+
} from './values.ts'
|
|
97
|
+
|
|
98
|
+
export { definedFields, idSchema, nullableTimestampSchema, timestampSchema } from './wire.ts'
|
|
99
|
+
export type { RecordTimestamps } from './wire.ts'
|
|
100
|
+
|
|
101
|
+
export { personBody, personSchema } from './person.ts'
|
|
102
|
+
export type { Person, PersonInput, SocialProfile } from './person.ts'
|
|
103
|
+
|
|
104
|
+
export { companyBody, companySchema } from './company.ts'
|
|
105
|
+
export type { Company, CompanyInput } from './company.ts'
|
|
106
|
+
|
|
107
|
+
export { createPositionBody, positionSchema, updatePositionBody } from './position.ts'
|
|
108
|
+
export type { CreatePositionInput, Position } from './position.ts'
|
|
109
|
+
|
|
110
|
+
export { dealBody, dealSchema } from './deal.ts'
|
|
111
|
+
export type { Deal, DealInput } from './deal.ts'
|
|
112
|
+
|
|
113
|
+
export { opportunityBody, opportunitySchema } from './opportunity.ts'
|
|
114
|
+
export type { Opportunity, OpportunityInput } from './opportunity.ts'
|
|
115
|
+
|
|
116
|
+
export { partnershipBody, partnershipSchema } from './partnership.ts'
|
|
117
|
+
export type { Partnership, PartnershipInput } from './partnership.ts'
|
|
118
|
+
|
|
119
|
+
export { raiseBody, raiseSchema } from './raise.ts'
|
|
120
|
+
export type { Raise, RaiseInput } from './raise.ts'
|
|
121
|
+
|
|
122
|
+
export { roleBody, roleSchema } from './role.ts'
|
|
123
|
+
export type { Role, RoleInput } from './role.ts'
|
|
124
|
+
|
|
125
|
+
export { candidateBody, candidateSchema, createCandidateBody } from './candidate.ts'
|
|
126
|
+
export type { Candidate, CandidateInput, CreateCandidateInput } from './candidate.ts'
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
createPipelineStageBody,
|
|
130
|
+
pipelineStageSchema,
|
|
131
|
+
updatePipelineStageBody,
|
|
132
|
+
} from './pipelineStage.ts'
|
|
133
|
+
export type {
|
|
134
|
+
CreatePipelineStageInput,
|
|
135
|
+
PipelineStage,
|
|
136
|
+
UpdatePipelineStageInput,
|
|
137
|
+
} from './pipelineStage.ts'
|
|
138
|
+
|
|
139
|
+
export { createNoteBody, noteBody, noteSchema } from './note.ts'
|
|
140
|
+
export type { CreateNoteInput, Note, NoteInput } from './note.ts'
|
|
141
|
+
|
|
142
|
+
export { createPlanItemBody, planItemBody, planItemSchema } from './planItem.ts'
|
|
143
|
+
export type { CreatePlanItemInput, PlanItem, PlanItemInput } from './planItem.ts'
|
|
144
|
+
|
|
145
|
+
export { createDecisionBody, decisionBody, decisionSchema } from './decision.ts'
|
|
146
|
+
export type { CreateDecisionInput, Decision, DecisionInput } from './decision.ts'
|
|
147
|
+
|
|
148
|
+
export {
|
|
149
|
+
MAX_HANDBOOK_DEPTH,
|
|
150
|
+
createHandbookPageBody,
|
|
151
|
+
handbookPageBody,
|
|
152
|
+
handbookPageSchema,
|
|
153
|
+
} from './handbookPage.ts'
|
|
154
|
+
export type {
|
|
155
|
+
CreateHandbookPageInput,
|
|
156
|
+
HandbookPage,
|
|
157
|
+
HandbookPageInput,
|
|
158
|
+
} from './handbookPage.ts'
|
|
159
|
+
|
|
160
|
+
export { createFormBody, formBody, formSchema } from './form.ts'
|
|
161
|
+
export type {
|
|
162
|
+
CreateFormInput,
|
|
163
|
+
Form,
|
|
164
|
+
FormField,
|
|
165
|
+
FormFieldInput,
|
|
166
|
+
FormFieldOption,
|
|
167
|
+
FormFieldOptionInput,
|
|
168
|
+
FormInput,
|
|
169
|
+
} from './form.ts'
|
|
170
|
+
|
|
171
|
+
export { formSubmissionSchema, formSubmitResultSchema } from './formSubmission.ts'
|
|
172
|
+
export type { FormSubmission, FormSubmitResult } from './formSubmission.ts'
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
CONFLICT_MODE_LABELS,
|
|
176
|
+
IMPORT_CONFLICT_MODES,
|
|
177
|
+
IMPORT_JOB_STATUSES,
|
|
178
|
+
IMPORT_OBJECTS,
|
|
179
|
+
IMPORT_PREVIEW_ROWS,
|
|
180
|
+
IMPORT_REPORTED_ERRORS,
|
|
181
|
+
IMPORT_ROW_ACTIONS,
|
|
182
|
+
IMPORT_SOURCES,
|
|
183
|
+
LIST_COLUMNS,
|
|
184
|
+
MATCH_KEYS,
|
|
185
|
+
MAX_IMPORT_FILE_BYTES,
|
|
186
|
+
MAX_IMPORT_ROWS,
|
|
187
|
+
OBJECT_COLUMNS,
|
|
188
|
+
OBJECT_LABELS,
|
|
189
|
+
SOURCE_LABELS,
|
|
190
|
+
SYNC_IMPORT_ROWS,
|
|
191
|
+
defaultMatchKeyId,
|
|
192
|
+
findMatchKey,
|
|
193
|
+
importJobSchema,
|
|
194
|
+
isImportJobSettled,
|
|
195
|
+
requiredColumns,
|
|
196
|
+
} from './importExport.ts'
|
|
197
|
+
export type {
|
|
198
|
+
CsvColumn,
|
|
199
|
+
ImportColumnMap,
|
|
200
|
+
ImportConflictMode,
|
|
201
|
+
ImportCounts,
|
|
202
|
+
ImportJob,
|
|
203
|
+
ImportJobStatus,
|
|
204
|
+
ImportObject,
|
|
205
|
+
ImportPreviewRow,
|
|
206
|
+
ImportRowAction,
|
|
207
|
+
ImportRowError,
|
|
208
|
+
ImportSource,
|
|
209
|
+
MatchKeyOption,
|
|
210
|
+
SettledRowAction,
|
|
211
|
+
} from './importExport.ts'
|
|
212
|
+
|
|
213
|
+
export {
|
|
214
|
+
WEBHOOK_SECRET_OVERLAP_HOURS,
|
|
215
|
+
createWebhookBody,
|
|
216
|
+
createdWebhookSchema,
|
|
217
|
+
rotateWebhookSecretBody,
|
|
218
|
+
webhookBody,
|
|
219
|
+
webhookDeliverySchema,
|
|
220
|
+
webhookSchema,
|
|
221
|
+
} from './webhook.ts'
|
|
222
|
+
export type {
|
|
223
|
+
CreateWebhookInput,
|
|
224
|
+
CreatedWebhook,
|
|
225
|
+
RotateWebhookSecretInput,
|
|
226
|
+
Webhook,
|
|
227
|
+
WebhookDelivery,
|
|
228
|
+
WebhookInput,
|
|
229
|
+
} from './webhook.ts'
|
|
230
|
+
|
|
231
|
+
export {
|
|
232
|
+
agentRunSchema,
|
|
233
|
+
agentTaskDefinitionSchema,
|
|
234
|
+
createRegisteredAgentBody,
|
|
235
|
+
registeredAgentBody,
|
|
236
|
+
registeredAgentSchema,
|
|
237
|
+
resolveAgentTaskBody,
|
|
238
|
+
resolvedAgentTaskSchema,
|
|
239
|
+
runAgentTaskBody,
|
|
240
|
+
} from './agentTask.ts'
|
|
241
|
+
export type {
|
|
242
|
+
AgentRun,
|
|
243
|
+
AgentTaskContextPack,
|
|
244
|
+
AgentTaskDefinition,
|
|
245
|
+
CreateRegisteredAgentInput,
|
|
246
|
+
RegisteredAgent,
|
|
247
|
+
RegisteredAgentInput,
|
|
248
|
+
ResolveAgentTaskInput,
|
|
249
|
+
ResolvedAgentTask,
|
|
250
|
+
RunAgentTaskInput,
|
|
251
|
+
} from './agentTask.ts'
|
|
252
|
+
|
|
253
|
+
export { activitySchema } from './activity.ts'
|
|
254
|
+
export type { Activity } from './activity.ts'
|
|
255
|
+
|
|
256
|
+
export { dashboardSchema } from './dashboard.ts'
|
|
257
|
+
export type {
|
|
258
|
+
Dashboard,
|
|
259
|
+
DashboardActivity,
|
|
260
|
+
DashboardDecision,
|
|
261
|
+
DashboardNote,
|
|
262
|
+
DashboardPipeline,
|
|
263
|
+
DashboardPlanItem,
|
|
264
|
+
DashboardSignal,
|
|
265
|
+
DashboardStaleContact,
|
|
266
|
+
DashboardTouchpoint,
|
|
267
|
+
TargetRef,
|
|
268
|
+
} from './dashboard.ts'
|
|
269
|
+
|
|
270
|
+
export { searchResultsSchema } from './search.ts'
|
|
271
|
+
export type { SearchResult, SearchResultGroup, SearchResults } from './search.ts'
|
|
272
|
+
|
|
273
|
+
export { memberSchema, updateMemberRoleBody } from './member.ts'
|
|
274
|
+
export type { Member, UpdateMemberRoleInput } from './member.ts'
|
|
275
|
+
|
|
276
|
+
export { moduleSettingSchema, updateModuleSettingBody } from './moduleSetting.ts'
|
|
277
|
+
export type { ModuleSetting, UpdateModuleSettingInput } from './moduleSetting.ts'
|
|
278
|
+
|
|
279
|
+
export { mcpToolSchema } from './mcpTool.ts'
|
|
280
|
+
export type { McpTool } from './mcpTool.ts'
|
|
281
|
+
|
|
282
|
+
export { createInviteBody, inviteSchema, resendInviteBody } from './invite.ts'
|
|
283
|
+
export type { CreateInviteInput, Invite, ResendInviteInput } from './invite.ts'
|
|
284
|
+
|
|
285
|
+
export {
|
|
286
|
+
confirmPasswordResetBody,
|
|
287
|
+
createWorkspaceBody,
|
|
288
|
+
logInBody,
|
|
289
|
+
requestPasswordResetBody,
|
|
290
|
+
sessionSchema,
|
|
291
|
+
signUpBody,
|
|
292
|
+
signedInAccountSchema,
|
|
293
|
+
updateWorkspaceBody,
|
|
294
|
+
workspaceSchema,
|
|
295
|
+
} from './session.ts'
|
|
296
|
+
export type {
|
|
297
|
+
ConfirmPasswordResetInput,
|
|
298
|
+
CreateWorkspaceInput,
|
|
299
|
+
LogInInput,
|
|
300
|
+
RequestPasswordResetInput,
|
|
301
|
+
Session,
|
|
302
|
+
SignUpInput,
|
|
303
|
+
SignedInAccount,
|
|
304
|
+
UpdateWorkspaceInput,
|
|
305
|
+
Workspace,
|
|
306
|
+
} from './session.ts'
|
|
307
|
+
|
|
308
|
+
export {
|
|
309
|
+
MINIMUM_PASSWORD_LENGTH,
|
|
310
|
+
accountPreferencesSchema,
|
|
311
|
+
accountSchema,
|
|
312
|
+
accountSessionSchema,
|
|
313
|
+
changePasswordBody,
|
|
314
|
+
updateAccountBody,
|
|
315
|
+
updateAccountPreferencesBody,
|
|
316
|
+
} from './account.ts'
|
|
317
|
+
export type {
|
|
318
|
+
Account,
|
|
319
|
+
AccountPreferences,
|
|
320
|
+
AccountSession,
|
|
321
|
+
ChangePasswordInput,
|
|
322
|
+
UpdateAccountInput,
|
|
323
|
+
UpdateAccountPreferencesInput,
|
|
324
|
+
} from './account.ts'
|