@bedrock-rbx/ocale 0.1.0-beta.1 → 0.1.0-beta.3
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/badges.d.mts +86 -3
- package/dist/badges.d.mts.map +1 -1
- package/dist/badges.mjs +114 -6
- package/dist/badges.mjs.map +1 -1
- package/dist/data.generated-DOaDx6J0.d.mts +485 -0
- package/dist/data.generated-DOaDx6J0.d.mts.map +1 -0
- package/dist/developer-products.d.mts +14 -5
- package/dist/developer-products.d.mts.map +1 -1
- package/dist/developer-products.mjs +6 -5
- package/dist/developer-products.mjs.map +1 -1
- package/dist/game-passes.d.mts +83 -2
- package/dist/game-passes.d.mts.map +1 -1
- package/dist/game-passes.mjs +112 -5
- package/dist/game-passes.mjs.map +1 -1
- package/dist/index.d.mts +75 -64
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -3
- package/dist/is-date-time-string-Ds8Ew-Xa.mjs +19 -0
- package/dist/is-date-time-string-Ds8Ew-Xa.mjs.map +1 -0
- package/dist/locales.d.mts +2 -0
- package/dist/locales.mjs +512 -0
- package/dist/locales.mjs.map +1 -0
- package/dist/luau-execution.d.mts +149 -0
- package/dist/luau-execution.d.mts.map +1 -0
- package/dist/luau-execution.mjs +164 -0
- package/dist/luau-execution.mjs.map +1 -0
- package/dist/places.d.mts +87 -8
- package/dist/places.d.mts.map +1 -1
- package/dist/places.mjs +58 -13
- package/dist/places.mjs.map +1 -1
- package/dist/poll-timeout-BdUcWv52.mjs +79 -0
- package/dist/poll-timeout-BdUcWv52.mjs.map +1 -0
- package/dist/polling-Cc50rgl6.d.mts +253 -0
- package/dist/polling-Cc50rgl6.d.mts.map +1 -0
- package/dist/polling-helpers-BVkmr6C7.mjs +636 -0
- package/dist/polling-helpers-BVkmr6C7.mjs.map +1 -0
- package/dist/{price-information-CmpscMc4.mjs → price-information-DFf89abd.mjs} +2 -2
- package/dist/{price-information-CmpscMc4.mjs.map → price-information-DFf89abd.mjs.map} +1 -1
- package/dist/rate-limit-BSbFNSGT.d.mts +92 -0
- package/dist/rate-limit-BSbFNSGT.d.mts.map +1 -0
- package/dist/{rate-limit-BBU_4xnZ.mjs → rate-limit-CKfuhxT1.mjs} +11 -3
- package/dist/rate-limit-CKfuhxT1.mjs.map +1 -0
- package/dist/{resource-client-CaS_j3yg.mjs → resource-client-opC6BUkL.mjs} +78 -15
- package/dist/resource-client-opC6BUkL.mjs.map +1 -0
- package/dist/storage.d.mts +380 -0
- package/dist/storage.d.mts.map +1 -0
- package/dist/storage.mjs +371 -0
- package/dist/storage.mjs.map +1 -0
- package/dist/{to-blob-1BtHsDGK.mjs → to-blob-DHN7UoM8.mjs} +1 -1
- package/dist/{to-blob-1BtHsDGK.mjs.map → to-blob-DHN7UoM8.mjs.map} +1 -1
- package/dist/{types-YCTsM8Qd.d.mts → types-DUzm6maA.d.mts} +1 -1
- package/dist/{types-YCTsM8Qd.d.mts.map → types-DUzm6maA.d.mts.map} +1 -1
- package/dist/universes.d.mts +37 -12
- package/dist/universes.d.mts.map +1 -1
- package/dist/universes.mjs +6 -5
- package/dist/universes.mjs.map +1 -1
- package/dist/{validation-CTZzJhmd.mjs → validation-VImVHzxg.mjs} +2 -2
- package/dist/validation-VImVHzxg.mjs.map +1 -0
- package/package.json +7 -3
- package/dist/rate-limit-BBU_4xnZ.mjs.map +0 -1
- package/dist/resource-client-CaS_j3yg.mjs.map +0 -1
- package/dist/validation-CTZzJhmd.mjs.map +0 -1
package/dist/badges.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { d as OpenCloudError, i as OpenCloudClientOptions, l as Result, s as RequestOptions } from "./types-
|
|
1
|
+
import { d as OpenCloudError, i as OpenCloudClientOptions, l as Result, s as RequestOptions } from "./types-DUzm6maA.mjs";
|
|
2
|
+
import { i as RobloxLocale, r as RobloxLanguageCode } from "./data.generated-DOaDx6J0.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/domains/badges/badges/types.d.ts
|
|
4
5
|
/**
|
|
@@ -101,13 +102,55 @@ interface Badge {
|
|
|
101
102
|
readonly updatedAt: Date;
|
|
102
103
|
}
|
|
103
104
|
//#endregion
|
|
105
|
+
//#region src/domains/game-internationalization/badge-icon/types.d.ts
|
|
106
|
+
/**
|
|
107
|
+
* Parameters for uploading or replacing the per-locale icon registered
|
|
108
|
+
* against a badge. A subsequent upload for the same `(badgeId, languageCode)`
|
|
109
|
+
* pair replaces the existing icon for that locale. Source-language icons
|
|
110
|
+
* are managed through `BadgesClient.uploadIcon`.
|
|
111
|
+
*/
|
|
112
|
+
interface UploadBadgeIconLocalizationParameters {
|
|
113
|
+
/** Stringified ID of the badge whose icon is being uploaded. */
|
|
114
|
+
readonly badgeId: string;
|
|
115
|
+
/** Image bytes to upload. PNG and JPEG are accepted by the server. */
|
|
116
|
+
readonly image: Blob | Uint8Array;
|
|
117
|
+
/**
|
|
118
|
+
* Roblox wire form the icon is being uploaded for. Either the
|
|
119
|
+
* Language form (e.g. `en`, `fil`, `zh-hans`) or the Locale form
|
|
120
|
+
* (e.g. `en_us`, `pt_br`, `ar_001`).
|
|
121
|
+
*/
|
|
122
|
+
readonly languageCode: RobloxLanguageCode | RobloxLocale;
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/domains/game-internationalization/badge-name-description/types.d.ts
|
|
126
|
+
/**
|
|
127
|
+
* Parameters for updating the per-locale name and/or description registered
|
|
128
|
+
* against a badge. Both `name` and `description` are optional; fields omitted
|
|
129
|
+
* from the call are not included in the JSON body so the server leaves the
|
|
130
|
+
* existing value for that locale untouched.
|
|
131
|
+
*/
|
|
132
|
+
interface UpdateBadgeNameDescriptionParameters {
|
|
133
|
+
/** Replacement display name for the supplied locale. */
|
|
134
|
+
readonly name?: string;
|
|
135
|
+
/** Stringified ID of the badge whose localization is being updated. */
|
|
136
|
+
readonly badgeId: string;
|
|
137
|
+
/** Replacement description for the supplied locale. */
|
|
138
|
+
readonly description?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Roblox wire form being updated. Either the Language form (e.g.
|
|
141
|
+
* `en`, `fil`, `zh-hans`) or the Locale form (e.g. `en_us`, `pt_br`,
|
|
142
|
+
* `ar_001`).
|
|
143
|
+
*/
|
|
144
|
+
readonly languageCode: RobloxLanguageCode | RobloxLocale;
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
104
147
|
//#region src/domains/publish/badge-icon/types.d.ts
|
|
105
148
|
/**
|
|
106
149
|
* Parameters for uploading or replacing the source-language icon
|
|
107
150
|
* registered against a badge. A subsequent upload for the same badge
|
|
108
151
|
* replaces the existing source icon; per-locale icon overlays live
|
|
109
152
|
* under a separate `legacy-game-internationalization` endpoint and
|
|
110
|
-
* are
|
|
153
|
+
* are managed through `BadgesClient.localization.uploadIcon`.
|
|
111
154
|
*/
|
|
112
155
|
interface UploadBadgeIconParameters {
|
|
113
156
|
/** Stringified ID of the badge whose icon is being uploaded. */
|
|
@@ -117,6 +160,36 @@ interface UploadBadgeIconParameters {
|
|
|
117
160
|
}
|
|
118
161
|
//#endregion
|
|
119
162
|
//#region src/resources/badges/client.d.ts
|
|
163
|
+
interface BadgeLocalizationHandle {
|
|
164
|
+
/**
|
|
165
|
+
* Updates the per-locale display name and/or description registered against
|
|
166
|
+
* a badge. Either `name`, `description`, or both may be supplied; omitted
|
|
167
|
+
* fields are not forwarded so the server leaves the existing value for
|
|
168
|
+
* that locale untouched. Mirrors the upstream `200 OK` echo body as
|
|
169
|
+
* `undefined` data.
|
|
170
|
+
*
|
|
171
|
+
* @param parameters - Badge and language identifiers plus the optional
|
|
172
|
+
* replacement values.
|
|
173
|
+
* @param options - Optional per-request overrides.
|
|
174
|
+
* @returns A success {@link Result} with no payload, or the
|
|
175
|
+
* {@link OpenCloudError} that caused the request to fail.
|
|
176
|
+
*/
|
|
177
|
+
updateNameDescription: (parameters: UpdateBadgeNameDescriptionParameters, options?: RequestOptions) => Promise<Result<undefined, OpenCloudError>>;
|
|
178
|
+
/**
|
|
179
|
+
* Uploads or replaces the per-locale icon for a badge. A subsequent
|
|
180
|
+
* upload for the same `(badgeId, languageCode)` pair replaces the
|
|
181
|
+
* existing icon for that locale. Does not retry on 5xx so a duplicate
|
|
182
|
+
* upload cannot be created if the server fails mid-write. Source-language
|
|
183
|
+
* icons remain on {@link BadgesClient.uploadIcon}.
|
|
184
|
+
*
|
|
185
|
+
* @param parameters - Badge and language identifiers plus the image bytes
|
|
186
|
+
* to upload.
|
|
187
|
+
* @param options - Optional per-request overrides.
|
|
188
|
+
* @returns A success {@link Result} with no payload, or the
|
|
189
|
+
* {@link OpenCloudError} that caused the request to fail.
|
|
190
|
+
*/
|
|
191
|
+
uploadIcon: (parameters: UploadBadgeIconLocalizationParameters, options?: RequestOptions) => Promise<Result<undefined, OpenCloudError>>;
|
|
192
|
+
}
|
|
120
193
|
/**
|
|
121
194
|
* Public client for the Roblox Open Cloud Badges API. Covers programmatic
|
|
122
195
|
* badge creation under a universe, partial updates of badge configuration
|
|
@@ -140,6 +213,16 @@ interface UploadBadgeIconParameters {
|
|
|
140
213
|
declare class BadgesClient {
|
|
141
214
|
#private;
|
|
142
215
|
/**
|
|
216
|
+
* Operation Group exposing per-locale localization Operations
|
|
217
|
+
* (`updateNameDescription`, `uploadIcon`) backed by the
|
|
218
|
+
* `legacy-game-internationalization` domain. Source-language values
|
|
219
|
+
* remain on {@link BadgesClient.update} and
|
|
220
|
+
* {@link BadgesClient.uploadIcon}; methods on this group set per-locale
|
|
221
|
+
* overlays on top. Shares the parent client's HTTP, rate-limit, and
|
|
222
|
+
* retry plumbing.
|
|
223
|
+
*/
|
|
224
|
+
readonly localization: BadgeLocalizationHandle;
|
|
225
|
+
/**
|
|
143
226
|
* Creates a new {@link BadgesClient}. Configuration is frozen on
|
|
144
227
|
* construction; per-request overrides are accepted on each method.
|
|
145
228
|
*
|
|
@@ -182,5 +265,5 @@ declare class BadgesClient {
|
|
|
182
265
|
uploadIcon(parameters: UploadBadgeIconParameters, options?: RequestOptions): Promise<Result<undefined, OpenCloudError>>;
|
|
183
266
|
}
|
|
184
267
|
//#endregion
|
|
185
|
-
export { type Badge, type BadgeAwarder, type BadgeAwarderType, type BadgePaymentSource, type BadgeStatistics, BadgesClient, type CreateBadgeParameters, type UpdateBadgeParameters, type UploadBadgeIconParameters };
|
|
268
|
+
export { type Badge, type BadgeAwarder, type BadgeAwarderType, type BadgePaymentSource, type BadgeStatistics, BadgesClient, type CreateBadgeParameters, type UpdateBadgeNameDescriptionParameters, type UpdateBadgeParameters, type UploadBadgeIconLocalizationParameters, type UploadBadgeIconParameters };
|
|
186
269
|
//# sourceMappingURL=badges.d.mts.map
|
package/dist/badges.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badges.d.mts","names":[],"sources":["../src/domains/badges/badges/types.ts","../src/domains/publish/badge-icon/types.ts","../src/resources/badges/client.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"badges.d.mts","names":[],"sources":["../src/domains/badges/badges/types.ts","../src/domains/game-internationalization/badge-icon/types.ts","../src/domains/game-internationalization/badge-name-description/types.ts","../src/domains/publish/badge-icon/types.ts","../src/resources/badges/client.ts"],"mappings":";;;;;;;;AAMA;;KAAY,gBAAA;;;AAMZ;;UAAiB,YAAA;EAMD;EAAA,SAJN,EAAA;;WAEA,IAAA;;WAEA,IAAA,EAAM,gBAAA;AAAA;AAMhB;;;AAAA,UAAiB,eAAA;;WAEP,YAAA;;WAEA,mBAAA;EAEA;EAAA,SAAA,iBAAA;AAAA;;;;KAME,kBAAA;;;;UAKK,qBAAA;;WAEP,IAAA;EAUgB;EAAA,SARhB,WAAA;;WAEA,YAAA;;WAEA,IAAA,EAAM,IAAA,GAAO,UAAA;;WAEb,QAAA;;WAEA,aAAA,GAAgB,kBAAA;;WAEhB,UAAA;AAAA;AAQV;;;;;AAAA,UAAiB,qBAAA;;WAEP,IAAA;;WAEA,OAAA;EAYV;EAAA,SAVU,WAAA;;WAEA,OAAA;AAAA;;;;;;UAQO,KAAA;;WAEP,EAAA;;WAEA,IAAA;;WAEA,OAAA,EAAS,YAAA;;WAET,SAAA,EAAW,IAAA;;WAEX,WAAA;;WAEA,kBAAA;;WAEA,kBAAA;;WAEA,WAAA;;WAEA,OAAA;;WAEA,WAAA;EC3FO;EAAA,SD6FP,UAAA,EAAY,eAAA;;WAEZ,SAAA,EAAW,IAAA;AAAA;;;;;;AAjGrB;;;UCEiB,qCAAA;EDFL;EAAA,SCIF,OAAA;EDEO;EAAA,SCAP,KAAA,EAAO,IAAA,GAAO,UAAA;EDMR;;;;;EAAA,SCAN,YAAA,EAAc,kBAAA,GAAqB,YAAA;AAAA;;;;;;ADZ7C;;;UEEiB,oCAAA;EFFL;EAAA,SEIF,IAAA;EFEO;EAAA,SEAP,OAAA;EFMM;EAAA,SEJN,WAAA;;;;;;WAMA,YAAA,EAAc,kBAAA,GAAqB,YAAA;AAAA;;;;;;;AFd7C;;;UGCiB,yBAAA;EHDL;EAAA,SGGF,OAAA;EHGO;EAAA,SGDP,IAAA,EAAM,IAAA,GAAO,UAAA;AAAA;;;UC4Eb,uBAAA;EJjFE;AAMZ;;;;;;;;;;AAYA;;EI6EC,qBAAA,GACC,UAAA,EAAY,oCAAA,EACZ,OAAA,GAAU,cAAA,KACN,OAAA,CAAQ,MAAA,YAAkB,cAAA;EJhFf;;;;;;AAYjB;;;;;AAKA;;EI6EC,UAAA,GACC,UAAA,EAAY,qCAAA,EACZ,OAAA,GAAU,cAAA,KACN,OAAA,CAAQ,MAAA,YAAkB,cAAA;AAAA;;;;;;;;;;;;;;;;;AJ1DhC;;;;cIiFa,YAAA;EAAA;;;;;AJjEb;;;;;WI6EiB,YAAA,EAAc,uBAAA;;;;;;;EAQ9B,WAAA,CAAY,OAAA,EAAS,sBAAA;;;;;;;;;;EAcrB,MAAA,CACC,UAAA,EAAY,qBAAA,EACZ,OAAA,GAAU,cAAA,GACR,OAAA,CAAQ,MAAA,CAAO,KAAA,EAAO,cAAA;;;;;;;;AH7K1B;;;;EG4LC,MAAA,CACC,UAAA,EAAY,qBAAA,EACZ,OAAA,GAAU,cAAA,GACR,OAAA,CAAQ,MAAA,YAAkB,cAAA;;;;;;;;;;;;EAe7B,UAAA,CACC,UAAA,EAAY,yBAAA,EACZ,OAAA,GAAU,cAAA,GACR,OAAA,CAAQ,MAAA,YAAkB,cAAA;AAAA"}
|
package/dist/badges.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { i as ApiError } from "./rate-limit-
|
|
2
|
-
import { t as toBlob } from "./to-blob-
|
|
3
|
-
import {
|
|
1
|
+
import { i as ApiError } from "./rate-limit-CKfuhxT1.mjs";
|
|
2
|
+
import { t as toBlob } from "./to-blob-DHN7UoM8.mjs";
|
|
3
|
+
import { t as isDateTimeString } from "./is-date-time-string-Ds8Ew-Xa.mjs";
|
|
4
|
+
import { a as IDEMPOTENT_METHOD_DEFAULTS, i as CREATE_METHOD_DEFAULTS, n as okRequest, r as parseEmptyResponse, s as isRecord, t as ResourceClient } from "./resource-client-opC6BUkL.mjs";
|
|
4
5
|
//#region src/domains/badges/badges/builders.ts
|
|
5
6
|
/**
|
|
6
7
|
* Builds a `POST` request for the legacy "create badge" endpoint.
|
|
@@ -31,7 +32,7 @@ function buildCreateRequest(parameters) {
|
|
|
31
32
|
* @param parameters - Identifier plus fields to update.
|
|
32
33
|
* @returns A pure {@link HttpRequest} describing the update call.
|
|
33
34
|
*/
|
|
34
|
-
function buildUpdateRequest(parameters) {
|
|
35
|
+
function buildUpdateRequest$1(parameters) {
|
|
35
36
|
const body = {};
|
|
36
37
|
if (parameters.name !== void 0) body["name"] = parameters.name;
|
|
37
38
|
if (parameters.description !== void 0) body["description"] = parameters.description;
|
|
@@ -134,7 +135,7 @@ function copyStatistics(statistics) {
|
|
|
134
135
|
};
|
|
135
136
|
}
|
|
136
137
|
function hasRequiredPrimitiveFields(body) {
|
|
137
|
-
return typeof body["id"] === "number" && typeof body["name"] === "string" && typeof body["description"] === "string" && typeof body["displayName"] === "string" && typeof body["displayDescription"] === "string" && typeof body["enabled"] === "boolean" && typeof body["iconImageId"] === "number" && typeof body["displayIconImageId"] === "number" &&
|
|
138
|
+
return typeof body["id"] === "number" && typeof body["name"] === "string" && typeof body["description"] === "string" && typeof body["displayName"] === "string" && typeof body["displayDescription"] === "string" && typeof body["enabled"] === "boolean" && typeof body["iconImageId"] === "number" && typeof body["displayIconImageId"] === "number" && isDateTimeString(body["created"]) && isDateTimeString(body["updated"]);
|
|
138
139
|
}
|
|
139
140
|
function isBadgeAwarderWire(value) {
|
|
140
141
|
if (!isRecord(value)) return false;
|
|
@@ -152,6 +153,68 @@ function isBadgeResponseV2Wire(body) {
|
|
|
152
153
|
return true;
|
|
153
154
|
}
|
|
154
155
|
//#endregion
|
|
156
|
+
//#region src/domains/game-internationalization/badge-icon/builders.ts
|
|
157
|
+
/**
|
|
158
|
+
* Builds a `POST` request for the localized "upload badge icon" endpoint. A
|
|
159
|
+
* successful upload replaces any existing icon for the same
|
|
160
|
+
* `(badgeId, languageCode)` pair.
|
|
161
|
+
*
|
|
162
|
+
* @param parameters - Badge and language identifiers plus the image bytes
|
|
163
|
+
* to upload.
|
|
164
|
+
* @returns A pure {@link HttpRequest} describing the upload call.
|
|
165
|
+
*/
|
|
166
|
+
function buildUploadIconRequest$1(parameters) {
|
|
167
|
+
const body = new FormData();
|
|
168
|
+
body.append("Files", toBlob(parameters.image));
|
|
169
|
+
return {
|
|
170
|
+
body,
|
|
171
|
+
method: "POST",
|
|
172
|
+
url: `/legacy-game-internationalization/v1/badges/${parameters.badgeId}/icons/language-codes/${parameters.languageCode}`
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/domains/game-internationalization/badge-name-description/builders.ts
|
|
177
|
+
/**
|
|
178
|
+
* Builds a `PATCH` request for the localized "update badge name/description"
|
|
179
|
+
* endpoint. Either `name`, `description`, or both may be supplied; omitted
|
|
180
|
+
* fields are not included in the JSON body so the server leaves the existing
|
|
181
|
+
* value for that locale untouched.
|
|
182
|
+
*
|
|
183
|
+
* @param parameters - Badge and language identifiers plus the optional
|
|
184
|
+
* replacement values.
|
|
185
|
+
* @returns A pure {@link HttpRequest} describing the update call.
|
|
186
|
+
*/
|
|
187
|
+
function buildUpdateRequest(parameters) {
|
|
188
|
+
const body = {};
|
|
189
|
+
if (parameters.name !== void 0) body["name"] = parameters.name;
|
|
190
|
+
if (parameters.description !== void 0) body["description"] = parameters.description;
|
|
191
|
+
return {
|
|
192
|
+
body,
|
|
193
|
+
method: "PATCH",
|
|
194
|
+
url: `/legacy-game-internationalization/v1/badges/${parameters.badgeId}/name-description/language-codes/${parameters.languageCode}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/domains/game-internationalization/badge-name-description/operations.ts
|
|
199
|
+
/**
|
|
200
|
+
* Per-second request ceiling for every badge localization Operation. The
|
|
201
|
+
* legacy `gameinternationalization` service caps each API key at 100
|
|
202
|
+
* requests per minute *shared across the entire service* (see the
|
|
203
|
+
* `x-roblox-rate-limits` extension on every operation in the vendored
|
|
204
|
+
* Open Cloud spec), so all badge localization methods queue against the
|
|
205
|
+
* same operation key.
|
|
206
|
+
*/
|
|
207
|
+
const LOCALIZATION_OPERATION_LIMIT = Object.freeze({
|
|
208
|
+
maxPerSecond: 100 / 60,
|
|
209
|
+
operationKey: "badge-localization"
|
|
210
|
+
});
|
|
211
|
+
/**
|
|
212
|
+
* Scopes required for every badge localization operation, sourced from
|
|
213
|
+
* `x-roblox-scopes` on the legacy `gameinternationalization` badge
|
|
214
|
+
* endpoints in the vendored OpenAPI schema.
|
|
215
|
+
*/
|
|
216
|
+
const LOCALIZATION_REQUIRED_SCOPES = Object.freeze(["legacy-badge:manage"]);
|
|
217
|
+
//#endregion
|
|
155
218
|
//#region src/domains/publish/badge-icon/builders.ts
|
|
156
219
|
/**
|
|
157
220
|
* Builds a `POST` request for the legacy "upload badge icon" endpoint. A
|
|
@@ -204,7 +267,7 @@ const CREATE_SPEC = makeSpec({
|
|
|
204
267
|
requiredScopes: CREATE_REQUIRED_SCOPES
|
|
205
268
|
});
|
|
206
269
|
const UPDATE_SPEC = makeSpec({
|
|
207
|
-
buildRequest: (parameters) => okRequest(buildUpdateRequest(parameters)),
|
|
270
|
+
buildRequest: (parameters) => okRequest(buildUpdateRequest$1(parameters)),
|
|
208
271
|
methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
|
|
209
272
|
methodKind: "idempotent",
|
|
210
273
|
operationLimit: UPDATE_OPERATION_LIMIT,
|
|
@@ -219,6 +282,22 @@ const UPLOAD_ICON_SPEC = makeSpec({
|
|
|
219
282
|
parse: parseEmptyResponse,
|
|
220
283
|
requiredScopes: UPLOAD_ICON_REQUIRED_SCOPES
|
|
221
284
|
});
|
|
285
|
+
const UPDATE_NAME_DESCRIPTION_SPEC = makeSpec({
|
|
286
|
+
buildRequest: (parameters) => okRequest(buildUpdateRequest(parameters)),
|
|
287
|
+
methodDefaults: IDEMPOTENT_METHOD_DEFAULTS,
|
|
288
|
+
methodKind: "idempotent",
|
|
289
|
+
operationLimit: LOCALIZATION_OPERATION_LIMIT,
|
|
290
|
+
parse: parseEmptyResponse,
|
|
291
|
+
requiredScopes: LOCALIZATION_REQUIRED_SCOPES
|
|
292
|
+
});
|
|
293
|
+
const UPLOAD_LOCALIZED_ICON_SPEC = makeSpec({
|
|
294
|
+
buildRequest: (parameters) => okRequest(buildUploadIconRequest$1(parameters)),
|
|
295
|
+
methodDefaults: CREATE_METHOD_DEFAULTS,
|
|
296
|
+
methodKind: "create",
|
|
297
|
+
operationLimit: LOCALIZATION_OPERATION_LIMIT,
|
|
298
|
+
parse: parseEmptyResponse,
|
|
299
|
+
requiredScopes: LOCALIZATION_REQUIRED_SCOPES
|
|
300
|
+
});
|
|
222
301
|
/**
|
|
223
302
|
* Public client for the Roblox Open Cloud Badges API. Covers programmatic
|
|
224
303
|
* badge creation under a universe, partial updates of badge configuration
|
|
@@ -242,6 +321,16 @@ const UPLOAD_ICON_SPEC = makeSpec({
|
|
|
242
321
|
var BadgesClient = class {
|
|
243
322
|
#inner;
|
|
244
323
|
/**
|
|
324
|
+
* Operation Group exposing per-locale localization Operations
|
|
325
|
+
* (`updateNameDescription`, `uploadIcon`) backed by the
|
|
326
|
+
* `legacy-game-internationalization` domain. Source-language values
|
|
327
|
+
* remain on {@link BadgesClient.update} and
|
|
328
|
+
* {@link BadgesClient.uploadIcon}; methods on this group set per-locale
|
|
329
|
+
* overlays on top. Shares the parent client's HTTP, rate-limit, and
|
|
330
|
+
* retry plumbing.
|
|
331
|
+
*/
|
|
332
|
+
localization;
|
|
333
|
+
/**
|
|
245
334
|
* Creates a new {@link BadgesClient}. Configuration is frozen on
|
|
246
335
|
* construction; per-request overrides are accepted on each method.
|
|
247
336
|
*
|
|
@@ -249,6 +338,7 @@ var BadgesClient = class {
|
|
|
249
338
|
*/
|
|
250
339
|
constructor(options) {
|
|
251
340
|
this.#inner = new ResourceClient(options);
|
|
341
|
+
this.localization = createLocalizationHandle(this.#inner);
|
|
252
342
|
}
|
|
253
343
|
/**
|
|
254
344
|
* Creates a new badge under the supplied universe.
|
|
@@ -303,6 +393,24 @@ var BadgesClient = class {
|
|
|
303
393
|
});
|
|
304
394
|
}
|
|
305
395
|
};
|
|
396
|
+
function createLocalizationHandle(inner) {
|
|
397
|
+
return {
|
|
398
|
+
async updateNameDescription(parameters, options) {
|
|
399
|
+
return inner.execute({
|
|
400
|
+
options,
|
|
401
|
+
parameters,
|
|
402
|
+
spec: UPDATE_NAME_DESCRIPTION_SPEC
|
|
403
|
+
});
|
|
404
|
+
},
|
|
405
|
+
async uploadIcon(parameters, options) {
|
|
406
|
+
return inner.execute({
|
|
407
|
+
options,
|
|
408
|
+
parameters,
|
|
409
|
+
spec: UPLOAD_LOCALIZED_ICON_SPEC
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
306
414
|
//#endregion
|
|
307
415
|
export { BadgesClient };
|
|
308
416
|
|
package/dist/badges.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badges.mjs","names":["#inner"],"sources":["../src/domains/badges/badges/builders.ts","../src/domains/badges/badges/operations.ts","../src/domains/badges/badges/parsers.ts","../src/domains/publish/badge-icon/builders.ts","../src/domains/publish/badge-icon/operations.ts","../src/resources/badges/client.ts"],"sourcesContent":["import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport { toBlob } from \"../../../internal/utils/to-blob.ts\";\nimport type { BadgePaymentSource, CreateBadgeParameters, UpdateBadgeParameters } from \"./types.ts\";\n\n/**\n * Builds a `POST` request for the legacy \"create badge\" endpoint.\n *\n * @param parameters - Fields describing the new badge; optional values\n * omitted here are left off the multipart payload entirely.\n * @returns A pure {@link HttpRequest} describing the create call.\n */\nexport function buildCreateRequest(parameters: CreateBadgeParameters): HttpRequest {\n\tconst body = new FormData();\n\tbody.append(\"name\", parameters.name);\n\tbody.append(\"files\", toBlob(parameters.icon));\n\tif (parameters.description !== undefined) {\n\t\tbody.append(\"description\", parameters.description);\n\t}\n\n\tif (parameters.isActive !== undefined) {\n\t\tbody.append(\"isActive\", String(parameters.isActive));\n\t}\n\n\tif (parameters.expectedCost !== undefined) {\n\t\tbody.append(\"expectedCost\", String(parameters.expectedCost));\n\t}\n\n\tif (parameters.paymentSource !== undefined) {\n\t\tbody.append(\"paymentSourceType\", toPaymentSourceWire(parameters.paymentSource));\n\t}\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"POST\",\n\t\turl: `/legacy-badges/v1/universes/${parameters.universeId}/badges`,\n\t};\n}\n\n/**\n * Builds a `PATCH` request for the legacy \"update badge\" endpoint. Every\n * field on `parameters` except the identifier is optional; omitted fields\n * are not appended to the JSON body so the server leaves them unchanged.\n *\n * @param parameters - Identifier plus fields to update.\n * @returns A pure {@link HttpRequest} describing the update call.\n */\nexport function buildUpdateRequest(parameters: UpdateBadgeParameters): HttpRequest {\n\tconst body: Record<string, boolean | string> = {};\n\tif (parameters.name !== undefined) {\n\t\tbody[\"name\"] = parameters.name;\n\t}\n\n\tif (parameters.description !== undefined) {\n\t\tbody[\"description\"] = parameters.description;\n\t}\n\n\tif (parameters.enabled !== undefined) {\n\t\tbody[\"enabled\"] = parameters.enabled;\n\t}\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"PATCH\",\n\t\turl: `/legacy-badges/v1/badges/${parameters.badgeId}`,\n\t};\n}\n\nfunction toPaymentSourceWire(source: BadgePaymentSource): \"1\" | \"2\" {\n\treturn source === \"User\" ? \"1\" : \"2\";\n}\n","import type { OperationLimit } from \"../../../internal/http/rate-limit-queue.ts\";\n\n/**\n * Per-second request ceiling for creating a badge, sourced from\n * `x-roblox-rate-limits` on the legacy badges create operation in the\n * vendored OpenAPI schema (100 per minute, per API key owner).\n */\nexport const CREATE_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.create\",\n});\n\n/**\n * Per-second request ceiling for updating a badge, sourced from\n * `x-roblox-rate-limits` on the legacy badges update operation in the\n * vendored OpenAPI schema. Keyed independently from\n * {@link CREATE_OPERATION_LIMIT} so create and update do not share a\n * queue, since Roblox does not document the per-minute quota as shared\n * between the POST and PATCH endpoints.\n */\nexport const UPDATE_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.update\",\n});\n\n/**\n * Scopes the API key or OAuth token must carry to create a badge,\n * sourced from `x-roblox-scopes` on the legacy badges create operation\n * in the vendored OpenAPI schema. The trailing\n * `:manage-and-spend-robux` reflects that badge creation may charge a\n * Robux fee.\n */\nexport const CREATE_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-universe.badge:manage-and-spend-robux\",\n]);\n\n/**\n * Scopes the API key or OAuth token must carry to update a badge,\n * sourced from `x-roblox-scopes` on the legacy badges update operation\n * in the vendored OpenAPI schema.\n */\nexport const UPDATE_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-universe.badge:write\",\n]);\n","import type { HttpResponse } from \"../../../client/types.ts\";\nimport { ApiError } from \"../../../errors/api-error.ts\";\nimport { isRecord } from \"../../../internal/utils/is-record.ts\";\nimport type { Result } from \"../../../types.ts\";\nimport type { Badge, BadgeAwarder, BadgeStatistics } from \"./types.ts\";\nimport type { BadgeAwarderWire, BadgeResponseV2Wire, BadgeStatisticsWire } from \"./wire.ts\";\n\n/**\n * Parses a successful Badges API response into the public `Badge` shape,\n * returning a `Result` so callers can handle malformed payloads without\n * exceptions.\n *\n * @param response - The full {@link HttpResponse} from the Open Cloud API.\n * The status code is included on the returned `ApiError` when validation\n * fails; the headers are available for future parsers that need them.\n * @returns A success result wrapping the converted `Badge`, or an\n * `ApiError` when the body does not match the wire schema.\n */\nexport function parseBadgeResponse(response: HttpResponse): Result<Badge, ApiError> {\n\tconst { body, status: statusCode } = response;\n\n\tif (!isBadgeResponseV2Wire(body)) {\n\t\treturn {\n\t\t\terr: new ApiError(\"Malformed badge response\", { statusCode }),\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tdata: {\n\t\t\tid: String(body.id),\n\t\t\tname: body.name,\n\t\t\tawarder: copyAwarder(body.awarder),\n\t\t\tcreatedAt: new Date(body.created),\n\t\t\tdescription: body.description,\n\t\t\tdisplayDescription: body.displayDescription,\n\t\t\tdisplayIconImageId:\n\t\t\t\tbody.displayIconImageId === 0 ? undefined : String(body.displayIconImageId),\n\t\t\tdisplayName: body.displayName,\n\t\t\tenabled: body.enabled,\n\t\t\ticonImageId: body.iconImageId === 0 ? undefined : String(body.iconImageId),\n\t\t\tstatistics: copyStatistics(body.statistics),\n\t\t\tupdatedAt: new Date(body.updated),\n\t\t},\n\t\tsuccess: true,\n\t};\n}\n\nfunction copyAwarder(awarder: BadgeAwarderWire): BadgeAwarder {\n\treturn { id: String(awarder.id), name: awarder.name, type: \"Place\" };\n}\n\nfunction copyStatistics(statistics: BadgeStatisticsWire): BadgeStatistics {\n\treturn {\n\t\tawardedCount: statistics.awardedCount,\n\t\tpastDayAwardedCount: statistics.pastDayAwardedCount,\n\t\twinRatePercentage: statistics.winRatePercentage,\n\t};\n}\n\nfunction hasRequiredPrimitiveFields(body: Record<string, unknown>): boolean {\n\treturn (\n\t\ttypeof body[\"id\"] === \"number\" &&\n\t\ttypeof body[\"name\"] === \"string\" &&\n\t\ttypeof body[\"description\"] === \"string\" &&\n\t\ttypeof body[\"displayName\"] === \"string\" &&\n\t\ttypeof body[\"displayDescription\"] === \"string\" &&\n\t\ttypeof body[\"enabled\"] === \"boolean\" &&\n\t\ttypeof body[\"iconImageId\"] === \"number\" &&\n\t\ttypeof body[\"displayIconImageId\"] === \"number\" &&\n\t\ttypeof body[\"created\"] === \"string\" &&\n\t\ttypeof body[\"updated\"] === \"string\"\n\t);\n}\n\nfunction isBadgeAwarderWire(value: unknown): value is BadgeAwarderWire {\n\tif (!isRecord(value)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\ttypeof value[\"id\"] === \"number\" && typeof value[\"name\"] === \"string\" && value[\"type\"] === 1\n\t);\n}\n\nfunction isBadgeStatisticsWire(value: unknown): value is BadgeStatisticsWire {\n\tif (!isRecord(value)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\ttypeof value[\"awardedCount\"] === \"number\" &&\n\t\ttypeof value[\"pastDayAwardedCount\"] === \"number\" &&\n\t\ttypeof value[\"winRatePercentage\"] === \"number\"\n\t);\n}\n\nfunction isBadgeResponseV2Wire(body: unknown): body is BadgeResponseV2Wire {\n\tif (!isRecord(body)) {\n\t\treturn false;\n\t}\n\n\tif (!hasRequiredPrimitiveFields(body)) {\n\t\treturn false;\n\t}\n\n\tif (!isBadgeAwarderWire(body[\"awarder\"])) {\n\t\treturn false;\n\t}\n\n\tif (!isBadgeStatisticsWire(body[\"statistics\"])) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n","import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport { toBlob } from \"../../../internal/utils/to-blob.ts\";\nimport type { UploadBadgeIconParameters } from \"./types.ts\";\n\n/**\n * Builds a `POST` request for the legacy \"upload badge icon\" endpoint. A\n * successful upload replaces any existing source-language icon on the\n * badge.\n *\n * @param parameters - Badge identifier plus the image bytes to upload.\n * @returns A pure {@link HttpRequest} describing the upload call.\n */\nexport function buildUploadIconRequest(parameters: UploadBadgeIconParameters): HttpRequest {\n\tconst body = new FormData();\n\tbody.append(\"Files\", toBlob(parameters.icon));\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"POST\",\n\t\turl: `/legacy-publish/v1/badges/${parameters.badgeId}/icon`,\n\t};\n}\n","import type { OperationLimit } from \"../../../internal/http/rate-limit-queue.ts\";\n\n/**\n * Per-second request ceiling for uploading a badge icon, sourced from\n * `x-roblox-rate-limits` on the legacy badge icon upload operation in\n * the vendored OpenAPI schema (100 per minute, per API key owner). Keyed\n * separately from the badges create and update buckets because Roblox\n * does not document the legacy-publish quota as shared with the\n * legacy-badges quota.\n */\nexport const UPLOAD_ICON_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.upload-icon\",\n});\n\n/**\n * Scopes the API key or OAuth token must carry to upload a badge icon,\n * sourced from `x-roblox-scopes` on the legacy badge icon upload\n * operation in the vendored OpenAPI schema.\n */\nexport const UPLOAD_ICON_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-badge:manage\",\n]);\n","import type { OpenCloudClientOptions, RequestOptions } from \"../../client/types.ts\";\nimport { buildCreateRequest, buildUpdateRequest } from \"../../domains/badges/badges/builders.ts\";\nimport {\n\tCREATE_OPERATION_LIMIT,\n\tCREATE_REQUIRED_SCOPES,\n\tUPDATE_OPERATION_LIMIT,\n\tUPDATE_REQUIRED_SCOPES,\n} from \"../../domains/badges/badges/operations.ts\";\nimport { parseBadgeResponse } from \"../../domains/badges/badges/parsers.ts\";\nimport type {\n\tBadge,\n\tCreateBadgeParameters,\n\tUpdateBadgeParameters,\n} from \"../../domains/badges/badges/types.ts\";\nimport { buildUploadIconRequest } from \"../../domains/publish/badge-icon/builders.ts\";\nimport {\n\tUPLOAD_ICON_OPERATION_LIMIT,\n\tUPLOAD_ICON_REQUIRED_SCOPES,\n} from \"../../domains/publish/badge-icon/operations.ts\";\nimport type { UploadBadgeIconParameters } from \"../../domains/publish/badge-icon/types.ts\";\nimport type { OpenCloudError } from \"../../errors/base.ts\";\nimport { CREATE_METHOD_DEFAULTS, IDEMPOTENT_METHOD_DEFAULTS } from \"../../internal/http/retry.ts\";\nimport {\n\tokRequest,\n\tparseEmptyResponse,\n\tResourceClient,\n\ttype ResourceMethodSpec,\n} from \"../../internal/resource-client.ts\";\nimport type { Result } from \"../../types.ts\";\n\nfunction makeSpec<P, R>(spec: ResourceMethodSpec<P, R>): ResourceMethodSpec<P, R> {\n\treturn Object.freeze(spec);\n}\n\nconst CREATE_SPEC = makeSpec<CreateBadgeParameters, Badge>({\n\tbuildRequest: (parameters) => okRequest(buildCreateRequest(parameters)),\n\tmethodDefaults: CREATE_METHOD_DEFAULTS,\n\tmethodKind: \"create\",\n\toperationLimit: CREATE_OPERATION_LIMIT,\n\tparse: parseBadgeResponse,\n\trequiredScopes: CREATE_REQUIRED_SCOPES,\n});\n\nconst UPDATE_SPEC = makeSpec<UpdateBadgeParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildUpdateRequest(parameters)),\n\tmethodDefaults: IDEMPOTENT_METHOD_DEFAULTS,\n\tmethodKind: \"idempotent\",\n\toperationLimit: UPDATE_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: UPDATE_REQUIRED_SCOPES,\n});\n\nconst UPLOAD_ICON_SPEC = makeSpec<UploadBadgeIconParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildUploadIconRequest(parameters)),\n\tmethodDefaults: CREATE_METHOD_DEFAULTS,\n\tmethodKind: \"create\",\n\toperationLimit: UPLOAD_ICON_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: UPLOAD_ICON_REQUIRED_SCOPES,\n});\n\n/**\n * Public client for the Roblox Open Cloud Badges API. Covers programmatic\n * badge creation under a universe, partial updates of badge configuration\n * (`name`, `description`, `enabled`), and source-language icon uploads.\n *\n * Wires the request builders, the injected\n * {@link OpenCloudClientOptions.httpClient}, and response parsers into a\n * single ergonomic surface. Every method returns a {@link Result} so\n * callers handle failure explicitly; no thrown {@link OpenCloudError}\n * ever escapes the client.\n *\n * @example\n *\n * ```ts\n * import { BadgesClient } from \"@bedrock-rbx/ocale/badges\";\n *\n * const client = new BadgesClient({ apiKey: \"your-key\" });\n * expect(client).toBeInstanceOf(BadgesClient);\n * ```\n */\nexport class BadgesClient {\n\treadonly #inner: ResourceClient;\n\n\t/**\n\t * Creates a new {@link BadgesClient}. Configuration is frozen on\n\t * construction; per-request overrides are accepted on each method.\n\t *\n\t * @param options - Client-level configuration including the API key.\n\t */\n\tconstructor(options: OpenCloudClientOptions) {\n\t\tthis.#inner = new ResourceClient(options);\n\t}\n\n\t/**\n\t * Creates a new badge under the supplied universe.\n\t *\n\t * @param parameters - Creation fields including the universe, name, and\n\t * icon image.\n\t * @param options - Optional per-request overrides.\n\t * @returns A {@link Result} wrapping the parsed {@link Badge} or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async create(\n\t\tparameters: CreateBadgeParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<Badge, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: CREATE_SPEC });\n\t}\n\n\t/**\n\t * Partially updates a badge's configuration. Mirrors the upstream\n\t * `200 OK` empty response: a successful update yields `undefined`\n\t * data. Only fields explicitly provided are forwarded to the server,\n\t * so omitted fields keep their current values.\n\t *\n\t * @param parameters - Identifier plus the fields to update.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async update(\n\t\tparameters: UpdateBadgeParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<undefined, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: UPDATE_SPEC });\n\t}\n\n\t/**\n\t * Uploads or replaces the source-language icon registered against a\n\t * badge. A subsequent upload for the same badge replaces the\n\t * existing source icon. Does not retry on 5xx so a duplicate icon\n\t * upload cannot be created if the server fails mid-write.\n\t *\n\t * @param parameters - Identifier plus the image bytes to upload.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async uploadIcon(\n\t\tparameters: UploadBadgeIconParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<undefined, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: UPLOAD_ICON_SPEC });\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"badges.mjs","names":["buildUpdateRequest","buildUploadIconRequest","buildUpdateRequest","buildLocaleNameDescRequest","buildLocaleUploadIconRequest","#inner"],"sources":["../src/domains/badges/badges/builders.ts","../src/domains/badges/badges/operations.ts","../src/domains/badges/badges/parsers.ts","../src/domains/game-internationalization/badge-icon/builders.ts","../src/domains/game-internationalization/badge-name-description/builders.ts","../src/domains/game-internationalization/badge-name-description/operations.ts","../src/domains/publish/badge-icon/builders.ts","../src/domains/publish/badge-icon/operations.ts","../src/resources/badges/client.ts"],"sourcesContent":["import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport { toBlob } from \"../../../internal/utils/to-blob.ts\";\nimport type { BadgePaymentSource, CreateBadgeParameters, UpdateBadgeParameters } from \"./types.ts\";\n\n/**\n * Builds a `POST` request for the legacy \"create badge\" endpoint.\n *\n * @param parameters - Fields describing the new badge; optional values\n * omitted here are left off the multipart payload entirely.\n * @returns A pure {@link HttpRequest} describing the create call.\n */\nexport function buildCreateRequest(parameters: CreateBadgeParameters): HttpRequest {\n\tconst body = new FormData();\n\tbody.append(\"name\", parameters.name);\n\tbody.append(\"files\", toBlob(parameters.icon));\n\tif (parameters.description !== undefined) {\n\t\tbody.append(\"description\", parameters.description);\n\t}\n\n\tif (parameters.isActive !== undefined) {\n\t\tbody.append(\"isActive\", String(parameters.isActive));\n\t}\n\n\tif (parameters.expectedCost !== undefined) {\n\t\tbody.append(\"expectedCost\", String(parameters.expectedCost));\n\t}\n\n\tif (parameters.paymentSource !== undefined) {\n\t\tbody.append(\"paymentSourceType\", toPaymentSourceWire(parameters.paymentSource));\n\t}\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"POST\",\n\t\turl: `/legacy-badges/v1/universes/${parameters.universeId}/badges`,\n\t};\n}\n\n/**\n * Builds a `PATCH` request for the legacy \"update badge\" endpoint. Every\n * field on `parameters` except the identifier is optional; omitted fields\n * are not appended to the JSON body so the server leaves them unchanged.\n *\n * @param parameters - Identifier plus fields to update.\n * @returns A pure {@link HttpRequest} describing the update call.\n */\nexport function buildUpdateRequest(parameters: UpdateBadgeParameters): HttpRequest {\n\tconst body: Record<string, boolean | string> = {};\n\tif (parameters.name !== undefined) {\n\t\tbody[\"name\"] = parameters.name;\n\t}\n\n\tif (parameters.description !== undefined) {\n\t\tbody[\"description\"] = parameters.description;\n\t}\n\n\tif (parameters.enabled !== undefined) {\n\t\tbody[\"enabled\"] = parameters.enabled;\n\t}\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"PATCH\",\n\t\turl: `/legacy-badges/v1/badges/${parameters.badgeId}`,\n\t};\n}\n\nfunction toPaymentSourceWire(source: BadgePaymentSource): \"1\" | \"2\" {\n\treturn source === \"User\" ? \"1\" : \"2\";\n}\n","import type { OperationLimit } from \"../../../internal/http/rate-limit-queue.ts\";\n\n/**\n * Per-second request ceiling for creating a badge, sourced from\n * `x-roblox-rate-limits` on the legacy badges create operation in the\n * vendored OpenAPI schema (100 per minute, per API key owner).\n */\nexport const CREATE_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.create\",\n});\n\n/**\n * Per-second request ceiling for updating a badge, sourced from\n * `x-roblox-rate-limits` on the legacy badges update operation in the\n * vendored OpenAPI schema. Keyed independently from\n * {@link CREATE_OPERATION_LIMIT} so create and update do not share a\n * queue, since Roblox does not document the per-minute quota as shared\n * between the POST and PATCH endpoints.\n */\nexport const UPDATE_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.update\",\n});\n\n/**\n * Scopes the API key or OAuth token must carry to create a badge,\n * sourced from `x-roblox-scopes` on the legacy badges create operation\n * in the vendored OpenAPI schema. The trailing\n * `:manage-and-spend-robux` reflects that badge creation may charge a\n * Robux fee.\n */\nexport const CREATE_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-universe.badge:manage-and-spend-robux\",\n]);\n\n/**\n * Scopes the API key or OAuth token must carry to update a badge,\n * sourced from `x-roblox-scopes` on the legacy badges update operation\n * in the vendored OpenAPI schema.\n */\nexport const UPDATE_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-universe.badge:write\",\n]);\n","import type { HttpResponse } from \"../../../client/types.ts\";\nimport { ApiError } from \"../../../errors/api-error.ts\";\nimport { isDateTimeString } from \"../../../internal/utils/is-date-time-string.ts\";\nimport { isRecord } from \"../../../internal/utils/is-record.ts\";\nimport type { Result } from \"../../../types.ts\";\nimport type { Badge, BadgeAwarder, BadgeStatistics } from \"./types.ts\";\nimport type { BadgeAwarderWire, BadgeResponseV2Wire, BadgeStatisticsWire } from \"./wire.ts\";\n\n/**\n * Parses a successful Badges API response into the public `Badge` shape,\n * returning a `Result` so callers can handle malformed payloads without\n * exceptions.\n *\n * @param response - The full {@link HttpResponse} from the Open Cloud API.\n * The status code is included on the returned `ApiError` when validation\n * fails; the headers are available for future parsers that need them.\n * @returns A success result wrapping the converted `Badge`, or an\n * `ApiError` when the body does not match the wire schema.\n */\nexport function parseBadgeResponse(response: HttpResponse): Result<Badge, ApiError> {\n\tconst { body, status: statusCode } = response;\n\n\tif (!isBadgeResponseV2Wire(body)) {\n\t\treturn {\n\t\t\terr: new ApiError(\"Malformed badge response\", { statusCode }),\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tdata: {\n\t\t\tid: String(body.id),\n\t\t\tname: body.name,\n\t\t\tawarder: copyAwarder(body.awarder),\n\t\t\tcreatedAt: new Date(body.created),\n\t\t\tdescription: body.description,\n\t\t\tdisplayDescription: body.displayDescription,\n\t\t\tdisplayIconImageId:\n\t\t\t\tbody.displayIconImageId === 0 ? undefined : String(body.displayIconImageId),\n\t\t\tdisplayName: body.displayName,\n\t\t\tenabled: body.enabled,\n\t\t\ticonImageId: body.iconImageId === 0 ? undefined : String(body.iconImageId),\n\t\t\tstatistics: copyStatistics(body.statistics),\n\t\t\tupdatedAt: new Date(body.updated),\n\t\t},\n\t\tsuccess: true,\n\t};\n}\n\nfunction copyAwarder(awarder: BadgeAwarderWire): BadgeAwarder {\n\treturn { id: String(awarder.id), name: awarder.name, type: \"Place\" };\n}\n\nfunction copyStatistics(statistics: BadgeStatisticsWire): BadgeStatistics {\n\treturn {\n\t\tawardedCount: statistics.awardedCount,\n\t\tpastDayAwardedCount: statistics.pastDayAwardedCount,\n\t\twinRatePercentage: statistics.winRatePercentage,\n\t};\n}\n\nfunction hasRequiredPrimitiveFields(body: Record<string, unknown>): boolean {\n\treturn (\n\t\ttypeof body[\"id\"] === \"number\" &&\n\t\ttypeof body[\"name\"] === \"string\" &&\n\t\ttypeof body[\"description\"] === \"string\" &&\n\t\ttypeof body[\"displayName\"] === \"string\" &&\n\t\ttypeof body[\"displayDescription\"] === \"string\" &&\n\t\ttypeof body[\"enabled\"] === \"boolean\" &&\n\t\ttypeof body[\"iconImageId\"] === \"number\" &&\n\t\ttypeof body[\"displayIconImageId\"] === \"number\" &&\n\t\tisDateTimeString(body[\"created\"]) &&\n\t\tisDateTimeString(body[\"updated\"])\n\t);\n}\n\nfunction isBadgeAwarderWire(value: unknown): value is BadgeAwarderWire {\n\tif (!isRecord(value)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\ttypeof value[\"id\"] === \"number\" && typeof value[\"name\"] === \"string\" && value[\"type\"] === 1\n\t);\n}\n\nfunction isBadgeStatisticsWire(value: unknown): value is BadgeStatisticsWire {\n\tif (!isRecord(value)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\ttypeof value[\"awardedCount\"] === \"number\" &&\n\t\ttypeof value[\"pastDayAwardedCount\"] === \"number\" &&\n\t\ttypeof value[\"winRatePercentage\"] === \"number\"\n\t);\n}\n\nfunction isBadgeResponseV2Wire(body: unknown): body is BadgeResponseV2Wire {\n\tif (!isRecord(body)) {\n\t\treturn false;\n\t}\n\n\tif (!hasRequiredPrimitiveFields(body)) {\n\t\treturn false;\n\t}\n\n\tif (!isBadgeAwarderWire(body[\"awarder\"])) {\n\t\treturn false;\n\t}\n\n\tif (!isBadgeStatisticsWire(body[\"statistics\"])) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n","import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport { toBlob } from \"../../../internal/utils/to-blob.ts\";\nimport type { UploadBadgeIconLocalizationParameters } from \"./types.ts\";\n\n/**\n * Builds a `POST` request for the localized \"upload badge icon\" endpoint. A\n * successful upload replaces any existing icon for the same\n * `(badgeId, languageCode)` pair.\n *\n * @param parameters - Badge and language identifiers plus the image bytes\n * to upload.\n * @returns A pure {@link HttpRequest} describing the upload call.\n */\nexport function buildUploadIconRequest(\n\tparameters: UploadBadgeIconLocalizationParameters,\n): HttpRequest {\n\tconst body = new FormData();\n\tbody.append(\"Files\", toBlob(parameters.image));\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"POST\",\n\t\turl: `/legacy-game-internationalization/v1/badges/${parameters.badgeId}/icons/language-codes/${parameters.languageCode}`,\n\t};\n}\n","import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport type { UpdateBadgeNameDescriptionParameters } from \"./types.ts\";\n\n/**\n * Builds a `PATCH` request for the localized \"update badge name/description\"\n * endpoint. Either `name`, `description`, or both may be supplied; omitted\n * fields are not included in the JSON body so the server leaves the existing\n * value for that locale untouched.\n *\n * @param parameters - Badge and language identifiers plus the optional\n * replacement values.\n * @returns A pure {@link HttpRequest} describing the update call.\n */\nexport function buildUpdateRequest(parameters: UpdateBadgeNameDescriptionParameters): HttpRequest {\n\tconst body: Record<string, string> = {};\n\tif (parameters.name !== undefined) {\n\t\tbody[\"name\"] = parameters.name;\n\t}\n\n\tif (parameters.description !== undefined) {\n\t\tbody[\"description\"] = parameters.description;\n\t}\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"PATCH\",\n\t\turl: `/legacy-game-internationalization/v1/badges/${parameters.badgeId}/name-description/language-codes/${parameters.languageCode}`,\n\t};\n}\n","import type { OperationLimit } from \"../../../internal/http/rate-limit-queue.ts\";\n\n/**\n * Per-second request ceiling for every badge localization Operation. The\n * legacy `gameinternationalization` service caps each API key at 100\n * requests per minute *shared across the entire service* (see the\n * `x-roblox-rate-limits` extension on every operation in the vendored\n * Open Cloud spec), so all badge localization methods queue against the\n * same operation key.\n */\nexport const LOCALIZATION_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badge-localization\",\n});\n\n/**\n * Scopes required for every badge localization operation, sourced from\n * `x-roblox-scopes` on the legacy `gameinternationalization` badge\n * endpoints in the vendored OpenAPI schema.\n */\nexport const LOCALIZATION_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-badge:manage\",\n]);\n","import type { HttpRequest } from \"../../../internal/http/types.ts\";\nimport { toBlob } from \"../../../internal/utils/to-blob.ts\";\nimport type { UploadBadgeIconParameters } from \"./types.ts\";\n\n/**\n * Builds a `POST` request for the legacy \"upload badge icon\" endpoint. A\n * successful upload replaces any existing source-language icon on the\n * badge.\n *\n * @param parameters - Badge identifier plus the image bytes to upload.\n * @returns A pure {@link HttpRequest} describing the upload call.\n */\nexport function buildUploadIconRequest(parameters: UploadBadgeIconParameters): HttpRequest {\n\tconst body = new FormData();\n\tbody.append(\"Files\", toBlob(parameters.icon));\n\n\treturn {\n\t\tbody,\n\t\tmethod: \"POST\",\n\t\turl: `/legacy-publish/v1/badges/${parameters.badgeId}/icon`,\n\t};\n}\n","import type { OperationLimit } from \"../../../internal/http/rate-limit-queue.ts\";\n\n/**\n * Per-second request ceiling for uploading a badge icon, sourced from\n * `x-roblox-rate-limits` on the legacy badge icon upload operation in\n * the vendored OpenAPI schema (100 per minute, per API key owner). Keyed\n * separately from the badges create and update buckets because Roblox\n * does not document the legacy-publish quota as shared with the\n * legacy-badges quota.\n */\nexport const UPLOAD_ICON_OPERATION_LIMIT: OperationLimit = Object.freeze({\n\tmaxPerSecond: 100 / 60,\n\toperationKey: \"badges.upload-icon\",\n});\n\n/**\n * Scopes the API key or OAuth token must carry to upload a badge icon,\n * sourced from `x-roblox-scopes` on the legacy badge icon upload\n * operation in the vendored OpenAPI schema.\n */\nexport const UPLOAD_ICON_REQUIRED_SCOPES: ReadonlyArray<string> = Object.freeze([\n\t\"legacy-badge:manage\",\n]);\n","import type { OpenCloudClientOptions, RequestOptions } from \"../../client/types.ts\";\nimport { buildCreateRequest, buildUpdateRequest } from \"../../domains/badges/badges/builders.ts\";\nimport {\n\tCREATE_OPERATION_LIMIT,\n\tCREATE_REQUIRED_SCOPES,\n\tUPDATE_OPERATION_LIMIT,\n\tUPDATE_REQUIRED_SCOPES,\n} from \"../../domains/badges/badges/operations.ts\";\nimport { parseBadgeResponse } from \"../../domains/badges/badges/parsers.ts\";\nimport type {\n\tBadge,\n\tCreateBadgeParameters,\n\tUpdateBadgeParameters,\n} from \"../../domains/badges/badges/types.ts\";\nimport { buildUploadIconRequest as buildLocaleUploadIconRequest } from \"../../domains/game-internationalization/badge-icon/builders.ts\";\nimport type { UploadBadgeIconLocalizationParameters } from \"../../domains/game-internationalization/badge-icon/types.ts\";\nimport { buildUpdateRequest as buildLocaleNameDescRequest } from \"../../domains/game-internationalization/badge-name-description/builders.ts\";\nimport {\n\tLOCALIZATION_OPERATION_LIMIT,\n\tLOCALIZATION_REQUIRED_SCOPES,\n} from \"../../domains/game-internationalization/badge-name-description/operations.ts\";\nimport type { UpdateBadgeNameDescriptionParameters } from \"../../domains/game-internationalization/badge-name-description/types.ts\";\nimport { buildUploadIconRequest } from \"../../domains/publish/badge-icon/builders.ts\";\nimport {\n\tUPLOAD_ICON_OPERATION_LIMIT,\n\tUPLOAD_ICON_REQUIRED_SCOPES,\n} from \"../../domains/publish/badge-icon/operations.ts\";\nimport type { UploadBadgeIconParameters } from \"../../domains/publish/badge-icon/types.ts\";\nimport type { OpenCloudError } from \"../../errors/base.ts\";\nimport { CREATE_METHOD_DEFAULTS, IDEMPOTENT_METHOD_DEFAULTS } from \"../../internal/http/retry.ts\";\nimport {\n\tokRequest,\n\tparseEmptyResponse,\n\tResourceClient,\n\ttype ResourceMethodSpec,\n} from \"../../internal/resource-client.ts\";\nimport type { Result } from \"../../types.ts\";\n\nfunction makeSpec<P, R>(spec: ResourceMethodSpec<P, R>): ResourceMethodSpec<P, R> {\n\treturn Object.freeze(spec);\n}\n\nconst CREATE_SPEC = makeSpec<CreateBadgeParameters, Badge>({\n\tbuildRequest: (parameters) => okRequest(buildCreateRequest(parameters)),\n\tmethodDefaults: CREATE_METHOD_DEFAULTS,\n\tmethodKind: \"create\",\n\toperationLimit: CREATE_OPERATION_LIMIT,\n\tparse: parseBadgeResponse,\n\trequiredScopes: CREATE_REQUIRED_SCOPES,\n});\n\nconst UPDATE_SPEC = makeSpec<UpdateBadgeParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildUpdateRequest(parameters)),\n\tmethodDefaults: IDEMPOTENT_METHOD_DEFAULTS,\n\tmethodKind: \"idempotent\",\n\toperationLimit: UPDATE_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: UPDATE_REQUIRED_SCOPES,\n});\n\nconst UPLOAD_ICON_SPEC = makeSpec<UploadBadgeIconParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildUploadIconRequest(parameters)),\n\tmethodDefaults: CREATE_METHOD_DEFAULTS,\n\tmethodKind: \"create\",\n\toperationLimit: UPLOAD_ICON_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: UPLOAD_ICON_REQUIRED_SCOPES,\n});\n\nconst UPDATE_NAME_DESCRIPTION_SPEC = makeSpec<UpdateBadgeNameDescriptionParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildLocaleNameDescRequest(parameters)),\n\tmethodDefaults: IDEMPOTENT_METHOD_DEFAULTS,\n\tmethodKind: \"idempotent\",\n\toperationLimit: LOCALIZATION_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: LOCALIZATION_REQUIRED_SCOPES,\n});\n\nconst UPLOAD_LOCALIZED_ICON_SPEC = makeSpec<UploadBadgeIconLocalizationParameters, undefined>({\n\tbuildRequest: (parameters) => okRequest(buildLocaleUploadIconRequest(parameters)),\n\tmethodDefaults: CREATE_METHOD_DEFAULTS,\n\tmethodKind: \"create\",\n\toperationLimit: LOCALIZATION_OPERATION_LIMIT,\n\tparse: parseEmptyResponse,\n\trequiredScopes: LOCALIZATION_REQUIRED_SCOPES,\n});\n\ninterface BadgeLocalizationHandle {\n\t/**\n\t * Updates the per-locale display name and/or description registered against\n\t * a badge. Either `name`, `description`, or both may be supplied; omitted\n\t * fields are not forwarded so the server leaves the existing value for\n\t * that locale untouched. Mirrors the upstream `200 OK` echo body as\n\t * `undefined` data.\n\t *\n\t * @param parameters - Badge and language identifiers plus the optional\n\t * replacement values.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tupdateNameDescription: (\n\t\tparameters: UpdateBadgeNameDescriptionParameters,\n\t\toptions?: RequestOptions,\n\t) => Promise<Result<undefined, OpenCloudError>>;\n\t/**\n\t * Uploads or replaces the per-locale icon for a badge. A subsequent\n\t * upload for the same `(badgeId, languageCode)` pair replaces the\n\t * existing icon for that locale. Does not retry on 5xx so a duplicate\n\t * upload cannot be created if the server fails mid-write. Source-language\n\t * icons remain on {@link BadgesClient.uploadIcon}.\n\t *\n\t * @param parameters - Badge and language identifiers plus the image bytes\n\t * to upload.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tuploadIcon: (\n\t\tparameters: UploadBadgeIconLocalizationParameters,\n\t\toptions?: RequestOptions,\n\t) => Promise<Result<undefined, OpenCloudError>>;\n}\n\n/**\n * Public client for the Roblox Open Cloud Badges API. Covers programmatic\n * badge creation under a universe, partial updates of badge configuration\n * (`name`, `description`, `enabled`), and source-language icon uploads.\n *\n * Wires the request builders, the injected\n * {@link OpenCloudClientOptions.httpClient}, and response parsers into a\n * single ergonomic surface. Every method returns a {@link Result} so\n * callers handle failure explicitly; no thrown {@link OpenCloudError}\n * ever escapes the client.\n *\n * @example\n *\n * ```ts\n * import { BadgesClient } from \"@bedrock-rbx/ocale/badges\";\n *\n * const client = new BadgesClient({ apiKey: \"your-key\" });\n * expect(client).toBeInstanceOf(BadgesClient);\n * ```\n */\nexport class BadgesClient {\n\treadonly #inner: ResourceClient;\n\n\t/**\n\t * Operation Group exposing per-locale localization Operations\n\t * (`updateNameDescription`, `uploadIcon`) backed by the\n\t * `legacy-game-internationalization` domain. Source-language values\n\t * remain on {@link BadgesClient.update} and\n\t * {@link BadgesClient.uploadIcon}; methods on this group set per-locale\n\t * overlays on top. Shares the parent client's HTTP, rate-limit, and\n\t * retry plumbing.\n\t */\n\tpublic readonly localization: BadgeLocalizationHandle;\n\n\t/**\n\t * Creates a new {@link BadgesClient}. Configuration is frozen on\n\t * construction; per-request overrides are accepted on each method.\n\t *\n\t * @param options - Client-level configuration including the API key.\n\t */\n\tconstructor(options: OpenCloudClientOptions) {\n\t\tthis.#inner = new ResourceClient(options);\n\t\tthis.localization = createLocalizationHandle(this.#inner);\n\t}\n\n\t/**\n\t * Creates a new badge under the supplied universe.\n\t *\n\t * @param parameters - Creation fields including the universe, name, and\n\t * icon image.\n\t * @param options - Optional per-request overrides.\n\t * @returns A {@link Result} wrapping the parsed {@link Badge} or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async create(\n\t\tparameters: CreateBadgeParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<Badge, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: CREATE_SPEC });\n\t}\n\n\t/**\n\t * Partially updates a badge's configuration. Mirrors the upstream\n\t * `200 OK` empty response: a successful update yields `undefined`\n\t * data. Only fields explicitly provided are forwarded to the server,\n\t * so omitted fields keep their current values.\n\t *\n\t * @param parameters - Identifier plus the fields to update.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async update(\n\t\tparameters: UpdateBadgeParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<undefined, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: UPDATE_SPEC });\n\t}\n\n\t/**\n\t * Uploads or replaces the source-language icon registered against a\n\t * badge. A subsequent upload for the same badge replaces the\n\t * existing source icon. Does not retry on 5xx so a duplicate icon\n\t * upload cannot be created if the server fails mid-write.\n\t *\n\t * @param parameters - Identifier plus the image bytes to upload.\n\t * @param options - Optional per-request overrides.\n\t * @returns A success {@link Result} with no payload, or the\n\t * {@link OpenCloudError} that caused the request to fail.\n\t */\n\tpublic async uploadIcon(\n\t\tparameters: UploadBadgeIconParameters,\n\t\toptions?: RequestOptions,\n\t): Promise<Result<undefined, OpenCloudError>> {\n\t\treturn this.#inner.execute({ options, parameters, spec: UPLOAD_ICON_SPEC });\n\t}\n}\n\nfunction createLocalizationHandle(inner: ResourceClient): BadgeLocalizationHandle {\n\treturn {\n\t\tasync updateNameDescription(parameters, options) {\n\t\t\treturn inner.execute({ options, parameters, spec: UPDATE_NAME_DESCRIPTION_SPEC });\n\t\t},\n\t\tasync uploadIcon(parameters, options) {\n\t\t\treturn inner.execute({ options, parameters, spec: UPLOAD_LOCALIZED_ICON_SPEC });\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|