functional
This commit is contained in:
11
src/flags.ts
Normal file
11
src/flags.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
const Flags = {
|
||||
dir: './storage'
|
||||
}
|
||||
|
||||
export function setFlag<T extends keyof typeof Flags>(key: T, val: typeof Flags[T]) {
|
||||
Flags[key] = val
|
||||
}
|
||||
|
||||
export function getFlag(key: keyof typeof Flags) {
|
||||
return Flags[key]
|
||||
}
|
||||
23
src/fs.ts
Normal file
23
src/fs.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Guild } from 'discord.js'
|
||||
import { readFileSync, writeFileSync, ensureDirSync, ensureFileSync } from 'fs-extra'
|
||||
import { getFlag } from './flags'
|
||||
|
||||
type storageTypes = 'global' | Guild
|
||||
|
||||
function filePath(storage: storageTypes) {
|
||||
if (storage === 'global') {
|
||||
return `${getFlag('dir')}/global.json`
|
||||
}
|
||||
return `${getFlag('dir')}/guild_${storage.id}.json`
|
||||
}
|
||||
|
||||
export function readFile(storage: storageTypes) {
|
||||
let path = filePath(storage)
|
||||
ensureFileSync(path)
|
||||
return readFileSync(path).toString()
|
||||
}
|
||||
|
||||
export function writeFile(storage: storageTypes, data: string) {
|
||||
ensureDirSync(getFlag('dir'))
|
||||
writeFileSync(filePath(storage), data)
|
||||
}
|
||||
69
src/main.ts
69
src/main.ts
@@ -1,52 +1,25 @@
|
||||
/*
|
||||
import { setFlag } from "./flags";
|
||||
import { globalStorage, initGlobalCache } from './storage'
|
||||
|
||||
initGlobalStorage()
|
||||
initChannelStorage(channel/channels)
|
||||
|
||||
channelStorage(channel) => Storage
|
||||
|
||||
Storage {
|
||||
get() => string
|
||||
set(string | json)
|
||||
|
||||
getJson() => json
|
||||
function test2() {
|
||||
let storage = globalStorage()
|
||||
storage.set({
|
||||
a: 'aaaaa',
|
||||
b: 'bbbbb',
|
||||
c: 'ccccc',
|
||||
})
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
import { JSONObject } from './util'
|
||||
|
||||
class StorageBase {
|
||||
val: string
|
||||
fallbackJSON: JSONObject
|
||||
constructor(val: string | JSONObject, fallbackJSON?: JSONObject) {
|
||||
if (typeof val !== 'string') {
|
||||
val = JSON.stringify(val)
|
||||
}
|
||||
if (fallbackJSON === undefined) {
|
||||
fallbackJSON = val.constructor() as JSONObject
|
||||
}
|
||||
this.val = val
|
||||
this.fallbackJSON = fallbackJSON
|
||||
}
|
||||
set(val: string | JSONObject) {
|
||||
if (typeof val !== 'string') {
|
||||
val = JSON.stringify(val)
|
||||
}
|
||||
this.val = val
|
||||
}
|
||||
|
||||
get(): string {
|
||||
return this.val
|
||||
}
|
||||
|
||||
getJson(): JSONObject {
|
||||
let val
|
||||
try {
|
||||
val = JSON.parse(this.val)
|
||||
} catch (e) {
|
||||
val = {}
|
||||
}
|
||||
return val
|
||||
}
|
||||
function test() {
|
||||
setFlag('dir', './data')
|
||||
initGlobalCache({
|
||||
a: 'aaa',
|
||||
b: 'bbb',
|
||||
})
|
||||
let storage = globalStorage()
|
||||
console.log(storage.get())
|
||||
test2()
|
||||
console.log(storage.get())
|
||||
}
|
||||
|
||||
test()
|
||||
|
||||
48
src/storage.ts
Normal file
48
src/storage.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Guild } from 'discord.js'
|
||||
import { readFile, writeFile } from './fs'
|
||||
import { GlobalStorage, GuildStorage } from './storageclass'
|
||||
import { defaultJson, JSONObject } from './util'
|
||||
|
||||
var GlobalCache = ''
|
||||
/** Map<guild id, stringified data> */
|
||||
const GuildCache = new Map<string, string>()
|
||||
|
||||
export function initGlobalCache(defaultValue?: string | JSONObject) {
|
||||
if (GlobalCache.length === 0) {
|
||||
let data = readFile('global')
|
||||
GlobalCache = defaultJson(data, defaultValue)
|
||||
}
|
||||
}
|
||||
|
||||
export function initGuildCache(guild: Guild, defaultValue?: string | JSONObject) {
|
||||
if (!GuildCache.has(guild.id)) {
|
||||
let data = readFile(guild)
|
||||
GuildCache.set(guild.id, defaultJson(data, defaultValue))
|
||||
}
|
||||
}
|
||||
|
||||
export function globalStorage() {
|
||||
initGlobalCache()
|
||||
|
||||
let val = {
|
||||
get: () => GlobalCache,
|
||||
set: (val: string) => {
|
||||
GlobalCache = val
|
||||
writeFile('global', val)
|
||||
},
|
||||
}
|
||||
return new GlobalStorage(val)
|
||||
}
|
||||
|
||||
export function guildStorage(guild: Guild) {
|
||||
initGuildCache(guild)
|
||||
|
||||
let val = {
|
||||
get: () => GuildCache.get(guild.id) || '',
|
||||
set: (val: string) => {
|
||||
GuildCache.set(guild.id, val)
|
||||
writeFile(guild, val)
|
||||
},
|
||||
}
|
||||
return new GuildStorage(guild, val)
|
||||
}
|
||||
46
src/storageclass.ts
Normal file
46
src/storageclass.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { JSONObject } from './util'
|
||||
import { Guild } from 'discord.js'
|
||||
|
||||
export interface StorageValue {
|
||||
get(): string
|
||||
set(val: string): void
|
||||
}
|
||||
|
||||
export class StorageBase {
|
||||
val: StorageValue
|
||||
|
||||
constructor(val: StorageValue) {
|
||||
this.val = val
|
||||
}
|
||||
set(val: string | JSONObject) {
|
||||
if (typeof val !== 'string') {
|
||||
val = JSON.stringify(val)
|
||||
}
|
||||
this.val.set(val)
|
||||
}
|
||||
|
||||
get(): string {
|
||||
return this.val.get()
|
||||
}
|
||||
|
||||
getJson(): JSONObject {
|
||||
let val
|
||||
try {
|
||||
val = JSON.parse(this.val.get())
|
||||
} catch (e) {
|
||||
val = {}
|
||||
}
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
export class GlobalStorage extends StorageBase {}
|
||||
|
||||
export class GuildStorage extends StorageBase {
|
||||
public guild: Guild
|
||||
|
||||
constructor(guild: Guild, val: StorageValue) {
|
||||
super(val)
|
||||
this.guild = guild
|
||||
}
|
||||
}
|
||||
40
src/util.ts
40
src/util.ts
@@ -2,3 +2,43 @@ export type JSONDataTypes = string | number | boolean
|
||||
export type JSONObject<Value = JSONDataTypes, Key extends string = string> = {
|
||||
[key in Key]: Value
|
||||
}
|
||||
|
||||
export function defaultJson(data: string, defaultValue: string | JSONObject = '') {
|
||||
|
||||
if (data.length === 0) {
|
||||
//no existing data, give the default value instead
|
||||
|
||||
if (typeof defaultValue === 'string') {
|
||||
return defaultValue
|
||||
} else {
|
||||
return JSON.stringify(defaultValue)
|
||||
}
|
||||
|
||||
} else if (typeof defaultValue !== 'string') {
|
||||
//existing data should be compared
|
||||
//nothing to compare if default value is string
|
||||
|
||||
try {
|
||||
let foundJson = JSON.parse(data)
|
||||
|
||||
for (let key in defaultValue) {
|
||||
if (
|
||||
!(key in foundJson) ||
|
||||
typeof foundJson[key] !== typeof defaultValue[key]
|
||||
) {
|
||||
//key doesnt exist OR key exists, but type is incorrect
|
||||
foundJson[key] = defaultValue[key]
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(foundJson)
|
||||
} catch (e) {
|
||||
//couldn't parse data
|
||||
return JSON.stringify(defaultValue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user