@mymehq/sdk 5.1.0 → 5.2.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/index.d.ts +81 -2
- package/dist/index.js +115 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MergeStrategy, ConflictSnapshot, MergePolicy, ItemState, Tier,
|
|
1
|
+
import { MergeStrategy, ConflictSnapshot, MergePolicy, ItemState, Tier, CreateItemInput, Item, PaginatedResult, ItemWithMetadata, Version, Edge, Metadata, SearchResult, CreateEdgeInput, EdgeTypeSchema, TypeSchema, CreateKeyInput, ApiKey, UpdateKeyInput, CreateWebhookInput, Webhook, UpdateWebhookInput, WebhookDelivery, ConnectionInstallResult, ConnectionUninstallResult, PreviewEventRequest, PreviewEventResult, TenantConfig, TenantQuota, Profile, UpdateProfileInput } from '@mymehq/shared';
|
|
2
2
|
export { ApiKey, ConflictSnapshot, CreateItemInput, CreateKeyInput, Item, ItemState, MergePolicy, MergeStrategy, Metadata, PaginatedResult, Profile, SearchResult, TypeSchema, UpdateKeyInput, UpdateProfileInput, Version } from '@mymehq/shared';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -199,6 +199,57 @@ interface BulkItemInput {
|
|
|
199
199
|
edges?: Record<string, string[]>;
|
|
200
200
|
}
|
|
201
201
|
type BulkMode = "upsert" | "create_only";
|
|
202
|
+
/**
|
|
203
|
+
* Input to `client.items.createWithAttachments(...)` (T-100). Wraps the
|
|
204
|
+
* existing blob-upload + `items.bulk` pattern: upload each attachment's
|
|
205
|
+
* blob, then issue one atomic bulk call containing the host item and the
|
|
206
|
+
* `core.file.*` items with inline `attached-to` edges from each
|
|
207
|
+
* attachment back to the host.
|
|
208
|
+
*/
|
|
209
|
+
interface CreateWithAttachmentsInput {
|
|
210
|
+
/** The host item — the thing the attachments are attached *to* (note,
|
|
211
|
+
* message, etc.). May carry an explicit `id` for client-minted UUIDs
|
|
212
|
+
* and arbitrary `edges` of its own (passed through unchanged into the
|
|
213
|
+
* bulk payload). */
|
|
214
|
+
item: CreateItemInput & {
|
|
215
|
+
id?: string;
|
|
216
|
+
edges?: Record<string, string[]>;
|
|
217
|
+
};
|
|
218
|
+
/** Attachments in caller-passed order. The returned `attachments`
|
|
219
|
+
* array preserves the same order. Empty arrays are valid: the helper
|
|
220
|
+
* still issues one `items.bulk` call with just the host item. */
|
|
221
|
+
attachments: CreateWithAttachmentsAttachment[];
|
|
222
|
+
/** Edge type from each attachment back to the host. Defaults to
|
|
223
|
+
* `"attached-to"` (the canonical attachment edge — T-108). Override
|
|
224
|
+
* for app-specific semantics like `"cover-image"`. */
|
|
225
|
+
edgeType?: string;
|
|
226
|
+
}
|
|
227
|
+
interface CreateWithAttachmentsAttachment {
|
|
228
|
+
/** Type id, e.g. `"core.file.image"`. */
|
|
229
|
+
type: string;
|
|
230
|
+
/** Raw blob bytes. Uploaded via `POST /blobs`. */
|
|
231
|
+
blob: Uint8Array | ArrayBuffer;
|
|
232
|
+
/** Sent as the `Content-Type` of the blob upload. Stamped onto the
|
|
233
|
+
* attachment item's `mime_type` property automatically. */
|
|
234
|
+
mimeType: string;
|
|
235
|
+
/** Caller-supplied properties for this attachment item (e.g. `width`
|
|
236
|
+
* and `height` for `core.file.image`). The helper auto-fills
|
|
237
|
+
* `blob_ref` (= upload hash) and `mime_type` after upload; do not
|
|
238
|
+
* pre-populate them. */
|
|
239
|
+
properties?: Record<string, unknown>;
|
|
240
|
+
/** Optional additional edges on the attachment item. The helper
|
|
241
|
+
* appends its own `[edgeType]: [hostId]` entry; if you pass a value
|
|
242
|
+
* for the same `edgeType`, your ids are merged with the host id
|
|
243
|
+
* (helper-added edges are additive, never stripping). */
|
|
244
|
+
edges?: Record<string, string[]>;
|
|
245
|
+
/** Explicit attachment id (defaults to a client-minted UUIDv7). */
|
|
246
|
+
id?: string;
|
|
247
|
+
}
|
|
248
|
+
interface CreateWithAttachmentsResult {
|
|
249
|
+
host: Item;
|
|
250
|
+
/** Attachment items in the same order as `input.attachments`. */
|
|
251
|
+
attachments: Item[];
|
|
252
|
+
}
|
|
202
253
|
interface BulkInput {
|
|
203
254
|
items: BulkItemInput[];
|
|
204
255
|
/** Default: `"upsert"`. */
|
|
@@ -404,6 +455,34 @@ declare class MymeClient {
|
|
|
404
455
|
* `atomic: true` (default) rolls back the whole batch on any failure.
|
|
405
456
|
*/
|
|
406
457
|
bulk: (input: BulkInput) => Promise<BulkResult>;
|
|
458
|
+
/**
|
|
459
|
+
* Create a host item plus a set of attached `core.file.*` items in
|
|
460
|
+
* one call (T-100). Wraps the existing `blobs.upload` + `items.bulk`
|
|
461
|
+
* primitives: each attachment's blob is uploaded concurrently, then a
|
|
462
|
+
* single atomic bulk call writes the host and the attachments
|
|
463
|
+
* together with inline `attached-to` edges from each attachment back
|
|
464
|
+
* to the host (matching T-108's spec direction).
|
|
465
|
+
*
|
|
466
|
+
* **Partial-failure contract.** Blob uploads run concurrently via
|
|
467
|
+
* `Promise.all`. On upload failure, throws with the failing
|
|
468
|
+
* attachment's index in the message. Successfully-uploaded blobs are
|
|
469
|
+
* not cleaned up; the server's CAS dedupe (`blob_ref` is the
|
|
470
|
+
* content hash) makes orphaned uploads cost-trivial — the same bytes
|
|
471
|
+
* uploaded later resolve to the same hash. Callers are expected to
|
|
472
|
+
* retry the whole call rather than reason about partial state.
|
|
473
|
+
*
|
|
474
|
+
* **Empty `attachments`** is valid and supported: the helper still
|
|
475
|
+
* issues one `items.bulk` call with just the host item, no blob
|
|
476
|
+
* uploads, no auto-edges. Lets callers use this method as a uniform
|
|
477
|
+
* entry point regardless of whether attachments are present.
|
|
478
|
+
*
|
|
479
|
+
* **Caller-provided edges co-exist with the auto-`attached-to`
|
|
480
|
+
* edges.** If the caller passes edges on the host item, they're
|
|
481
|
+
* passed through unchanged. If the caller passes edges on an
|
|
482
|
+
* attachment item with the same `edgeType` key, the helper's host id
|
|
483
|
+
* is appended to that array (additive, never strip-and-replace).
|
|
484
|
+
*/
|
|
485
|
+
createWithAttachments: (input: CreateWithAttachmentsInput) => Promise<CreateWithAttachmentsResult>;
|
|
407
486
|
/**
|
|
408
487
|
* Apply one action to every item matching a filter. Six actions
|
|
409
488
|
* discriminated on `action`. Purge is admin-only and requires
|
|
@@ -815,4 +894,4 @@ interface VerifyWebhookSignatureInput {
|
|
|
815
894
|
*/
|
|
816
895
|
declare function verifyWebhookSignature(input: VerifyWebhookSignatureInput): WebhookVerifyResult;
|
|
817
896
|
|
|
818
|
-
export { type BulkActionErrorEntry, type BulkActionFilter, type BulkActionInput, type BulkActionResult, type BulkEdgeInput, type BulkEdgeInputItem, type BulkEdgeResult, type BulkEdgeResultEntry, type BulkInput, type BulkItemInput, type BulkMode, type BulkOutcome, type BulkResult, type BulkResultEntry, type ClientConfig, type ConflictAutoMergeListener, type ConflictAutoMergedEvent, type ConflictData, ConflictError, type ConflictResolver, type ConflictStrategy, ForbiddenError, type ItemWithExtensions, type ListFilters, type MetadataInput, MymeClient, MymeError, NotFoundError, type SearchFilters, UnauthorizedError, type UpdateOptions, ValidationError, type VerifyWebhookSignatureInput, type WebhookVerifyReason, type WebhookVerifyResult, defineType, verifyWebhookSignature };
|
|
897
|
+
export { type BulkActionErrorEntry, type BulkActionFilter, type BulkActionInput, type BulkActionResult, type BulkEdgeInput, type BulkEdgeInputItem, type BulkEdgeResult, type BulkEdgeResultEntry, type BulkInput, type BulkItemInput, type BulkMode, type BulkOutcome, type BulkResult, type BulkResultEntry, type ClientConfig, type ConflictAutoMergeListener, type ConflictAutoMergedEvent, type ConflictData, ConflictError, type ConflictResolver, type ConflictStrategy, type CreateWithAttachmentsAttachment, type CreateWithAttachmentsInput, type CreateWithAttachmentsResult, ForbiddenError, type ItemWithExtensions, type ListFilters, type MetadataInput, MymeClient, MymeError, NotFoundError, type SearchFilters, UnauthorizedError, type UpdateOptions, ValidationError, type VerifyWebhookSignatureInput, type WebhookVerifyReason, type WebhookVerifyResult, defineType, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { generateId } from "@mymehq/shared";
|
|
3
|
+
|
|
1
4
|
// src/errors.ts
|
|
2
5
|
var MymeError = class extends Error {
|
|
3
6
|
code;
|
|
@@ -525,6 +528,118 @@ var MymeClient = class {
|
|
|
525
528
|
body: input
|
|
526
529
|
});
|
|
527
530
|
},
|
|
531
|
+
/**
|
|
532
|
+
* Create a host item plus a set of attached `core.file.*` items in
|
|
533
|
+
* one call (T-100). Wraps the existing `blobs.upload` + `items.bulk`
|
|
534
|
+
* primitives: each attachment's blob is uploaded concurrently, then a
|
|
535
|
+
* single atomic bulk call writes the host and the attachments
|
|
536
|
+
* together with inline `attached-to` edges from each attachment back
|
|
537
|
+
* to the host (matching T-108's spec direction).
|
|
538
|
+
*
|
|
539
|
+
* **Partial-failure contract.** Blob uploads run concurrently via
|
|
540
|
+
* `Promise.all`. On upload failure, throws with the failing
|
|
541
|
+
* attachment's index in the message. Successfully-uploaded blobs are
|
|
542
|
+
* not cleaned up; the server's CAS dedupe (`blob_ref` is the
|
|
543
|
+
* content hash) makes orphaned uploads cost-trivial — the same bytes
|
|
544
|
+
* uploaded later resolve to the same hash. Callers are expected to
|
|
545
|
+
* retry the whole call rather than reason about partial state.
|
|
546
|
+
*
|
|
547
|
+
* **Empty `attachments`** is valid and supported: the helper still
|
|
548
|
+
* issues one `items.bulk` call with just the host item, no blob
|
|
549
|
+
* uploads, no auto-edges. Lets callers use this method as a uniform
|
|
550
|
+
* entry point regardless of whether attachments are present.
|
|
551
|
+
*
|
|
552
|
+
* **Caller-provided edges co-exist with the auto-`attached-to`
|
|
553
|
+
* edges.** If the caller passes edges on the host item, they're
|
|
554
|
+
* passed through unchanged. If the caller passes edges on an
|
|
555
|
+
* attachment item with the same `edgeType` key, the helper's host id
|
|
556
|
+
* is appended to that array (additive, never strip-and-replace).
|
|
557
|
+
*/
|
|
558
|
+
createWithAttachments: async (input) => {
|
|
559
|
+
const edgeType = input.edgeType ?? "attached-to";
|
|
560
|
+
const hostId = input.item.id ?? generateId();
|
|
561
|
+
const uploadResults = await Promise.all(
|
|
562
|
+
input.attachments.map(async (att, idx) => {
|
|
563
|
+
try {
|
|
564
|
+
return await this.blobs.upload(att.blob, att.mimeType);
|
|
565
|
+
} catch (err) {
|
|
566
|
+
throw new MymeError(
|
|
567
|
+
"blob_upload_failed",
|
|
568
|
+
`createWithAttachments: blob upload failed for attachments[${String(idx)}] (type=${att.type}): ${err instanceof Error ? err.message : String(err)}`,
|
|
569
|
+
502
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
})
|
|
573
|
+
);
|
|
574
|
+
const hostBulkItem = {
|
|
575
|
+
...input.item,
|
|
576
|
+
id: hostId
|
|
577
|
+
};
|
|
578
|
+
const attachmentIds = [];
|
|
579
|
+
const attachmentBulkItems = input.attachments.map(
|
|
580
|
+
(att, idx) => {
|
|
581
|
+
const attachmentId = att.id ?? generateId();
|
|
582
|
+
attachmentIds.push(attachmentId);
|
|
583
|
+
const upload = uploadResults[idx];
|
|
584
|
+
if (!upload) {
|
|
585
|
+
throw new MymeError(
|
|
586
|
+
"internal_error",
|
|
587
|
+
`createWithAttachments: upload result missing for attachments[${String(idx)}]`,
|
|
588
|
+
500
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
const callerEdges = att.edges ?? {};
|
|
592
|
+
const callerSameType = callerEdges[edgeType] ?? [];
|
|
593
|
+
const mergedEdges = {
|
|
594
|
+
...callerEdges,
|
|
595
|
+
[edgeType]: [...callerSameType, hostId]
|
|
596
|
+
};
|
|
597
|
+
return {
|
|
598
|
+
id: attachmentId,
|
|
599
|
+
type: att.type,
|
|
600
|
+
properties: {
|
|
601
|
+
...att.properties ?? {},
|
|
602
|
+
blob_ref: upload.hash,
|
|
603
|
+
mime_type: att.mimeType
|
|
604
|
+
},
|
|
605
|
+
edges: mergedEdges
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
);
|
|
609
|
+
const bulkResult = await this.items.bulk({
|
|
610
|
+
items: [hostBulkItem, ...attachmentBulkItems],
|
|
611
|
+
mode: "create_only",
|
|
612
|
+
atomic: true
|
|
613
|
+
});
|
|
614
|
+
const errored = bulkResult.results.find((r) => r.outcome === "errored");
|
|
615
|
+
if (errored) {
|
|
616
|
+
throw new MymeError(
|
|
617
|
+
errored.error?.code ?? "bulk_failed",
|
|
618
|
+
`createWithAttachments: bulk write failed at index ${String(errored.index)}: ${errored.error?.message ?? errored.reason ?? "unknown"}`,
|
|
619
|
+
400
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
const skipped = bulkResult.results.find((r) => r.outcome === "skipped");
|
|
623
|
+
if (skipped) {
|
|
624
|
+
throw new MymeError(
|
|
625
|
+
"duplicate_id",
|
|
626
|
+
`createWithAttachments: bulk write skipped at index ${String(skipped.index)} (reason: ${skipped.reason ?? "unknown"}). The helper requires fresh ids \u2014 if you passed an explicit \`item.id\`, it must not already exist.`,
|
|
627
|
+
409
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
const hydrated = await Promise.all(
|
|
631
|
+
[hostId, ...attachmentIds].map((id) => this.items.get(id))
|
|
632
|
+
);
|
|
633
|
+
const [host, ...attachments] = hydrated;
|
|
634
|
+
if (!host) {
|
|
635
|
+
throw new MymeError(
|
|
636
|
+
"internal_error",
|
|
637
|
+
"createWithAttachments: host hydration returned no item",
|
|
638
|
+
500
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
return { host, attachments };
|
|
642
|
+
},
|
|
528
643
|
/**
|
|
529
644
|
* Apply one action to every item matching a filter. Six actions
|
|
530
645
|
* discriminated on `action`. Purge is admin-only and requires
|