Added Interactive Setup CLI (Unfinished)

Added the first part of the interactive setup CLI. You can explore the interface but some parts will not work yet. It will also not save to the config file yet.

The "Quick Setup" & "Manage Plugins" parts of the CLI will arrive later this week.
This commit is contained in:
DJj123dj
2025-04-06 19:04:09 +02:00
parent 831e120093
commit 5f79ae909b
10 changed files with 649 additions and 79 deletions
+54 -31
View File
@@ -289,6 +289,16 @@ export class ODCheckerFunctionManager extends ODManager<ODCheckerFunction> {
*/
export type ODCheckerLocationTrace = (string|number)[]
/**## ODCheckerOptions `interface`
* This interface contains all optional properties to customise in the `ODChecker` class.
*/
export interface ODCheckerOptions {
/**The name of this config in the Interactive Setup CLI. */
cliDisplayName?:string
/**The description of this config in the Interactive Setup CLI. */
cliDisplayDescription?:string
}
/**## ODChecker `class`
* This is an Open Ticket config checker.
*
@@ -310,13 +320,16 @@ export class ODChecker extends ODManagerData {
messages: ODCheckerMessage[] = []
/**Temporary storage for the quit status from the check() method (not recommended to use) */
quit: boolean = false
/**All additional properties of this config checker. */
options: ODCheckerOptions
constructor(id:ODValidId, storage: ODCheckerStorage, priority:number, config:ODConfig, structure: ODCheckerStructure){
constructor(id:ODValidId, storage: ODCheckerStorage, priority:number, config:ODConfig, structure:ODCheckerStructure, options?:ODCheckerOptions){
super(id)
this.storage = storage
this.priority = priority
this.config = config
this.structure = structure
this.options = options ?? {}
}
/**Run this checker. Returns all errors*/
@@ -391,7 +404,13 @@ export interface ODCheckerStructureOptions {
/**Add a custom checker function. Returns `true` when valid. */
custom?:(checker:ODChecker, value:ODValidJsonType, locationTrace:ODCheckerLocationTrace, locationId:ODId, locationDocs:string|null) => boolean,
/**Set the url to the documentation of this variable. */
docs?:string
docs?:string,
/**The name of this config in the Interactive Setup CLI. */
cliDisplayName?:string
/**The description of this config in the Interactive Setup CLI. */
cliDisplayDescription?:string
/**The default value of this variable when creating it in the Interactive Setup CLI. When not specified, the user will be asked to insert a value. */
cliInitDefaultValue?:string
}
/**## ODCheckerStructure `class`
@@ -426,7 +445,13 @@ export class ODCheckerStructure {
*/
export interface ODCheckerObjectStructureOptions extends ODCheckerStructureOptions {
/**Add a checker for a property in an object (can also be optional) */
children?:{key:string, checker:ODCheckerStructure, priority:number, optional:boolean}[]
children?:{key:string, priority:number, optional:boolean, cliHideInEditMode?:boolean, checker:ODCheckerStructure}[],
/**A list of keys to skip when creating this object with the Interactive Setup CLI. The default value of these properties will be used instead. */
cliInitSkipKeys?:string[],
/**The key of a (primitive) property in this object to show the value of in the Interactive Setup CLI when listed in an array. */
cliDisplayKeyInParentArray?:string,
/**A list of additional (primitive) property keys in this object to show the value of in the Interactive Setup CLI when listed in an array. */
cliDisplayAdditionalKeysInParentArray?:string[]
}
/**## ODCheckerObjectStructure `class`
@@ -500,7 +525,9 @@ export interface ODCheckerStringStructureOptions extends ODCheckerStructureOptio
/**You need to choose between ... */
choices?:string[],
/**The string needs to match this regex */
regex?:RegExp
regex?:RegExp,
/**Provide an optional list for autocomplete when using the Interactive Setup CLI. Defaults to the `choices` option. */
cliAutocompleteList?:string[]
}
/**## ODCheckerStringStructure `class`
@@ -718,7 +745,9 @@ export interface ODCheckerArrayStructureOptions extends ODCheckerStructureOption
/**Allow double values (only for `string`, `number` & `boolean`) */
allowDoubles?:boolean
/**Only allow these types in the array (for multi-type propertyCheckers) */
allowedTypes?:("string"|"number"|"boolean"|"null"|"array"|"object"|"other")[]
allowedTypes?:("string"|"number"|"boolean"|"null"|"array"|"object"|"other")[],
/**The name of the properties inside this array. Used in the GUI of the Interactive Setup CLI. */
cliDisplayPropertyName?:string
}
/**## ODCheckerArrayStructure `class`
@@ -863,9 +892,9 @@ export interface ODCheckerTypeSwitchStructureOptions extends ODCheckerStructureO
/**A checker when the property is a boolean */
boolean?:ODCheckerBooleanStructure,
/**A checker when the property is null */
null?:ODCheckerStructure,
null?:ODCheckerNullStructure,
/**A checker when the property is an array */
array?:ODCheckerStructure,
array?:ODCheckerArrayStructure,
/**A checker when the property is an object */
object?:ODCheckerObjectStructure,
/**A checker when the property is something else */
@@ -1390,32 +1419,26 @@ export class ODCheckerCustomStructure_UniqueIdArray extends ODCheckerArrayStruct
constructor(id:ODValidId, source:string, scope:string, usedScope?:string, options?:ODCheckerArrayStructureOptions){
//add premade custom structure checker
const newOptions = options ?? {}
newOptions.custom = (checker,value,locationTrace,locationId,locationDocs) => {
const lt = checker.locationTraceDeref(locationTrace)
newOptions.propertyChecker = new ODCheckerStringStructure("opendiscord:unique-id",{minLength:1,custom:(checker,value,locationTrace,locationId,locationDocs) => {
if (typeof value != "string") return false
const localLt = checker.locationTraceDeref(locationTrace)
localLt.pop()
if (!Array.isArray(value)) return false
const uniqueArray: string[] = (checker.storage.get(source,scope) === null) ? [] : checker.storage.get(source,scope)
let localQuit = false
value.forEach((id,index) => {
if (typeof id != "string") return
const localLt = checker.locationTraceDeref(lt)
localLt.push(index)
if (uniqueArray.includes(id)){
//exists
if (usedScope){
const current: string[] = checker.storage.get(source,usedScope) ?? []
current.push(id)
checker.storage.set(source,usedScope,current)
}
}else{
//doesn't exist
checker.createMessage("opendiscord:id-non-existent","error",`The id "${id}" doesn't exist!`,localLt,null,[`"${id}"`],this.id,(this.options.docs ?? null))
localQuit = true
const uniqueArray: string[] = checker.storage.get(source,scope) ?? []
if (uniqueArray.includes(value)){
//exists
if (usedScope){
const current: string[] = checker.storage.get(source,usedScope) ?? []
current.push(value)
checker.storage.set(source,usedScope,current)
}
})
return !localQuit
}
return true
}else{
//doesn't exist
checker.createMessage("opendiscord:id-non-existent","error",`The id "${value}" doesn't exist!`,localLt,null,[`"${value}"`],locationId,locationDocs)
return false
}
}})
super(id,newOptions)
this.source = source
this.scope = scope