From f567caca04d848e36cb71ce04673f2716fce8b5c Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Mon, 24 Jul 2023 19:13:04 +0200 Subject: [PATCH 1/6] Updated Table / Removed unused functions --- src/MarcSync/MarcSyncv0.5.lua | 197 ++++++++++------------------------ 1 file changed, 57 insertions(+), 140 deletions(-) diff --git a/src/MarcSync/MarcSyncv0.5.lua b/src/MarcSync/MarcSyncv0.5.lua index 82235cd..f2964a7 100644 --- a/src/MarcSync/MarcSyncv0.5.lua +++ b/src/MarcSync/MarcSyncv0.5.lua @@ -18,23 +18,6 @@ type DefaultResult = { local HttpService = game:GetService("HttpService") -local reqQueue = {} - -coroutine.wrap(function() - while wait(5) do - for i,v in pairs(reqQueue) do - local result; - local success, Error = pcall(function() result = v.method(v.arguments) end) - if not success and Error == "Number of requests exceeded limit" then - break - else - v.event:__Fire(result) - table.remove(reqQueue, i) - end - end - end -end) - function signal() local RBXSignal = {} RBXSignal._bindableEvent = Instance.new("BindableEvent") @@ -53,63 +36,10 @@ function signal() return RBXSignal end -local marcsync = {} -marcsync.__index = marcsync -marcsync.request = {} -function marcsync.new(token: string) - if not token then warn("Token not provided while creating a new MarcSync Object.") end - if not tokens[token] then warn("Token provided for creating a new MarcSync Object not Found in Token Table, using it as token instead.") else token = tokens[token] end - local self = setmetatable({}, marcsync) - self._token = token - self.request._parent = self - self.request.version._parent = self.request - self.request.database._parent = self.request - self.request.collection._parent = self.request - self.utils._parent = self - return self -end +local MarcSyncClient = {} -function marcsync:_checkInstallation() - if not self then error("Please Setup MarcSync before using MarcSync.") end - if not self._token then error("[MarcSync] Please set a Token before using MarcSync.") end - --print(HttpService.HttpEnabled) - --if not HttpService.HttpEnabled then error("Please Enable HTTPService in order to use MarcSync.") end -end - -function marcsync._errorHandler(RBXSignal: {}, Error: string) - spawn(function() - RBXSignal:_Fire({ - ["success"] = false, - ["errorMessage"] = Error - }) - end) - return {["onResult"] = RBXSignal} -end - -function marcsync:_requestHandler(result: {}, Error: string):{["onResult"]: {}} - if result == nil then return self._errorHandler(signal(), Error) end - local errorResult; - local signalevent; - if #result.Body == 0 and not result.Success then - errorResult = "HTTP "..result.StatusCode.." ("..result.StatusMessage..")" result = false - elseif not pcall(function() HttpService:JSONDecode(result.Body) end) then - error("Unexpected MarcSync Result.") - else - result = result.Body - signalevent = {["onResult"]=signal()} - end - spawn(function() - if not result then return end - signalevent.onResult:_Fire(result) - end) - return signalevent or self._errorHandler(signal(), errorResult) -end - -marcsync.request.version = {} -function marcsync.request.version:get(clientId: number?):{["success"]:boolean,["version"]:string,["update_server"]:string} - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() +MarcSyncClient.getVersion = function(self:typeof(MarcSyncClient), clientId: number?):{["success"]:boolean,["version"]:string,["update_server"]:string} + self:_checkInstallation() local url = "" if clientId then url = "/"..clientId end local result = nil; @@ -117,95 +47,82 @@ function marcsync.request.version:get(clientId: number?):{["success"]:boolean,[" result = any end) repeat - wait() + task.wait() until result ~= nil return result end -marcsync.request.collection = {} -function marcsync.request.collection:create(collectionName: string):typeof(require(script.Parent.Objects.Collection)) - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() +MarcSyncClient.createCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) + if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end if not collectionName then error("No CollectionName Provided") end local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._parent._parent._token)).onResult:Connect(function(any) + Utils.handleResponse(Utils.makeHTTPRequest("POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken)).onResult:Connect(function(any) if not any["success"] then result = false return end - result = require(script.Parent.Objects.Collection)._new(collectionName, self._parent._parent._token) + result = require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) end) repeat - wait() + task.wait() until result ~= nil return result end -function marcsync.request.collection:fetch(collectionName: string):typeof(require(script.Parent.Objects.Collection)) - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() +MarcSyncClient.fetchCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) + self:_checkInstallation() if not collectionName then error("No CollectionName Provided") end local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._parent._parent._token)).onResult:Connect(function(any) + Utils.handleResponse(Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken)).onResult:Connect(function(any) if not any["success"] then result = false return end - result = require(script.Parent.Objects.Collection)._new(collectionName, self._parent._parent._token) + result = require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) end) repeat - wait() + task.wait() until result ~= nil return result end -function marcsync.request.collection:get(collectionName: string):typeof(require(script.Parent.Objects.Collection)) +MarcSyncClient.getCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() + self:_checkInstallation() if not collectionName then error("No CollectionName Provided") end - return require(script.Parent.Objects.Collection)._new(collectionName, self._parent._parent._token) + return require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) end -marcsync.request.database = {} -function marcsync.request.database:fetch(databaseId: number):DefaultResult - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() - if not databaseId then error("No DatabaseId Provided") end - local result; - local success, Error = pcall(function() result = HttpService:RequestAsync({Url = "https://api.marcthedev.it/marcsync/v0/database/"..databaseId, Headers = {["Authorization"]=self._parent._parent._token}}) end) - return self._parent._parent:_requestHandler(result, Error) -end -function marcsync.request.database:delete(databaseId: number):DefaultResult - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._parent then error("[MarcSync] Please set a Token before using MarcSync.") end - self._parent._parent:_checkInstallation() - if not databaseId then error("No DatabaseId Provided") end - local result; - local success, Error = pcall(function() result = HttpService:RequestAsync({Url = "https://api.marcthedev.it/marcsync/v0/database/"..databaseId, Headers = {["Authorization"]=self._parent._parent._token}}) end) - return self._parent._parent:_requestHandler(result, Error) -end -marcsync.utils = {} -function marcsync.utils.safeRequest(method: Function, arguments: {}) - --_checkInstallation() - - - --[[ - spawn(function() - local result; - local success, Error = pcall(function() result = method(arguments) end) - if not success and Error == "Number of requests exceeded limit" then - reqQueue[#reqQueue] = {["method"] = method, ["arguments"] = arguments, ["event"] = RBXSignal} - elseif success then - RBXSignal:__Fire(result) - end - end) - - return { ["onResult"] = RBXSignal} - --]] -end -function marcsync.utils.bulkRequest(methods: {}, safeReq: boolean?):{} - --_checkInstallation() - local returns = {} - for i,method in pairs(methods) do if safeReq then marcsync.safeRequest(method[1], method[2]).onResult:Connect(function(result) returns[i] = result end) else returns[i] = method[1](method[2]) end end - while #methods ~= #returns do - wait() + +return function(accessToken: string):typeof(MarcSyncClient) + if not accessToken then warn("Token not provided while creating a new MarcSync Object.") end + if not tokens[accessToken] then warn("Token provided for creating a new MarcSync Object not Found in Token Table, using it as token instead.") else accessToken = tokens[accessToken] end + local self = setmetatable({}, MarcSyncClient) + self._accessToken = accessToken + self._checkInstallation = function() + if not self then error("Please Setup MarcSync before using MarcSync.") end + if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end + --print(HttpService.HttpEnabled) + --if not HttpService.HttpEnabled then error("Please Enable HTTPService in order to use MarcSync.") end + end + self._errorHandler = function(RBXSignal: {}, Error: string) + task.spawn(function() + RBXSignal:_Fire({ + ["success"] = false, + ["errorMessage"] = Error + }) + end) + return {["onResult"] = RBXSignal} + end + self._requestHandler = function(result: {}, Error: string):{["onResult"]: {}} + if result == nil then return self._errorHandler(signal(), Error) end + local errorResult; + local signalevent; + if #result.Body == 0 and not result.Success then + errorResult = "HTTP "..result.StatusCode.." ("..result.StatusMessage..")" result = false + elseif not pcall(function() HttpService:JSONDecode(result.Body) end) then + error("Unexpected MarcSync Result.") + else + result = result.Body + signalevent = {["onResult"]=signal()} + end + task.spawn(function() + if not result then return end + signalevent.onResult:_Fire(result) + end) + return signalevent or self._errorHandler(signal(), errorResult) end - return returns -end -return marcsync \ No newline at end of file + return self +end \ No newline at end of file From fe4c648b0721a225f766bde3125ba1315798e4d7 Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Tue, 25 Jul 2023 02:02:21 +0200 Subject: [PATCH 2/6] Updated Types --- src/MarcSync/Errors/Authorization.lua | 5 +++++ src/MarcSync/Errors/Collection.lua | 8 ++++++++ src/MarcSync/Errors/Entry.lua | 8 ++++++++ src/MarcSync/Types/EntryData.lua | 9 +++++++++ src/MarcSync/Types/MARCSYNC_COLLECTION.lua | 1 - src/MarcSync/Types/MARCSYNC_ENTRY.lua | 1 - src/MarcSync/Types/MARCSYNC_UTILS.lua | 1 - 7 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 src/MarcSync/Errors/Authorization.lua create mode 100644 src/MarcSync/Errors/Collection.lua create mode 100644 src/MarcSync/Errors/Entry.lua create mode 100644 src/MarcSync/Types/EntryData.lua delete mode 100644 src/MarcSync/Types/MARCSYNC_COLLECTION.lua delete mode 100644 src/MarcSync/Types/MARCSYNC_ENTRY.lua delete mode 100644 src/MarcSync/Types/MARCSYNC_UTILS.lua diff --git a/src/MarcSync/Errors/Authorization.lua b/src/MarcSync/Errors/Authorization.lua new file mode 100644 index 0000000..cfb685d --- /dev/null +++ b/src/MarcSync/Errors/Authorization.lua @@ -0,0 +1,5 @@ +return { + InvalidAccessToken = function(message: string):string + return ("[MarcSync Exception] InvalidAccessToken: %s"):format(message) + end +} \ No newline at end of file diff --git a/src/MarcSync/Errors/Collection.lua b/src/MarcSync/Errors/Collection.lua new file mode 100644 index 0000000..c59ddde --- /dev/null +++ b/src/MarcSync/Errors/Collection.lua @@ -0,0 +1,8 @@ +return { + CollectionNotFound = function(message: string):string + return ("[MarcSync Exception] CollectionNotFound: %s"):format(message) + end, + CollectionAlreadyExists = function(message: string):string + return ("[MarcSync Exception] CollectionAlreadyExists: %s"):format(message) + end +} \ No newline at end of file diff --git a/src/MarcSync/Errors/Entry.lua b/src/MarcSync/Errors/Entry.lua new file mode 100644 index 0000000..5d51edb --- /dev/null +++ b/src/MarcSync/Errors/Entry.lua @@ -0,0 +1,8 @@ +return { + InvalidEntryData = function(message: string):string + return ("[MarcSync Exception] InvalidEntryData: %s"):format(message) + end, + EntryNotFound = function(message: string):string + return ("[MarcSync Exception] EntryNotFound: %s"):format(message) + end +} \ No newline at end of file diff --git a/src/MarcSync/Types/EntryData.lua b/src/MarcSync/Types/EntryData.lua new file mode 100644 index 0000000..c9f8aa1 --- /dev/null +++ b/src/MarcSync/Types/EntryData.lua @@ -0,0 +1,9 @@ +type EntryData = { + [string]: any +} + +return { + getType = function(): EntryData + return {} + end, +} \ No newline at end of file diff --git a/src/MarcSync/Types/MARCSYNC_COLLECTION.lua b/src/MarcSync/Types/MARCSYNC_COLLECTION.lua deleted file mode 100644 index a1f19fd..0000000 --- a/src/MarcSync/Types/MARCSYNC_COLLECTION.lua +++ /dev/null @@ -1 +0,0 @@ -return require(script.Parent.Parent.Parent.Objects.Collection) \ No newline at end of file diff --git a/src/MarcSync/Types/MARCSYNC_ENTRY.lua b/src/MarcSync/Types/MARCSYNC_ENTRY.lua deleted file mode 100644 index 04ee486..0000000 --- a/src/MarcSync/Types/MARCSYNC_ENTRY.lua +++ /dev/null @@ -1 +0,0 @@ -return require(script.Parent.Parent.Parent.Objects.Entry) \ No newline at end of file diff --git a/src/MarcSync/Types/MARCSYNC_UTILS.lua b/src/MarcSync/Types/MARCSYNC_UTILS.lua deleted file mode 100644 index 03630f8..0000000 --- a/src/MarcSync/Types/MARCSYNC_UTILS.lua +++ /dev/null @@ -1 +0,0 @@ -return require(script.Parent.Parent) \ No newline at end of file From df41bf428b16aebfed735938e494fb2fd4892722 Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Tue, 25 Jul 2023 02:03:06 +0200 Subject: [PATCH 3/6] Removed useless code & improved error handler --- src/MarcSync/Utils.lua | 87 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/src/MarcSync/Utils.lua b/src/MarcSync/Utils.lua index fd33163..095c8e1 100644 --- a/src/MarcSync/Utils.lua +++ b/src/MarcSync/Utils.lua @@ -1,64 +1,63 @@ +local AuthorizationError = require(script.Parent.Errors.Authorization) +local CollectionError = require(script.Parent.Errors.Collection) +local EntryError = require(script.Parent.Errors.Entry) + local HttpService = game:GetService("HttpService") -function errorHandler(RBXSignal: {}, result: any) +function errorHandler(type: string, resultBody: any, resultObject: {}) local Error; - if typeof(result) == typeof({}) and result["message"] then - Error = result["message"] - elseif typeof(result) == typeof("") then - Error = result + if typeof(resultBody) == typeof({}) and resultBody["message"] then + Error = resultBody["message"] + elseif typeof(resultBody) == typeof("") then + Error = resultBody else Error = "An Unexpected Error occoured." end - spawn(function() - RBXSignal:_Fire({ - ["success"] = false, - ["errorMessage"] = Error - }) - end) - return {["onResult"] = RBXSignal} + + if type == "collection" then + if resultObject["StatusCode"] == 401 then + Error = AuthorizationError.InvalidAccessToken("InvalidAccessToken") + elseif resultObject["StatusCode"] == 404 then + Error = CollectionError.CollectionNotFound("CollectionNotFound") + elseif resultObject["StatusCode"] == 400 then + Error = CollectionError.CollectionAlreadyExists("CollectionAlreadyExists") + end + elseif type == "entry" or type == "entryId" then + if resultObject["StatusCode"] == 401 then + Error = AuthorizationError.InvalidAccessToken("InvalidAccessToken") + elseif resultObject["StatusCode"] == 404 then + Error = CollectionError.CollectionNotFound("CollectionNotFound") + elseif resultObject["StatusCode"] == 400 then + Error = EntryError.InvalidEntryData("InvalidEntryData") + elseif type == "entryId" and ((resultBody["modifiedEntries"] and resultBody["modifiedEntries"] == 0) or (resultBody["deletedEntries"] and resultBody["deletedEntries"] == 0)) then + Error = EntryError.EntryNotFound("EntryNotFound") + end + end + + return {["success"] = false, ["errorMessage"] = Error} end local utils = {} -function utils._signal() - local RBXSignal = {} - RBXSignal._bindableEvent = Instance.new("BindableEvent") - function RBXSignal:_Fire(...) - RBXSignal._bindableEvent:Fire(...) - end - function RBXSignal:Connect(handler: ({success: boolean, result: {}}) -> ({success: boolean, result: {}})) - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not (type(handler) == "function") then - error(("connect(%s)"):format(typeof(handler)), 2) - end - RBXSignal._bindableEvent.Event:Connect(function(...) - handler(...) - end) - end - return RBXSignal -end -function utils.handleResponse(result: any, error: boolean, signal: RBXScriptSignal?) - if error then return result end - spawn(function() - signal:_Fire(result) - end) - return {["onResult"] = signal} -end -function utils.makeHTTPRequest(method: string, url: string, body: {}, authorization: string):{["success"]: boolean, ["message"]: string} - local result; +function utils.makeHTTPRequest(type: string, method: string, url: string, body: {}, authorization: string):{["success"]: boolean, ["message"]: string} + local resultObj; + local resultBody; local success = pcall(function() if body then body = HttpService:JSONEncode(body) end if (method == "GET" or method == "HEAD") then - result = HttpService:JSONDecode(HttpService:RequestAsync({Method=method, Url=url, Headers={["Authorization"]=authorization,["Content-Type"]="application/json"}})["Body"]) + resultObj = HttpService:RequestAsync({Method=method, Url=url, Headers={["Authorization"]=authorization,["Content-Type"]="application/json"}}) + resultBody = HttpService:JSONDecode(resultObj["Body"]) else - result = HttpService:JSONDecode(HttpService:RequestAsync({Method=method, Url=url, Headers={["Authorization"]=authorization,["Content-Type"]="application/json"}, Body=body})["Body"]) + resultObj = HttpService:RequestAsync({Method=method, Url=url, Headers={["Authorization"]=authorization,["Content-Type"]="application/json"}, Body=body}) + resultBody = HttpService:JSONDecode(resultObj["Body"]) end end) - if success and result and result["success"] then - if result["warning"] then warn('[MarcSync HTTPRequest Handler] MarcSync HTTP Request returned warning for URL "'..url..'" with body: "'..HttpService:JSONEncode(body)..'": '..result["warning"]) end - return result, false, utils._signal() + if success and resultBody and resultBody["success"] then + if type == "entryId" and ((resultBody["modifiedEntries"] and resultBody["modifiedEntries"] == 0) or (resultBody["deletedEntries"] and resultBody["deletedEntries"] == 0)) then return errorHandler(type, resultBody, resultObj) end + if resultBody["warning"] then warn('[MarcSync HTTPRequest Handler] MarcSync HTTP Request returned warning for URL "'..url..'" with body: "'..HttpService:JSONEncode(body)..'": '..resultBody["warning"]) end + return resultBody end - return errorHandler(utils._signal(), result), true + return errorHandler(type, resultBody, resultObj) end return utils \ No newline at end of file From 6033e8fc141b2c52b9315eafbbfa3ae8e27d674b Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Tue, 25 Jul 2023 02:03:28 +0200 Subject: [PATCH 4/6] Changed Syntax, updated Utils implementation --- src/MarcSync/MarcSyncv0.5.lua | 129 ++++++------------------ src/MarcSync/Objects/Collection.lua | 151 +++++++++++----------------- src/MarcSync/Objects/Entry.lua | 88 ++++++++-------- 3 files changed, 134 insertions(+), 234 deletions(-) diff --git a/src/MarcSync/MarcSyncv0.5.lua b/src/MarcSync/MarcSyncv0.5.lua index f2964a7..c1bdd05 100644 --- a/src/MarcSync/MarcSyncv0.5.lua +++ b/src/MarcSync/MarcSyncv0.5.lua @@ -1,4 +1,3 @@ - local tokens = { ["exampleToken"] = "" } @@ -7,122 +6,60 @@ local tokens = { -- DO NOT EDIT THE FOLLOWING LINES BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! local Utils = require(script.Parent.Utils) - -type Function = () -> () -type DefaultResultType = (success: boolean, errorMessage: string) -> () -type DefaultResult = { - ["onResult"]: { - ["Connect"]:DefaultResultType - } -} - -local HttpService = game:GetService("HttpService") - -function signal() - local RBXSignal = {} - RBXSignal._bindableEvent = Instance.new("BindableEvent") - function RBXSignal:_Fire(...) - RBXSignal._bindableEvent:Fire(...) - end - function RBXSignal:Connect(handler: ({success: boolean, result: {}}) -> ({success: boolean, result: {}})) - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not (type(handler) == "function") then - error(("connect(%s)"):format(typeof(handler)), 2) - end - RBXSignal._bindableEvent.Event:Connect(function(...) - handler(...) - end) - end - return RBXSignal -end - local MarcSyncClient = {} MarcSyncClient.getVersion = function(self:typeof(MarcSyncClient), clientId: number?):{["success"]:boolean,["version"]:string,["update_server"]:string} self:_checkInstallation() local url = "" if clientId then url = "/"..clientId end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/utils/version"..url)).onResult:Connect(function(any) - result = any - end) - repeat - task.wait() - until result ~= nil + local result = Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/utils/version"..url); return result end -MarcSyncClient.createCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) +MarcSyncClient.createCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new()) if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end if not collectionName then error("No CollectionName Provided") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken)).onResult:Connect(function(any) - if not any["success"] then result = false return end - result = require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) - end) - repeat - task.wait() - until result ~= nil + local result = Utils.makeHTTPRequest("collection", "POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken); + + if not result["success"] then error(result["errorMessage"]) end + result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken) + return result end -MarcSyncClient.fetchCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) +MarcSyncClient.fetchCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new()) self:_checkInstallation() if not collectionName then error("No CollectionName Provided") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken)).onResult:Connect(function(any) - if not any["success"] then result = false return end - result = require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) - end) - repeat - task.wait() - until result ~= nil + local result = Utils.makeHTTPRequest("collection", "GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken); + + if not result["success"] then error(result["errorMessage"]) end + result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken) + return result end -MarcSyncClient.getCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection)) +MarcSyncClient.getCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new()) if typeof(self) ~= "table" then error("Please use : instead of .") end self:_checkInstallation() if not collectionName then error("No CollectionName Provided") end - return require(script.Parent.Objects.Collection)._new(collectionName, self._accessToken) + return require(script.Parent.Objects.Collection).new(collectionName, self._accessToken) end -return function(accessToken: string):typeof(MarcSyncClient) - if not accessToken then warn("Token not provided while creating a new MarcSync Object.") end - if not tokens[accessToken] then warn("Token provided for creating a new MarcSync Object not Found in Token Table, using it as token instead.") else accessToken = tokens[accessToken] end - local self = setmetatable({}, MarcSyncClient) - self._accessToken = accessToken - self._checkInstallation = function() - if not self then error("Please Setup MarcSync before using MarcSync.") end - if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end - --print(HttpService.HttpEnabled) - --if not HttpService.HttpEnabled then error("Please Enable HTTPService in order to use MarcSync.") end - end - self._errorHandler = function(RBXSignal: {}, Error: string) - task.spawn(function() - RBXSignal:_Fire({ - ["success"] = false, - ["errorMessage"] = Error - }) - end) - return {["onResult"] = RBXSignal} - end - self._requestHandler = function(result: {}, Error: string):{["onResult"]: {}} - if result == nil then return self._errorHandler(signal(), Error) end - local errorResult; - local signalevent; - if #result.Body == 0 and not result.Success then - errorResult = "HTTP "..result.StatusCode.." ("..result.StatusMessage..")" result = false - elseif not pcall(function() HttpService:JSONDecode(result.Body) end) then - error("Unexpected MarcSync Result.") - else - result = result.Body - signalevent = {["onResult"]=signal()} +return { + new = function(accessToken: string):typeof(MarcSyncClient) + if not accessToken then warn("Token not provided while creating a new MarcSync Object.") end + if not tokens[accessToken] then warn("Token provided for creating a new MarcSync Object not Found in Token Table, using it as token instead.") else accessToken = tokens[accessToken] end + local self = {} + self._accessToken = accessToken + self._checkInstallation = function() + if not self then error("Please Setup MarcSync before using MarcSync.") end + if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end + --print(HttpService.HttpEnabled) + --if not HttpService.HttpEnabled then error("Please Enable HTTPService in order to use MarcSync.") end end - task.spawn(function() - if not result then return end - signalevent.onResult:_Fire(result) - end) - return signalevent or self._errorHandler(signal(), errorResult) - end - return self -end \ No newline at end of file + self = setmetatable(self, { + __index = MarcSyncClient + }) + + return self + end +} \ No newline at end of file diff --git a/src/MarcSync/Objects/Collection.lua b/src/MarcSync/Objects/Collection.lua index 746c570..d680dbf 100644 --- a/src/MarcSync/Objects/Collection.lua +++ b/src/MarcSync/Objects/Collection.lua @@ -1,109 +1,78 @@ +local HttpService = game:GetService("HttpService") local Utils = require(script.Parent.Parent.Utils) local Entry = require(script.Parent.Entry) -local collection = {} -collection.__index = collection - -local filterSheme = { - ["values"]=typeof({ ["key"]=... }), - ["startsWith"]=typeof({ "key" }), - ["ignoreCases"]=typeof({ "key" }) +local types = { + EntryData = require(script.Parent.Parent.Types.EntryData).getType() } -function collection:insert(data:{key:any}):typeof(Entry)? - if typeof(self) ~= "table" then error("Please use : instead of .") end +local Collection = {} + +Collection.createEntry = function(self:typeof(Collection), data:typeof(types.EntryData)):typeof(Entry.new()) if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("POST", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["data"]=data}, self._token)).onResult:Connect(function(any) - if any["success"] and any["objectId"] then - data["_id"] = any["objectId"] - result = require(script.Parent.Entry)._new(self._collectionName, data, self._token) - return + local result = Utils.makeHTTPRequest("entry", "POST", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["data"]=data}, self._accessToken); + + if result["success"] and result["objectId"] then + data["_id"] = result["objectId"] + result = require(script.Parent.Entry).new(self._collectionName, data, self._accessToken) + else + error(result["errorMessage"]) + end + + return result +end + +Collection.updateEntries = function(self:typeof(Collection), filters:typeof(types.EntryData), data:typeof(types.EntryData)):number + if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end + local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters,["data"]=data}, self._accessToken); + if not result["success"] then error(result["errorMessage"]) end + + return result["modifiedEntries"] +end + +Collection.getEntries = function(self:typeof(Collection), filters:typeof(types.EntryData)):{[number]:typeof(Entry.new())} + if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end + if not filters then filters = {} end + local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName.."?isQuery=true", {["filters"]=filters}, self._accessToken); + if result["success"] and result["entries"] then + local _result = {} + for index,entry in pairs(result["entries"]) do + _result[index] = require(script.Parent.Entry).new(self._collectionName, entry, self._accessToken) end - result = any - end) - repeat - wait() - until result ~= nil + result = _result + else + error(result["errorMessage"]) + end + return result end -function collection:update(filters:typeof(filterSheme),data:{key:any}):{message:string?,errorMessage:string?,success:boolean,modifiedEntries:number?} - if typeof(self) ~= "table" then error("Please use : instead of .") end +Collection.deleteEntries = function(self:typeof(Collection), filters:typeof(types.EntryData)):number if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end - local result = nil; - if not filters.values then error("[MarcSync: Collection] Invalid arguments given for collection:select(). Expected filters.values, got nil") end - filters.values["_startsWith"] = filters.startsWith or {} - filters.values["_ignoreCases"] = filters.ignoreCases or {} - Utils.handleResponse(Utils.makeHTTPRequest("PUT", "https://api.marcsync.dev/v1/entries/"..self._collectionName, {["filters"]=filters.values,["data"]=data}, self._token)).onResult:Connect(function(any) - result = any - end) - repeat - wait() - until result ~= nil - return result + local result = Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters}, self._accessToken); + if not result["success"] then error(result["errorMessage"]) end + + return result["deletedEntries"] end -function collection:select(filters:typeof(filterSheme),limit:number):{entries:{a:typeof(Entry)?,b:typeof(Entry)?,c:typeof(Entry)?}?,success:boolean,message:string?,errorMessage:string?} - if typeof(self) ~= "table" then error("Please use : instead of .") end +Collection.drop = function(self:typeof(Collection)) if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end - local result = nil; - if not filters.values then error("[MarcSync: Collection] Invalid arguments given for collection:select(). Expected filters.values, got nil") end - filters.values["_startsWith"] = filters.startsWith or {} - filters.values["_ignoreCases"] = filters.ignoreCases or {} - Utils.handleResponse(Utils.makeHTTPRequest("PATCH", "https://api.marcsync.dev/v1/entries/"..self._collectionName.."?methodOverwrite=GET", {["filters"]=filters.values, ["limit"]=limit}, self._token)).onResult:Connect(function(any) - if any["success"] and any["entries"] then - local _result = {["entries"]={},["success"]=true} - for index,entry in pairs(any["entries"]) do - _result["entries"][index] = require(script.Parent.Entry)._new(self._collectionName, entry, self._token) - end - result = _result - return - end - result = any - end) - repeat - wait() - until result ~= nil - return result + local result = Utils.makeHTTPRequest("collection", "DELETE", "https://api.marcsync.dev/v0/collection/"..self._collectionName, {}, self._accessToken); + if not result["success"] then error(result["errorMessage"]) end + self._collectionName = nil + self._accessToken = nil end -function collection:delete(filters:typeof(filterSheme)):{message:string?,errorMessage:string?,success:boolean,deletedEntries:number?} - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end - local result = nil; - if not filters.values then error("[MarcSync: Collection] Invalid arguments given for collection:select(). Expected filters.values, got nil") end - filters.values["_startsWith"] = filters.startsWith or {} - filters.values["_ignoreCases"] = filters.ignoreCases or {} - Utils.handleResponse(Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v1/entries/"..self._collectionName, {["filters"]=filters.values}, self._token)).onResult:Connect(function(any) - result = any - end) - repeat - wait() - until result ~= nil - return result -end +return { + new = function(collectionName: string, accessToken: string):typeof(Collection) + local self = {} + self._collectionName = collectionName + self._accessToken = accessToken -function collection:drop():{success:boolean,message:string?,errorMessage:string?} - if typeof(self) ~= "table" then error("Please use : instead of .") end - if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v0/collection/"..self._collectionName, {}, self._token)).onResult:Connect(function(any) - result = any - end) - repeat - wait() - until result ~= nil - return result -end + self = setmetatable(self, { + __index = Collection + }) -collection._collectionName = nil - -function collection._new(_collectionName: string, _token: string):typeof(collection) - local self = setmetatable({}, collection) - self._collectionName = _collectionName - self._token = _token - return self -end - -return collection \ No newline at end of file + return self + end +} \ No newline at end of file diff --git a/src/MarcSync/Objects/Entry.lua b/src/MarcSync/Objects/Entry.lua index 0524f71..37f7031 100644 --- a/src/MarcSync/Objects/Entry.lua +++ b/src/MarcSync/Objects/Entry.lua @@ -1,62 +1,56 @@ local Utils = require(script.Parent.Parent.Utils) -local entry = {} -entry.__index = entry +local types = { + EntryData = require(script.Parent.Parent.Types.EntryData).getType() +} -function entry:getValue(value:string):any - if typeof(self) ~= "table" then error("Please use : instead of .") end +local Entry = {} + +Entry.getValue = function(self:typeof(Entry), value:string):any if not value then return nil end - return self._values[value] + return self._entryData[value] end -function entry:getValues():{} - if typeof(self) ~= "table" then error("Please use : instead of .") end - return self._values +Entry.getValues = function(self:typeof(Entry)):typeof(types.EntryData) + return self._entryData end -function entry:update(newData:{key:any}):{success:boolean,errorMessage:string?,message:string?,modifiedEntries:IntValue?} - if typeof(self) ~= "table" then error("Please use : instead of .") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=newData}, self._token)).onResult:Connect(function(any) - if any["success"] and any["modifiedEntries"] and any["modifiedEntries"] > 0 then - for i,v in pairs(newData) do - self._values[i] = v - end +Entry.updateValues = function(self:typeof(Entry), values:typeof(types.EntryData)):number + local result = Utils.makeHTTPRequest("entryId", "PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=values}, self._accessToken); + + if result["success"] and result["modifiedEntries"] and result["modifiedEntries"] > 0 then + for i,v in pairs(values) do + self._entryData[i] = v end - result = any - end) - repeat - wait() - until result ~= nil - return result + elseif not result["success"] then + error(result["errorMessage"]) + end + + return result["modifiedEntries"] end -function entry:delete():{success:boolean,errorMessage:string?,message:string?,deletedEntries:IntValue?} +Entry.delete = function(self:typeof(Entry)) if typeof(self) ~= "table" then error("Please use : instead of .") end - local result = nil; - Utils.handleResponse(Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._token)).onResult:Connect(function(any) - if any["success"] and any["deletedEntries"] then - if any["deletedEntries"] < 1 then result = false return end - spawn(function() - self = nil - end) - end - result = any - end) - repeat - wait() - until result ~= nil - return result + local result = Utils.makeHTTPRequest("entryId", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._accessToken); + + if not result["success"] then error(result["errorMessage"]) end + self = nil + end -function entry._new(_tableId:string, _values:{}, _token:string):typeof(entry) - if not _tableId or not _values or not _values["_id"] then error("[MarcSync: Entry] Tried creating invalid Entry Object.") end - local self = setmetatable({}, entry) - self._tableId = _tableId - self._values = _values - self._objectId = _values["_id"] - self._token = _token - return self -end +return { + new = function(tableId:string, entryData:typeof(types.EntryData), accessToken:string):typeof(Entry) + if not tableId or not entryData or not entryData["_id"] or not accessToken then error("[MarcSync: Entry] Tried creating invalid Entry Object.") end + local self = {} + self._tableId = tableId + self._entryData = entryData + self._objectId = entryData["_id"] + self._accessToken = accessToken -return entry \ No newline at end of file + self = setmetatable(self, { + __index = Entry + }) + + return self + end +} \ No newline at end of file From 7fb36d47df261c3f40aef2566f87c312ba8ef8ee Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Tue, 25 Jul 2023 16:56:14 +0200 Subject: [PATCH 5/6] Removed Exceptions & unused components --- src/MarcSync/Objects/Collection.lua | 4 +--- src/MarcSync/Objects/Entry.lua | 4 ++-- src/MarcSync/Utils.lua | 5 +---- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/MarcSync/Objects/Collection.lua b/src/MarcSync/Objects/Collection.lua index d680dbf..73c0d79 100644 --- a/src/MarcSync/Objects/Collection.lua +++ b/src/MarcSync/Objects/Collection.lua @@ -1,4 +1,3 @@ -local HttpService = game:GetService("HttpService") local Utils = require(script.Parent.Parent.Utils) local Entry = require(script.Parent.Entry) @@ -59,8 +58,7 @@ Collection.drop = function(self:typeof(Collection)) if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end local result = Utils.makeHTTPRequest("collection", "DELETE", "https://api.marcsync.dev/v0/collection/"..self._collectionName, {}, self._accessToken); if not result["success"] then error(result["errorMessage"]) end - self._collectionName = nil - self._accessToken = nil + self = nil end return { diff --git a/src/MarcSync/Objects/Entry.lua b/src/MarcSync/Objects/Entry.lua index 37f7031..3756ee7 100644 --- a/src/MarcSync/Objects/Entry.lua +++ b/src/MarcSync/Objects/Entry.lua @@ -16,7 +16,7 @@ Entry.getValues = function(self:typeof(Entry)):typeof(types.EntryData) end Entry.updateValues = function(self:typeof(Entry), values:typeof(types.EntryData)):number - local result = Utils.makeHTTPRequest("entryId", "PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=values}, self._accessToken); + local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=values}, self._accessToken); if result["success"] and result["modifiedEntries"] and result["modifiedEntries"] > 0 then for i,v in pairs(values) do @@ -31,7 +31,7 @@ end Entry.delete = function(self:typeof(Entry)) if typeof(self) ~= "table" then error("Please use : instead of .") end - local result = Utils.makeHTTPRequest("entryId", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._accessToken); + local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._accessToken); if not result["success"] then error(result["errorMessage"]) end self = nil diff --git a/src/MarcSync/Utils.lua b/src/MarcSync/Utils.lua index 095c8e1..194e2b2 100644 --- a/src/MarcSync/Utils.lua +++ b/src/MarcSync/Utils.lua @@ -22,15 +22,13 @@ function errorHandler(type: string, resultBody: any, resultObject: {}) elseif resultObject["StatusCode"] == 400 then Error = CollectionError.CollectionAlreadyExists("CollectionAlreadyExists") end - elseif type == "entry" or type == "entryId" then + elseif type == "entry" then if resultObject["StatusCode"] == 401 then Error = AuthorizationError.InvalidAccessToken("InvalidAccessToken") elseif resultObject["StatusCode"] == 404 then Error = CollectionError.CollectionNotFound("CollectionNotFound") elseif resultObject["StatusCode"] == 400 then Error = EntryError.InvalidEntryData("InvalidEntryData") - elseif type == "entryId" and ((resultBody["modifiedEntries"] and resultBody["modifiedEntries"] == 0) or (resultBody["deletedEntries"] and resultBody["deletedEntries"] == 0)) then - Error = EntryError.EntryNotFound("EntryNotFound") end end @@ -53,7 +51,6 @@ function utils.makeHTTPRequest(type: string, method: string, url: string, body: end end) if success and resultBody and resultBody["success"] then - if type == "entryId" and ((resultBody["modifiedEntries"] and resultBody["modifiedEntries"] == 0) or (resultBody["deletedEntries"] and resultBody["deletedEntries"] == 0)) then return errorHandler(type, resultBody, resultObj) end if resultBody["warning"] then warn('[MarcSync HTTPRequest Handler] MarcSync HTTP Request returned warning for URL "'..url..'" with body: "'..HttpService:JSONEncode(body)..'": '..resultBody["warning"]) end return resultBody end From 465628509c163e5d6b7fb268862132811710cfb2 Mon Sep 17 00:00:00 2001 From: Marcel Lorbeer Date: Tue, 25 Jul 2023 17:00:03 +0200 Subject: [PATCH 6/6] Updated Version & changed Version Return --- src/MarcSync/{MarcSyncv0.5.lua => MarcSyncv1.0.lua} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/MarcSync/{MarcSyncv0.5.lua => MarcSyncv1.0.lua} (96%) diff --git a/src/MarcSync/MarcSyncv0.5.lua b/src/MarcSync/MarcSyncv1.0.lua similarity index 96% rename from src/MarcSync/MarcSyncv0.5.lua rename to src/MarcSync/MarcSyncv1.0.lua index c1bdd05..ef8a2b5 100644 --- a/src/MarcSync/MarcSyncv0.5.lua +++ b/src/MarcSync/MarcSyncv1.0.lua @@ -8,12 +8,12 @@ local tokens = { local Utils = require(script.Parent.Utils) local MarcSyncClient = {} -MarcSyncClient.getVersion = function(self:typeof(MarcSyncClient), clientId: number?):{["success"]:boolean,["version"]:string,["update_server"]:string} +MarcSyncClient.getVersion = function(self:typeof(MarcSyncClient), clientId: number?):string self:_checkInstallation() local url = "" if clientId then url = "/"..clientId end local result = Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/utils/version"..url); - return result + return result["version"] end MarcSyncClient.createCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new())