@bedrock-rbx/ocale 0.1.0-beta.8 → 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.
Files changed (81) hide show
  1. package/README.md +182 -0
  2. package/dist/badges.d.mts +33 -2
  3. package/dist/badges.d.mts.map +1 -1
  4. package/dist/badges.mjs +16 -4
  5. package/dist/badges.mjs.map +1 -1
  6. package/dist/{data.generated-Cb6g6asv.d.mts → data.generated-B2ceLfSn.d.mts} +9 -1
  7. package/dist/data.generated-B2ceLfSn.d.mts.map +1 -0
  8. package/dist/developer-products.d.mts +38 -2
  9. package/dist/developer-products.d.mts.map +1 -1
  10. package/dist/developer-products.mjs +32 -8
  11. package/dist/developer-products.mjs.map +1 -1
  12. package/dist/game-passes.d.mts +40 -2
  13. package/dist/game-passes.d.mts.map +1 -1
  14. package/dist/game-passes.mjs +30 -6
  15. package/dist/game-passes.mjs.map +1 -1
  16. package/dist/index.d.mts +21 -12
  17. package/dist/index.d.mts.map +1 -1
  18. package/dist/index.mjs +5 -5
  19. package/dist/locales.d.mts +1 -1
  20. package/dist/locales.mjs +2 -0
  21. package/dist/locales.mjs.map +1 -1
  22. package/dist/luau-execution.d.mts +22 -3
  23. package/dist/luau-execution.d.mts.map +1 -1
  24. package/dist/luau-execution.mjs +29 -13
  25. package/dist/luau-execution.mjs.map +1 -1
  26. package/dist/places.d.mts +20 -2
  27. package/dist/places.d.mts.map +1 -1
  28. package/dist/places.mjs +34 -14
  29. package/dist/places.mjs.map +1 -1
  30. package/dist/{poll-timeout-Dg_QFEqi.mjs → poll-timeout-C0nmJzOd.mjs} +6 -2
  31. package/dist/poll-timeout-C0nmJzOd.mjs.map +1 -0
  32. package/dist/{polling-helpers-CS00apdU.mjs → polling-helpers-BcycDhDm.mjs} +225 -78
  33. package/dist/polling-helpers-BcycDhDm.mjs.map +1 -0
  34. package/dist/{polling-BMrYajok.d.mts → polling-rj0dGREg.d.mts} +73 -14
  35. package/dist/polling-rj0dGREg.d.mts.map +1 -0
  36. package/dist/{price-information-DIrvwCmd.mjs → price-information-DK83Wul1.mjs} +2 -2
  37. package/dist/{price-information-DIrvwCmd.mjs.map → price-information-DK83Wul1.mjs.map} +1 -1
  38. package/dist/{rate-limit-D1q2Js-z.mjs → rate-limit-Co9i28qi.mjs} +30 -2
  39. package/dist/rate-limit-Co9i28qi.mjs.map +1 -0
  40. package/dist/{resource-client-D6Efj9fU.mjs → resource-client-C_D--PYX.mjs} +328 -243
  41. package/dist/resource-client-C_D--PYX.mjs.map +1 -0
  42. package/dist/retry-CbHBw60o.mjs +380 -0
  43. package/dist/retry-CbHBw60o.mjs.map +1 -0
  44. package/dist/retry-r1TXe5Zd.d.mts +189 -0
  45. package/dist/retry-r1TXe5Zd.d.mts.map +1 -0
  46. package/dist/{signatures-B5Fojgn0.mjs → signatures-JF-7Psce.mjs} +1 -1
  47. package/dist/{signatures-B5Fojgn0.mjs.map → signatures-JF-7Psce.mjs.map} +1 -1
  48. package/dist/storage.d.mts +316 -31
  49. package/dist/storage.d.mts.map +1 -1
  50. package/dist/storage.mjs +525 -24
  51. package/dist/storage.mjs.map +1 -1
  52. package/dist/testing.d.mts +24 -9
  53. package/dist/testing.d.mts.map +1 -1
  54. package/dist/testing.mjs +2 -2
  55. package/dist/testing.mjs.map +1 -1
  56. package/dist/{to-blob-B27VhoRp.mjs → to-blob-RPqMBuft.mjs} +1 -1
  57. package/dist/{to-blob-B27VhoRp.mjs.map → to-blob-RPqMBuft.mjs.map} +1 -1
  58. package/dist/{types-CwtZT1ek.d.mts → types-CRiJg5EQ.d.mts} +46 -4
  59. package/dist/types-CRiJg5EQ.d.mts.map +1 -0
  60. package/dist/universes.d.mts +47 -5
  61. package/dist/universes.d.mts.map +1 -1
  62. package/dist/universes.mjs +31 -15
  63. package/dist/universes.mjs.map +1 -1
  64. package/dist/{validation-DkL5KQqz.mjs → validation-9oU6qNNQ.mjs} +4 -2
  65. package/dist/validation-9oU6qNNQ.mjs.map +1 -0
  66. package/dist/{wire-CeL6W_V7.d.mts → wire-D3K-a-UP.d.mts} +3 -1
  67. package/dist/wire-D3K-a-UP.d.mts.map +1 -0
  68. package/package.json +7 -6
  69. package/dist/data.generated-Cb6g6asv.d.mts.map +0 -1
  70. package/dist/permission-error-DOVtNq3A.mjs +0 -46
  71. package/dist/permission-error-DOVtNq3A.mjs.map +0 -1
  72. package/dist/poll-timeout-Dg_QFEqi.mjs.map +0 -1
  73. package/dist/polling-BMrYajok.d.mts.map +0 -1
  74. package/dist/polling-helpers-CS00apdU.mjs.map +0 -1
  75. package/dist/rate-limit-BYuizHoD.d.mts +0 -92
  76. package/dist/rate-limit-BYuizHoD.d.mts.map +0 -1
  77. package/dist/rate-limit-D1q2Js-z.mjs.map +0 -1
  78. package/dist/resource-client-D6Efj9fU.mjs.map +0 -1
  79. package/dist/types-CwtZT1ek.d.mts.map +0 -1
  80. package/dist/validation-DkL5KQqz.mjs.map +0 -1
  81. package/dist/wire-CeL6W_V7.d.mts.map +0 -1
package/dist/storage.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { r as ApiError } from "./rate-limit-D1q2Js-z.mjs";
2
- import { a as IDEMPOTENT_METHOD_DEFAULTS, c as isDateTimeString, i as CREATE_METHOD_DEFAULTS, n as okRequest, r as parseEmptyResponse, s as isRecord, t as ResourceClient } from "./resource-client-D6Efj9fU.mjs";
1
+ import { r as ApiError } from "./rate-limit-Co9i28qi.mjs";
2
+ import { n as IDEMPOTENT_METHOD_DEFAULTS, t as CREATE_METHOD_DEFAULTS } from "./retry-CbHBw60o.mjs";
3
+ import { a as isDateTimeString, i as isRecord, n as okRequest, r as parseEmptyResponse, t as ResourceClient } from "./resource-client-C_D--PYX.mjs";
3
4
  //#region src/domains/cloud-v2/memory-store-queues/builders.ts
4
5
  /**
5
6
  * Builds a `POST` request for the Open Cloud
@@ -72,7 +73,7 @@ function buildDiscardRequest(parameters) {
72
73
  //#endregion
73
74
  //#region src/domains/cloud-v2/memory-store-queues/operations.ts
74
75
  const ENQUEUE_PER_MINUTE = 1e6;
75
- const SECONDS_PER_MINUTE = 60;
76
+ const SECONDS_PER_MINUTE$1 = 60;
76
77
  /**
77
78
  * Per-second request ceiling for enqueueing a memory-store queue item,
78
79
  * from the Open Cloud OpenAPI schema (1,000,000 requests per minute per
@@ -82,7 +83,7 @@ const SECONDS_PER_MINUTE = 60;
82
83
  * is fewer cross-method contention surprises.
83
84
  */
84
85
  const ENQUEUE_OPERATION_LIMIT = Object.freeze({
85
- maxPerSecond: ENQUEUE_PER_MINUTE / SECONDS_PER_MINUTE,
86
+ maxPerSecond: ENQUEUE_PER_MINUTE / SECONDS_PER_MINUTE$1,
86
87
  operationKey: "memory-store-queues.enqueue"
87
88
  });
88
89
  /**
@@ -97,7 +98,7 @@ const ENQUEUE_REQUIRED_SCOPES = Object.freeze(["memory-store.queue:add"]);
97
98
  * per API key owner). Keyed independently from enqueue and discard.
98
99
  */
99
100
  const DEQUEUE_OPERATION_LIMIT = Object.freeze({
100
- maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
101
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE$1,
101
102
  operationKey: "memory-store-queues.dequeue"
102
103
  });
103
104
  /**
@@ -113,7 +114,7 @@ const DEQUEUE_REQUIRED_SCOPES = Object.freeze(["memory-store.queue:dequeue"]);
113
114
  * dequeue.
114
115
  */
115
116
  const DISCARD_OPERATION_LIMIT = Object.freeze({
116
- maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
117
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE$1,
117
118
  operationKey: "memory-store-queues.discard"
118
119
  });
119
120
  /**
@@ -124,7 +125,7 @@ const DISCARD_OPERATION_LIMIT = Object.freeze({
124
125
  const DISCARD_REQUIRED_SCOPES = Object.freeze(["memory-store.queue:discard"]);
125
126
  //#endregion
126
127
  //#region src/domains/cloud-v2/memory-store-queues/parsers.ts
127
- const PATH_PATTERN = /^cloud\/v2\/universes\/(\d+)\/memory-store\/queues\/([^/]+)\/items\/([^/]+)$/;
128
+ const PATH_PATTERN$1 = /^cloud\/v2\/universes\/(\d+)\/memory-store\/queues\/([^/]+)\/items\/([^/]+)$/;
128
129
  const MALFORMED_QUEUE_ITEM_MESSAGE = "Malformed memory-store queue item response";
129
130
  const MALFORMED_DEQUEUE_MESSAGE = "Malformed memory-store dequeue response";
130
131
  /**
@@ -138,7 +139,7 @@ const MALFORMED_DEQUEUE_MESSAGE = "Malformed memory-store dequeue response";
138
139
  */
139
140
  function parseQueueItemResponse(response) {
140
141
  const item = wireBodyToQueueItem(response.body);
141
- if (item === void 0) return malformedQueueItem(response.status);
142
+ if (item === void 0) return malformedQueueItem(response.status, response.body);
142
143
  return {
143
144
  data: item,
144
145
  success: true
@@ -157,11 +158,12 @@ function parseQueueItemResponse(response) {
157
158
  */
158
159
  function parseDequeueResponse(response) {
159
160
  const { body, status: statusCode } = response;
160
- if (!isRecord(body)) return malformedDequeue(statusCode);
161
+ if (!isRecord(body)) return malformedDequeue(statusCode, body);
161
162
  const { id, queueItems } = body;
162
- if (typeof id !== "string" || !Array.isArray(queueItems)) return malformedDequeue(statusCode);
163
- const items = queueItems.map(wireBodyToQueueItem);
164
- if (!items.every(isQueueItem)) return malformedDequeue(statusCode);
163
+ if (typeof id !== "string") return malformedDequeue(statusCode, body);
164
+ if (queueItems !== void 0 && queueItems !== null && !Array.isArray(queueItems)) return malformedDequeue(statusCode, body);
165
+ const items = (queueItems ?? []).map(wireBodyToQueueItem);
166
+ if (!items.every(isQueueItem)) return malformedDequeue(statusCode, body);
165
167
  return {
166
168
  data: {
167
169
  items,
@@ -177,7 +179,7 @@ function isQueueItemWire(body) {
177
179
  }
178
180
  function wireBodyToQueueItem(body) {
179
181
  if (!isQueueItemWire(body)) return;
180
- const match = PATH_PATTERN.exec(body.path);
182
+ const match = PATH_PATTERN$1.exec(body.path);
181
183
  const universeId = match?.[1];
182
184
  const queueId = match?.[2];
183
185
  const id = match?.[3];
@@ -191,27 +193,33 @@ function wireBodyToQueueItem(body) {
191
193
  universeId
192
194
  };
193
195
  }
194
- function malformedQueueItem(statusCode) {
196
+ function malformedQueueItem(statusCode, body) {
195
197
  return {
196
- err: new ApiError(MALFORMED_QUEUE_ITEM_MESSAGE, { statusCode }),
198
+ err: new ApiError(MALFORMED_QUEUE_ITEM_MESSAGE, {
199
+ details: body,
200
+ statusCode
201
+ }),
197
202
  success: false
198
203
  };
199
204
  }
200
205
  function isQueueItem(item) {
201
206
  return item !== void 0;
202
207
  }
203
- function malformedDequeue(statusCode) {
208
+ function malformedDequeue(statusCode, body) {
204
209
  return {
205
- err: new ApiError(MALFORMED_DEQUEUE_MESSAGE, { statusCode }),
210
+ err: new ApiError(MALFORMED_DEQUEUE_MESSAGE, {
211
+ details: body,
212
+ statusCode
213
+ }),
206
214
  success: false
207
215
  };
208
216
  }
209
217
  //#endregion
210
218
  //#region src/resources/storage/queues-group.ts
211
- function makeSpec(spec) {
219
+ function makeSpec$1(spec) {
212
220
  return Object.freeze(spec);
213
221
  }
214
- const ENQUEUE_SPEC = makeSpec({
222
+ const ENQUEUE_SPEC = makeSpec$1({
215
223
  buildRequest: (parameters) => okRequest(buildEnqueueRequest(parameters)),
216
224
  methodDefaults: CREATE_METHOD_DEFAULTS,
217
225
  methodKind: "create",
@@ -219,7 +227,7 @@ const ENQUEUE_SPEC = makeSpec({
219
227
  parse: parseQueueItemResponse,
220
228
  requiredScopes: ENQUEUE_REQUIRED_SCOPES
221
229
  });
222
- const DEQUEUE_SPEC = makeSpec({
230
+ const DEQUEUE_SPEC = makeSpec$1({
223
231
  buildRequest: (parameters) => okRequest(buildDequeueRequest(parameters)),
224
232
  methodDefaults: CREATE_METHOD_DEFAULTS,
225
233
  methodKind: "create",
@@ -227,7 +235,7 @@ const DEQUEUE_SPEC = makeSpec({
227
235
  parse: parseDequeueResponse,
228
236
  requiredScopes: DEQUEUE_REQUIRED_SCOPES
229
237
  });
230
- const DISCARD_SPEC = makeSpec({
238
+ const DISCARD_SPEC = makeSpec$1({
231
239
  buildRequest: (parameters) => okRequest(buildDiscardRequest(parameters)),
232
240
  methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
233
241
  methodKind: "idempotent",
@@ -330,17 +338,507 @@ var MemoryStoreQueuesGroup = class {
330
338
  }
331
339
  };
332
340
  //#endregion
341
+ //#region src/domains/cloud-v2/memory-store-sorted-maps/builders.ts
342
+ /**
343
+ * Builds a `POST` request for the Open Cloud
344
+ * `Cloud_CreateMemoryStoreSortedMapItem` endpoint. The caller-supplied
345
+ * `itemId` travels as the `id` query parameter (URL-encoded by
346
+ * `URLSearchParams`); the body carries `value`, the optional `ttl`
347
+ * (serialized as a Google protobuf `Duration` string in seconds), and
348
+ * one of `stringSortKey`/`numericSortKey` projected from the
349
+ * {@link SortKey} discriminated union.
350
+ *
351
+ * @param parameters - Universe, sorted-map, item identifiers, the
352
+ * value to store, and optional `sortKey` and `ttl`.
353
+ * @returns A pure {@link HttpRequest} describing the create call.
354
+ */
355
+ function buildCreateRequest(parameters) {
356
+ const { itemId, mapId, sortKey, ttl, universeId, value } = parameters;
357
+ const body = { value };
358
+ if (ttl !== void 0) body["ttl"] = `${ttl}s`;
359
+ applySortKeyToBody(body, sortKey);
360
+ const query = new URLSearchParams({ id: itemId });
361
+ return {
362
+ body,
363
+ headers: { "content-type": "application/json" },
364
+ method: "POST",
365
+ url: `/cloud/v2/universes/${encodeURIComponent(universeId)}/memory-store/sorted-maps/${encodeURIComponent(mapId)}/items?${query.toString()}`
366
+ };
367
+ }
368
+ /**
369
+ * Builds a `DELETE` request for the Open Cloud
370
+ * `Cloud_DeleteMemoryStoreSortedMapItem` endpoint. Every path segment
371
+ * (universe, sorted-map, item identifiers) is URL-encoded so callers
372
+ * can pass values containing reserved characters without manual
373
+ * escaping.
374
+ *
375
+ * @param parameters - Universe, sorted-map, and item identifiers.
376
+ * @returns A pure {@link HttpRequest} describing the delete call.
377
+ */
378
+ function buildDeleteRequest(parameters) {
379
+ const { itemId, mapId, universeId } = parameters;
380
+ return {
381
+ method: "DELETE",
382
+ url: `/cloud/v2/universes/${encodeURIComponent(universeId)}/memory-store/sorted-maps/${encodeURIComponent(mapId)}/items/${encodeURIComponent(itemId)}`
383
+ };
384
+ }
385
+ /**
386
+ * Builds a `GET` request for the Open Cloud
387
+ * `Cloud_GetMemoryStoreSortedMapItem` endpoint. Every path segment
388
+ * (universe, sorted-map, item identifiers) is URL-encoded so callers
389
+ * can pass values containing reserved characters without manual
390
+ * escaping.
391
+ *
392
+ * @param parameters - Universe, sorted-map, and item identifiers.
393
+ * @returns A pure {@link HttpRequest} describing the get call.
394
+ */
395
+ function buildGetRequest(parameters) {
396
+ const { itemId, mapId, universeId } = parameters;
397
+ return {
398
+ method: "GET",
399
+ url: `/cloud/v2/universes/${encodeURIComponent(universeId)}/memory-store/sorted-maps/${encodeURIComponent(mapId)}/items/${encodeURIComponent(itemId)}`
400
+ };
401
+ }
402
+ /**
403
+ * Builds a `GET` request for the Open Cloud
404
+ * `Cloud_ListMemoryStoreSortedMapItems` endpoint. Optional `filter`,
405
+ * `maxPageSize`, `orderBy`, and `pageToken` parameters travel as query
406
+ * string parameters and are omitted when unset.
407
+ *
408
+ * @param parameters - Universe and sorted-map identifiers, plus
409
+ * optional pagination and filter parameters.
410
+ * @returns A pure {@link HttpRequest} describing the list call.
411
+ */
412
+ function buildListRequest(parameters) {
413
+ const { filter, mapId, maxPageSize, orderBy, pageToken, universeId } = parameters;
414
+ const query = new URLSearchParams();
415
+ if (maxPageSize !== void 0) query.append("maxPageSize", String(maxPageSize));
416
+ if (pageToken !== void 0) query.append("pageToken", pageToken);
417
+ if (orderBy !== void 0) query.append("orderBy", orderBy);
418
+ if (filter !== void 0) query.append("filter", filter);
419
+ const base = `/cloud/v2/universes/${encodeURIComponent(universeId)}/memory-store/sorted-maps/${encodeURIComponent(mapId)}/items`;
420
+ const queryString = query.toString();
421
+ return {
422
+ method: "GET",
423
+ url: queryString === "" ? base : `${base}?${queryString}`
424
+ };
425
+ }
426
+ /**
427
+ * Builds a `PATCH` request for the Open Cloud
428
+ * `Cloud_UpdateMemoryStoreSortedMapItem` endpoint. Body fields are
429
+ * conditionally included so a partial update sends only the changed
430
+ * fields; the optional `allowMissing` query string drives
431
+ * upsert-on-missing behaviour server-side.
432
+ *
433
+ * @param parameters - Universe, sorted-map, and item identifiers,
434
+ * plus any subset of `value`, `ttl`, `sortKey`, and `allowMissing`.
435
+ * @returns A pure {@link HttpRequest} describing the update call.
436
+ */
437
+ function buildUpdateRequest(parameters) {
438
+ const { allowMissing: shouldAllowMissing, itemId, mapId, universeId } = parameters;
439
+ const base = `/cloud/v2/universes/${encodeURIComponent(universeId)}/memory-store/sorted-maps/${encodeURIComponent(mapId)}/items/${encodeURIComponent(itemId)}`;
440
+ const query = new URLSearchParams();
441
+ if (shouldAllowMissing !== void 0) query.append("allowMissing", String(shouldAllowMissing));
442
+ const queryString = query.toString();
443
+ return {
444
+ body: buildUpdateBody(parameters),
445
+ headers: { "content-type": "application/json" },
446
+ method: "PATCH",
447
+ url: queryString === "" ? base : `${base}?${queryString}`
448
+ };
449
+ }
450
+ function applySortKeyToBody(body, sortKey) {
451
+ if (sortKey === void 0) return;
452
+ if (sortKey.kind === "string") {
453
+ body["stringSortKey"] = sortKey.value;
454
+ return;
455
+ }
456
+ body["numericSortKey"] = sortKey.value;
457
+ }
458
+ function buildUpdateBody(parameters) {
459
+ const { sortKey, ttl, value } = parameters;
460
+ const body = {};
461
+ if (value !== void 0) body["value"] = value;
462
+ if (ttl !== void 0) body["ttl"] = `${ttl}s`;
463
+ applySortKeyToBody(body, sortKey);
464
+ return body;
465
+ }
466
+ //#endregion
467
+ //#region src/domains/cloud-v2/memory-store-sorted-maps/operations.ts
468
+ const CREATE_PER_MINUTE = 1e6;
469
+ const SECONDS_PER_MINUTE = 60;
470
+ const WRITE_SCOPE = "memory-store.sorted-map:write";
471
+ /**
472
+ * Per-second request ceiling for creating a memory-store sorted-map
473
+ * item, from the Open Cloud OpenAPI schema (1,000,000 requests per
474
+ * minute per API key owner). Keyed independently from the get, update,
475
+ * delete, and list operations so the five do not share a queue.
476
+ */
477
+ const CREATE_OPERATION_LIMIT = Object.freeze({
478
+ maxPerSecond: CREATE_PER_MINUTE / SECONDS_PER_MINUTE,
479
+ operationKey: "memory-store-sorted-maps.create"
480
+ });
481
+ /**
482
+ * Scopes required to create a memory-store sorted-map item, sourced
483
+ * from `x-roblox-scopes` on the `Cloud_CreateMemoryStoreSortedMapItem`
484
+ * operation in the vendored OpenAPI schema.
485
+ */
486
+ const CREATE_REQUIRED_SCOPES = Object.freeze([WRITE_SCOPE]);
487
+ /**
488
+ * Per-second request ceiling for deleting a memory-store sorted-map
489
+ * item, from the Open Cloud OpenAPI schema (1,000,000 requests per
490
+ * minute per API key owner).
491
+ */
492
+ const DELETE_OPERATION_LIMIT = Object.freeze({
493
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
494
+ operationKey: "memory-store-sorted-maps.delete"
495
+ });
496
+ /**
497
+ * Scopes required to delete a memory-store sorted-map item, sourced
498
+ * from `x-roblox-scopes` on the `Cloud_DeleteMemoryStoreSortedMapItem`
499
+ * operation in the vendored OpenAPI schema.
500
+ */
501
+ const DELETE_REQUIRED_SCOPES = Object.freeze([WRITE_SCOPE]);
502
+ /**
503
+ * Per-second request ceiling for reading a memory-store sorted-map
504
+ * item, from the Open Cloud OpenAPI schema (1,000,000 requests per
505
+ * minute per API key owner).
506
+ */
507
+ const GET_OPERATION_LIMIT = Object.freeze({
508
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
509
+ operationKey: "memory-store-sorted-maps.get"
510
+ });
511
+ /**
512
+ * Scopes required to read a memory-store sorted-map item, sourced from
513
+ * `x-roblox-scopes` on the `Cloud_GetMemoryStoreSortedMapItem`
514
+ * operation in the vendored OpenAPI schema.
515
+ */
516
+ const GET_REQUIRED_SCOPES = Object.freeze(["memory-store.sorted-map:read"]);
517
+ /**
518
+ * Per-second request ceiling for listing memory-store sorted-map
519
+ * items, from the Open Cloud OpenAPI schema (1,000,000 requests per
520
+ * minute per API key owner).
521
+ */
522
+ const LIST_OPERATION_LIMIT = Object.freeze({
523
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
524
+ operationKey: "memory-store-sorted-maps.list"
525
+ });
526
+ /**
527
+ * Scopes required to list memory-store sorted-map items, sourced from
528
+ * `x-roblox-scopes` on the `Cloud_ListMemoryStoreSortedMapItems`
529
+ * operation in the vendored OpenAPI schema.
530
+ */
531
+ const LIST_REQUIRED_SCOPES = Object.freeze(["memory-store.sorted-map:read"]);
532
+ /**
533
+ * Per-second request ceiling for updating a memory-store sorted-map
534
+ * item, from the Open Cloud OpenAPI schema (1,000,000 requests per
535
+ * minute per API key owner).
536
+ */
537
+ const UPDATE_OPERATION_LIMIT = Object.freeze({
538
+ maxPerSecond: 1e6 / SECONDS_PER_MINUTE,
539
+ operationKey: "memory-store-sorted-maps.update"
540
+ });
541
+ /**
542
+ * Scopes required to update a memory-store sorted-map item, sourced
543
+ * from `x-roblox-scopes` on the `Cloud_UpdateMemoryStoreSortedMapItem`
544
+ * operation in the vendored OpenAPI schema.
545
+ */
546
+ const UPDATE_REQUIRED_SCOPES = Object.freeze([WRITE_SCOPE]);
547
+ //#endregion
548
+ //#region src/domains/cloud-v2/memory-store-sorted-maps/parsers.ts
549
+ const PATH_PATTERN = /^cloud\/v2\/universes\/(\d+)\/memory-stores?\/sorted-maps\/([^/]+)\/items\/([^/]+)$/;
550
+ const MALFORMED_MESSAGE = "Malformed memory-store sorted-map item response";
551
+ const MALFORMED_LIST_MESSAGE = "Malformed memory-store sorted-map list response";
552
+ /**
553
+ * Parses a successful memory-store sorted-map item response body (the
554
+ * happy path for create, get, and update) into the public
555
+ * {@link SortedMapItem} shape.
556
+ *
557
+ * @param response - The full {@link HttpResponse} from the Open Cloud API.
558
+ * @returns A success result wrapping the parsed {@link SortedMapItem},
559
+ * or an {@link ApiError} when the body does not match the wire schema.
560
+ */
561
+ function parseSortedMapItemResponse(response) {
562
+ const item = wireBodyToSortedMapItem(response.body);
563
+ if (item === void 0) return malformedSortedMapItem(response.status, response.body);
564
+ return {
565
+ data: item,
566
+ success: true
567
+ };
568
+ }
569
+ /**
570
+ * Parses a successful `Cloud_ListMemoryStoreSortedMapItems` response
571
+ * body into the public {@link ListSortedMapItemsResult} shape. Each
572
+ * item in the `items` array is validated through the same
573
+ * path-and-shape checks as {@link parseSortedMapItemResponse}; a
574
+ * malformed entry rejects the whole response.
575
+ *
576
+ * @param response - The full {@link HttpResponse} from the Open Cloud API.
577
+ * @returns A success result wrapping the parsed
578
+ * {@link ListSortedMapItemsResult}, or an {@link ApiError} when the
579
+ * response shape is wrong.
580
+ */
581
+ function parseListResponse(response) {
582
+ const { body, status: statusCode } = response;
583
+ if (!isRecord(body)) return malformedList(statusCode, body);
584
+ const { items: rawItemsField, nextPageToken } = body;
585
+ if (rawItemsField !== void 0 && rawItemsField !== null && !Array.isArray(rawItemsField)) return malformedList(statusCode, body);
586
+ const normalizedToken = nextPageToken ?? void 0;
587
+ if (normalizedToken !== void 0 && typeof normalizedToken !== "string") return malformedList(statusCode, body);
588
+ const items = (rawItemsField ?? []).map(wireBodyToSortedMapItem);
589
+ if (!items.every(isSortedMapItem)) return malformedList(statusCode, body);
590
+ return {
591
+ data: {
592
+ items,
593
+ nextPageToken: normalizedToken
594
+ },
595
+ success: true
596
+ };
597
+ }
598
+ function isSortedMapItemWire(body) {
599
+ if (!isRecord(body)) return false;
600
+ const { id, etag, expireTime, numericSortKey, path, stringSortKey, value } = body;
601
+ return typeof path === "string" && typeof etag === "string" && typeof id === "string" && isDateTimeString(expireTime) && value !== void 0 && (stringSortKey === void 0 || stringSortKey === null || typeof stringSortKey === "string") && (numericSortKey === void 0 || numericSortKey === null || typeof numericSortKey === "number");
602
+ }
603
+ function extractSortKey(body) {
604
+ const hasStringKey = typeof body.stringSortKey === "string";
605
+ const hasNumericKey = typeof body.numericSortKey === "number";
606
+ if (hasStringKey && hasNumericKey) return "conflict";
607
+ if (hasStringKey) return {
608
+ kind: "string",
609
+ value: body.stringSortKey
610
+ };
611
+ if (hasNumericKey) return {
612
+ kind: "numeric",
613
+ value: body.numericSortKey
614
+ };
615
+ }
616
+ function wireBodyToSortedMapItem(body) {
617
+ if (!isSortedMapItemWire(body)) return;
618
+ const match = PATH_PATTERN.exec(body.path);
619
+ const universeId = match?.[1];
620
+ const mapId = match?.[2];
621
+ if (universeId === void 0 || mapId === void 0) return;
622
+ const sortKey = extractSortKey(body);
623
+ if (sortKey === "conflict") return;
624
+ return {
625
+ id: body.id,
626
+ etag: body.etag,
627
+ expiresAt: new Date(body.expireTime),
628
+ mapId,
629
+ sortKey,
630
+ universeId,
631
+ value: body.value
632
+ };
633
+ }
634
+ function malformedSortedMapItem(statusCode, body) {
635
+ return {
636
+ err: new ApiError(MALFORMED_MESSAGE, {
637
+ details: body,
638
+ statusCode
639
+ }),
640
+ success: false
641
+ };
642
+ }
643
+ function isSortedMapItem(item) {
644
+ return item !== void 0;
645
+ }
646
+ function malformedList(statusCode, body) {
647
+ return {
648
+ err: new ApiError(MALFORMED_LIST_MESSAGE, {
649
+ details: body,
650
+ statusCode
651
+ }),
652
+ success: false
653
+ };
654
+ }
655
+ //#endregion
656
+ //#region src/resources/storage/sorted-maps-group.ts
657
+ function makeSpec(spec) {
658
+ return Object.freeze(spec);
659
+ }
660
+ const CREATE_SPEC = makeSpec({
661
+ buildRequest: (parameters) => okRequest(buildCreateRequest(parameters)),
662
+ methodDefaults: CREATE_METHOD_DEFAULTS,
663
+ methodKind: "create",
664
+ operationLimit: CREATE_OPERATION_LIMIT,
665
+ parse: parseSortedMapItemResponse,
666
+ requiredScopes: CREATE_REQUIRED_SCOPES
667
+ });
668
+ const DELETE_SPEC = makeSpec({
669
+ buildRequest: (parameters) => okRequest(buildDeleteRequest(parameters)),
670
+ methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
671
+ methodKind: "idempotent",
672
+ operationLimit: DELETE_OPERATION_LIMIT,
673
+ parse: parseEmptyResponse,
674
+ requiredScopes: DELETE_REQUIRED_SCOPES
675
+ });
676
+ const GET_SPEC = makeSpec({
677
+ buildRequest: (parameters) => okRequest(buildGetRequest(parameters)),
678
+ methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
679
+ methodKind: "idempotent",
680
+ operationLimit: GET_OPERATION_LIMIT,
681
+ parse: parseSortedMapItemResponse,
682
+ requiredScopes: GET_REQUIRED_SCOPES
683
+ });
684
+ const LIST_SPEC = makeSpec({
685
+ buildRequest: (parameters) => okRequest(buildListRequest(parameters)),
686
+ methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
687
+ methodKind: "idempotent",
688
+ operationLimit: LIST_OPERATION_LIMIT,
689
+ parse: parseListResponse,
690
+ requiredScopes: LIST_REQUIRED_SCOPES
691
+ });
692
+ const UPDATE_SPEC = makeSpec({
693
+ buildRequest: (parameters) => okRequest(buildUpdateRequest(parameters)),
694
+ methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
695
+ methodKind: "idempotent",
696
+ operationLimit: UPDATE_OPERATION_LIMIT,
697
+ parse: parseSortedMapItemResponse,
698
+ requiredScopes: UPDATE_REQUIRED_SCOPES
699
+ });
700
+ /**
701
+ * Operation Group on `StorageClient` that exposes the memory-store
702
+ * sorted-map endpoints. Sorted maps are ordered collections of
703
+ * (id, value, sortKey) triples; consumers create, read, update, list,
704
+ * and delete items keyed by a caller-supplied identifier and ordered
705
+ * by an optional string or numeric sort key.
706
+ */
707
+ var MemoryStoreSortedMapsGroup = class {
708
+ #inner;
709
+ /**
710
+ * Wraps the shared {@link ResourceClient} so the Operation Group
711
+ * routes calls through the same retry, hooks, and rate-limit queues
712
+ * as the rest of the parent client.
713
+ *
714
+ * @param inner - The shared {@link ResourceClient} owned by the
715
+ * parent client.
716
+ */
717
+ constructor(inner) {
718
+ this.#inner = inner;
719
+ }
720
+ /**
721
+ * Creates a single item in a sorted map. The sorted map is
722
+ * auto-created on first use; the map identifier is any string the
723
+ * caller picks. Items are keyed by `itemId` (case-sensitive) and
724
+ * ordered by an optional `sortKey`. Items expire and are removed
725
+ * automatically after `ttl` seconds, or after a server-default
726
+ * lifetime when omitted.
727
+ *
728
+ * On 5xx, create does not retry: Roblox Open Cloud has no
729
+ * idempotency-key support, so a retry of a transient failure risks
730
+ * producing a duplicate item.
731
+ *
732
+ * @param parameters - Universe, sorted-map, item identifiers, the
733
+ * value to store, and optional `sortKey` and `ttl`.
734
+ * @param options - Optional per-request overrides (e.g. A different
735
+ * {@link OpenCloudClientOptions.apiKey} for this call only).
736
+ * @returns A {@link Result} wrapping the parsed {@link SortedMapItem}
737
+ * or the {@link OpenCloudError} that caused the request to fail.
738
+ */
739
+ async create(parameters, options) {
740
+ return this.#inner.execute({
741
+ options,
742
+ parameters,
743
+ spec: CREATE_SPEC
744
+ });
745
+ }
746
+ /**
747
+ * Removes a single item from a sorted map. The call is idempotent:
748
+ * a second `delete` against the same item is a no-op once the
749
+ * server has dropped the row. The retry policy retries both 429
750
+ * and 5xx.
751
+ *
752
+ * @param parameters - Universe, sorted-map, and item identifiers.
753
+ * @param options - Optional per-request overrides.
754
+ * @returns A {@link Result} wrapping `undefined` on success or the
755
+ * {@link OpenCloudError} that caused the request to fail.
756
+ */
757
+ async delete(parameters, options) {
758
+ return this.#inner.execute({
759
+ options,
760
+ parameters,
761
+ spec: DELETE_SPEC
762
+ });
763
+ }
764
+ /**
765
+ * Reads a single item from a sorted map. Returns the parsed
766
+ * {@link SortedMapItem} with the server-recorded `etag` for use in
767
+ * subsequent conditional updates (once the SDK begins emitting
768
+ * `If-Match`; see the package README).
769
+ *
770
+ * @param parameters - Universe, sorted-map, and item identifiers.
771
+ * @param options - Optional per-request overrides.
772
+ * @returns A {@link Result} wrapping the parsed {@link SortedMapItem}
773
+ * or the {@link OpenCloudError} that caused the request to fail.
774
+ */
775
+ async get(parameters, options) {
776
+ return this.#inner.execute({
777
+ options,
778
+ parameters,
779
+ spec: GET_SPEC
780
+ });
781
+ }
782
+ /**
783
+ * Lists items in a sorted map. The server caps `maxPageSize` at
784
+ * `100` and defaults it to `1` when omitted, so callers explicitly
785
+ * pass `maxPageSize` to retrieve more than a single item per page.
786
+ * The `filter` parameter accepts a CEL expression on `id` and
787
+ * `sortKey` (operators `<`, `>`, `&&` only).
788
+ *
789
+ * @param parameters - Universe and sorted-map identifiers, plus
790
+ * optional pagination and filter parameters.
791
+ * @param options - Optional per-request overrides.
792
+ * @returns A {@link Result} wrapping the parsed
793
+ * {@link ListSortedMapItemsResult} or the {@link OpenCloudError}
794
+ * that caused the request to fail.
795
+ */
796
+ async list(parameters, options) {
797
+ return this.#inner.execute({
798
+ options,
799
+ parameters,
800
+ spec: LIST_SPEC
801
+ });
802
+ }
803
+ /**
804
+ * Updates a sorted-map item under PATCH semantics: omitted body
805
+ * fields are left unchanged on the server, supplied fields replace
806
+ * their existing values. Passing `allowMissing: true` creates the
807
+ * item when no row exists instead of returning 404.
808
+ *
809
+ * Retries 5xx because PATCH with the same body produces the same
810
+ * server state.
811
+ *
812
+ * @param parameters - Universe, sorted-map, and item identifiers,
813
+ * plus any subset of `value`, `ttl`, `sortKey`, and
814
+ * `allowMissing`.
815
+ * @param options - Optional per-request overrides.
816
+ * @returns A {@link Result} wrapping the parsed {@link SortedMapItem}
817
+ * or the {@link OpenCloudError} that caused the request to fail.
818
+ */
819
+ async update(parameters, options) {
820
+ return this.#inner.execute({
821
+ options,
822
+ parameters,
823
+ spec: UPDATE_SPEC
824
+ });
825
+ }
826
+ };
827
+ //#endregion
333
828
  //#region src/resources/storage/client.ts
334
829
  /**
335
830
  * Public client for the Roblox Open Cloud `Data and memory stores`
336
831
  * Feature. Today it covers memory-store queues via the
337
- * {@link StorageClient.queues} Operation Group; future Operation
338
- * Groups for sorted maps and data stores slot in as siblings on the
339
- * same client.
832
+ * {@link StorageClient.queues} Operation Group and memory-store sorted
833
+ * maps via the {@link StorageClient.sortedMaps} Operation Group; a
834
+ * future data-stores Operation Group slots in as a sibling on the same
835
+ * client.
340
836
  *
341
837
  * Every method returns a `Result` so callers handle failure
342
838
  * explicitly; no thrown error ever escapes the client.
343
839
  *
840
+ * @since 0.1.0
841
+ *
344
842
  * @example
345
843
  *
346
844
  * ```ts
@@ -353,6 +851,8 @@ var MemoryStoreQueuesGroup = class {
353
851
  var StorageClient = class {
354
852
  /** Memory-store queue Operation Group. */
355
853
  queues;
854
+ /** Memory-store sorted-map Operation Group. */
855
+ sortedMaps;
356
856
  /**
357
857
  * Creates a new {@link StorageClient}. Configuration is frozen on
358
858
  * construction; per-request overrides are accepted on each method.
@@ -362,6 +862,7 @@ var StorageClient = class {
362
862
  constructor(options) {
363
863
  const inner = new ResourceClient(options);
364
864
  this.queues = new MemoryStoreQueuesGroup(inner);
865
+ this.sortedMaps = new MemoryStoreSortedMapsGroup(inner);
365
866
  }
366
867
  };
367
868
  //#endregion