From 6f76fc971ab754154420f803022258c89441b6fa Mon Sep 17 00:00:00 2001 From: "AsynchronousMatrix (Jack)" Date: Tue, 2 Jul 2024 15:45:47 +0100 Subject: [PATCH] ENG-157: implement moonwave documentation for all of Metriks public API --- Src/API/ActionBuilder.luau | 96 ++++++++++++++++++++++++++++++++++++-- Src/Client.luau | 27 +++++------ Src/Server.luau | 41 ++++++++-------- Src/init.luau | 77 ++++++++++++++++++++++++++++++ aftman.toml | 1 + 5 files changed, 201 insertions(+), 41 deletions(-) diff --git a/Src/API/ActionBuilder.luau b/Src/API/ActionBuilder.luau index 588e1ea..a3c11e8 100644 --- a/Src/API/ActionBuilder.luau +++ b/Src/API/ActionBuilder.luau @@ -2,10 +2,6 @@ local Sift = require(script.Parent.Parent.Packages.Sift) local ActionService = require(script.Parent.Parent.Services.ActionService) ---[[ - Metrik SDK ActionBuilder & Action -]] - --[=[ @class ActionBuilder @@ -31,14 +27,36 @@ Action.Prototype = {} ActionBuilder.Public = {} ActionBuilder.Prototype = {} +--[=[ + CanRun is called when the Action is run, this method is used to determine if the Action can be run. + + @method CanRun + @within Action + @return boolean +]=] function Action.Prototype:CanRun(...: unknown) return true end +--[=[ + OnRun is called when the Action is run, this method is used to execute the Action. + + @method OnRun + @within Action + @return boolean +]=] function Action.Prototype:OnRun(...: unknown) print(`Method ':OnRun' has been called on Action<"{self.Name}">`) end +--[=[ + SetName is used to set the name of the Action. + + @method SetName + @param actionName string + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Prototype.SetName(self: ActionBuilder, actionName: string): ActionBuilder assert(#actionName <= 50, `Action name is too large, action name ranges between 1 <-> 50 characters!`) @@ -54,6 +72,14 @@ function ActionBuilder.Prototype.SetName(self: ActionBuilder, actionName: string return self end +--[=[ + SetDescription is used to set the description of the Action. + + @method SetDescription + @param description string + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Prototype.SetDescription(self: ActionBuilder, description: string): ActionBuilder assert(string.len(description) <= 500, "Action Description must be under 500 characters!") @@ -62,18 +88,49 @@ function ActionBuilder.Prototype.SetDescription(self: ActionBuilder, description return self end +--[=[ + OnRun is used to set the callback that is called when the Action is run. + + @method OnRun + @param callback (Action, ...any) -> ...any + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Prototype.OnRun(self: ActionBuilder, callback: (Action, ...any) -> ...any): ActionBuilder self.Prototype.OnRun = callback return self end -function ActionBuilder.Prototype.CanRun(self: ActionBuilder, callback: (Action, ...any) -> ...any): ActionBuilder +--[=[ + CanRun is used to set the callback that is called when the Action can be run. + + @method CanRun + @param callback (Action, ...any) -> boolean + @within ActionBuilder + @return ActionBuilder +]=] +function ActionBuilder.Prototype.CanRun(self: ActionBuilder, callback: (Action, ...any) -> boolean): ActionBuilder self.Prototype.CanRun = callback return self end +--[=[ + AddArgument is used to add an argument to the Action. + + @method AddArgument + @param argumentName string + @param argumentMetadata { + Type: ("string" | "number" | "boolean")?, + Description: string?, + Required: boolean?, + IsArray: boolean?, + Default: any, + }? + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Prototype.AddArgument(self: ActionBuilder, argumentName: string, argumentMetadata: ArgumentMetadata?): ActionBuilder local filteredArgumentName = string.lower(argumentName) local argumentsDict = self.Prototype.Arguments :: { } @@ -95,6 +152,21 @@ function ActionBuilder.Prototype.AddArgument(self: ActionBuilder, argumentName: return self end +--[=[ + AddArguments is used to add multiple arguments to the Action. + + @method AddArguments + @param arguments { + [string]: { + Type: ("string" | "number" | "boolean")?, + Description: string?, + Required: boolean?, + Default: any, + } + } + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Prototype.AddArguments(self: ActionBuilder, arguments: { [string]: { Type: ("string" | "number" | "boolean")?, @@ -115,6 +187,13 @@ function ActionBuilder.Prototype.AddArguments(self: ActionBuilder, arguments: { return self end +--[=[ + Build is used to build the Action. + + @method Build + @within ActionBuilder + @return Action +]=] function ActionBuilder.Prototype.Build(self: ActionBuilder): Action assert(self.Prototype.Name ~= nil, "Actions are required to have a 'Name', please call ':SetName'") assert(Action.Instantiated[self.Prototype.Key] == nil, `Action '{self.Prototype.Name}' is a duplicate action!`) @@ -133,6 +212,13 @@ function ActionBuilder.Prototype.Build(self: ActionBuilder): Action return Action.Instantiated[self.Prototype.Key] end +--[=[ + Creates a new ActionBuilder. + + @function new + @within ActionBuilder + @return ActionBuilder +]=] function ActionBuilder.Public.new(): ActionBuilder return setmetatable({ Prototype = { diff --git a/Src/Client.luau b/Src/Client.luau index a50781f..72629d4 100644 --- a/Src/Client.luau +++ b/Src/Client.luau @@ -20,7 +20,7 @@ local ON_START_LIFECYCLE_NAME = "OnStart" --[=[ @class MetrikSDK.Client - The base class developers will be interacting with. *(TO-DO: add a descriptive class description!)* + The MetrikSDK.Client class is the main entry point for interacting with the Metrik Service on the Client. ]=] local MetrikSDK = {} @@ -41,9 +41,10 @@ function MetrikSDK.Private.AwaitUntilReady(self: MetrikPrivateAPI) end --[=[ - ... + Defer to @MetrikSDK.CreateBreadcrumb @method CreateBreadcrumb + @param message string @within MetrikSDK.Client @return () @@ -56,9 +57,10 @@ function MetrikSDK.Public.CreateBreadcrumb(self: MetrikPublicAPI, message: strin end --[=[ - ... + Defer to @MetrikSDK.SetContext @method SetContext + @param context { [string]: any } @within MetrikSDK.Client @return () @@ -71,12 +73,13 @@ function MetrikSDK.Public.SetContext(self: MetrikPublicAPI, context: { [string]: end --[=[ - ... + Defer to @MetrikSDK.GetFlag - @method EvaluateFlag - @within MetrikSDK.Server + @method GetFlag + @param context { [string]: any } + @within MetrikSDK.Client - @return () + @return boolean ]=] -- function MetrikSDK.Public.GetFlag(self: MetrikPublicAPI, flagName: string) @@ -86,16 +89,10 @@ function MetrikSDK.Public.GetFlag(self: MetrikPublicAPI, flagName: string) end --[=[ - Start the Metrik SDK, once this function has been called, internal Metrik Services and Controllers should come online and start to respond and - handle Metrik backend calls made to the current Roblox server. - - :::warning - Please ensure that any pre-init variables are set before calling this function, otherwise Metrik will have issues attempting to authenticate - the current SDK! - ::: + Defer to @MetrikSDK.InitializeAsync @method InitializeAsync - @within MetrikSDK + @within MetrikSDK.Client @return Promise<()> ]=] diff --git a/Src/Server.luau b/Src/Server.luau index 9f4a03a..27d5b3a 100644 --- a/Src/Server.luau +++ b/Src/Server.luau @@ -28,7 +28,7 @@ local ON_START_LIFECYCLE_NAME = "OnStart" --[=[ @class MetrikSDK.Server - The base class developers will be interacting with. *(TO-DO: add a descriptive class description!)* + The MetrikSDK.Server class is the main entry point for interacting with the Metrik Service on the Server. ]=] local MetrikSDK = {} @@ -46,7 +46,12 @@ MetrikSDK.Private.ProjectId = "" @prop ActionBuilder ActionBuilder @within MetrikSDK.Server ]=] --- + +--[=[ + @prop ActionBuilder ActionBuilder + @within MetrikSDK.Server +]=] + MetrikSDK.Public.ActionBuilder = ActionBuilder function MetrikSDK.Private.FromError(_: MetrikPrivateAPI, errorEnum: string, ...: string) @@ -78,38 +83,39 @@ function MetrikSDK.Private.GetCallingScript(_: MetrikPrivateAPI) end --[=[ - ... + Defer to @MetrikSDK.CreateBreadcrumb @method CreateBreadcrumb + @param message string @within MetrikSDK.Server @return () ]=] --- function MetrikSDK.Public.CreateBreadcrumb(self: MetrikPublicAPI, message: string) BreadcrumbService:CreateBreadcrumbFor(nil, self.Private:GetCallingScript(), message) end --[=[ - ... + Defer to @MetrikSDK.SetContext @method SetContext + @param context { [string]: any } @within MetrikSDK.Server @return () ]=] --- function MetrikSDK.Public.SetContext(self: MetrikPublicAPI, context: { [string]: any }) ContextService:CreateContextFor(nil, self.Private:GetCallingScript(), context) end --[=[ + Defer to @MetrikSDK.IsServerUpToDate + @method IsServerUpToDate @within MetrikSDK.Server - @return () + @return boolean ]=] --- function MetrikSDK.Public.IsServerUpToDate(self: MetrikPublicAPI) local success, response = ApiService:GetAsync(string.format(ApiPaths.GetLatestPlaceVersion, ApiService.ProjectId), { }):await() @@ -125,34 +131,27 @@ function MetrikSDK.Public.IsServerUpToDate(self: MetrikPublicAPI) end --[=[ - ... + Defer to @MetrikSDK.GetFlag - @method EvaluateFlag + @method GetFlag + @param flagName string @within MetrikSDK.Server - @return () + @return boolean ]=] --- function MetrikSDK.Public.GetFlag(self: MetrikPublicAPI, flagName: string) return FlagsService:EvaluateFlag(flagName) end --[=[ - Start the Metrik SDK, once this function has been called, internal Metrik Services and Controllers should come online and start to respond and - handle Metrik backend calls made to the current Roblox server. - - :::warning - Please ensure that any pre-init variables are set before calling this function, otherwise Metrik will have issues attempting to authenticate - the current SDK! - ::: + Defer to @MetrikSDK.InitializeAsync @method InitializeAsync @param settings { projectId: string, authenticationSecret: Secret } - @within MetrikSDK.Server + @within MetrikSDK.Client @return Promise<()> ]=] --- function MetrikSDK.Public.InitializeAsync(self: MetrikPublicAPI, settings: { projectId: string, authenticationSecret: Secret diff --git a/Src/init.luau b/Src/init.luau index b4be179..5d7fed7 100644 --- a/Src/init.luau +++ b/Src/init.luau @@ -4,7 +4,44 @@ local RunService = game:GetService("RunService") @class MetrikSDK The MetrikSDK class is the main entry point for interacting with the Metrik backend. + + ```lua + local MetrikSDK = require(script.Parent.MetrikSDK) + + MetrikSDK:InitializeAsync({ + projectId = "", + authenticationSecret = HttpService:GetSecret("metrik_token") + }):andThen(function() + warn("Metrik SDK loaded!") + end):catch(function(exception) + warn("Metrik SDK failed: ", exception) + end) + ``` +]=] + +--[=[ + @prop Disabled boolean + @within MetrikSDK +]=] + +--[=[ + @prop Client MetrikSDK.Client + @within MetrikSDK + @client ]=] + +--[=[ + @prop Server MetrikSDK.Server + @within MetrikSDK + @server +]=] + +--[=[ + @prop ActionBuilder ActionBuilder + @within MetrikSDK + @server +]=] + local MetrikSDK = {} if not RunService:IsRunning() then @@ -14,9 +51,18 @@ else MetrikSDK.Client = require(script.Client) else MetrikSDK.Server = require(script.Server) + MetrikSDK.ActionBuilder = MetrikSDK.Server.ActionBuilder end end +--[=[ + Initialize the Metrik SDK, once this function has been called, internal Metrik Services and Controllers should come online and start to respond and handle Metrik backend calls made for the current Roblox server. + + @method InitializeAsync + @param settings { projectId: string, authenticationSecret: Secret } + @return Promise<()> + @within MetrikSDK +]=] function MetrikSDK.InitializeAsync(self: MetrikSDK, settings: { projectId: string, authenticationSecret: Secret @@ -28,6 +74,14 @@ function MetrikSDK.InitializeAsync(self: MetrikSDK, settings: { end end +--[=[ + Get the current flag value for the given flag name, flags are set via the Metrik dashboard. + + @method GetFlag + @param flagName string + @return boolean + @within MetrikSDK +]=] function MetrikSDK.GetFlag(self: MetrikSDK, flagName: string) if MetrikSDK.Server then return MetrikSDK.Server:GetFlag(flagName) @@ -36,6 +90,15 @@ function MetrikSDK.GetFlag(self: MetrikSDK, flagName: string) end end +--[=[ + Validate that the current Roblox server is up to date with the Roblox server running the Metrik SDK. + + @method IsServerUpToDate + @return boolean + @within MetrikSDK + + @server +]=] function MetrikSDK.IsServerUpToDate(self: MetrikSDK) if MetrikSDK.Server then return MetrikSDK.Server:IsServerUpToDate() @@ -44,6 +107,13 @@ function MetrikSDK.IsServerUpToDate(self: MetrikSDK) end end +--[=[ + Create a breadcrumb with the given message. Breadcrumbs are used to track events that lead up to an error. + + @method CreateBreadcrumb + @param message string + @within MetrikSDK +]=] function MetrikSDK.CreateBreadcrumb(self: MetrikSDK, message: string) if MetrikSDK.Server then return MetrikSDK.Server:CreateBreadcrumb(message) @@ -52,6 +122,13 @@ function MetrikSDK.CreateBreadcrumb(self: MetrikSDK, message: string) end end +--[=[ + Set the context of the current script to the given context. Context is a table that will be sent to the Metrik backend if an error occurs in that script. + + @method SetContext + @param context { [string]: any } + @within MetrikSDK +]=] function MetrikSDK.SetContext(self: MetrikSDK, context: { [string]: any }) if MetrikSDK.Server then return MetrikSDK.Server:SetContext(context) diff --git a/aftman.toml b/aftman.toml index 1532bcc..32657d6 100644 --- a/aftman.toml +++ b/aftman.toml @@ -11,3 +11,4 @@ wally-package-types = "JohnnyMorganz/wally-package-types@1.2.1" luaulsp = "JohnnyMorganz/luau-lsp@1.24.1" zap = "red-blox/zap@0.6.8" lune = "lune-org/lune@0.8.6" +moonwave = "evaera/moonwave@1.1.2" \ No newline at end of file