Files
ms/packages/molang/src/env/env.ts
MiaoWoo 6816e51239 feat: add molang package
1. upgrade bukkit chat
2. fix config update error

Signed-off-by: MiaoWoo <admin@yumc.pw>
2022-02-12 16:29:40 +08:00

144 lines
3.3 KiB
TypeScript

import { standardEnv } from './standardEnv'
export type TVariableHandler = (
variableName: string,
variables: Record<string, unknown>
) => unknown
export interface IEnvConfig {
useRadians?: boolean
convertUndefined?: boolean
variableHandler?: TVariableHandler
isFlat?: boolean
}
export class ExecutionEnvironment {
protected env: Record<string, any>
constructor(env: Record<string, any>, public readonly config: IEnvConfig) {
if (!env) throw new Error(`Provided environment must be an object`)
if (config.isFlat)
this.env = Object.assign(
env,
standardEnv(config.useRadians ?? false)
)
else
this.env = {
...standardEnv(config.useRadians ?? false),
...this.flattenEnv(env),
}
}
updateConfig({
variableHandler,
convertUndefined,
useRadians,
}: IEnvConfig) {
if (convertUndefined !== undefined)
this.config.convertUndefined = convertUndefined
if (typeof variableHandler === 'function')
this.config.variableHandler = variableHandler
if (!!this.config.useRadians !== !!useRadians) {
this.env = Object.assign(this.env, standardEnv(!!useRadians))
}
}
protected flattenEnv(
newEnv: Record<string, any>,
addKey = '',
current: any = {}
) {
for (let key in newEnv) {
if (key[1] === '.') {
switch (key[0]) {
case 'q':
key = 'query' + key.substring(1, key.length)
break
case 't':
key = 'temp' + key.substring(1, key.length)
break
case 'v':
key = 'variable' + key.substring(1, key.length)
break
case 'c':
key = 'context' + key.substring(1, key.length)
break
case 'f':
key = 'function' + key.substring(1, key.length)
break
}
}
if (newEnv[key].__isContext) {
current[`${addKey}${key}`] = newEnv[key].env
} else if (
typeof newEnv[key] === 'object' &&
!Array.isArray(newEnv[key])
) {
this.flattenEnv(newEnv[key], `${addKey}${key}.`, current)
} else {
current[`${addKey}${key}`] = newEnv[key]
}
}
return current
}
setAt(lookup: string, value: unknown) {
if (lookup[1] === '.') {
switch (lookup[0]) {
case 'q':
lookup = 'query' + lookup.substring(1, lookup.length)
break
case 't':
lookup = 'temp' + lookup.substring(1, lookup.length)
break
case 'v':
lookup = 'variable' + lookup.substring(1, lookup.length)
break
case 'c':
lookup = 'context' + lookup.substring(1, lookup.length)
break
case 'f':
lookup = 'function' + lookup.substring(1, lookup.length)
break
}
}
return (this.env[lookup] = value)
}
getFrom(lookup: string) {
if (lookup[1] === '.') {
switch (lookup[0]) {
case 'q':
lookup = 'query' + lookup.substring(1, lookup.length)
break
case 't':
lookup = 'temp' + lookup.substring(1, lookup.length)
break
case 'v':
lookup = 'variable' + lookup.substring(1, lookup.length)
break
case 'c':
lookup = 'context' + lookup.substring(1, lookup.length)
break
case 'f':
lookup = 'function' + lookup.substring(1, lookup.length)
break
}
}
const res =
this.env[lookup] ?? this.config.variableHandler?.(lookup, this.env)
return res === undefined && this.config.convertUndefined ? 0 : res
}
}
export class Context {
public readonly __isContext = true
constructor(public readonly env: any) {}
}