rozod 6.7.1 → 6.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +75 -451
- package/lib/endpoints/accountinformationv1.d.ts +92 -95
- package/lib/endpoints/accountsettingsv1.d.ts +88 -110
- package/lib/endpoints/adconfigurationv2.d.ts +108 -215
- package/lib/endpoints/assetdeliveryv1.d.ts +267 -230
- package/lib/endpoints/assetdeliveryv1.js +38 -0
- package/lib/endpoints/assetdeliveryv2.d.ts +201 -176
- package/lib/endpoints/assetdeliveryv2.js +26 -0
- package/lib/endpoints/authv1.d.ts +480 -517
- package/lib/endpoints/authv1.js +3 -1
- package/lib/endpoints/authv2.d.ts +210 -222
- package/lib/endpoints/authv2.js +1 -1
- package/lib/endpoints/authv3.d.ts +32 -35
- package/lib/endpoints/avatarv1.d.ts +112 -117
- package/lib/endpoints/avatarv2.d.ts +71 -76
- package/lib/endpoints/avatarv3.d.ts +27 -33
- package/lib/endpoints/badgesv1.d.ts +96 -99
- package/lib/endpoints/badgesv1.js +4 -0
- package/lib/endpoints/catalogv1.d.ts +209 -234
- package/lib/endpoints/catalogv1.js +2 -1
- package/lib/endpoints/catalogv2.d.ts +106 -136
- package/lib/endpoints/catalogv2.js +21 -17
- package/lib/endpoints/chatv2.d.ts +778 -778
- package/lib/endpoints/clientsettingsv1.d.ts +33 -35
- package/lib/endpoints/clientsettingsv2.d.ts +62 -68
- package/lib/endpoints/contactsv1.d.ts +18 -20
- package/lib/endpoints/developv1.d.ts +233 -293
- package/lib/endpoints/developv1.js +3 -0
- package/lib/endpoints/developv2.d.ts +87 -138
- package/lib/endpoints/developv2.js +3 -1
- package/lib/endpoints/economycreatorstatsv1.d.ts +12 -12
- package/lib/endpoints/economyv1.d.ts +6 -6
- package/lib/endpoints/engagementpayoutsv1.d.ts +9 -9
- package/lib/endpoints/followingsv1.d.ts +33 -34
- package/lib/endpoints/followingsv2.d.ts +9 -9
- package/lib/endpoints/friendsv1.d.ts +416 -545
- package/lib/endpoints/friendsv1.js +213 -313
- package/lib/endpoints/gameinternationalizationv1.d.ts +1509 -1642
- package/lib/endpoints/gameinternationalizationv2.d.ts +62 -64
- package/lib/endpoints/gamejoinv1.d.ts +458 -458
- package/lib/endpoints/gamesv1.d.ts +183 -143
- package/lib/endpoints/gamesv1.js +2 -0
- package/lib/endpoints/gamesv2.d.ts +161 -158
- package/lib/endpoints/gamesv2.js +9 -0
- package/lib/endpoints/groupsv1.d.ts +967 -976
- package/lib/endpoints/groupsv1.js +48 -4
- package/lib/endpoints/groupsv2.d.ts +259 -277
- package/lib/endpoints/groupsv2.js +1 -0
- package/lib/endpoints/inventoryv1.d.ts +93 -122
- package/lib/endpoints/inventoryv1.js +3 -1
- package/lib/endpoints/inventoryv2.d.ts +163 -178
- package/lib/endpoints/inventoryv2.js +2 -0
- package/lib/endpoints/itemconfigurationv1.d.ts +33 -40
- package/lib/endpoints/localev1.d.ts +47 -48
- package/lib/endpoints/localizationtablesv1.d.ts +315 -353
- package/lib/endpoints/matchmakingv1.d.ts +184 -190
- package/lib/endpoints/metricsv1.d.ts +88 -88
- package/lib/endpoints/notificationsv2.d.ts +144 -158
- package/lib/endpoints/premiumfeaturesv1.d.ts +14 -14
- package/lib/endpoints/presencev1.d.ts +7 -12
- package/lib/endpoints/privatemessagesv1.d.ts +56 -64
- package/lib/endpoints/publishv1.d.ts +32 -32
- package/lib/endpoints/thumbnailsresizerv1.d.ts +52 -53
- package/lib/endpoints/thumbnailsv1.d.ts +317 -361
- package/lib/endpoints/thumbnailsv1.js +25 -0
- package/lib/endpoints/tradesv1.d.ts +92 -104
- package/lib/endpoints/tradesv2.d.ts +81 -84
- package/lib/endpoints/translationrolesv1.d.ts +46 -51
- package/lib/endpoints/twostepverificationv1.d.ts +233 -237
- package/lib/endpoints/usersv1.d.ts +110 -114
- package/lib/index.d.ts +152 -4
- package/lib/index.js +273 -4
- package/lib/opencloud/v1/asset-permissions.d.ts +1 -1
- package/lib/opencloud/v1/assets.d.ts +9 -9
- package/lib/opencloud/v1/datastores-ordered.d.ts +6 -6
- package/lib/opencloud/v1/datastores.d.ts +8 -8
- package/lib/opencloud/v1/developer-products.d.ts +4 -4
- package/lib/opencloud/v1/game-passes.d.ts +4 -4
- package/lib/opencloud/v1/messaging.d.ts +1 -1
- package/lib/opencloud/v1/open-eval.d.ts +2 -2
- package/lib/opencloud/v1/secrets-store.d.ts +5 -5
- package/lib/opencloud/v1/toolbox.d.ts +2 -2
- package/lib/opencloud/v1/universes.d.ts +1 -1
- package/lib/opencloud/v2/cloud.d.ts +172 -84
- package/lib/opencloud/v2/cloud.js +25 -9
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.endpoint = exports.hbaClient = void 0;
|
|
3
|
+
exports.endpoint = exports.OperationSchema = exports.hbaClient = void 0;
|
|
4
4
|
exports.configureServer = configureServer;
|
|
5
5
|
exports.clearServerConfig = clearServerConfig;
|
|
6
6
|
exports.getServerConfig = getServerConfig;
|
|
@@ -14,6 +14,8 @@ exports.fetchApi = fetchApi;
|
|
|
14
14
|
exports.fetchApiSplit = fetchApiSplit;
|
|
15
15
|
exports.fetchApiPages = fetchApiPages;
|
|
16
16
|
exports.fetchApiPagesGenerator = fetchApiPagesGenerator;
|
|
17
|
+
exports.pollOperation = pollOperation;
|
|
18
|
+
exports.fetchApiOperation = fetchApiOperation;
|
|
17
19
|
const zod_1 = require("zod");
|
|
18
20
|
const cache_1 = require("./cache");
|
|
19
21
|
const roblox_bat_1 = require("roblox-bat");
|
|
@@ -78,6 +80,10 @@ function prepareRequestUrl(endpoint, extendedParams) {
|
|
|
78
80
|
if (key === 'body' || usedPathParams.has(key))
|
|
79
81
|
continue;
|
|
80
82
|
const value = paramsObject[key];
|
|
83
|
+
// An unset optional parameter must be omitted, not serialized as the literal
|
|
84
|
+
// string "undefined"/"null" (which the API would reject as an invalid value).
|
|
85
|
+
if (value === undefined || value === null)
|
|
86
|
+
continue;
|
|
81
87
|
const serializationMethod = endpoint.serializationMethod?.[key];
|
|
82
88
|
// Handle exploded arrays by creating separate query params for each element
|
|
83
89
|
if (Array.isArray(value) && serializationMethod?.explode) {
|
|
@@ -129,9 +135,119 @@ function prepareRequestBody(method, requestFormat, body, headers) {
|
|
|
129
135
|
return body;
|
|
130
136
|
}
|
|
131
137
|
const onRobloxSite = 'document' in globalThis && globalThis.location.href.includes('.roblox.com');
|
|
132
|
-
|
|
138
|
+
/** How long a failed token metadata lookup is remembered before retrying. */
|
|
139
|
+
const HBA_METADATA_FAILURE_TTL = 5 * 60 * 1000;
|
|
140
|
+
/** Upper bound on the token metadata page fetch. */
|
|
141
|
+
const HBA_METADATA_FETCH_TIMEOUT = 10_000;
|
|
142
|
+
/**
|
|
143
|
+
* HBAClient hardened for server (Node/Bun) usage:
|
|
144
|
+
*
|
|
145
|
+
* - `generateBaseHeaders` short-circuits when no crypto key source exists
|
|
146
|
+
* (no supplied key pair and no IndexedDB): a BAT can never be signed, so
|
|
147
|
+
* the token metadata page must not be fetched at all.
|
|
148
|
+
* - `getTokenMetadata` remembers failed lookups for a TTL. The base class
|
|
149
|
+
* only caches successes, so an unparseable metadata page (e.g. a bot
|
|
150
|
+
* challenge served to a datacenter IP) would otherwise be refetched on
|
|
151
|
+
* every request — unbounded network and memory churn on hot paths.
|
|
152
|
+
* - The metadata page fetch is bounded by a timeout and sent with the
|
|
153
|
+
* configured server user agent instead of the runtime default, which is
|
|
154
|
+
* far more likely to receive a challenge page.
|
|
155
|
+
*/
|
|
156
|
+
class ServerSafeHBAClient extends roblox_bat_1.HBAClient {
|
|
157
|
+
metadataFailureAt = 0;
|
|
158
|
+
metadataInFlight;
|
|
159
|
+
metadataSource;
|
|
160
|
+
constructor(props) {
|
|
161
|
+
super(props);
|
|
162
|
+
this.metadataSource = props?.metadataSource;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Forget a remembered metadata failure so the next lookup retries
|
|
166
|
+
* immediately. Called when HBA keys are (re)configured — a lookup that
|
|
167
|
+
* failed under the old configuration says nothing about the new one.
|
|
168
|
+
*/
|
|
169
|
+
resetMetadataFailure() {
|
|
170
|
+
this.metadataFailureAt = 0;
|
|
171
|
+
}
|
|
172
|
+
async generateBaseHeaders(requestUrl, requestMethod, includeCredentials, body) {
|
|
173
|
+
if (!this.suppliedCryptoKeyPair && !('indexedDB' in globalThis)) {
|
|
174
|
+
return {};
|
|
175
|
+
}
|
|
176
|
+
return super.generateBaseHeaders(requestUrl, requestMethod, includeCredentials, body);
|
|
177
|
+
}
|
|
178
|
+
async getTokenMetadata(uncached) {
|
|
179
|
+
// Token metadata is account-agnostic; per-cookie clients delegate to
|
|
180
|
+
// one shared client so its caches (success, failure TTL, in-flight)
|
|
181
|
+
// apply pool-wide instead of once per account.
|
|
182
|
+
if (this.metadataSource) {
|
|
183
|
+
return this.metadataSource.getTokenMetadata(uncached);
|
|
184
|
+
}
|
|
185
|
+
if (!uncached) {
|
|
186
|
+
if (this.metadataFailureAt && Date.now() - this.metadataFailureAt < HBA_METADATA_FAILURE_TTL) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
// The base class only shares in-flight lookups that resolve
|
|
190
|
+
// successfully; sharing here makes concurrent callers ride one
|
|
191
|
+
// lookup even when it fails, instead of each retrying in turn.
|
|
192
|
+
if (this.metadataInFlight) {
|
|
193
|
+
return this.metadataInFlight;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
let promise;
|
|
197
|
+
promise = (async () => {
|
|
198
|
+
try {
|
|
199
|
+
const metadata = await super.getTokenMetadata(uncached);
|
|
200
|
+
this.metadataFailureAt = metadata ? 0 : Date.now();
|
|
201
|
+
return metadata;
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
// Guarded so an overlapping lookup's reference is not clobbered
|
|
205
|
+
if (this.metadataInFlight === promise) {
|
|
206
|
+
this.metadataInFlight = undefined;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
210
|
+
this.metadataInFlight = promise;
|
|
211
|
+
return promise;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.hbaClient = new ServerSafeHBAClient({
|
|
133
215
|
onSite: onRobloxSite,
|
|
216
|
+
// Applies to every non-on-site context, including extension background
|
|
217
|
+
// and popup pages: the timeout is desirable everywhere, and browsers
|
|
218
|
+
// silently drop the user-agent header (it is fetch-forbidden), so this
|
|
219
|
+
// only takes effect in Node/Bun.
|
|
220
|
+
...(onRobloxSite
|
|
221
|
+
? {}
|
|
222
|
+
: {
|
|
223
|
+
fetch: (url, params) => {
|
|
224
|
+
const headers = new Headers(params?.headers);
|
|
225
|
+
if (!headers.has('user-agent')) {
|
|
226
|
+
const userAgent = getServerUserAgent();
|
|
227
|
+
if (userAgent) {
|
|
228
|
+
headers.set('user-agent', userAgent);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return globalThis.fetch(url, {
|
|
232
|
+
...params,
|
|
233
|
+
headers,
|
|
234
|
+
signal: AbortSignal.timeout(HBA_METADATA_FETCH_TIMEOUT),
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
134
238
|
});
|
|
239
|
+
/**
|
|
240
|
+
* BAT signing clients aligned index-for-index with the configured cookie
|
|
241
|
+
* pool. `null` marks cookies whose sessions have no registered key. Unset
|
|
242
|
+
* when hbaKeys was not configured as an array.
|
|
243
|
+
*/
|
|
244
|
+
let perCookieHbaClients;
|
|
245
|
+
function hbaClientForCookie(cookieIndex) {
|
|
246
|
+
if (cookieIndex === undefined || !perCookieHbaClients) {
|
|
247
|
+
return exports.hbaClient;
|
|
248
|
+
}
|
|
249
|
+
return perCookieHbaClients[cookieIndex] ?? exports.hbaClient;
|
|
250
|
+
}
|
|
135
251
|
// ============================================================================
|
|
136
252
|
// Server/Node.js Configuration
|
|
137
253
|
// ============================================================================
|
|
@@ -194,6 +310,38 @@ function configureServer(config) {
|
|
|
194
310
|
serverConfig.userAgents = config.userAgents;
|
|
195
311
|
serverConfig.userAgentRotation = config.userAgentRotation;
|
|
196
312
|
serverConfig.onCookieRefresh = config.onCookieRefresh;
|
|
313
|
+
// Keys live on the HBA clients, not in serverConfig — they are the single
|
|
314
|
+
// source of truth that getServerConfig() reads back from. A single shared
|
|
315
|
+
// pair is kept when hbaKeys is omitted so changeHBAKeys() callers keep
|
|
316
|
+
// theirs, but per-cookie keys are positionally bound to the cookies array
|
|
317
|
+
// passed in the same call: reconfiguring without them must drop them, or
|
|
318
|
+
// a changed pool would sign with other sessions' keys.
|
|
319
|
+
if (config.hbaKeys === undefined) {
|
|
320
|
+
perCookieHbaClients = undefined;
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
if (Array.isArray(config.hbaKeys)) {
|
|
324
|
+
const poolSize = Array.isArray(config.cookies) ? config.cookies.length : config.cookies ? 1 : 0;
|
|
325
|
+
if (config.hbaKeys.length !== poolSize) {
|
|
326
|
+
throw new Error(`hbaKeys array length (${config.hbaKeys.length}) must match the cookie pool length (${poolSize}); use null for cookies without registered keys`);
|
|
327
|
+
}
|
|
328
|
+
perCookieHbaClients = config.hbaKeys.map((keys) => keys
|
|
329
|
+
? new ServerSafeHBAClient({
|
|
330
|
+
onSite: onRobloxSite,
|
|
331
|
+
keys,
|
|
332
|
+
metadataSource: exports.hbaClient,
|
|
333
|
+
})
|
|
334
|
+
: null);
|
|
335
|
+
// The shared client must not sign: requests that bypass the cookie
|
|
336
|
+
// pool have no session to match a key to.
|
|
337
|
+
exports.hbaClient.suppliedCryptoKeyPair = undefined;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
exports.hbaClient.suppliedCryptoKeyPair = config.hbaKeys;
|
|
341
|
+
perCookieHbaClients = undefined;
|
|
342
|
+
}
|
|
343
|
+
exports.hbaClient.resetMetadataFailure();
|
|
344
|
+
}
|
|
197
345
|
// Reset indices and session values when config changes
|
|
198
346
|
serverConfig._cookieIndex = 0;
|
|
199
347
|
serverConfig._userAgentIndex = 0;
|
|
@@ -210,6 +358,8 @@ function clearServerConfig() {
|
|
|
210
358
|
serverConfig.userAgents = undefined;
|
|
211
359
|
serverConfig.userAgentRotation = undefined;
|
|
212
360
|
serverConfig.onCookieRefresh = undefined;
|
|
361
|
+
exports.hbaClient.suppliedCryptoKeyPair = undefined;
|
|
362
|
+
perCookieHbaClients = undefined;
|
|
213
363
|
serverConfig._cookieIndex = 0;
|
|
214
364
|
serverConfig._userAgentIndex = 0;
|
|
215
365
|
serverConfig._sessionUserAgent = undefined;
|
|
@@ -226,6 +376,9 @@ function getServerConfig() {
|
|
|
226
376
|
userAgents: serverConfig.userAgents,
|
|
227
377
|
userAgentRotation: serverConfig.userAgentRotation,
|
|
228
378
|
onCookieRefresh: serverConfig.onCookieRefresh,
|
|
379
|
+
hbaKeys: perCookieHbaClients
|
|
380
|
+
? perCookieHbaClients.map((client) => client?.suppliedCryptoKeyPair ?? null)
|
|
381
|
+
: exports.hbaClient.suppliedCryptoKeyPair,
|
|
229
382
|
};
|
|
230
383
|
}
|
|
231
384
|
function selectFromPool(pool, rotation, indexKey, sessionKey) {
|
|
@@ -633,10 +786,11 @@ async function fetch(url, info, challengeData, csrfRetries = 0, challengeRetries
|
|
|
633
786
|
// Normal flow: apply all defaults including cookie selection
|
|
634
787
|
cookieSelection = applyServerDefaults(headers, url);
|
|
635
788
|
}
|
|
789
|
+
const activeHbaClient = hbaClientForCookie(cookieSelection?.index);
|
|
636
790
|
if (!onRobloxSite) {
|
|
637
|
-
|
|
791
|
+
activeHbaClient.isAuthenticated = headers.get('cookie')?.includes('.ROBLOSECURITY');
|
|
638
792
|
}
|
|
639
|
-
const setHeaders = await
|
|
793
|
+
const setHeaders = await activeHbaClient.generateBaseHeaders(url, info?.method, info?.credentials === 'include', info?.body);
|
|
640
794
|
for (const key in setHeaders) {
|
|
641
795
|
headers.set(key, setHeaders[key]);
|
|
642
796
|
}
|
|
@@ -688,10 +842,18 @@ async function fetch(url, info, challengeData, csrfRetries = 0, challengeRetries
|
|
|
688
842
|
/**
|
|
689
843
|
* Allows you to change the Crypto Key pair used by the internal hardware-based authentication signatures. This should only be used in a NodeJS context.
|
|
690
844
|
*
|
|
845
|
+
* The pair applies to every request: any per-cookie keys configured via
|
|
846
|
+
* `configureServer({ hbaKeys: [...] })` are discarded. To key individual
|
|
847
|
+
* cookies in a pool, use `configureServer` instead.
|
|
848
|
+
*
|
|
691
849
|
* @param keys The crypto key pair.
|
|
692
850
|
*/
|
|
693
851
|
function changeHBAKeys(keys) {
|
|
694
852
|
exports.hbaClient.suppliedCryptoKeyPair = keys;
|
|
853
|
+
perCookieHbaClients = undefined;
|
|
854
|
+
if (keys) {
|
|
855
|
+
exports.hbaClient.resetMetadataFailure();
|
|
856
|
+
}
|
|
695
857
|
}
|
|
696
858
|
async function handleRetryFetch(url, requestOptions, retries, retryDelay, body, method) {
|
|
697
859
|
let response = undefined;
|
|
@@ -971,3 +1133,110 @@ async function* fetchApiPagesGenerator(endpoint, initialParams, requestOptions,
|
|
|
971
1133
|
cursor = nextCursor;
|
|
972
1134
|
}
|
|
973
1135
|
}
|
|
1136
|
+
/**
|
|
1137
|
+
* Roblox Open Cloud long-running operation envelope. Endpoints such as
|
|
1138
|
+
* `generateThumbnail` / `generateAsset` return this instead of the final
|
|
1139
|
+
* result: `done` is false until the work completes, at which point `response`
|
|
1140
|
+
* holds the payload. Fields are optional because the API omits `response`
|
|
1141
|
+
* (and sometimes `done`) while the operation is still in progress.
|
|
1142
|
+
*/
|
|
1143
|
+
exports.OperationSchema = zod_1.z.object({
|
|
1144
|
+
path: zod_1.z.string(),
|
|
1145
|
+
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(),
|
|
1146
|
+
done: zod_1.z.boolean().optional(),
|
|
1147
|
+
error: zod_1.z
|
|
1148
|
+
.object({
|
|
1149
|
+
code: zod_1.z.number().optional(),
|
|
1150
|
+
message: zod_1.z.string().optional(),
|
|
1151
|
+
details: zod_1.z.array(zod_1.z.any()).optional(),
|
|
1152
|
+
})
|
|
1153
|
+
.partial()
|
|
1154
|
+
.optional(),
|
|
1155
|
+
response: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(),
|
|
1156
|
+
});
|
|
1157
|
+
function sleep(ms, signal) {
|
|
1158
|
+
return new Promise((resolve, reject) => {
|
|
1159
|
+
if (signal?.aborted) {
|
|
1160
|
+
reject(signal.reason ?? new Error('Aborted'));
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
const timer = setTimeout(() => {
|
|
1164
|
+
signal?.removeEventListener('abort', onAbort);
|
|
1165
|
+
resolve();
|
|
1166
|
+
}, ms);
|
|
1167
|
+
const onAbort = () => {
|
|
1168
|
+
clearTimeout(timer);
|
|
1169
|
+
reject(signal?.reason ?? new Error('Aborted'));
|
|
1170
|
+
};
|
|
1171
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
function buildOperationUrl(endpoint, operationPath, options) {
|
|
1175
|
+
const base = (options?.baseUrl ?? endpoint.baseUrl).replace(/\/+$/, '');
|
|
1176
|
+
let prefix = options?.pathPrefix;
|
|
1177
|
+
if (prefix === undefined) {
|
|
1178
|
+
// Derive the version prefix by locating the operation path's leading segment
|
|
1179
|
+
// within the originating endpoint's path (e.g. `/cloud/v2/users/:id:generate…` → `/cloud/v2`).
|
|
1180
|
+
const firstSegment = operationPath.replace(/^\/+/, '').split('/')[0];
|
|
1181
|
+
const marker = '/' + firstSegment + '/';
|
|
1182
|
+
const idx = firstSegment ? endpoint.path.indexOf(marker) : -1;
|
|
1183
|
+
prefix = idx > 0 ? endpoint.path.slice(0, idx) : '';
|
|
1184
|
+
}
|
|
1185
|
+
const cleanPrefix = prefix ? '/' + prefix.replace(/^\/+|\/+$/g, '') : '';
|
|
1186
|
+
const cleanPath = operationPath.replace(/^\/+/, '');
|
|
1187
|
+
return `${base}${cleanPrefix}/${cleanPath}`;
|
|
1188
|
+
}
|
|
1189
|
+
function isZodSchema(value) {
|
|
1190
|
+
return typeof value?.safeParse === 'function';
|
|
1191
|
+
}
|
|
1192
|
+
async function pollOperation(endpoint, operation, resultSchemaOrOptions, maybeOptions = {}) {
|
|
1193
|
+
const explicitSchema = isZodSchema(resultSchemaOrOptions) ? resultSchemaOrOptions : undefined;
|
|
1194
|
+
const options = explicitSchema ? maybeOptions : (resultSchemaOrOptions ?? {});
|
|
1195
|
+
const schema = explicitSchema ?? endpoint.resultResponse;
|
|
1196
|
+
const interval = options.interval ?? 1000;
|
|
1197
|
+
const timeout = options.timeout ?? 30000;
|
|
1198
|
+
const deadline = Date.now() + timeout;
|
|
1199
|
+
const finish = (op) => {
|
|
1200
|
+
if (op.error && (op.error.message || op.error.code)) {
|
|
1201
|
+
throw new Error(op.error.message ?? `Operation failed with code ${op.error.code}`);
|
|
1202
|
+
}
|
|
1203
|
+
return schema ? schema.parse(op.response) : op.response;
|
|
1204
|
+
};
|
|
1205
|
+
if (operation.done) {
|
|
1206
|
+
return finish(operation);
|
|
1207
|
+
}
|
|
1208
|
+
const url = buildOperationUrl(endpoint, operation.path, options);
|
|
1209
|
+
const pollEndpoint = {
|
|
1210
|
+
method: 'GET',
|
|
1211
|
+
path: '',
|
|
1212
|
+
baseUrl: url,
|
|
1213
|
+
requestFormat: 'json',
|
|
1214
|
+
parameters: {},
|
|
1215
|
+
response: exports.OperationSchema,
|
|
1216
|
+
errors: [],
|
|
1217
|
+
};
|
|
1218
|
+
while (true) {
|
|
1219
|
+
await sleep(interval, options.signal);
|
|
1220
|
+
const polled = (await fetchApi(pollEndpoint, {}, {
|
|
1221
|
+
...options.requestOptions,
|
|
1222
|
+
throwOnError: true,
|
|
1223
|
+
}));
|
|
1224
|
+
if (polled.done) {
|
|
1225
|
+
return finish(polled);
|
|
1226
|
+
}
|
|
1227
|
+
if (Date.now() >= deadline) {
|
|
1228
|
+
throw new Error(`Operation "${operation.path}" did not complete within ${timeout}ms`);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
async function fetchApiOperation(endpoint, params, resultSchemaOrOptions, maybeOptions = {}) {
|
|
1233
|
+
const explicitSchema = isZodSchema(resultSchemaOrOptions) ? resultSchemaOrOptions : undefined;
|
|
1234
|
+
const options = explicitSchema ? maybeOptions : (resultSchemaOrOptions ?? {});
|
|
1235
|
+
const operation = (await fetchApi(endpoint, params, {
|
|
1236
|
+
...options.requestOptions,
|
|
1237
|
+
throwOnError: true,
|
|
1238
|
+
}));
|
|
1239
|
+
return explicitSchema
|
|
1240
|
+
? pollOperation(endpoint, operation, explicitSchema, options)
|
|
1241
|
+
: pollOperation(endpoint, operation, options);
|
|
1242
|
+
}
|
|
@@ -80,7 +80,7 @@ export declare const postAssets: import("../..").EndpointGeneric<{}, {
|
|
|
80
80
|
};
|
|
81
81
|
};
|
|
82
82
|
fileContent: File;
|
|
83
|
-
}>;
|
|
83
|
+
}, undefined>;
|
|
84
84
|
/**
|
|
85
85
|
* **Get Asset** · `BETA`
|
|
86
86
|
*
|
|
@@ -123,7 +123,7 @@ export declare const getAssetsAssetId: import("../..").EndpointGeneric<{
|
|
|
123
123
|
title: string;
|
|
124
124
|
uri: string;
|
|
125
125
|
};
|
|
126
|
-
}, undefined>;
|
|
126
|
+
}, undefined, undefined>;
|
|
127
127
|
/**
|
|
128
128
|
* **Update Asset** · `BETA`
|
|
129
129
|
*
|
|
@@ -209,7 +209,7 @@ export declare const patchAssetsAssetId: import("../..").EndpointGeneric<{
|
|
|
209
209
|
};
|
|
210
210
|
} | undefined;
|
|
211
211
|
fileContent?: File | undefined;
|
|
212
|
-
}>;
|
|
212
|
+
}, undefined>;
|
|
213
213
|
/**
|
|
214
214
|
* **Archive Asset** · `BETA`
|
|
215
215
|
*
|
|
@@ -250,7 +250,7 @@ export declare const postAssetsAssetIdArchive: import("../..").EndpointGeneric<{
|
|
|
250
250
|
title: string;
|
|
251
251
|
uri: string;
|
|
252
252
|
};
|
|
253
|
-
}, undefined>;
|
|
253
|
+
}, undefined, undefined>;
|
|
254
254
|
/**
|
|
255
255
|
* **Restore Asset** · `BETA`
|
|
256
256
|
*
|
|
@@ -291,7 +291,7 @@ export declare const postAssetsAssetIdRestore: import("../..").EndpointGeneric<{
|
|
|
291
291
|
title: string;
|
|
292
292
|
uri: string;
|
|
293
293
|
};
|
|
294
|
-
}, undefined>;
|
|
294
|
+
}, undefined, undefined>;
|
|
295
295
|
/**
|
|
296
296
|
* **List Asset Versions** · `BETA`
|
|
297
297
|
*
|
|
@@ -321,7 +321,7 @@ export declare const getAssetsAssetIdVersions: import("../..").EndpointGeneric<{
|
|
|
321
321
|
moderationState: string;
|
|
322
322
|
};
|
|
323
323
|
published: boolean;
|
|
324
|
-
}[], undefined>;
|
|
324
|
+
}[], undefined, undefined>;
|
|
325
325
|
/**
|
|
326
326
|
* **Rollback Asset Version** · `BETA`
|
|
327
327
|
*
|
|
@@ -352,7 +352,7 @@ export declare const postAssetsAssetIdVersionsRollback: import("../..").Endpoint
|
|
|
352
352
|
published: boolean;
|
|
353
353
|
}, {
|
|
354
354
|
assetVersion: string;
|
|
355
|
-
}>;
|
|
355
|
+
}, undefined>;
|
|
356
356
|
/**
|
|
357
357
|
* **Get Asset Version** · `BETA`
|
|
358
358
|
*
|
|
@@ -380,7 +380,7 @@ export declare const getAssetsAssetIdVersionsVersionNumber: import("../..").Endp
|
|
|
380
380
|
moderationState: string;
|
|
381
381
|
};
|
|
382
382
|
published: boolean;
|
|
383
|
-
}, undefined>;
|
|
383
|
+
}, undefined, undefined>;
|
|
384
384
|
/**
|
|
385
385
|
* **Get Operation** · `BETA`
|
|
386
386
|
*
|
|
@@ -429,4 +429,4 @@ export declare const getOperationsOperationId: import("../..").EndpointGeneric<{
|
|
|
429
429
|
uri: string;
|
|
430
430
|
};
|
|
431
431
|
};
|
|
432
|
-
}, undefined>;
|
|
432
|
+
}, undefined, undefined>;
|
|
@@ -30,7 +30,7 @@ export declare const getUniversesUniverseIdOrderedDataStoresOrderedDataStoreScop
|
|
|
30
30
|
value: number;
|
|
31
31
|
}[];
|
|
32
32
|
nextPageToken: string;
|
|
33
|
-
}, undefined>;
|
|
33
|
+
}, undefined, undefined>;
|
|
34
34
|
/**
|
|
35
35
|
* **Create** · `BETA`
|
|
36
36
|
*
|
|
@@ -57,7 +57,7 @@ export declare const postUniversesUniverseIdOrderedDataStoresOrderedDataStoreSco
|
|
|
57
57
|
value: number;
|
|
58
58
|
}, {
|
|
59
59
|
value: number;
|
|
60
|
-
}>;
|
|
60
|
+
}, undefined>;
|
|
61
61
|
/**
|
|
62
62
|
* **Get** · `BETA`
|
|
63
63
|
*
|
|
@@ -81,7 +81,7 @@ export declare const getUniversesUniverseIdOrderedDataStoresOrderedDataStoreScop
|
|
|
81
81
|
path: string;
|
|
82
82
|
id: string;
|
|
83
83
|
value: number;
|
|
84
|
-
}, undefined>;
|
|
84
|
+
}, undefined, undefined>;
|
|
85
85
|
/**
|
|
86
86
|
* **Delete** · `BETA`
|
|
87
87
|
*
|
|
@@ -101,7 +101,7 @@ export declare const deleteUniversesUniverseIdOrderedDataStoresOrderedDataStoreS
|
|
|
101
101
|
scope: string;
|
|
102
102
|
orderedDataStore: string;
|
|
103
103
|
entry: string;
|
|
104
|
-
}, void, undefined>;
|
|
104
|
+
}, void, undefined, undefined>;
|
|
105
105
|
/**
|
|
106
106
|
* **Update** · `BETA`
|
|
107
107
|
*
|
|
@@ -130,7 +130,7 @@ export declare const patchUniversesUniverseIdOrderedDataStoresOrderedDataStoreSc
|
|
|
130
130
|
value: number;
|
|
131
131
|
}, {
|
|
132
132
|
value?: number | undefined;
|
|
133
|
-
}>;
|
|
133
|
+
}, undefined>;
|
|
134
134
|
/**
|
|
135
135
|
* **Increment** · `BETA`
|
|
136
136
|
*
|
|
@@ -159,4 +159,4 @@ export declare const postUniversesUniverseIdOrderedDataStoresOrderedDataStoreSco
|
|
|
159
159
|
value: number;
|
|
160
160
|
}, {
|
|
161
161
|
amount: number;
|
|
162
|
-
}>;
|
|
162
|
+
}, undefined>;
|
|
@@ -24,7 +24,7 @@ export declare const getUniversesUniverseIdDatastores: import("../..").EndpointG
|
|
|
24
24
|
createdTime: string | null;
|
|
25
25
|
}[];
|
|
26
26
|
nextPageCursor: string | null;
|
|
27
|
-
}, undefined>;
|
|
27
|
+
}, undefined, undefined>;
|
|
28
28
|
/**
|
|
29
29
|
* **List Entries** · `BETA`
|
|
30
30
|
*
|
|
@@ -57,7 +57,7 @@ export declare const getUniversesUniverseIdDatastoresDatastoreEntries: import(".
|
|
|
57
57
|
}, {
|
|
58
58
|
keys: string[];
|
|
59
59
|
nextPageCursor: string | null;
|
|
60
|
-
}, undefined>;
|
|
60
|
+
}, undefined, undefined>;
|
|
61
61
|
/**
|
|
62
62
|
* **Get Entry** · `BETA`
|
|
63
63
|
*
|
|
@@ -101,7 +101,7 @@ export declare const getUniversesUniverseIdDatastoresDatastoreEntriesEntry: impo
|
|
|
101
101
|
datastoreName?: string | null | undefined;
|
|
102
102
|
scope?: string | null | undefined;
|
|
103
103
|
entryKey?: string | null | undefined;
|
|
104
|
-
}, Record<string, never>, undefined>;
|
|
104
|
+
}, Record<string, never>, undefined, undefined>;
|
|
105
105
|
/**
|
|
106
106
|
* **Set Entry** · `BETA`
|
|
107
107
|
*
|
|
@@ -136,7 +136,7 @@ export declare const postUniversesUniverseIdDatastoresDatastoreEntriesEntry: imp
|
|
|
136
136
|
"roblox-entry-attributes"?: string | null | undefined;
|
|
137
137
|
"roblox-entry-userids"?: string | null | undefined;
|
|
138
138
|
"content-md5"?: string | null | undefined;
|
|
139
|
-
}, void, string>;
|
|
139
|
+
}, void, string, undefined>;
|
|
140
140
|
/**
|
|
141
141
|
* **Delete Entry** · `BETA`
|
|
142
142
|
*
|
|
@@ -158,7 +158,7 @@ export declare const deleteUniversesUniverseIdDatastoresDatastoreEntriesEntry: i
|
|
|
158
158
|
datastoreName?: string | null | undefined;
|
|
159
159
|
scope?: string | null | undefined;
|
|
160
160
|
entryKey?: string | null | undefined;
|
|
161
|
-
}, void, undefined>;
|
|
161
|
+
}, void, undefined, undefined>;
|
|
162
162
|
/**
|
|
163
163
|
* **Increment Entry** · `BETA`
|
|
164
164
|
*
|
|
@@ -206,7 +206,7 @@ export declare const postUniversesUniverseIdDatastoresDatastoreEntriesEntryIncre
|
|
|
206
206
|
"roblox-entry-attributes"?: string | null | undefined;
|
|
207
207
|
"roblox-entry-userids"?: string | null | undefined;
|
|
208
208
|
incrementBy?: number | undefined;
|
|
209
|
-
}, Record<string, never>, undefined>;
|
|
209
|
+
}, Record<string, never>, undefined, undefined>;
|
|
210
210
|
/**
|
|
211
211
|
* **List Entry Versions** · `BETA`
|
|
212
212
|
*
|
|
@@ -238,7 +238,7 @@ export declare const getUniversesUniverseIdDatastoresDatastoreEntriesEntryVersio
|
|
|
238
238
|
scope?: string | null | undefined;
|
|
239
239
|
entryKey?: string | null | undefined;
|
|
240
240
|
sortOrder?: string | null | undefined;
|
|
241
|
-
}, void, undefined>;
|
|
241
|
+
}, void, undefined, undefined>;
|
|
242
242
|
/**
|
|
243
243
|
* **Get Entry Version** · `BETA`
|
|
244
244
|
*
|
|
@@ -282,4 +282,4 @@ export declare const getUniversesUniverseIdDatastoresDatastoreEntriesEntryVersio
|
|
|
282
282
|
scope?: string | null | undefined;
|
|
283
283
|
entryKey?: string | null | undefined;
|
|
284
284
|
versionId?: string | null | undefined;
|
|
285
|
-
}, Record<string, never>, undefined>;
|
|
285
|
+
}, Record<string, never>, undefined, undefined>;
|
|
@@ -33,7 +33,7 @@ export declare const postDeveloperProductsV2UniversesUniverseIdDeveloperProducts
|
|
|
33
33
|
price?: number | null | undefined;
|
|
34
34
|
imageFile?: File | null | undefined;
|
|
35
35
|
isRegionalPricingEnabled?: boolean | null | undefined;
|
|
36
|
-
}>;
|
|
36
|
+
}, undefined>;
|
|
37
37
|
/**
|
|
38
38
|
* `BETA`
|
|
39
39
|
*
|
|
@@ -58,7 +58,7 @@ export declare const patchDeveloperProductsV2UniversesUniverseIdDeveloperProduct
|
|
|
58
58
|
imageFile?: File | null | undefined;
|
|
59
59
|
isRegionalPricingEnabled?: boolean | null | undefined;
|
|
60
60
|
storePageEnabled?: boolean | null | undefined;
|
|
61
|
-
}>;
|
|
61
|
+
}, undefined>;
|
|
62
62
|
/**
|
|
63
63
|
* `BETA`
|
|
64
64
|
*
|
|
@@ -88,7 +88,7 @@ export declare const getDeveloperProductsV2UniversesUniverseIdDeveloperProductsP
|
|
|
88
88
|
isImmutable: boolean;
|
|
89
89
|
createdTimestamp: string;
|
|
90
90
|
updatedTimestamp: string;
|
|
91
|
-
}, undefined>;
|
|
91
|
+
}, undefined, undefined>;
|
|
92
92
|
/**
|
|
93
93
|
* `BETA`
|
|
94
94
|
*
|
|
@@ -123,4 +123,4 @@ export declare const getDeveloperProductsV2UniversesUniverseIdDeveloperProductsC
|
|
|
123
123
|
updatedTimestamp: string;
|
|
124
124
|
}[];
|
|
125
125
|
nextPageToken: string | null;
|
|
126
|
-
}, undefined>;
|
|
126
|
+
}, undefined, undefined>;
|
|
@@ -30,7 +30,7 @@ export declare const postGamePassesV1UniversesUniverseIdGamePasses: import("../.
|
|
|
30
30
|
isForSale?: boolean | null | undefined;
|
|
31
31
|
price?: number | null | undefined;
|
|
32
32
|
isRegionalPricingEnabled?: boolean | null | undefined;
|
|
33
|
-
}>;
|
|
33
|
+
}, undefined>;
|
|
34
34
|
/**
|
|
35
35
|
* `BETA`
|
|
36
36
|
*
|
|
@@ -54,7 +54,7 @@ export declare const patchGamePassesV1UniversesUniverseIdGamePassesGamePassId: i
|
|
|
54
54
|
isForSale?: boolean | null | undefined;
|
|
55
55
|
price?: number | null | undefined;
|
|
56
56
|
isRegionalPricingEnabled?: boolean | null | undefined;
|
|
57
|
-
}>;
|
|
57
|
+
}, undefined>;
|
|
58
58
|
/**
|
|
59
59
|
* `BETA`
|
|
60
60
|
*
|
|
@@ -81,7 +81,7 @@ export declare const getGamePassesV1UniversesUniverseIdGamePassesGamePassIdCreat
|
|
|
81
81
|
defaultPriceInRobux: number | null;
|
|
82
82
|
enabledFeatures: ("Invalid" | "PriceOptimization" | "UserFixedPrice" | "RegionalPricing")[];
|
|
83
83
|
} | null;
|
|
84
|
-
}, undefined>;
|
|
84
|
+
}, undefined, undefined>;
|
|
85
85
|
/**
|
|
86
86
|
* `BETA`
|
|
87
87
|
*
|
|
@@ -113,4 +113,4 @@ export declare const getGamePassesV1UniversesUniverseIdGamePassesCreator: import
|
|
|
113
113
|
} | null;
|
|
114
114
|
}[];
|
|
115
115
|
nextPageToken: string | null;
|
|
116
|
-
}, undefined>;
|
|
116
|
+
}, undefined, undefined>;
|
|
@@ -23,7 +23,7 @@ export declare const postOpenEvalApiV1Eval: import("../..").EndpointGeneric<{},
|
|
|
23
23
|
model_version?: string | null | undefined;
|
|
24
24
|
api_key?: string | null | undefined;
|
|
25
25
|
} | undefined;
|
|
26
|
-
}>;
|
|
26
|
+
}, undefined>;
|
|
27
27
|
/**
|
|
28
28
|
* `BETA`
|
|
29
29
|
*
|
|
@@ -64,4 +64,4 @@ export declare const getOpenEvalApiV1EvalRecordsJobId: import("../..").EndpointG
|
|
|
64
64
|
fullLogs?: string | null | undefined;
|
|
65
65
|
evalSucceeded?: string | null | undefined;
|
|
66
66
|
createUtc?: string | null | undefined;
|
|
67
|
-
}, undefined>;
|
|
67
|
+
}, undefined, undefined>;
|
|
@@ -37,7 +37,7 @@ export declare const postCloudV2UniversesUniverseIdSecrets: import("../..").Endp
|
|
|
37
37
|
domain: string | null;
|
|
38
38
|
create_time: string | null;
|
|
39
39
|
update_time: string | null;
|
|
40
|
-
}>;
|
|
40
|
+
}, undefined>;
|
|
41
41
|
/**
|
|
42
42
|
* `BETA`
|
|
43
43
|
*
|
|
@@ -69,7 +69,7 @@ export declare const getCloudV2UniversesUniverseIdSecrets: import("../..").Endpo
|
|
|
69
69
|
}[] | null;
|
|
70
70
|
nextPageCursor: string | null;
|
|
71
71
|
previousPageCursor: string | null;
|
|
72
|
-
}, undefined>;
|
|
72
|
+
}, undefined, undefined>;
|
|
73
73
|
/**
|
|
74
74
|
* `BETA`
|
|
75
75
|
*
|
|
@@ -113,7 +113,7 @@ export declare const patchCloudV2UniversesUniverseIdSecretsSecretId: import("../
|
|
|
113
113
|
domain?: string | null | undefined;
|
|
114
114
|
create_time?: string | null | undefined;
|
|
115
115
|
update_time?: string | null | undefined;
|
|
116
|
-
}>;
|
|
116
|
+
}, undefined>;
|
|
117
117
|
/**
|
|
118
118
|
* `BETA`
|
|
119
119
|
*
|
|
@@ -133,7 +133,7 @@ This operation is irreversible. Make sure you no longer need the secret before d
|
|
|
133
133
|
export declare const deleteCloudV2UniversesUniverseIdSecretsSecretId: import("../..").EndpointGeneric<{
|
|
134
134
|
universeId: number;
|
|
135
135
|
secretId: string;
|
|
136
|
-
}, void, undefined>;
|
|
136
|
+
}, void, undefined, undefined>;
|
|
137
137
|
/**
|
|
138
138
|
* `BETA`
|
|
139
139
|
*
|
|
@@ -165,4 +165,4 @@ export declare const getCloudV2UniversesUniverseIdSecretsPublicKey: import("../.
|
|
|
165
165
|
domain: string | null;
|
|
166
166
|
create_time: string | null;
|
|
167
167
|
update_time: string | null;
|
|
168
|
-
}, undefined>;
|
|
168
|
+
}, undefined, undefined>;
|