@corto-ai/dexter-integrations 0.0.0-stage → 0.1.0-dev.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 (4) hide show
  1. package/README.md +59 -2
  2. package/index.d.ts +426 -0
  3. package/index.js +3975 -0
  4. package/package.json +23 -4
package/README.md CHANGED
@@ -1,3 +1,60 @@
1
- # Temporary Holding Version
1
+ # @corto-ai/dexter-integrations
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Connect a table editor to Dexter. Dexter supplies matter context and owns Save; your app edits field values and displays errors.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @corto-ai/dexter-integrations
9
+ ```
10
+
11
+ ## Use
12
+
13
+ ```typescript
14
+ import { createTableAppClient } from '@corto-ai/dexter-integrations';
15
+
16
+ const client = createTableAppClient();
17
+
18
+ client.handleMatterUpdate((update) => {
19
+ // Initialise your editor from update.table and update.tableLookups.
20
+ // Later updates are external changes: your app decides how to handle them.
21
+ // update also includes matter, lookups and tableId.
22
+ });
23
+
24
+ client.handleSaveSuccess(() => {
25
+ // Persistence succeeded. This callback has no payload.
26
+ // Updated data arrives separately through handleMatterUpdate.
27
+ });
28
+
29
+ client.handleSaveError((error) => {
30
+ // Display error.message in your app.
31
+ });
32
+
33
+ // After EVERY edit, send the complete current set of field values:
34
+ client.sendChanges({
35
+ values: { 'your-field-id': 'New value' },
36
+ isValid: true
37
+ });
38
+
39
+ // For an invalid edit, send no values:
40
+ client.sendChanges({ isValid: false });
41
+
42
+ // On teardown:
43
+ client.disconnect();
44
+ ```
45
+
46
+ Replace the comments with your editor's behaviour. Connection starts automatically; no context request is needed. A late matter-update handler receives the latest context. Registering a handler replaces its previous callback.
47
+
48
+ The matter-update callback receives `{ matter, lookups, tableId, table, tableLookups }`, using Dexter API DTOs.
49
+
50
+ ## Editing
51
+
52
+ Only use field IDs permitted by `tableLookups.fields`. You can populate an allowed field that is not yet present in the table. An empty string clears a value; omitted values also count as empty, so always send the complete draft.
53
+
54
+ Send only `{ isValid: false }` for invalid edits. The SDK discards draft values and blocks Save; invalid edits still count as unsaved for leave protection. Dexter independently validates changes, tracks unsaved values and enables Save when appropriate. Reverting to persisted values clears the dirty state. Your app may continue editing during a save.
55
+
56
+ Save success acknowledges persistence without returning data. Dexter forwards its own context updates separately; the SDK does not fetch, merge or reorder them. External updates do not merge or replace a valid submitted draft. If your app adopts updated values, call `sendChanges` again. Reloading the iframe discards the draft.
57
+
58
+ `handleSaveError` also reports invalid changes and connection failures. The initial handshake keeps retrying until Dexter is ready or the app is torn down. After 10 seconds it reports a one-time waiting warning and continues trying. The SDK never automatically retries saves.
59
+
60
+ Callback errors are reported through `handleSaveError` without disconnecting. Errors thrown by the error handler itself are logged to the browser console to avoid recursive reporting.
package/index.d.ts ADDED
@@ -0,0 +1,426 @@
1
+ type CountryCode = 'AU' | 'GB' | 'US' | 'CA' | 'IE' | 'NZ' | 'AD' | 'AE' | 'AF' | 'AG' | 'AI' | 'AL' | 'AM' | 'AO' | 'AQ' | 'AR' | 'AS' | 'AT' | 'AW' | 'AX' | 'AZ' | 'BA' | 'BB' | 'BD' | 'BE' | 'BF' | 'BG' | 'BH' | 'BI' | 'BJ' | 'BL' | 'BM' | 'BN' | 'BO' | 'BQ' | 'BR' | 'BS' | 'BT' | 'BV' | 'BW' | 'BY' | 'BZ' | 'CC' | 'CD' | 'CF' | 'CG' | 'CH' | 'CI' | 'CK' | 'CL' | 'CM' | 'CN' | 'CO' | 'CR' | 'CU' | 'CV' | 'CW' | 'CX' | 'CY' | 'CZ' | 'DE' | 'DJ' | 'DK' | 'DM' | 'DO' | 'DZ' | 'EC' | 'EE' | 'EG' | 'EH' | 'ER' | 'ES' | 'ET' | 'FI' | 'FJ' | 'FK' | 'FM' | 'FO' | 'FR' | 'GA' | 'GD' | 'GE' | 'GF' | 'GG' | 'GH' | 'GI' | 'GL' | 'GM' | 'GN' | 'GP' | 'GQ' | 'GR' | 'GS' | 'GT' | 'GU' | 'GW' | 'GY' | 'HK' | 'HM' | 'HN' | 'HR' | 'HT' | 'HU' | 'ID' | 'IL' | 'IM' | 'IN' | 'IO' | 'IQ' | 'IR' | 'IS' | 'IT' | 'JE' | 'JM' | 'JO' | 'JP' | 'KE' | 'KG' | 'KH' | 'KI' | 'KM' | 'KN' | 'KP' | 'KR' | 'KW' | 'KY' | 'KZ' | 'LA' | 'LB' | 'LC' | 'LI' | 'LK' | 'LR' | 'LS' | 'LT' | 'LU' | 'LV' | 'LY' | 'MA' | 'MC' | 'MD' | 'ME' | 'MF' | 'MG' | 'MH' | 'MK' | 'ML' | 'MM' | 'MN' | 'MO' | 'MP' | 'MQ' | 'MR' | 'MS' | 'MT' | 'MU' | 'MV' | 'MW' | 'MX' | 'MY' | 'MZ' | 'NA' | 'NC' | 'NE' | 'NF' | 'NG' | 'NI' | 'NL' | 'NO' | 'NP' | 'NR' | 'NU' | 'OM' | 'PA' | 'PE' | 'PF' | 'PG' | 'PH' | 'PK' | 'PL' | 'PM' | 'PN' | 'PR' | 'PS' | 'PT' | 'PW' | 'PY' | 'QA' | 'RE' | 'RO' | 'RS' | 'RU' | 'RW' | 'SA' | 'SB' | 'SC' | 'SD' | 'SE' | 'SG' | 'SH' | 'SI' | 'SJ' | 'SK' | 'SL' | 'SM' | 'SN' | 'SO' | 'SR' | 'SS' | 'ST' | 'SV' | 'SX' | 'SY' | 'SZ' | 'TC' | 'TD' | 'TF' | 'TG' | 'TH' | 'TJ' | 'TK' | 'TL' | 'TM' | 'TN' | 'TO' | 'TR' | 'TT' | 'TV' | 'TW' | 'TZ' | 'UA' | 'UG' | 'UM' | 'UY' | 'UZ' | 'VA' | 'VC' | 'VE' | 'VG' | 'VI' | 'VN' | 'VU' | 'WF' | 'WS' | 'YE' | 'YT' | 'ZA' | 'ZM' | 'ZW' | 'Invalid';
2
+
3
+ type CandidateStatus = 'Pending' | 'Confirmed' | 'Rejected';
4
+
5
+ interface CandidateReferenceDto {
6
+ clientDocumentId?: string;
7
+ documentName?: string;
8
+ sourceQuote?: string;
9
+ }
10
+
11
+ interface ValueProvenanceDto {
12
+ references: Array<CandidateReferenceDto>;
13
+ }
14
+
15
+ interface DateTimeValueCandidateDto {
16
+ decidedByUserId?: string;
17
+ id: string;
18
+ isBestMatch: boolean;
19
+ provenance: ValueProvenanceDto;
20
+ status: CandidateStatus;
21
+ value: string;
22
+ }
23
+
24
+ type UpdateSource = 'User' | 'AI' | 'Admin';
25
+
26
+ interface ValueAttributionDto {
27
+ source: UpdateSource;
28
+ updatedAt: string;
29
+ userId?: string;
30
+ }
31
+
32
+ interface CriticalDateDto {
33
+ attribution?: ValueAttributionDto;
34
+ candidates: Array<DateTimeValueCandidateDto>;
35
+ date?: string;
36
+ id: string;
37
+ name: string;
38
+ }
39
+
40
+ interface ActorType {
41
+ id?: string;
42
+ name?: string;
43
+ }
44
+
45
+ type EmailAddressType = 'Home' | 'Work';
46
+
47
+ interface StringValueCandidateDto {
48
+ decidedByUserId?: string;
49
+ id: string;
50
+ isBestMatch: boolean;
51
+ provenance: ValueProvenanceDto;
52
+ status: CandidateStatus;
53
+ value: string;
54
+ }
55
+
56
+ interface EmailAddressV2Dto {
57
+ attribution?: ValueAttributionDto;
58
+ candidates: Array<StringValueCandidateDto>;
59
+ type: EmailAddressType;
60
+ value: string;
61
+ }
62
+
63
+ type OrganisationType = 'Business' | 'Family' | 'Government' | 'Trust';
64
+
65
+ type PartyNature = 'Person' | 'Organisation';
66
+
67
+ type PhoneNumberType = 'Home' | 'Work' | 'Mobile';
68
+
69
+ interface PhoneNumberV2Dto {
70
+ attribution?: ValueAttributionDto;
71
+ candidates: Array<StringValueCandidateDto>;
72
+ type: PhoneNumberType;
73
+ value: string;
74
+ }
75
+
76
+ type StreetAddressType = 'Home' | 'Work';
77
+
78
+ interface StreetAddressValueDto {
79
+ buildingName?: string;
80
+ city: string;
81
+ country: string;
82
+ number: string;
83
+ postalCode: string;
84
+ state: string;
85
+ street: string;
86
+ unitFlatShop?: string;
87
+ }
88
+
89
+ interface StreetAddressValueDtoValueCandidateDto {
90
+ decidedByUserId?: string;
91
+ id: string;
92
+ isBestMatch: boolean;
93
+ provenance: ValueProvenanceDto;
94
+ status: CandidateStatus;
95
+ value: StreetAddressValueDto;
96
+ }
97
+
98
+ interface StreetAddressV2Dto {
99
+ attribution?: ValueAttributionDto;
100
+ buildingName?: string;
101
+ candidates: Array<StreetAddressValueDtoValueCandidateDto>;
102
+ city: string;
103
+ country: string;
104
+ number: string;
105
+ postalCode: string;
106
+ state: string;
107
+ street: string;
108
+ type: StreetAddressType;
109
+ unitFlatShop?: string;
110
+ }
111
+
112
+ interface ContactDetailsDto {
113
+ emailAddresses: Array<EmailAddressV2Dto>;
114
+ fullName: string;
115
+ id: string;
116
+ organisationType?: OrganisationType;
117
+ partyNature?: PartyNature;
118
+ phoneNumbers: Array<PhoneNumberV2Dto>;
119
+ streetAddresses: Array<StreetAddressV2Dto>;
120
+ }
121
+
122
+ interface EmailAddressDto {
123
+ type: EmailAddressType;
124
+ value: string;
125
+ }
126
+
127
+ interface FieldV2Dto {
128
+ attribution?: ValueAttributionDto;
129
+ candidates: Array<StringValueCandidateDto>;
130
+ dataType: string;
131
+ description: string;
132
+ groupName: string;
133
+ id: string;
134
+ isBaseTableField?: boolean;
135
+ name: string;
136
+ sortOrder?: number;
137
+ value: string;
138
+ }
139
+
140
+ interface PartyParentDto {
141
+ attribution?: ValueAttributionDto;
142
+ id: string;
143
+ isSuppressed?: boolean;
144
+ parentPartyId?: string;
145
+ parentTableId?: string;
146
+ provenance: ValueProvenanceDto;
147
+ suppressedAt?: string;
148
+ }
149
+
150
+ interface BaseRole {
151
+ id?: string;
152
+ name?: string;
153
+ }
154
+
155
+ interface BaseRoleValueCandidateDto {
156
+ decidedByUserId?: string;
157
+ id: string;
158
+ isBestMatch: boolean;
159
+ provenance: ValueProvenanceDto;
160
+ status: CandidateStatus;
161
+ value: BaseRole;
162
+ }
163
+
164
+ interface PartyBaseRoleV2Dto {
165
+ attribution?: ValueAttributionDto;
166
+ candidates: Array<BaseRoleValueCandidateDto>;
167
+ value?: BaseRole;
168
+ }
169
+
170
+ interface PartyRoleValueV2Dto {
171
+ id: string;
172
+ name: string;
173
+ }
174
+
175
+ interface PartyRoleValueV2DtoValueCandidateDto {
176
+ decidedByUserId?: string;
177
+ id: string;
178
+ isBestMatch: boolean;
179
+ provenance: ValueProvenanceDto;
180
+ status: CandidateStatus;
181
+ value: PartyRoleValueV2Dto;
182
+ }
183
+
184
+ interface PartyRoleInfoV2Dto {
185
+ attribution?: ValueAttributionDto;
186
+ baseRole: PartyBaseRoleV2Dto;
187
+ candidates: Array<PartyRoleValueV2DtoValueCandidateDto>;
188
+ value: PartyRoleValueV2Dto;
189
+ }
190
+
191
+ interface PhoneNumberDto {
192
+ type: PhoneNumberType;
193
+ value: string;
194
+ }
195
+
196
+ interface StreetAddressDto {
197
+ buildingName?: string;
198
+ city: string;
199
+ country: string;
200
+ number: string;
201
+ postalCode: string;
202
+ state: string;
203
+ street: string;
204
+ type: StreetAddressType;
205
+ unitFlatShop?: string;
206
+ }
207
+
208
+ interface MatterPartyDto {
209
+ actorType?: ActorType;
210
+ contact?: ContactDetailsDto;
211
+ contactId?: string;
212
+ /** @deprecated */ emailAddresses: Array<EmailAddressDto>;
213
+ fields: Array<FieldV2Dto>;
214
+ /** @deprecated */ fullName: string;
215
+ id: string;
216
+ parents: Array<PartyParentDto>;
217
+ /** @deprecated */ phoneNumbers: Array<PhoneNumberDto>;
218
+ roleInfo: PartyRoleInfoV2Dto;
219
+ sortOrder?: number;
220
+ /** @deprecated */ streetAddresses: Array<StreetAddressDto>;
221
+ }
222
+
223
+ interface MatterStageDto {
224
+ id: string;
225
+ name: string;
226
+ }
227
+
228
+ type MatterSyncStatus = 'Never' | 'Started' | 'Finished';
229
+
230
+ interface StaffMemberDto {
231
+ id: string;
232
+ name?: string;
233
+ }
234
+
235
+ interface StaffDto {
236
+ acting?: StaffMemberDto;
237
+ assisting?: StaffMemberDto;
238
+ credit?: StaffMemberDto;
239
+ responsible?: StaffMemberDto;
240
+ }
241
+
242
+ interface TableDto$1 {
243
+ description: string;
244
+ fields: Array<FieldV2Dto>;
245
+ id: string;
246
+ name: string;
247
+ parentPartyId?: string;
248
+ parentTableId?: string;
249
+ sortOrder?: number;
250
+ templateTableId: string;
251
+ }
252
+
253
+ interface MatterDto$1 {
254
+ countryCode: CountryCode;
255
+ criticalDates: Array<CriticalDateDto>;
256
+ description: string;
257
+ firmId: string;
258
+ id: string;
259
+ industryCategoryId: string;
260
+ industryCategoryName: string;
261
+ isUserManaged: boolean;
262
+ matterTypeDescription?: string;
263
+ matterTypeId?: string;
264
+ matterTypeName?: string;
265
+ name: string;
266
+ parties: Array<MatterPartyDto>;
267
+ staff: StaffDto;
268
+ state?: string;
269
+ status?: MatterStageDto;
270
+ syncStatus: MatterSyncStatus;
271
+ tables: Array<TableDto$1>;
272
+ }
273
+
274
+ interface AreaOfLawLookupDto {
275
+ id: string;
276
+ name: string;
277
+ }
278
+
279
+ interface StateLookupDto {
280
+ code: string;
281
+ name: string;
282
+ }
283
+
284
+ interface CountryLookupDto {
285
+ code: CountryCode;
286
+ name: string;
287
+ states?: Array<StateLookupDto>;
288
+ }
289
+
290
+ interface CriticalDateLookupDto {
291
+ description: string;
292
+ id: string;
293
+ name: string;
294
+ }
295
+
296
+ interface CurrencyLookupDto {
297
+ code: string;
298
+ name: string;
299
+ }
300
+
301
+ interface IndustryCategoryLookupDto {
302
+ id: string;
303
+ name: string;
304
+ }
305
+
306
+ interface MatterTypeTreeLeafDto {
307
+ ancestry?: Array<string>;
308
+ description: string;
309
+ id: string;
310
+ name: string;
311
+ }
312
+
313
+ interface MatterTypeFolderTreeDto {
314
+ ancestry?: Array<string>;
315
+ folders?: Array<MatterTypeFolderTreeDto>;
316
+ id: string;
317
+ matterTypes?: Array<MatterTypeTreeLeafDto>;
318
+ name: string;
319
+ sortOrder?: number;
320
+ }
321
+
322
+ interface FieldLookupDto {
323
+ allowableValues: Array<string>;
324
+ dataType: string;
325
+ description: string;
326
+ fieldId: string;
327
+ groupName: string;
328
+ name: string;
329
+ sortOrder?: number;
330
+ tableId: string;
331
+ }
332
+
333
+ interface PartyRoleLookupDto {
334
+ candidateBaseRoles?: Array<BaseRole>;
335
+ fields?: Array<FieldLookupDto>;
336
+ id: string;
337
+ name: string;
338
+ parentId?: string;
339
+ sortOrder?: number;
340
+ }
341
+
342
+ interface RepresentationRoleDto {
343
+ id: string;
344
+ name: string;
345
+ }
346
+
347
+ interface RepresentationRoleLookupDto {
348
+ actingFor?: Array<RepresentationRoleDto>;
349
+ opposing?: Array<RepresentationRoleDto>;
350
+ }
351
+
352
+ interface StaffLookupDto {
353
+ id: string;
354
+ name: string;
355
+ }
356
+
357
+ interface StatusLookupDto {
358
+ description: string;
359
+ id: string;
360
+ name: string;
361
+ }
362
+
363
+ interface TableLookupDto {
364
+ description: string;
365
+ fields?: Array<FieldLookupDto>;
366
+ id: string;
367
+ name: string;
368
+ parentId?: string;
369
+ sortOrder?: number;
370
+ }
371
+
372
+ interface MatterLookupsDto {
373
+ areasOfLaw?: Array<AreaOfLawLookupDto>;
374
+ countries?: Array<CountryLookupDto>;
375
+ criticalDates?: Array<CriticalDateLookupDto>;
376
+ currencies?: Array<CurrencyLookupDto>;
377
+ industryCategories?: Array<IndustryCategoryLookupDto>;
378
+ matterTypeTree?: Array<MatterTypeFolderTreeDto>;
379
+ partyRoles?: Array<PartyRoleLookupDto>;
380
+ representationRoles?: RepresentationRoleLookupDto;
381
+ staff?: Array<StaffLookupDto>;
382
+ statuses?: Array<StatusLookupDto>;
383
+ tables?: Array<TableLookupDto>;
384
+ }
385
+
386
+ type TableDto = TableDto$1 & {
387
+ appUrl?: string;
388
+ };
389
+ type MatterDto = Omit<MatterDto$1, 'tables'> & {
390
+ tables: TableDto[];
391
+ };
392
+
393
+ interface MatterContext {
394
+ matter: MatterDto;
395
+ lookups: MatterLookupsDto;
396
+ }
397
+ interface TableAppUpdate extends MatterContext {
398
+ tableId: string;
399
+ table: TableDto;
400
+ tableLookups: TableLookupDto;
401
+ }
402
+ type TableAppChanges = {
403
+ isValid: true;
404
+ values: Record<string, string>;
405
+ } | {
406
+ isValid: false;
407
+ values?: never;
408
+ };
409
+
410
+ interface TransportOptions {
411
+ /** Report a slow initial handshake after this delay; keep waiting. Defaults to 10 seconds. */
412
+ timeoutMs?: number;
413
+ }
414
+
415
+ interface TableAppClient {
416
+ handleMatterUpdate(callback: (update: TableAppUpdate) => void): void;
417
+ sendChanges(changes: TableAppChanges): void;
418
+ handleSaveSuccess(callback: () => void): void;
419
+ handleSaveError(callback: (error: Error) => void): void;
420
+ disconnect(): void;
421
+ }
422
+ type TableAppClientOptions = TransportOptions;
423
+ declare const createTableAppClient: (options?: TableAppClientOptions) => TableAppClient;
424
+
425
+ export { createTableAppClient };
426
+ export type { FieldV2Dto, MatterContext, MatterDto, MatterLookupsDto, TableAppChanges, TableAppClient, TableAppClientOptions, TableAppUpdate, TableDto, TableLookupDto };