From 579f11e2e89460e1ea8dcd2ba1f2191ae6d240e5 Mon Sep 17 00:00:00 2001 From: Cameron Campbell Date: Tue, 1 Oct 2024 03:47:09 +0100 Subject: [PATCH] cf worker support and luau execution api rework --- docs/docs.json | 283 ++++++++++++++++-- package.json | 114 +++++++ src/apis/apiGroup/apiGroup.ts | 90 ++---- src/apis/apiGroup/apiGroup.types.ts | 8 +- src/apis/cloud/luauExecution/luauExecution.ts | 73 +++-- .../luauExecution/luauExecution.types.ts | 49 ++- src/config/config.ts | 18 +- src/file/file.shell.ts | 3 + src/file/file.ts | 12 +- src/helpers/index.ts | 2 +- src/helpers/poll.ts | 59 ++-- src/queries/classic/groupsQuery.ts | 2 +- src/queries/queries.utils.ts | 6 +- 13 files changed, 566 insertions(+), 153 deletions(-) create mode 100644 package.json create mode 100644 src/file/file.shell.ts diff --git a/docs/docs.json b/docs/docs.json index fe94806..8d585ae 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -924,6 +924,126 @@ ] } }, + "luauExecution": { + "executeLuau": { + "description": "Executes a roblox luau script for a given place.", + "tags": { + "endpoint": "POST /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-session-tasks\nPOST /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-session-tasks", + "example": "const { data: executed } = await LuauExecutionApi.executeLuau({\n universeId: 5795192361,\n placeId: 16866553538,\n script: `local x, y = 3, 4; return x + y`,\n});", + "exampleData": "{\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n user: \"45348281\",\n state: \"PROCESSING\",\n script: \"local x, y = 3, 4; return x + y\",\n universeId: \"5795192361\",\n placeId: \"16866553538\",\n version: 26,\n sessionId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n taskId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n}\n", + "exampleRawBody": "{\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n user: \"45348281\",\n state: \"PROCESSING\",\n script: \"local x, y = 3, 4; return x + y\",\n}\n" + }, + "params": [ + { + "name": "universeId", + "type": "UniverseId", + "description": "The ID of the universe to execute the script under." + }, + { + "name": "placeId", + "type": "PlaceId", + "description": "The ID of the place to execute the script under." + }, + { + "name": "version?", + "type": "Version", + "description": "The optional version number of the place to execute the script under." + }, + { + "name": "script", + "type": "string | Buffer | ArrayNonEmptyIfConst", + "description": "The script to execute." + } + ] + }, + "luauExecutionTask": { + "description": "Gets a luau execution task.", + "tags": { + "endpoint": "GET /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-session-tasks\nGET /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-session-tasks\nGET /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-sessions/{sessionId}/tasks\nGET /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-sessions/{sessionId}/tasks", + "example": "import { pollMethod } from \"openblox/helpers\";\n\ntype Results = number[];\nconst { data: executedTask } = await pollMethod(\n LuauExecutionApi.luauExecutionTask({\n universeId: 5795192361,\n placeId: 16866553538,\n version: 26,\n sessionId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n taskId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n }),\n async ({ data }, stopPolling) => data.state === \"COMPLETE\" && stopPolling(),\n);", + "exampleData": "{\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n createTime: \"2024-10-01T02:31:46.304Z\",\n updateTime: \"2024-10-01T02:31:49.959Z\",\n user: \"45348281\",\n state: \"COMPLETE\",\n script: \"\",\n output: { results: [7] },\n universeId: \"5795192361\",\n placeId: \"16866553538\",\n version: 26,\n sessionId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n taskId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n}\n", + "exampleRawBody": "{\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n createTime: \"2024-10-01T02:31:46.304Z\",\n updateTime: \"2024-10-01T02:31:49.959Z\",\n user: \"45348281\",\n state: \"COMPLETE\",\n script: \"\",\n output: { results: [7] },\n}\n" + }, + "params": [ + { + "name": "universeId", + "type": "Identifier", + "description": "The ID of the universe to get the luau execution task from." + }, + { + "name": "placeId", + "type": "Identifier", + "description": "The ID of the place to get the luau execution task from." + }, + { + "name": "version?", + "type": "number", + "description": "The optional version number of the place to get the luau execution task for." + }, + { + "name": "sessionId", + "type": "string", + "description": "The ID of the session to get the luau execution task for." + }, + { + "name": "taskId", + "type": "string", + "description": "The ID of the task to get the luau execution task for." + }, + { + "name": "view?", + "type": "\"BASIC\" | \"FULL\"", + "description": "If the response should return the script source (`\"FULL\"`) instead of an empty string." + } + ] + }, + "listLuauExecutionLogs": { + "description": "Lists luau execution logs.", + "tags": { + "endpoint": "GET /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-session-tasks/{taskId}/logs\nGET /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-sessions/{sessionId}/tasks/{taskId}/logs\nGET /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-session-tasks/{taskId}/logs\nGET /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-sessions/{sessionId}/tasks/{taskId}/logs", + "example": "const { data: logs } = await LuauExecutionApi.listLuauExecutionLogs({\n universeId: 5795192361,\n placeId: 16866553538,\n version: 26,\n sessionId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n taskId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n});", + "exampleData": "[\n {\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/logs/1\",\n messages: [],\n universeId: \"5795192361\",\n placeId: \"16866553538\",\n version: 26,\n sessionId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n taskId: \"67823af7-1f99-4fc5-b3bb-da7ab3456b5d\",\n },\n]\n", + "exampleRawBody": "{\n luauExecutionSessionTaskLogs: [\n {\n path: \"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/logs/1\",\n messages: [],\n },\n ],\n nextPageToken: \"\",\n}\n" + }, + "params": [ + { + "name": "universeId", + "type": "UniverseId", + "description": "The ID of the universe to list logs for." + }, + { + "name": "placeId", + "type": "PlaceId", + "description": "The ID of the place to list logs for." + }, + { + "name": "version?", + "type": "Version", + "description": "The optional version number of the place to list logs for." + }, + { + "name": "sessionId?", + "type": "SessionId", + "description": "The ID of the session to get logs for." + }, + { + "name": "taskId", + "type": "TaskId", + "description": "The ID of the task to get logs for." + }, + { + "name": "limit?", + "type": "number", + "description": "The maximum amount of logs to return. The service might return fewer than this value. If unspecified, at most 10000 luau execution session task logs are returned. The maximum value is 10000 and higher values are set to 10000." + }, + { + "name": "cursor?", + "type": "string", + "description": "A page token, received from a previous call, to retrieve a subsequent page." + } + ] + } + }, "memoryStores": { "sortedMapItem": { "description": "Gets a sorted map item.", @@ -1221,7 +1341,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: entries } = await OrderedDatastoresApi_V1.listOrderedDatastoreEntries({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: entries } = await OrderedDataStoresApi_V1.listOrderedDatastoreEntries({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n});", "exampleData": "[\n {\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n },\n]\n", "exampleRawBody": "{\n entries: [\n {\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n },\n ],\n nextPageToken: \"\",\n}\n" }, @@ -1268,7 +1389,8 @@ "tags": { "endpoint": "POST /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: createdEntry } = await OrderedDatastoresApi_V1.createOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348282\",\n value: 54,\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: createdEntry } = await OrderedDataStoresApi_V1.createOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348282\",\n value: 54,\n});", "exampleData": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n}\n" }, @@ -1305,7 +1427,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: entry } = await OrderedDatastoresApi_V1.orderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: entry } = await OrderedDataStoresApi_V1.orderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n});", "exampleData": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 54,\n id: \"45348281\",\n}\n" }, @@ -1337,7 +1460,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: success } = await OrderedDatastoresApi_V1.deleteOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: success } = await OrderedDataStoresApi_V1.deleteOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n});", "exampleData": "", "exampleRawBody": "{}\n" }, @@ -1369,7 +1493,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: updatedEntry } = await OrderedDatastoresApi_V1.updateOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n newValue: 58,\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: updatedEntry } = await OrderedDataStoresApi_V1.updateOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n newValue: 58,\n});", "exampleData": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 58,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 58,\n id: \"45348281\",\n}\n" }, @@ -1411,7 +1536,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/orderedDataStores/{orderedDataStore}/scopes/{scope}/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: incrementedEntry } = await OrderedDatastoresApi_V1.incrementOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n incrementBy: 26,\n createIfNoEntryExists: true,\n});", + "deprecated": "Please use `OrderedDataStoresApi_V2` for new work.", + "example": "const { data: incrementedEntry } = await OrderedDataStoresApi_V1.incrementOrderedDatastoreEntry({\n universeId: 5097539509,\n orderedDataStore: \"PointsStore\",\n scope: \"global\",\n id: \"45348281\",\n incrementBy: 26,\n createIfNoEntryExists: true,\n});", "exampleData": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 66,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/orderedDataStores/PointsStore/scopes/global/entries/45348281\",\n value: 66,\n id: \"45348281\",\n}\n" }, @@ -1454,7 +1580,7 @@ "description": "Lists entries in an ordered data store.", "tags": { "endpoint": "GET /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries", - "example": "const { data: entries } = await OrderedDatastoresApi_V2.listOrderedDatastoreEntries({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n sortOrder: \"Desc\",\n lessThanOrEq: 80,\n moreThanOrEq: 70,\n});", + "example": "const { data: entries } = await OrderedDataStoresApi_V2.listOrderedDatastoreEntries({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n sortOrder: \"Desc\",\n lessThanOrEq: 80,\n moreThanOrEq: 70,\n});", "exampleData": "[\n {\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 78,\n id: \"45348281\",\n },\n]\n", "exampleRawBody": "{\n orderedDataStoreEntries: [\n {\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 78,\n id: \"45348281\",\n },\n ],\n}\n" }, @@ -1488,6 +1614,16 @@ "name": "moreThanOrEq?", "type": "number", "description": "Filters the results to include those more than or equal to a specific number (can be used in tangent with `lessThabOrEq`)." + }, + { + "name": "limit?", + "type": "number", + "description": "The number of results per request." + }, + { + "name": "cursor?", + "type": "string", + "description": "The paging cursor for the previous or next page." } ] }, @@ -1495,7 +1631,7 @@ "description": "Creates a new entry in an ordered data store.", "tags": { "endpoint": "POST /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries", - "example": "const { data: entry } = await OrderedDatastoresApi_V2.createOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"453482811\",\n entryValue: 15,\n});", + "example": "const { data: entry } = await OrderedDataStoresApi_V2.createOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"453482811\",\n entryValue: 15,\n});", "exampleData": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 15,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 15,\n id: \"45348281\",\n}\n" }, @@ -1526,7 +1662,7 @@ "description": "Gets an new entry in an ordered data store.", "tags": { "endpoint": "GET /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries", - "example": "const { data: entry } = await OrderedDatastoresApi_V2.orderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n});", + "example": "const { data: entry } = await OrderedDataStoresApi_V2.orderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n});", "exampleData": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 78,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 78,\n id: \"45348281\",\n}\n" }, @@ -1557,7 +1693,7 @@ "description": "Deletes an entry from an ordered data store.", "tags": { "endpoint": "DELETE /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries", - "example": "const { data: success } = await OrderedDatastoresApi_V2.deleteOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n});", + "example": "const { data: success } = await OrderedDataStoresApi_V2.deleteOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n});", "exampleData": "", "exampleRawBody": "{}\n" }, @@ -1588,7 +1724,7 @@ "description": "Updates an entry in an ordered data store.", "tags": { "endpoint": "PATCH /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries/{entryId}", - "example": "const { data: entry } = await OrderedDatastoresApi_V2.updateOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n newEntryValue: 45,\n});", + "example": "const { data: entry } = await OrderedDataStoresApi_V2.updateOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n newEntryValue: 45,\n});", "exampleData": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 45,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 45,\n id: \"45348281\",\n}\n" }, @@ -1619,7 +1755,7 @@ "description": "Updates an entry in an ordered data store.", "tags": { "endpoint": "PATCH /v2/universes/{universeId}/ordered-data-stores/{dataStoreId}/scopes/{scope}/entries/{entryId}:increment", - "example": "const { data: entry } = await OrderedDatastoresApi_V2.incrementOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n incrementBy: 42,\n});", + "example": "const { data: entry } = await OrderedDataStoresApi_V2.incrementOrderedDataStoreEntry({\n universeId: 5097539509,\n dataStoreId: \"PointsStore\",\n scope: \"global\",\n entryId: \"45348281\",\n incrementBy: 42,\n});", "exampleData": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 42,\n id: \"45348281\",\n}\n", "exampleRawBody": "{\n path: \"universes/5097539509/ordered-data-stores/PointsStore/scopes/global/entries/45348281\",\n value: 42,\n id: \"45348281\",\n}\n" }, @@ -1653,7 +1789,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/standard-datastores", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: datastores } = await StandardDatastoresApi_V1.listStandardDatastores({ universeId: 5097539509 });", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "const { data: datastores } = await StandardDataStoresApi_V1.listStandardDatastores({ universeId: 5097539509 });", "exampleData": "[{ name: \"InventoryStore\", createdTime: \"2023-09-16T11:03:03.868Z\" }]\n", "exampleRawBody": "{\n datastores: [\n { name: \"InventoryStore\", createdTime: \"2023-09-16T11:03:03.868331Z\" },\n ],\n nextPageCursor: \"\",\n}\n" }, @@ -1685,7 +1822,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/standard-datastores/datastore/entries", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: keys } = await StandardDatastoresApi_V1.standardDatastoreKeys({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "const { data: keys } = await StandardDataStoresApi_V1.standardDatastoreKeys({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n});", "exampleData": "[\"user/45348281\"]\n", "exampleRawBody": "{\n keys: [{ key: \"user/45348281\" }],\n nextPageCursor: \"eyJ2ZXJzaW9uIjoxLCJjdXJzb3IiOiIxMyMifQ==\",\n}\n" }, @@ -1732,7 +1870,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/standard-datastores/datastore/entries/entry", "tags": "[ \"Cloud Key\" ]", - "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: entryInfo } = await StandardDatastoresApi_V1.standardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n});\nif (!entryInfo.checksumsMatch) console.log(\"checksums do not match, data may be invalid!\");\nelse console.log(\"checksums match! ->\", entryInfo.entry);", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: entryInfo } = await StandardDataStoresApi_V1.standardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n});\nif (!entryInfo.checksumsMatch) console.log(\"checksums do not match, data may be invalid!\");\nelse console.log(\"checksums match! ->\", entryInfo.entry);", "exampleData": "{\n entry: { Gold: 6, Iron: 57 },\n checksumsMatch: true,\n metadata: {\n contentMD5: \"hGwoaGwduF4bOhexREYGkA==\",\n entryVersion: \"08DBB6A47FDE6132.0000000016.08DBB782CEE11766.01\",\n entryCreatedTime: \"2023-09-16T11:03:03.922Z\",\n entryVersionCreatedTime: \"2023-09-17T13:34:24.754Z\",\n entryAttributes: null,\n entryUserIds: [45348281],\n },\n}\n", "exampleRawBody": "{\n entry: { Gold: 6, Iron: 57 },\n checksumsMatch: true,\n metadata: {\n contentMD5: \"hGwoaGwduF4bOhexREYGkA==\",\n entryVersion: \"08DBB6A47FDE6132.0000000016.08DBB782CEE11766.01\",\n entryCreatedTime: \"2023-09-16T11:03:03.922Z\",\n entryVersionCreatedTime: \"2023-09-17T13:34:24.754Z\",\n entryAttributes: null,\n entryUserIds: [45348281],\n },\n}\n" }, @@ -1764,7 +1903,8 @@ "tags": { "endpoint": "POST /v1/universes/{universeId}/standard-datastores/datastore/entries/entry", "tags": "[ \"Cloud Key\" ]", - "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: response } = await StandardDatastoresApi_V1.setStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n entryValue: { Gold: 6 },\n entryUserIds: [45348281],\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: response } = await StandardDataStoresApi_V1.setStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n entryValue: { Gold: 6 },\n entryUserIds: [45348281],\n});", "exampleData": "{\n version: \"08DBB6A47FDE6132.000000000E.08DBB780C616DF0C.01\",\n deleted: false,\n contentLength: 20,\n createdTime: \"2023-09-17T13:19:51.014Z\",\n objectCreatedTime: \"2023-09-16T11:03:03.922Z\",\n}\n", "exampleRawBody": "{\n version: \"08DBB6A47FDE6132.000000000E.08DBB780C616DF0C.01\",\n deleted: false,\n contentLength: 20,\n createdTime: \"2023-09-17T13:19:51.014Z\",\n objectCreatedTime: \"2023-09-16T11:03:03.922Z\",\n}\n" }, @@ -1816,7 +1956,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/standard-datastores/datastore/entries/entry", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: success } = await StandardDatastoresApi_V1.deleteStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "const { data: success } = await StandardDataStoresApi_V1.deleteStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n});", "exampleData": "", "exampleRawBody": "" }, @@ -1848,7 +1989,8 @@ "tags": { "endpoint": "POST /v1/universes/{universeId}/standard-datastores/datastore/entries/entry/increment", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: incrementedEntry } = await StandardDatastoresApi_V1.incrementStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"LoremIpsum\",\n entryKey: \"user/45348281\",\n incrementBy: 1,\n entryUserIds: [45348281],\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "const { data: incrementedEntry } = await StandardDataStoresApi_V1.incrementStandardDatastoreEntry({\n universeId: 5097539509,\n datastoreName: \"LoremIpsum\",\n entryKey: \"user/45348281\",\n incrementBy: 1,\n entryUserIds: [45348281],\n});", "exampleData": "", "exampleRawBody": "" }, @@ -1895,7 +2037,8 @@ "tags": { "endpoint": "POST /v1/universes/{universeId}/standard-datastores/datastore/entries/entry/versions/version", "tags": "[ \"Cloud Key\" ]", - "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: entry } = await StandardDatastoresApi_V1.standardDatastoreEntryOfVersion({\n universeId: 5097539509,\n datastoreName: \"LoremIpsum\",\n entryKey: \"user/45348281\",\n versionId: \"08DC7742E4BD78AF.0000000001.08DC7742E4BD78AF.01\",\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "type InventorySchema = { Iron?: number; Gold?: number; Copper?: number; Stone?: number; Wood?: number };\nconst { data: entry } = await StandardDataStoresApi_V1.standardDatastoreEntryOfVersion({\n universeId: 5097539509,\n datastoreName: \"LoremIpsum\",\n entryKey: \"user/45348281\",\n versionId: \"08DC7742E4BD78AF.0000000001.08DC7742E4BD78AF.01\",\n});", "exampleData": "{\n entry: { Gold: 6, Iron: 57 },\n checksumsMatch: true,\n metadata: {\n contentMD5: \"hGwoaGwduF4bOhexREYGkA==\",\n entryVersion: \"08DBB6A47FDE6132.0000000016.08DBB782CEE11766.01\",\n entryCreatedTime: \"2023-09-16T11:03:03.922Z\",\n entryVersionCreatedTime: \"2023-09-17T13:34:24.754Z\",\n entryAttributes: null,\n entryUserIds: [45348281],\n },\n}\n", "exampleRawBody": "{\n entry: { Gold: 6, Iron: 57 },\n checksumsMatch: true,\n metadata: {\n contentMD5: \"hGwoaGwduF4bOhexREYGkA==\",\n entryVersion: \"08DBB6A47FDE6132.0000000016.08DBB782CEE11766.01\",\n entryCreatedTime: \"2023-09-16T11:03:03.922Z\",\n entryVersionCreatedTime: \"2023-09-17T13:34:24.754Z\",\n entryAttributes: null,\n entryUserIds: [45348281],\n },\n}\n" }, @@ -1932,7 +2075,8 @@ "tags": { "endpoint": "GET /v1/universes/{universeId}/standard-datastores/datastore/entries/entry/versions", "tags": "[ \"Cloud Key\" ]", - "example": "const { data: versions } = await StandardDatastoresApi_V1.listStandardDatastoreEntryVersions({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n sortOrder: \"Ascending\",\n limit: 1,\n});", + "deprecated": "Please use `StandardDataStoresApi_V2` for new work.", + "example": "const { data: versions } = await StandardDataStoresApi_V1.listStandardDatastoreEntryVersions({\n universeId: 5097539509,\n datastoreName: \"InventoryStore\",\n entryKey: \"user/45348281\",\n sortOrder: \"Ascending\",\n limit: 1,\n});", "exampleData": "[\n {\n version: \"08DBB6A47FDE6132.0000000010.08DBB781B9579F00.01\",\n deleted: false,\n contentLength: 20,\n createdTime: \"2023-09-17T13:26:39.124Z\",\n objectCreatedTime: \"2023-09-16T11:03:03.922Z\",\n },\n]\n", "exampleRawBody": "{\n versions: [\n {\n version: \"08DBB6A47FDE6132.0000000010.08DBB781B9579F00.01\",\n deleted: false,\n contentLength: 20,\n createdTime: \"2023-09-17T13:26:39.124Z\",\n objectCreatedTime: \"2023-09-16T11:03:03.922Z\",\n },\n ],\n}\n" }, @@ -2345,11 +2489,11 @@ } }, "userRestrictions": { - "restrictions": { + "listRestrictions": { "description": "Gets restrictions for a user.", "tags": { "endpoint": "PATCH /v2/universes/{universe}/user-restrictions/{user-restriction}\nPATCH /v2/universes/{universeId}/places/{placeId}/user-restrictions/{userId}", - "example": "const { data: restrictions } = await UserRestrictionsApi.restrictions({\n universeId: 5795192361,\n placeId: 18210254887,\n userId: 6193495014,\n});", + "example": "const { data: restrictions } = await UserRestrictionsApi.listRestrictions({\n universeId: 5795192361,\n placeId: 18210254887,\n userId: 6193495014,\n});", "exampleData": "{\n path: \"universes/5795192361/places/18210254887/user-restrictions/6193495014\",\n user: \"users/6193495014\",\n gameJoinRestriction: {\n active: true,\n startTime: \"2024-06-25T22:56:58.873Z\",\n duration: \"31540000s\",\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n inherited: false,\n },\n}\n", "exampleRawBody": "{\n path: \"universes/5795192361/places/18210254887/user-restrictions/6193495014\",\n user: \"users/6193495014\",\n gameJoinRestriction: {\n active: true,\n startTime: \"2024-06-25T22:56:58.873Z\",\n duration: \"31540000s\",\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n inherited: false,\n },\n}\n" }, @@ -2371,11 +2515,32 @@ } ] }, + "restrictionForUser": { + "description": "Gets the active restriction for a user in a given universe.", + "tags": { + "endpoint": "GET /cloud/v2/universes/{universeId}/user-restrictions/{userId}", + "example": "", + "exampleData": "", + "exampleRawBody": "" + }, + "params": [ + { + "name": "universeId", + "type": "Identifier", + "description": "The ID of the universe to get restriction from." + }, + { + "name": "userId", + "type": "Identifier", + "description": "The ID of the user to get restriction for." + } + ] + }, "updateRestrictionsForUser": { "description": "Updates restrctions for a user.", "tags": { "endpoint": "PATCH /v2/universes/{universe}/user-restrictions/{user-restriction}\nPATCH /v2/universes/{universeId}/places/{placeId}/user-restrictions/{userId}", - "example": "import { v4 as uuidv4 } from \"uuid\";\nconst idempotencyKey = uuidv4(),\n firstSent = new Date();\n\nconst { data: updatedRestrictions } = await UserRestrictionsApi.updateRestrictionsForUser({\n universeId: 5795192361,\n placeId: 18210254887,\n userId: 6193495014,\n idempotencyKey,\n firstSent,\n updatedData: {\n gameJoinRestriction: {\n active: true,\n duration: \"31540000s\", // 1 year.\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n inherited: true,\n },\n },\n});", + "example": "import { v4 as uuidv4 } from \"uuid\";\nconst idempotencyKey = uuidv4(),\n firstSent = new Date();\n\nconst { data: updatedRestrictions } = await UserRestrictionsApi.updateRestrictionsForUser({\n universeId: 5795192361,\n placeId: 18210254887,\n userId: 6193495014,\n idempotencyKey,\n firstSent,\n updatedData: {\n gameJoinRestriction: {\n active: true,\n duration: \"31540000s\", // 1 year.\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n },\n },\n});", "exampleData": "{\n path: \"universes/5795192361/places/18210254887/user-restrictions/6193495014\",\n user: \"users/6193495014\",\n gameJoinRestriction: {\n active: true,\n startTime: \"2024-06-25T22:54:39.245Z\",\n duration: \"31540000s\",\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n inherited: false,\n },\n}\n", "exampleRawBody": "{\n path: \"universes/5795192361/places/18210254887/user-restrictions/6193495014\",\n user: \"users/6193495014\",\n gameJoinRestriction: {\n active: true,\n startTime: \"2024-06-25T22:54:39.245Z\",\n duration: \"31540000s\",\n privateReason: \"Being a meanie :/\",\n displayReason: \"Annoying other players.\",\n excludeAltAccounts: false,\n inherited: false,\n },\n}\n" }, @@ -4586,6 +4751,50 @@ ] } }, + "gameInternationalization": { + "universeAutoTranslationsAllowed": { + "description": "Sees if automatic translations are allowed for a particular universe.", + "tags": { + "endpoint": "GET /v1/automatic-translation/games/{universeId}/feature-status", + "example": "const { data: allowed } = await ClassicGameInternationalizationApi.universeAutoTranslationsAllowed({\n universeId: 1685831367,\n});", + "exampleData": "{\n gameId: 1685831367,\n isAutomaticTranslationAllowed: true,\n isAutomaticTranslationSwitchesUIEnabled: true,\n}\n", + "exampleRawBody": "{\n gameId: 1685831367,\n isAutomaticTranslationAllowed: true,\n isAutomaticTranslationSwitchesUIEnabled: true,\n}\n" + }, + "params": [ + { + "name": "universeId", + "type": "UniverseId", + "description": "The ID of the universe to see if automatic translations are allowed." + } + ] + }, + "universeAutoTranslationQuota": { + "description": "Gets automatic translation quota for a particular universe.", + "tags": { + "endpoint": "GET /v1/automatic-translation/games/{universeId}/quota", + "example": "const { data: quota } = await ClassicGameInternationalizationApi.universeAutoTranslationQuota({\n universeId: 1685831367,\n});", + "exampleData": "{\n monthlyQuota: {\n previousRefreshDate: \"0001-01-01T00:00:00\",\n nextRefreshDate: \"2024-09-10T15:29:26.849Z\",\n remaining: 550000,\n capacity: 550000,\n },\n bankQuota: { remaining: 2750000, capacity: 2750000 },\n}\n", + "exampleRawBody": "{\n monthlyQuota: {\n previousRefreshDate: \"0001-01-01T00:00:00\",\n nextRefreshDate: \"2024-09-10T15:29:26.849Z\",\n remaining: 550000,\n capacity: 550000,\n },\n bankQuota: { remaining: 2750000, capacity: 2750000 },\n}\n" + }, + "params": [ + { + "name": "universeId", + "type": "Identifier", + "description": "The ID of the universe to get automatic translation quota from." + } + ] + }, + "autoTranslatableLanguagesForSource": { + "description": "DESCRIPTION", + "tags": { + "endpoint": "REST /...", + "example": "const { data: autoTranslationsAllowed } = await ClassicGameInternationalizationApi.autoTranslatableLanguagesForSource({\n languageCode: \"en\",\n targetLanguageCodes: [\"fr\"],\n});", + "exampleData": "{ fr: true }\n", + "exampleRawBody": "{\n sourceLanguage: \"en\",\n targetLanguages: [\n { languageCode: \"fr\", isAutomaticTranslationAllowed: true },\n ],\n}\n" + }, + "params": [] + } + }, "gamePasses": { "gamePassInfo": { "description": "Gets information about a game pass.", @@ -4657,6 +4866,16 @@ "name": "icon?", "type": "string | File", "description": "The new icon for the game pass." + }, + { + "name": "price?", + "type": "number", + "description": "The new price for the game pass." + }, + { + "name": "isForSale?", + "type": "boolean", + "description": "If the game pass should be for sale." } ] }, @@ -7018,6 +7237,24 @@ ] } }, + "shareLinks": { + "shareLinkInfo": { + "description": "Gets information about a share link.", + "tags": { + "endpoint": "POST /v1/resolve-link", + "example": "const { data: linkInfo } = await ClassicShareLinksApi.shareLinkInfo({\n shareLinkId: \"0629f8e684039c4d800a1a03623e7a6f\",\n});", + "exampleData": "{\n experienceInviteData: null,\n friendInviteData: null,\n notificationExperienceInviteData: null,\n profileLinkResolutionResponseData: null,\n screenshotInviteData: null,\n privateServerInviteData: {\n status: \"Valid\",\n ownerUserId: 45348281,\n universeId: 6430220996,\n privateServerId: 1630945839,\n linkCode: \"67771413747491684286858666824242\",\n placeId: 18980972074,\n },\n experienceDetailsInviteData: null,\n avatarItemDetailsData: null,\n contentPostData: null,\n experienceAffiliateData: null,\n}\n", + "exampleRawBody": "{\n experienceInviteData: null,\n friendInviteData: null,\n notificationExperienceInviteData: null,\n profileLinkResolutionResponseData: null,\n screenshotInviteData: null,\n privateServerInviteData: {\n status: \"Valid\",\n ownerUserId: 45348281,\n universeId: 6430220996,\n privateServerId: 1630945839,\n linkCode: \"67771413747491684286858666824242\",\n placeId: 18980972074,\n },\n experienceDetailsInviteData: null,\n avatarItemDetailsData: null,\n contentPostData: null,\n experienceAffiliateData: null,\n}\n" + }, + "params": [ + { + "name": "shareLinkId", + "type": "string", + "description": "The ID (code) of the share link." + } + ] + } + }, "subscriptions": { "createSubscription": { "description": "Creates a subscription for a specified universe.", diff --git a/package.json b/package.json new file mode 100644 index 0000000..d1af133 --- /dev/null +++ b/package.json @@ -0,0 +1,114 @@ +{ + "name": "openblox", + "description": "Roblox API Wrapper For Both Classic And OpenCloud APIs.", + "type": "commonjs", + "version": "1.0.53", + "license": "MIT", + "bugs": { + "url": "https://github.com/MightyPart/openblox/issues" + }, + "repository": { + "type": "github", + "url": "https://github.com/MightyPart/openblox", + "directory": "main" + }, + "keywords": [ + "Roblox", + "RobloxApiWrapper", + "Opencloud", + "Bedev", + "Bedev2" + ], + "exports_DEV": { + ".": "./src/index.ts", + "./config": "./src/config/index.ts", + "./classic": "./src/apis/classic/index.ts", + "./classic/*": "./src/apis/classic/*/index.ts", + "./cloud": "./src/apis/cloud/index.ts", + "./cloud/*": "./src/apis/cloud/*/index.ts", + "./cache/adapters": "./src/cache/cacheAdapters/index.ts", + "./http": "./src/http/http.utils.ts", + "./types": "./src/types.ts", + "./queries/cloud": "./src/queries/cloud/index.ts", + "./queries/classic": "./src/queries/classic/index.ts", + "./queries/classic/types": "./src/queries/classic/index.types.ts", + "./helpers": "./src/helpers/index.ts" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./config": { + "types": "./dist/config/index.d.ts", + "default": "./dist/config/index.js" + }, + "./classic": { + "types": "./dist/apis/classic/index.d.ts", + "default": "./dist/apis/classic/index.js" + }, + "./classic/*": { + "types": "./dist/apis/classic/*/index.d.ts", + "default": "./dist/apis/classic/*/index.js" + }, + "./cloud": { + "types": "./dist/apis/cloud/index.d.ts", + "default": "./dist/apis/cloud/index.js" + }, + "./cloud/*": { + "types": "./dist/apis/cloud/*/index.d.ts", + "default": "./dist/apis/cloud/*/index.js" + }, + "./cache/adapters": { + "types": "./dist/cache/cacheAdapters/index.d.ts", + "default": "./dist/cache/cacheAdapters/index.js" + }, + "./http": { + "types": "./dist/http/http.utils.d.ts", + "default": "./dist/http/http.utils.js" + }, + "./types": { + "types": "./dist/types.d.ts", + "default": "./dist/types.ts" + }, + "./queries/cloud": { + "types": "./dist/queries/cloud/index.d.ts", + "default": "./dist/queries/cloud/index.js" + }, + "./queries/classic": { + "types": "./dist/queries/classic/index.d.ts", + "default": "./dist/queries/classic/index.js" + }, + "./queries/classic/types": { + "types": "./dist/queries/classic/index.types.d.ts", + "default": "./dist/queries/classic/index.types.js" + }, + "./helpers": { + "types": "./dist/helpers/index.d.ts", + "default": "./dist/helpers/index.js" + } + }, + "dependencies": { + "lodash": "^4.17.21", + "parse-roblox-errors": "^1.1.10" + }, + "devDependencies": { + "@types/lodash": "^4.17.0", + "@types/node": "^22.1.0", + "esbuild": "^0.21.5", + "prettier": "^3.2.5", + "tablemark": "^3.1.0", + "ts-arithmetic": "^0.1.1", + "ts-morph": "^22.0.0", + "delete-cli": "^0.1.3" + }, + "peerDependencies": { + "typescript": "^5.0.0", + "typeforge": "^0.0.23" + }, + "scripts": { + "build:code": "delete dist && bun run ./build.ts && tsc --emitDeclarationOnly", + "build:docs": "bun run ./docs/buildDocs.ts", + "build": "bun run build:docs && bun run build:code" + } +} \ No newline at end of file diff --git a/src/apis/apiGroup/apiGroup.ts b/src/apis/apiGroup/apiGroup.ts index 677f4d5..2126432 100644 --- a/src/apis/apiGroup/apiGroup.ts +++ b/src/apis/apiGroup/apiGroup.ts @@ -52,11 +52,8 @@ const defaultGetCursors = (rawData: Record) => { } function isObjectEmpty(obj: Record) { - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) - return false; - } - return true; + for (var prop in obj) if (obj.hasOwnProperty(prop)) return false + return true } const isNoMoreData = (data: any) => { @@ -91,12 +88,6 @@ const paginate = ( } ) -const sleep = async (s: number) => new Promise(resolve => setTimeout(resolve, s * 1000)) - -const expBackoff = (delay: number, lastIter: number) => { - return delay + (5 * lastIter) -} - const pollForResponse = async (url: string, operationPath: string, cloudKey: string) => { const operationPrefix = operationPath.match(/^(\/?)cloud\/v[1-9]+(\/?)/) ? operationPrefixRegexWithoutVersion.exec(url)?.[1] as UrlSecure @@ -107,9 +98,9 @@ const pollForResponse = async (url: string, operationPath: string, cloudKey: str const headers = { "x-api-key": cloudKey } let response: any - await pollHttp<{ done?: boolean }>({ method: "GET", url: operationUrl, headers }, async (response, stopPolling) => { - if (!response.body.done) return - response = response + await pollHttp<{ done?: boolean }>({ method: "GET", url: operationUrl, headers }, async (polledResponse, stopPolling) => { + if (!polledResponse.body.done) return + response = polledResponse stopPolling() }) @@ -153,54 +144,39 @@ export const createApiGroup: CreateApiGroupFn = ({ name:groupName, baseUrl, defa if (oauthToken) headers["Authorization"] = `Bearer ${oauthToken}` } - let response: HttpResponse = await HttpHandler({ method, url, body, formData, headers }) as any // TODO - - if (!(response instanceof HttpResponse)) throw response - let rawData = response.body - - // Uncompleted long running operation. - let opPath = rawData?.path - if (opPath && rawData?.done === false && isOpenCloudUrl(url)) { - console.warn(`Polling '${groupName}.${name}' (Please be patient)...`) - response = await pollForResponse(url, pathToPoll ? pathToPoll(rawData) : opPath, cloudKey) - - //if (pathToPoll) opPath = pathToPoll(rawData) - - /*const operationPrefix = opPath.match(/^(\/?)cloud\/v[1-9]+(\/?)/) - ? operationPrefixRegexWithoutVersion.exec(url)?.[1] as UrlSecure - : operationPrefixRegexWithVersion.exec(url)?.[1] as UrlSecure - const opUrl = `${operationPrefix}${opPath}` as UrlSecure - - const headers = { "x-api-key": cloudKey }*/ - - /*let delay = 0 - for (let iter = 0; iter > -1; iter++) { - response = await HttpHandler({ method: "GET", url: opUrl, headers }) - if (!(response instanceof HttpResponse)) throw response + let main: () => Promise + main = async () => { + let response: HttpResponse = await HttpHandler({ method, url, body, formData, headers }) as any // TODO + if (!(response instanceof HttpResponse)) throw response + let rawData = response.body + + // Uncompleted long running operation. + let opPath = rawData?.path + if (opPath && rawData?.done === false && isOpenCloudUrl(url)) { + console.warn(`Polling '${groupName}.${name}' (Please be patient)...`) + response = await pollForResponse(url, pathToPoll ? pathToPoll(rawData) : opPath, cloudKey) rawData = response.body + } - if (rawData?.done === true) break - - await sleep(delay) - delay = expBackoff(delay, iter) - }*/ - } - - let apiMethodResult: ApiMethodResponse - if (formatRawDataFn) apiMethodResult = { response, get data() { return formatRawDataFn(rawData, response) } } - else apiMethodResult = { response, data: rawData } - - if (handlerFnCursorArg) { - let [ previousCursor, nextCursor ] = (getCursorsFn ?? thisDefaultGetCursors)(rawData); - apiMethodResult.cursors = { previous: previousCursor, next: nextCursor } - if (args && !("__notRoot" in args)) { - (apiMethodResult as any as ApiMethodResponse)[Symbol.asyncIterator] = paginate( - apiMethodResult, callApiMethod as CallApiMethod, args as Record, overrides, handlerFnCursorArg - ) as any + let apiMethodResult: ApiMethodResponse = formatRawDataFn + ? { response, again: main, get data() { return formatRawDataFn(rawData, response) } } + : { response, again: main, data: rawData } + + // Applies async iterator if method is paginated. + if (handlerFnCursorArg) { + let [ previousCursor, nextCursor ] = (getCursorsFn ?? thisDefaultGetCursors)(rawData); + apiMethodResult.cursors = { previous: previousCursor, next: nextCursor } + if (args && !("__notRoot" in args)) { + (apiMethodResult as any as ApiMethodResponse)[Symbol.asyncIterator] = paginate( + apiMethodResult, callApiMethod as CallApiMethod, args as Record, overrides, handlerFnCursorArg + ) as any + } } + + return apiMethodResult as any } - return apiMethodResult as any + return await main() } } ) \ No newline at end of file diff --git a/src/apis/apiGroup/apiGroup.types.ts b/src/apis/apiGroup/apiGroup.types.ts index 3c09aea..10f243f 100644 --- a/src/apis/apiGroup/apiGroup.types.ts +++ b/src/apis/apiGroup/apiGroup.types.ts @@ -101,13 +101,15 @@ type AddApiMethodHandlerFn, MethodData extends Api export type ApiMethodResponse< RawData = any, PrettifiedData = any, ArgsContainsCursor extends boolean | null = null, IsRoot extends boolean = true > = ArgsContainsCursor extends false - ? ApiMethodResponse_WithoutPagination - : ApiMethodResponse_WithPagination + ? ApiMethodResponse_WithoutPagination & + { again: () => Promise> } + : ApiMethodResponse_WithPagination & + { again: () => Promise> } type ApiMethodResponse_WithoutPagination = ObjectPrettify< { data: PrettifiedData, - response: ObjectPrettify>, + response: ObjectPrettify> } > diff --git a/src/apis/cloud/luauExecution/luauExecution.ts b/src/apis/cloud/luauExecution/luauExecution.ts index 96e0bfb..8c4c181 100644 --- a/src/apis/cloud/luauExecution/luauExecution.ts +++ b/src/apis/cloud/luauExecution/luauExecution.ts @@ -1,6 +1,5 @@ // [ Modules ] /////////////////////////////////////////////////////////////////// import { createApiGroup } from "../../apiGroup" -import { toCamel } from "../../../utils/utils" ////////////////////////////////////////////////////////////////////////////////// @@ -8,13 +7,16 @@ import { toCamel } from "../../../utils/utils" import type { ArrayNonEmptyIfConst, Identifier } from "typeforge" import type { ApiMethod } from "../../apiGroup" -import type { ExecuteLuauData, FormattedListLuauExecutionLogs, RawListLuauExecutionLogs } from "./luauExecution.types" +import type { RawExecuteLuauData, FormattedListLuauExecutionLogs, RawListLuauExecutionLogs, FormattedExecuteLuauData, LuauExecutionPathItems, RawLuauExecutionTaskData, FormattedLuauExecutionTaskData } from "./luauExecution.types" import { readFile } from "../../../file" +import { cloneAndMutateObject } from "../../../utils/utils" ////////////////////////////////////////////////////////////////////////////////// // [ Variables ] ///////////////////////////////////////////////////////////////// const addApiMethod = createApiGroup({ name: "LuauExecution", baseUrl: "https://apis.roblox.com/cloud" }) + +const executedLuauPathRegex = /universes\/([0-9]+)\/places\/([0-9]+)\/versions\/([0-9]+)\/luau-execution-sessions\/([^/]+)\/tasks\/([^/]+)/ ////////////////////////////////////////////////////////////////////////////////// @@ -33,6 +35,19 @@ const combineScripts = async (scripts: ArrayNonEmptyIfConst) => return combined } + +const addPathItemsToExecutedLuauResponse = < + RawData extends { path: string } & Record +>(rawData: RawData) => cloneAndMutateObject(rawData, (obj: RawData & LuauExecutionPathItems) => { + const splitPath = executedLuauPathRegex.exec(obj.path) + if (!splitPath) return + + obj.universeId = splitPath[1] as `${number}` + obj.placeId = splitPath[2] as `${number}` + obj.version = parseInt(splitPath[3] as `${number}`) as any + obj.sessionId = splitPath[4] as string + obj.taskId = splitPath[5] as string +}) as any ////////////////////////////////////////////////////////////////////////////////// @@ -51,21 +66,26 @@ const combineScripts = async (scripts: ArrayNonEmptyIfConst) => * const { data:executed } = await LuauExecutionApi.executeLuau({ * universeId: 5795192361, placeId: 16866553538, script: `local x, y = 3, 4; return x + y` * }) - * @exampleData {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/31710728-48c7-4447-ae13-f30c7a38bf42/tasks/31710728-48c7-4447-ae13-f30c7a38bf42","user":"45348281","state":"PROCESSING","script":"local x, y = 3, 4; return x + y"} - * @exampleRawBody {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/31710728-48c7-4447-ae13-f30c7a38bf42/tasks/31710728-48c7-4447-ae13-f30c7a38bf42","user":"45348281","state":"PROCESSING","script":"local x, y = 3, 4; return x + y"} + * @exampleData {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d","user":"45348281","state":"PROCESSING","script":"local x, y = 3, 4; return x + y","universeId":"5795192361","placeId":"16866553538","version":26,"sessionId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d","taskId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d"} + * @exampleRawBody {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d","user":"45348281","state":"PROCESSING","script":"local x, y = 3, 4; return x + y"} */ export const executeLuau = addApiMethod(async < UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined = undefined >( { universeId, placeId, version, script }: { universeId: UniverseId, placeId: PlaceId, version?: Version, script: string | Buffer | ArrayNonEmptyIfConst } -): ApiMethod> => ({ +): ApiMethod< + RawExecuteLuauData, + FormattedExecuteLuauData +> => ({ method: "POST", path: `/v2/universes/${universeId}/places/${placeId}${ version ? `/versions/${version}` : "" }/luau-execution-session-tasks`, body: { script: Array.isArray(script) ? await combineScripts(script) : await ensureScriptSource(script) }, name: `executeLuau`, + + formatRawDataFn: addPathItemsToExecutedLuauResponse })) @@ -86,28 +106,23 @@ export const executeLuau = addApiMethod(async < * @param view If the response should return the script source (`"FULL"`) instead of an empty string. * * @example - * // This example exponentially polls until the task is complete. - * - * import { poll } from "openblox/helpers"; + * import { pollMethod } from "openblox/helpers"; * - * let task - * await poll(LuauExecutionApi.luauExecutionTask, { - * universeId: 5795192361, placeId: 16866553538, version: 26, - * sessionId: "66d01389-6bac-4d6e-8414-ec9d5dab8297", taskId: "66d01389-6bac-4d6e-8414-ec9d5dab8297" - * }, async ({ data }, stopPolling) => { - * if (data.state !== "COMPLETE") return - * task = data - * stopPolling() - * }) - * @exampleData {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/66d01389-6bac-4d6e-8414-ec9d5dab8297/tasks/66d01389-6bac-4d6e-8414-ec9d5dab8297","createTime":"2024-09-26T09:34:09.014Z","updateTime":"2024-09-26T09:34:12.360Z","user":"45348281","state":"COMPLETE","script":"","output":{"results":[7]}} - * @exampleRawBody {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/66d01389-6bac-4d6e-8414-ec9d5dab8297/tasks/66d01389-6bac-4d6e-8414-ec9d5dab8297","createTime":"2024-09-26T09:34:09.014Z","updateTime":"2024-09-26T09:34:12.360Z","user":"45348281","state":"COMPLETE","script":"","output":{"results":[7]}} + * type Results = number[] + * const { data:executedTask } = await pollMethod( + * LuauExecutionApi.luauExecutionTask({ + * universeId: 5795192361, placeId: 16866553538, version: 26, + * sessionId: "67823af7-1f99-4fc5-b3bb-da7ab3456b5d", taskId: "67823af7-1f99-4fc5-b3bb-da7ab3456b5d" + * }), + * async ({ data }, stopPolling) => data.state === "COMPLETE" && stopPolling() + * ) + * @exampleData {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d","createTime":"2024-10-01T02:31:46.304Z","updateTime":"2024-10-01T02:31:49.959Z","user":"45348281","state":"COMPLETE","script":"","output":{"results":[7]},"universeId":"5795192361","placeId":"16866553538","version":26,"sessionId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d","taskId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d"} + * @exampleRawBody {"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d","createTime":"2024-10-01T02:31:46.304Z","updateTime":"2024-10-01T02:31:49.959Z","user":"45348281","state":"COMPLETE","script":"","output":{"results":[7]}} */ -export const luauExecutionTask = addApiMethod(async < - UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined = undefined ->( +export const luauExecutionTask = addApiMethod(async ( { universeId, placeId, version, sessionId, taskId, view }: - { universeId: UniverseId, placeId: PlaceId, version?: Version, sessionId: string, taskId: string, view?: "BASIC" | "FULL" } -): ApiMethod> => ({ + { universeId: Identifier, placeId: Identifier, version?: number, sessionId: string, taskId: string, view?: "BASIC" | "FULL" } +): ApiMethod, FormattedLuauExecutionTaskData> => ({ method: "GET", path: `/v2/universes/${universeId}/places/${placeId}${ version ? `/versions/${version}` : "" @@ -117,6 +132,8 @@ export const luauExecutionTask = addApiMethod(async < searchParams: { view }, name: `getLuauExecutionTask`, + + formatRawDataFn: addPathItemsToExecutedLuauResponse })) @@ -138,10 +155,10 @@ export const luauExecutionTask = addApiMethod(async < * * @example const { data:logs } = await LuauExecutionApi.listLuauExecutionLogs({ * universeId: 5795192361, placeId: 16866553538, version: 26, - * sessionId: "31710728-48c7-4447-ae13-f30c7a38bf42", taskId: "31710728-48c7-4447-ae13-f30c7a38bf42" + * sessionId: "67823af7-1f99-4fc5-b3bb-da7ab3456b5d", taskId: "67823af7-1f99-4fc5-b3bb-da7ab3456b5d" * }) - * @exampleData [{"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/66d01389-6bac-4d6e-8414-ec9d5dab8297/tasks/66d01389-6bac-4d6e-8414-ec9d5dab8297/logs/1","messages":[]}] - * @exampleRawBody {"luauExecutionSessionTaskLogs":[{"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/66d01389-6bac-4d6e-8414-ec9d5dab8297/tasks/66d01389-6bac-4d6e-8414-ec9d5dab8297/logs/1","messages":[]}],"nextPageToken":""} + * @exampleData [{"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/logs/1","messages":[],"universeId":"5795192361","placeId":"16866553538","version":26,"sessionId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d","taskId":"67823af7-1f99-4fc5-b3bb-da7ab3456b5d"}] + * @exampleRawBody {"luauExecutionSessionTaskLogs":[{"path":"universes/5795192361/places/16866553538/versions/26/luau-execution-sessions/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/tasks/67823af7-1f99-4fc5-b3bb-da7ab3456b5d/logs/1","messages":[]}],"nextPageToken":""} */ export const listLuauExecutionLogs = addApiMethod(async < UniverseId extends Identifier, PlaceId extends Identifier, SessionId extends string, @@ -163,7 +180,7 @@ export const listLuauExecutionLogs = addApiMethod(async < searchParams: { maxPageSize: limit, pageToken: cursor }, name: `listLuauExecutionLogs`, - formatRawDataFn: ({ luauExecutionSessionTaskLogs }) => luauExecutionSessionTaskLogs, + formatRawDataFn: ({ luauExecutionSessionTaskLogs }) => luauExecutionSessionTaskLogs.map(addPathItemsToExecutedLuauResponse), getCursorsFn: ({ nextPageToken }) => [ null, nextPageToken ] }) diff --git a/src/apis/cloud/luauExecution/luauExecution.types.ts b/src/apis/cloud/luauExecution/luauExecution.types.ts index c021fb8..963c4cf 100644 --- a/src/apis/cloud/luauExecution/luauExecution.types.ts +++ b/src/apis/cloud/luauExecution/luauExecution.types.ts @@ -1,16 +1,26 @@ -import { Identifier, ISODateTime, UnionPrettify } from "typeforge" +import { Identifier, ISODateTime, ObjectEither, ObjectPrettify, Prettify, UnionPrettify } from "typeforge" type LuauExecutionState = UnionPrettify<"STATE_UNSPECIFIED" | "QUEUED" | "PROCESSING" | "CANCELLED" | "COMPLETE" | "FAILED"> type LuauExecutionError = UnionPrettify<"ERROR_CODE_UNSPECIFIED" | "SCRIPT_ERROR" | "DEADLINE_EXCEEDED" | "OUTPUT_SIZE_LIMIT_EXCEEDED" | "INTERNAL_ERROR"> +export type LuauExecutionPathItems< + UniverseId extends Identifier = Identifier, PlaceId extends Identifier = Identifier, Version extends number | undefined = number | undefined +> = { + universeId: UniverseId, + placeId: PlaceId, + version: Version extends undefined ? number : Version, + sessionId: string, + taskId: string +} + /* POST /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-session-tasks POST /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-session-tasks POST /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-sessions/{sessionId}/tasks POST /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-sessions/{sessionId}/tasks */ -export type ExecuteLuauData< +export type RawExecuteLuauData< UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined > = { path: `/v2/universes/${UniverseId}/places/${PlaceId}${ @@ -20,6 +30,10 @@ export type ExecuteLuauData< state: LuauExecutionState, script: string } + +export type FormattedExecuteLuauData< + UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined +> = RawExecuteLuauData & LuauExecutionPathItems // ------------------------------------------------------------------------------------------------------------------- @@ -29,21 +43,34 @@ export type ExecuteLuauData< GET /cloud/v2/universes/{universeId}/places/{placeId}/luau-execution-sessions/{sessionId}/tasks GET /cloud/v2/universes/{universeId}/places/{placeId}/versions/{version}/luau-execution-sessions/{sessionId}/tasks */ -export type LuauExecutionTaskData< - UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined +export type RawLuauExecutionTaskData< + Results extends any[] = any[] > = { - path: `/v2/universes/${UniverseId}/places/${PlaceId}${ - Version extends number ? `/versions/${Version}` : "" + path: `/v2/universes/${Identifier}/places/${Identifier}${ + `/versions/${number}` | "" }/luau-execution-sessions/${string}/tasks/${string}`, createTime: ISODateTime, updateTime: ISODateTime, user: Identifier, state: LuauExecutionState, script: string, - output: { - result: any +} & ObjectEither< + { + error: { + code: LuauExecutionError, + message: "string" + } + }, + { + output: { + results: Prettify + } } -} +> + +export type FormattedLuauExecutionTaskData< + Results extends any[] = any[] +> = RawLuauExecutionTaskData & LuauExecutionPathItems // ------------------------------------------------------------------------------------------------------------------- @@ -71,10 +98,10 @@ export type RawListLuauExecutionLogs< export type FormattedListLuauExecutionLogs< UniverseId extends Identifier, PlaceId extends Identifier, Version extends number | undefined, SessionId extends string, TaskId extends string -> = { +> = ObjectPrettify<({ path: `universes/${UniverseId}/places/${PlaceId}${ Version extends number ? `/versions/${Version}` : "" }/luau-execution-sessions/${SessionId}/tasks/${TaskId}/logs/1`, messages: any[], -}[] +} & LuauExecutionPathItems)>[] // ------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/config/config.ts b/src/config/config.ts index 7b40fc5..e976440 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -14,13 +14,21 @@ import type { RobloxCookie } from "../http/http.utils" export type OpenbloxConfig = { cookie?: RobloxCookie, cloudKey?: string, + http?: { adapter?: HttpAdapter, - csrfMaxAttempts?: number + csrfMaxAttempts?: number, + + polling?: { + disabled?: boolean, + iterations?: number, + multiplyer?: number, + retryOffset?: number, + debugMessages?: boolean + }, }, - cache?: { - [alias: string]: ReturnType> - } + + cache?: ReturnType>[] } ////////////////////////////////////////////////////////////////////////////////// @@ -32,7 +40,7 @@ export const config: OpenbloxConfig = { cookie: (initialCookie && `.ROBLOSECURITY=${initialCookie}; RBXEventTrackerV2=CreateDate=1/1/1 1:1:1 PM&rbxid=1&browserid=1;`) as any as RobloxCookie | undefined, cloudKey: process.env.ROBLOX_CLOUD_KEY, - cache: { default: TtlCacheAdapter({ included: { lifetime: 300 } }) } + cache: [ TtlCacheAdapter({ included: { lifetime: 300 } }) ] }; ////////////////////////////////////////////////////////////////////////////////// diff --git a/src/file/file.shell.ts b/src/file/file.shell.ts new file mode 100644 index 0000000..2386acb --- /dev/null +++ b/src/file/file.shell.ts @@ -0,0 +1,3 @@ +export const readFile = async (path: string) => { + throw new Error("Can't read files using cloudflare workers!") +} \ No newline at end of file diff --git a/src/file/file.ts b/src/file/file.ts index d73c107..eaac3fc 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -1,9 +1,19 @@ +const getUserAgent = () => { + try { return navigator?.userAgent } + catch { return null } +} + const runtime = process.versions.bun ? "bun" : "node" +const userAgent = getUserAgent() type Lib = { readFile: (path: string) => Promise } -const lib: Lib = runtime == "bun" ? require("./file.bun") : require("./file.nde") + +const lib: Lib = + runtime == "bun" ? require("./file.bun") : + userAgent === 'Cloudflare-Workers' ? require("./file.shell") : + require("./file.nde") export const readFile = lib.readFile \ No newline at end of file diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 06e4939..7190c3d 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,4 +1,4 @@ export * from "./poll" -export * from "./aggregatePages" +//export * from "./aggregatePages" export * from "./deepLinkHelpers/createDeepLink" export * from "./deepLinkHelpers/parseDeepLink" \ No newline at end of file diff --git a/src/helpers/poll.ts b/src/helpers/poll.ts index 83a38bf..844064b 100644 --- a/src/helpers/poll.ts +++ b/src/helpers/poll.ts @@ -21,17 +21,31 @@ const expBackoff = (iter: number, stepMultiplier: number) => stepMultiplier * (i ////////////////////////////////////////////////////////////////////////////////// -export const pollMethod = async >( - method: CallMethod, args: Parameters[0], - handlerFn: (result: Awaited>, stopPolling: () => void) => Promise, - config?: PollConfig -): Promise => { - const iterations = config?.iterations ?? 15, multiplyer = config?.multiplyer ?? 200, retryOffset = config?.retryOffset ?? 5, debug = config?.debug - let offset = 0, isSuccess = false +export const pollMethod = async < + MethodBase extends ReturnType>, + Method extends MethodBase | Awaited +>( + method: Method, + handlerFn: (result: Awaited, stopPolling: () => void) => Promise, + config?: PollConfig +): Promise> => { + // Makes sure the method is awaited. + const methodAwaited = await method - let polling = true + let polling = true, dataToReturn = methodAwaited const stopPolling = () => polling = false + // Checks to see if polling can be avoided all together. + await handlerFn(methodAwaited, stopPolling) + if (!polling) return dataToReturn + + const iterations = config?.iterations ?? 15, multiplyer = config?.multiplyer ?? 200, retryOffset = config?.retryOffset ?? 5, debug = config?.debug + let offset = 0, newIteration = false + + const again = methodAwaited.again + + console.warn(`Polling method (Please be patient)...`) + while (polling) { for (let iter = 1 + offset; iter <= iterations + offset; iter++) { const backoff = expBackoff(iter, multiplyer) @@ -39,20 +53,25 @@ export const pollMethod = async >, stopPolling)) ?? false + const response: Awaited = await again() as any + newIteration = await handlerFn(response, stopPolling) ?? false - if (!polling) break + if (!polling) { + dataToReturn = response + break + } if (debug) console.log(`iteration ${iter} end.\n`) // if a new / valid response was gotten then breaks out of the current iteration cycle. - if (isSuccess) break + if (newIteration) break } - offset = isSuccess ? 0 : retryOffset - isSuccess = false + offset = newIteration ? 0 : retryOffset + newIteration = false } + + return dataToReturn } @@ -62,11 +81,11 @@ export const pollHttp = async ( config?: PollConfig ): Promise => { const iterations = config?.iterations ?? 15, multiplyer = config?.multiplyer ?? 200, retryOffset = config?.retryOffset ?? 5, debug = config?.debug - let offset = 0, isSuccess = false + let offset = 0, newIteration = false let polling = true const stopPolling = () => polling = false - + const httpAdapter = openbloxConfig.http?.adapter ?? FetchAdapter while (polling) { @@ -77,17 +96,17 @@ export const pollHttp = async ( if (backoff !== 0) await sleep(backoff) const response = await httpAdapter(httpArgs) - isSuccess = (await handlerFn(response as HttpResponse, stopPolling)) ?? false + newIteration = await handlerFn(response as HttpResponse, stopPolling) ?? false if (!polling) break if (debug) console.log(`iteration ${iter} end.\n`) // if a new / valid response was gotten then breaks out of the current iteration cycle. - if (isSuccess) break + if (newIteration) break } - offset = isSuccess ? 0 : retryOffset - isSuccess = false + offset = newIteration ? 0 : retryOffset + newIteration = false } } \ No newline at end of file diff --git a/src/queries/classic/groupsQuery.ts b/src/queries/classic/groupsQuery.ts index e800cee..5d38ba3 100644 --- a/src/queries/classic/groupsQuery.ts +++ b/src/queries/classic/groupsQuery.ts @@ -6,7 +6,7 @@ import { addObjectToFunction, pollForLatest } from "../queries.utils" // [ Types ] ///////////////////////////////////////////////////////////////////// import type { Identifier, ObjectPrettify } from "typeforge" -import { poll, type PollConfig } from "../../helpers" +import { pollMethod, type PollConfig } from "../../helpers" import type { GroupAuditLogActionType, PrettifiedGroupAuditLogsData, PrettifiedGroupJoinRequests, PrettifiedGroupWallPostsData_V2 } from "../../apis/classic/groups/groups.types" import { PrettifiedGroupTransactionHistoryData } from "../../apis/classic/economy/economy.types" diff --git a/src/queries/queries.utils.ts b/src/queries/queries.utils.ts index 6b522a1..1f1ec0e 100644 --- a/src/queries/queries.utils.ts +++ b/src/queries/queries.utils.ts @@ -1,5 +1,5 @@ import { CallApiMethod } from "../apis/apiGroup/apiGroup.types" -import { poll, PollConfig } from "../helpers" +import { pollMethod, PollConfig } from "../helpers" export const addObjectToFunction = < Fn extends (...args: any) => any, Obj extends Record, @@ -56,7 +56,7 @@ export const pollForLatest = < const _resultsAfterDate = typeof dateKey === "string" ? resultsAfterDate : resultsAfterDateWithMiddleware - return poll(method, args, async ({ data }) => { + return pollMethod(method(args), async ({ data }) => { const thisPolledTime = new Date().getTime() const newResults = _resultsAfterDate(data, dateKey as any, lastPolledTime) @@ -66,5 +66,5 @@ export const pollForLatest = < lastPolledTime = thisPolledTime return true - }, config) + }, config) as any as Promise } \ No newline at end of file