@onlyworlds/sdk 4.27.1 → 4.27.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ earlier history lives in git log only.
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.27.2] — 2026-10-16
9
+
10
+ ### Fixed
11
+ - **`bulk` mints an id for each element that has none, as `create` does.** It sent id-less elements
12
+ bare and keel minted them. With an `idempotencyKey`, each id is now derived from the key and the
13
+ element's position in `items` (the ids the Python package mints), so the same key and items send the
14
+ same body from either client, and a resend after keel's 24-hour replay window rewrites the same
15
+ elements instead of creating new ones. Without a key, a fresh UUIDv7 each. Ids you pass are kept, and
16
+ your items are not changed. Found by Quillon's parity audit of the Unity SDK (h37 #5794).
17
+
8
18
  ## [4.27.1] — 2026-10-16
9
19
 
10
20
  ### Fixed
package/dist/index.d.ts CHANGED
@@ -2610,6 +2610,10 @@ declare class OwV2Client {
2610
2610
  * After an atomic:true request with errors:true NOTHING was written, yet the slots of
2611
2611
  * the items that would have succeeded still say 201 with the ids and timestamps they
2612
2612
  * would have had (keel's "counterfactual 201s"): do not record those ids as created.
2613
+ * An element without an id gets one, as `create` mints it, by its position in `items`: with an
2614
+ * `idempotencyKey`, derived from the key and the position (the ids the Python package mints),
2615
+ * so a retry with the same key and items sends the same body; without one, a
2616
+ * fresh UUIDv7. Ids you supply are kept.
2613
2617
  */
2614
2618
  bulk(items: OwBulkItem[], opts?: {
2615
2619
  atomic?: boolean;
package/dist/index.js CHANGED
@@ -399,10 +399,20 @@ var OwV2Client = class {
399
399
  * After an atomic:true request with errors:true NOTHING was written, yet the slots of
400
400
  * the items that would have succeeded still say 201 with the ids and timestamps they
401
401
  * would have had (keel's "counterfactual 201s"): do not record those ids as created.
402
+ * An element without an id gets one, as `create` mints it, by its position in `items`: with an
403
+ * `idempotencyKey`, derived from the key and the position (the ids the Python package mints),
404
+ * so a retry with the same key and items sends the same body; without one, a
405
+ * fresh UUIDv7. Ids you supply are kept.
402
406
  */
403
407
  async bulk(items, opts = {}) {
404
408
  const body = {
405
- items: items.map((it) => ({ type: it.type, element: sanitizePayload(it.element) })),
409
+ items: items.map((it, index) => {
410
+ const element = sanitizePayload(it.element);
411
+ if (element.id === void 0 || element.id === null || element.id === "") {
412
+ element.id = opts.idempotencyKey ? keyedId(opts.idempotencyKey, index) : mintUuid();
413
+ }
414
+ return { type: it.type, element };
415
+ }),
406
416
  atomic: opts.atomic ?? false
407
417
  };
408
418
  return this.request("POST", "/bulk/", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlyworlds/sdk",
3
- "version": "4.27.1",
3
+ "version": "4.27.2",
4
4
  "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
5
  "type": "module",
6
6
  "exports": {