@bedrock-rbx/ocale 0.1.0-beta.1 → 0.1.0-beta.10

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