@opencxh/domain 1.228.0 → 1.231.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entities/work/cycle.test.d.ts +1 -0
- package/dist/entities/work/keys.d.ts +9 -0
- package/dist/entities/work/types.d.ts +135 -0
- package/dist/index.cjs +10 -10
- package/dist/index.js +154 -145
- package/dist/platform/connector.d.ts +140 -1
- package/dist/platform/sync.d.ts +17 -0
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ export declare const CONNECTOR_PROVIDER_GROUP = "connector";
|
|
|
13
13
|
* headline deliberately omits — a Jira issue has a description, comments and custom fields; a
|
|
14
14
|
* To Do task has nothing the headline leaves out, and declares none.
|
|
15
15
|
*/
|
|
16
|
-
export type ConnectorCapability = "list" | "get" | "fields" | "write" | "comment" | "options";
|
|
16
|
+
export type ConnectorCapability = "list" | "get" | "fields" | "write" | "create" | "comment" | "attach" | "options";
|
|
17
17
|
/**
|
|
18
18
|
* Continuous or one-off — a real difference, not a label.
|
|
19
19
|
*
|
|
@@ -191,6 +191,17 @@ export interface ConnectorListResponse {
|
|
|
191
191
|
cursor?: unknown;
|
|
192
192
|
/** No more data after this page. The runtime then does not chain on. */
|
|
193
193
|
done: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* "Everything of this kind I could still see" — handed to the landing app as-is.
|
|
196
|
+
*
|
|
197
|
+
* Only meaningful on the **last page of a full sweep**, which is the only moment a connector
|
|
198
|
+
* has enumerated exhaustively. See {@link SyncLandRequest.reconcile} for what the other side
|
|
199
|
+
* does with it, and why an incomplete list must be left absent rather than sent short.
|
|
200
|
+
*/
|
|
201
|
+
reconcile?: {
|
|
202
|
+
kind: string;
|
|
203
|
+
seenExternalIds: string[];
|
|
204
|
+
};
|
|
194
205
|
/**
|
|
195
206
|
* The connector is rate-limited; wait at least this long before the next attempt.
|
|
196
207
|
*
|
|
@@ -245,6 +256,50 @@ export interface ConnectorWriteResponse {
|
|
|
245
256
|
*/
|
|
246
257
|
data: Record<string, unknown>;
|
|
247
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* `POST /provider/connector/create` — make a new record in the system that owns the container.
|
|
261
|
+
*
|
|
262
|
+
* The sibling of {@link ConnectorWriteRequest} and deliberately a separate route: a create has no
|
|
263
|
+
* `externalId` yet (it is what comes back) and it is addressed to a *container* instead of a
|
|
264
|
+
* record. Folding the two would make both fields optional, and "which of these two is missing"
|
|
265
|
+
* is exactly the kind of question a contract should not have to ask at runtime.
|
|
266
|
+
*
|
|
267
|
+
* Why this exists at all, given that proxy is "the truth stays with them": it is the same promise
|
|
268
|
+
* as a write. A screen that offers "new item" inside an imported project has to put that item
|
|
269
|
+
* where the work actually lives — the alternative is a local row with our own numbering sitting
|
|
270
|
+
* between theirs, invisible at the source and undone by nothing, for ever.
|
|
271
|
+
*/
|
|
272
|
+
export interface ConnectorCreateRequest {
|
|
273
|
+
/** → {@link ConnectorDefinition.id} */
|
|
274
|
+
sourceId: string;
|
|
275
|
+
connectionId: string;
|
|
276
|
+
/** The {@link ManagedAccount} to talk with. Absent when no credential is needed. */
|
|
277
|
+
accountId?: string;
|
|
278
|
+
settings?: Record<string, unknown>;
|
|
279
|
+
/** From {@link ConnectorDefinition.kinds}. */
|
|
280
|
+
kind: string;
|
|
281
|
+
/**
|
|
282
|
+
* Where the new record goes, in the source's own id space: the project, the board, the list.
|
|
283
|
+
*
|
|
284
|
+
* Required, and there is no "somewhere sensible" fallback. A connector that guessed a container
|
|
285
|
+
* would put work in a project nobody is looking at, and report success.
|
|
286
|
+
*/
|
|
287
|
+
containerExternalId: string;
|
|
288
|
+
/** The new record, in the **target app's** field names — same vocabulary as `patch`. */
|
|
289
|
+
data: Record<string, unknown>;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Answer to `POST /provider/connector/create`. Wrapped in `ResponseFactory`.
|
|
293
|
+
*
|
|
294
|
+
* Identical in shape to {@link ConnectorWriteResponse} on purpose: the caller lands both through
|
|
295
|
+
* the same upsert, so the record it gets back carries the source's id and the source's version of
|
|
296
|
+
* every field it filled in itself — a key, a workflow's opening status, a default type.
|
|
297
|
+
*/
|
|
298
|
+
export interface ConnectorCreateResponse {
|
|
299
|
+
/** The id the source gave it. This is what makes the new row findable on the next round. */
|
|
300
|
+
externalId: string;
|
|
301
|
+
data: Record<string, unknown>;
|
|
302
|
+
}
|
|
248
303
|
/**
|
|
249
304
|
* One editable field of a **record**, as the connector describes it.
|
|
250
305
|
*
|
|
@@ -351,11 +406,37 @@ export interface ConnectorComment {
|
|
|
351
406
|
/** Epoch ms. */
|
|
352
407
|
createdAt?: number;
|
|
353
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* One attachment on a record — its **description**, never its bytes.
|
|
411
|
+
*
|
|
412
|
+
* Metadata is cheap and a list of it is what a screen draws; the file itself is fetched only
|
|
413
|
+
* when somebody asks for it, over `POST /provider/connector/attachment`. Sending bytes with the
|
|
414
|
+
* detail would put every attachment of every opened issue on the wire.
|
|
415
|
+
*/
|
|
416
|
+
export interface ConnectorAttachment {
|
|
417
|
+
/** The source's own id, and what the fetch route is addressed with. */
|
|
418
|
+
id: string;
|
|
419
|
+
filename: string;
|
|
420
|
+
mimeType: string;
|
|
421
|
+
/** Bytes. Absent when the source does not say, which is not the same as zero. */
|
|
422
|
+
size?: number;
|
|
423
|
+
/** The author's display name, like {@link ConnectorComment.author}. */
|
|
424
|
+
author?: string;
|
|
425
|
+
/** Epoch ms. */
|
|
426
|
+
createdAt?: number;
|
|
427
|
+
}
|
|
354
428
|
/** Answer to `POST /provider/connector/get`. Wrapped in `ResponseFactory`. */
|
|
355
429
|
export interface ConnectorGetResponse {
|
|
356
430
|
/** Plain text. Empty is a valid answer and means the record has none. */
|
|
357
431
|
description?: string;
|
|
358
432
|
comments?: ConnectorComment[];
|
|
433
|
+
/**
|
|
434
|
+
* What hangs off this record at the source. Metadata only — see {@link ConnectorAttachment}.
|
|
435
|
+
*
|
|
436
|
+
* Beside `comments` because it is the same kind of thing: shown while the screen is open,
|
|
437
|
+
* never stored. A proxy row holds no truth, and an attachment is the least storable part of it.
|
|
438
|
+
*/
|
|
439
|
+
attachments?: ConnectorAttachment[];
|
|
359
440
|
/** A deep link into the source system, so a person can always go to the real thing. */
|
|
360
441
|
url?: string;
|
|
361
442
|
/**
|
|
@@ -369,6 +450,64 @@ export interface ConnectorGetResponse {
|
|
|
369
450
|
value: string;
|
|
370
451
|
}[];
|
|
371
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* `POST /provider/connector/attachment` — fetch one attachment's bytes.
|
|
455
|
+
*
|
|
456
|
+
* Separate from `get` for the reason stated on {@link ConnectorAttachment}: the list is drawn
|
|
457
|
+
* every time a record opens, the bytes only when somebody clicks. A vendor's own content URL is
|
|
458
|
+
* not an answer here — it needs the vendor's credential, which lives on the connection and not
|
|
459
|
+
* in a browser.
|
|
460
|
+
*/
|
|
461
|
+
export interface ConnectorAttachmentRequest {
|
|
462
|
+
/** → {@link ConnectorDefinition.id} */
|
|
463
|
+
sourceId: string;
|
|
464
|
+
connectionId: string;
|
|
465
|
+
/** The {@link ManagedAccount} to talk with. Absent when no credential is needed. */
|
|
466
|
+
accountId?: string;
|
|
467
|
+
settings?: Record<string, unknown>;
|
|
468
|
+
/** From {@link ConnectorDefinition.kinds}. */
|
|
469
|
+
kind: string;
|
|
470
|
+
/** The record the attachment hangs on. */
|
|
471
|
+
externalId: string;
|
|
472
|
+
/** → {@link ConnectorAttachment.id} */
|
|
473
|
+
attachmentId: string;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Answer to `POST /provider/connector/attachment`. Wrapped in `ResponseFactory`.
|
|
477
|
+
*
|
|
478
|
+
* **base64**, because the hop to the browser is JSON either way and a single encoding across all
|
|
479
|
+
* three hops is one fewer place to get it wrong. The same choice comms made for mail attachments.
|
|
480
|
+
*/
|
|
481
|
+
export interface ConnectorAttachmentResponse {
|
|
482
|
+
filename: string;
|
|
483
|
+
mimeType: string;
|
|
484
|
+
base64: string;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* `POST /provider/connector/attach` — add a file to a record at the source.
|
|
488
|
+
*
|
|
489
|
+
* The write half of the `attach` capability, and it throws on refusal like every other writer:
|
|
490
|
+
* an upload that silently did not arrive leaves the person believing the file is where it is not.
|
|
491
|
+
*/
|
|
492
|
+
export interface ConnectorAttachRequest {
|
|
493
|
+
/** → {@link ConnectorDefinition.id} */
|
|
494
|
+
sourceId: string;
|
|
495
|
+
connectionId: string;
|
|
496
|
+
/** The {@link ManagedAccount} to talk with. Absent when no credential is needed. */
|
|
497
|
+
accountId?: string;
|
|
498
|
+
settings?: Record<string, unknown>;
|
|
499
|
+
/** From {@link ConnectorDefinition.kinds}. */
|
|
500
|
+
kind: string;
|
|
501
|
+
externalId: string;
|
|
502
|
+
filename: string;
|
|
503
|
+
mimeType: string;
|
|
504
|
+
/** base64, for the reason on {@link ConnectorAttachmentResponse}. */
|
|
505
|
+
base64: string;
|
|
506
|
+
}
|
|
507
|
+
/** Answer to `POST /provider/connector/attach`: the attachment as the source now has it. */
|
|
508
|
+
export interface ConnectorAttachResponse {
|
|
509
|
+
attachment: ConnectorAttachment;
|
|
510
|
+
}
|
|
372
511
|
/**
|
|
373
512
|
* `POST /provider/connector/options` — the choices for one settings field.
|
|
374
513
|
*
|
package/dist/platform/sync.d.ts
CHANGED
|
@@ -76,6 +76,23 @@ export interface SyncLandRequest {
|
|
|
76
76
|
*/
|
|
77
77
|
proxy?: boolean;
|
|
78
78
|
records: SyncRecord[];
|
|
79
|
+
/**
|
|
80
|
+
* "These are all the records of this kind I could see. Anything else of mine is gone."
|
|
81
|
+
*
|
|
82
|
+
* The answer to a deletion a source cannot report. A cursor on `updated` sees edits and new
|
|
83
|
+
* records; a delete leaves no trace it will ever return, and neither does a permission change
|
|
84
|
+
* that makes a record invisible. So the reconcile sweep says what it *did* see, and the landing
|
|
85
|
+
* app — the only side that knows what it holds — works out the difference.
|
|
86
|
+
*
|
|
87
|
+
* Sent once, on the last page of a sweep, next to the records of that page. A connector that
|
|
88
|
+
* cannot enumerate exhaustively must leave this absent: an incomplete list here reads as a mass
|
|
89
|
+
* deletion, which is the one failure worse than a stale row.
|
|
90
|
+
*/
|
|
91
|
+
reconcile?: {
|
|
92
|
+
/** From `ConnectorDefinition.kinds`. One kind per reconcile — a sweep may send several. */
|
|
93
|
+
kind: string;
|
|
94
|
+
seenExternalIds: string[];
|
|
95
|
+
};
|
|
79
96
|
}
|
|
80
97
|
/** What happened to one record. */
|
|
81
98
|
export interface SyncLandOutcome {
|