-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from regal/feat/26-api
feat(api): Implements Game.postStartCommand and related game configuration
- Loading branch information
Showing
9 changed files
with
425 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { RegalError } from "../error"; | ||
|
||
/** | ||
* Represents game options that are configurable by a Regal client. | ||
*/ | ||
export interface GameOptions { | ||
/** Whether output of type `DEBUG` should be returned to the client. Defaults to false. */ | ||
debug: boolean; | ||
|
||
/** | ||
* Game options that cannot be changed by a Regal client. | ||
* Can be an array of strings or a boolean. | ||
* | ||
* If an array of strings, these options will not be configurable by a Regal client. | ||
* If `true`, no options will be configurable. | ||
* If `false`, all options will be configurable. | ||
*/ | ||
forbidChanges: string[] | boolean; | ||
|
||
/** Whether output of type `MINOR` should be returned to the client. Defaults to true. */ | ||
showMinor: boolean; | ||
} | ||
|
||
export const DEFAULT_GAME_OPTIONS: GameOptions = { | ||
debug: false, | ||
forbidChanges: false, | ||
showMinor: true | ||
}; | ||
|
||
export const OPTION_KEYS = Object.keys(DEFAULT_GAME_OPTIONS); | ||
|
||
export const validateOptions = (options: Partial<GameOptions>): void => { | ||
// Ensure no extraneous options were included. | ||
Object.keys(options).forEach(key => { | ||
if (!OPTION_KEYS.includes(key)) { | ||
throw new RegalError(`Invalid option name <${key}>.`); | ||
} | ||
}); | ||
|
||
const checkTypeIfDefined = ( | ||
key: keyof GameOptions, | ||
expectedType: string | ||
): void => { | ||
const value = options[key]; | ||
const actualType = typeof value; | ||
|
||
if (options[key] !== undefined) { | ||
if (actualType !== expectedType) { | ||
throw new RegalError( | ||
`The option <${key}> is of type <${actualType}>, must be of type <${expectedType}>.` | ||
); | ||
} | ||
} | ||
}; | ||
|
||
checkTypeIfDefined("debug", "boolean"); | ||
|
||
if (options.forbidChanges !== undefined) { | ||
if (Array.isArray(options.forbidChanges)) { | ||
options.forbidChanges.forEach(optionName => { | ||
if (!OPTION_KEYS.includes(optionName)) { | ||
throw new RegalError( | ||
`The option <${optionName}> does not exist.` | ||
); | ||
} | ||
}); | ||
} else if (typeof options.forbidChanges !== "boolean") { | ||
throw new RegalError( | ||
`The option <forbidChanges> is of type <${typeof options.forbidChanges}>, must be of type <boolean> or <string[]>.` | ||
); | ||
} | ||
} | ||
|
||
checkTypeIfDefined("showMinor", "boolean"); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { InstanceOptions } from "./instance-options"; | ||
export { GameOptions, DEFAULT_GAME_OPTIONS, OPTION_KEYS } from "./game-options"; | ||
export { GameMetadata } from "./game-metadata"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { RegalError } from "../error"; | ||
import GameInstance from "../game-instance"; | ||
import { | ||
DEFAULT_GAME_OPTIONS, | ||
GameOptions, | ||
validateOptions | ||
} from "./game-options"; | ||
|
||
const OPTION_OVERRIDES_PROXY_HANDLER = { | ||
set( | ||
target: Partial<GameOptions>, | ||
propertKey: PropertyKey, | ||
value: any, | ||
receiver: object | ||
) { | ||
throw new RegalError( | ||
"Cannot modify the properties of the instance overrides." | ||
); | ||
} | ||
}; | ||
|
||
const INSTANCE_OPTIONS_PROXY_HANDLER = { | ||
get(target: InstanceOptions, propertyKey: PropertyKey, receiver: object) { | ||
return target[propertyKey] === undefined | ||
? DEFAULT_GAME_OPTIONS[propertyKey] | ||
: Reflect.get(target, propertyKey, receiver); | ||
}, | ||
|
||
set( | ||
target: InstanceOptions, | ||
propertKey: PropertyKey, | ||
value: any, | ||
receiver: object | ||
) { | ||
throw new RegalError( | ||
"Cannot modify the properties of InstanceOptions." | ||
); | ||
} | ||
}; | ||
|
||
export class InstanceOptions implements GameOptions { | ||
public debug: boolean; | ||
public forbidChanges: string[] | boolean; | ||
public showMinor: boolean; | ||
|
||
public overrides: Readonly<Partial<GameOptions>>; | ||
|
||
constructor(public game: GameInstance, overrides: Partial<GameOptions>) { | ||
this.overrides = new Proxy(overrides, OPTION_OVERRIDES_PROXY_HANDLER); | ||
|
||
validateOptions(overrides); | ||
|
||
Object.keys(overrides).forEach(key => (this[key] = overrides[key])); | ||
|
||
return new Proxy(this, INSTANCE_OPTIONS_PROXY_HANDLER); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.