@foul11/awesome-db 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/BitFields.d.ts +29 -0
- package/dist/BitFields.d.ts.map +1 -0
- package/dist/Error.d.ts +21 -0
- package/dist/Error.d.ts.map +1 -0
- package/dist/ORM.d.ts +14 -0
- package/dist/ORM.d.ts.map +1 -0
- package/dist/SQLParser.d.ts +1394 -0
- package/dist/SQLParser.d.ts.map +1 -0
- package/dist/WebpackFileProvider.d.ts +12 -0
- package/dist/WebpackFileProvider.d.ts.map +1 -0
- package/dist/alter/column_add.d.ts +7 -0
- package/dist/alter/column_add.d.ts.map +1 -0
- package/dist/alter/column_drop.d.ts +6 -0
- package/dist/alter/column_drop.d.ts.map +1 -0
- package/dist/alter/column_rename.d.ts +6 -0
- package/dist/alter/column_rename.d.ts.map +1 -0
- package/dist/alter/column_update.d.ts +7 -0
- package/dist/alter/column_update.d.ts.map +1 -0
- package/dist/alter/columns_order.d.ts +6 -0
- package/dist/alter/columns_order.d.ts.map +1 -0
- package/dist/alter/index.d.ts +7 -0
- package/dist/alter/index.d.ts.map +1 -0
- package/dist/alter/pragma.d.ts +4 -0
- package/dist/alter/pragma.d.ts.map +1 -0
- package/dist/alter/utils.d.ts +6 -0
- package/dist/alter/utils.d.ts.map +1 -0
- package/dist/defaults.d.ts +2 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +1540 -0
- package/dist/index.mjs.map +1 -0
- package/dist/indexer.d.ts +12 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/log/access_log.d.ts +7 -0
- package/dist/log/access_log.d.ts.map +1 -0
- package/dist/log/db.d.ts +6 -0
- package/dist/log/db.d.ts.map +1 -0
- package/dist/log/index.d.ts +3 -0
- package/dist/log/index.d.ts.map +1 -0
- package/dist/tables/AccessLog/index.d.ts +79 -0
- package/dist/tables/AccessLog/index.d.ts.map +1 -0
- package/dist/tables/AccessLog/schema.d.ts +17 -0
- package/dist/tables/AccessLog/schema.d.ts.map +1 -0
- package/dist/tables/Permission/index.d.ts +43 -0
- package/dist/tables/Permission/index.d.ts.map +1 -0
- package/dist/tables/Permission/schema.d.ts +12 -0
- package/dist/tables/Permission/schema.d.ts.map +1 -0
- package/dist/tables/SetString/index.d.ts +10 -0
- package/dist/tables/SetString/index.d.ts.map +1 -0
- package/dist/tables/SetString/schema.d.ts +7 -0
- package/dist/tables/SetString/schema.d.ts.map +1 -0
- package/dist/tables/Settings/index.d.ts +42 -0
- package/dist/tables/Settings/index.d.ts.map +1 -0
- package/dist/tables/Settings/schema.d.ts +8 -0
- package/dist/tables/Settings/schema.d.ts.map +1 -0
- package/dist/tables/Transaction/index.d.ts +90 -0
- package/dist/tables/Transaction/index.d.ts.map +1 -0
- package/dist/tables/Transaction/schema.d.ts +16 -0
- package/dist/tables/Transaction/schema.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils.d.ts +42 -0
- package/dist/utils.d.ts.map +1 -0
- package/eslint.config.js +7 -0
- package/package.json +54 -0
- package/src/BitFields.ts +160 -0
- package/src/Error.ts +13 -0
- package/src/ORM.ts +49 -0
- package/src/SQLParser.js +1204 -0
- package/src/WebpackFileProvider.ts +63 -0
- package/src/alter/column_add.ts +79 -0
- package/src/alter/column_drop.ts +54 -0
- package/src/alter/column_rename.ts +55 -0
- package/src/alter/column_update.ts +92 -0
- package/src/alter/columns_order.ts +60 -0
- package/src/alter/index.ts +6 -0
- package/src/alter/pragma.ts +10 -0
- package/src/alter/utils.ts +70 -0
- package/src/defaults.ts +3 -0
- package/src/index.ts +227 -0
- package/src/indexer.ts +75 -0
- package/src/log/access_log.ts +29 -0
- package/src/log/db.ts +28 -0
- package/src/log/index.ts +2 -0
- package/src/tables/AccessLog/index.ts +252 -0
- package/src/tables/AccessLog/schema.ts +20 -0
- package/src/tables/Permission/index.ts +220 -0
- package/src/tables/Permission/schema.ts +13 -0
- package/src/tables/SetString/index.ts +45 -0
- package/src/tables/SetString/schema.ts +7 -0
- package/src/tables/Settings/index.ts +135 -0
- package/src/tables/Settings/schema.ts +8 -0
- package/src/tables/Transaction/index.ts +343 -0
- package/src/tables/Transaction/schema.ts +20 -0
- package/src/types/index.ts +33 -0
- package/src/utils.ts +48 -0
- package/test/sqliteExtExpert.test.ts +39 -0
- package/tsconfig.build.json +17 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
export * from './schema';
|
|
2
|
+
|
|
3
|
+
import { master_table } from '../../utils';
|
|
4
|
+
import { ORM } from '../../ORM';
|
|
5
|
+
|
|
6
|
+
import type { Kysely } from 'kysely';
|
|
7
|
+
import type { DBTablesByType } from '../../types';
|
|
8
|
+
import type { TablePermission, TablePermissionGroup } from './schema';
|
|
9
|
+
|
|
10
|
+
type DefaultKeyPermission = 'permission';
|
|
11
|
+
interface DefaultKyselyPermission {
|
|
12
|
+
permission: TablePermission
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PermissionStore {
|
|
16
|
+
getPermissions(id: number): Promise<string[]>
|
|
17
|
+
hasPermission(id: number, permission: string): Promise<boolean>
|
|
18
|
+
addPermission(id: number, permission: string): Promise<void>
|
|
19
|
+
delPermission(id: number, permission: string): Promise<void>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class PermissionStoreDB implements PermissionStore {
|
|
23
|
+
protected readonly db: Kysely<DefaultKyselyPermission>;
|
|
24
|
+
protected readonly domain: DefaultKeyPermission;
|
|
25
|
+
|
|
26
|
+
private constructor(db: any, domain: any) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
this.domain = domain;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static async create<
|
|
32
|
+
DB,
|
|
33
|
+
Domain extends DBTablesByType<DB, TablePermission>,
|
|
34
|
+
>(
|
|
35
|
+
db: Kysely<DB>,
|
|
36
|
+
domain: Domain,
|
|
37
|
+
) {
|
|
38
|
+
const master = await master_table(db);
|
|
39
|
+
const info = master.find(r => r.name == domain && r.type == 'table');
|
|
40
|
+
|
|
41
|
+
if (!info)
|
|
42
|
+
throw new Error(`Table ${domain} not found, can't create permission store`);
|
|
43
|
+
|
|
44
|
+
return new PermissionStoreDB(db, domain);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getPermissions(id: number): Promise<string[]> {
|
|
48
|
+
return (
|
|
49
|
+
await this.db
|
|
50
|
+
.selectFrom(this.domain)
|
|
51
|
+
.select('name')
|
|
52
|
+
.where('fk_id', '=', id)
|
|
53
|
+
.execute()
|
|
54
|
+
).map(r => r.name);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async hasPermission(id: number, permission: string): Promise<boolean> {
|
|
58
|
+
const perms_chunks = permission.split('.');
|
|
59
|
+
const perms = [];
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < perms_chunks.length; i++) {
|
|
62
|
+
perms.push(perms_chunks.slice(0, i + 1).join('.'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return !!(
|
|
66
|
+
await this.db
|
|
67
|
+
.selectFrom(this.domain)
|
|
68
|
+
.select(eb => eb.lit(true).as('exists'))
|
|
69
|
+
.where('name', 'in', perms)
|
|
70
|
+
.where('fk_id', '=', id)
|
|
71
|
+
.executeTakeFirst()
|
|
72
|
+
)?.exists;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async addPermission(id: number, permission: string): Promise<void> {
|
|
76
|
+
return void (
|
|
77
|
+
await this.db
|
|
78
|
+
.insertInto(this.domain)
|
|
79
|
+
.values({
|
|
80
|
+
fk_id: id,
|
|
81
|
+
name: permission,
|
|
82
|
+
})
|
|
83
|
+
.onConflict(oc => oc
|
|
84
|
+
.doNothing())
|
|
85
|
+
.executeTakeFirst()
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async delPermission(id: number, permission: string): Promise<void> {
|
|
90
|
+
return void (
|
|
91
|
+
await this.db
|
|
92
|
+
.deleteFrom(this.domain)
|
|
93
|
+
.where('fk_id', '=', id)
|
|
94
|
+
.where('name', '=', permission)
|
|
95
|
+
.executeTakeFirst()
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class Permission extends ORM {
|
|
101
|
+
protected readonly parent: Permission | undefined;
|
|
102
|
+
protected readonly store: PermissionStore;
|
|
103
|
+
protected readonly name: string;
|
|
104
|
+
protected readonly children: Map<string, Permission> = new Map();
|
|
105
|
+
|
|
106
|
+
protected constructor(store: PermissionStore, name: string, parent?: Permission) {
|
|
107
|
+
super();
|
|
108
|
+
|
|
109
|
+
this.parent = parent;
|
|
110
|
+
this.store = store;
|
|
111
|
+
this.name = name;
|
|
112
|
+
|
|
113
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(this.name))
|
|
114
|
+
throw new Error('Invalid permission name');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static newRoot(options: {
|
|
118
|
+
store: PermissionStore
|
|
119
|
+
name?: string
|
|
120
|
+
}): Permission {
|
|
121
|
+
return new Permission(options.store, options.name || 'root');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
static async has(id: number, perm: Permission): Promise<boolean> {
|
|
125
|
+
return perm.store.hasPermission(id, perm.getFullName());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static async add(id: number, perm: Permission): Promise<void> {
|
|
129
|
+
return perm.store.addPermission(id, perm.getFullName());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static async del(id: number, perm: Permission): Promise<void> {
|
|
133
|
+
return perm.store.delPermission(id, perm.getFullName());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getFlatPermissions(): string[] {
|
|
137
|
+
const result = [
|
|
138
|
+
this.getFullName(),
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
for (const child of this.children.values())
|
|
142
|
+
result.push(...child.getFlatPermissions());
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
getFullName(): string {
|
|
148
|
+
if (!this.parent)
|
|
149
|
+
return this.name;
|
|
150
|
+
|
|
151
|
+
return this.parent.getFullName() + '.' + this.name;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
child(name: string) {
|
|
155
|
+
const child = new Permission(this.store, name, this);
|
|
156
|
+
|
|
157
|
+
this.children.set(name, child);
|
|
158
|
+
|
|
159
|
+
return child;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// export class PermissionGroup {
|
|
164
|
+
// // Domain -> Set<PermissionName> Что бы не допускать дубликатов
|
|
165
|
+
// static groups: Map<string, Set<string>> = new Map();
|
|
166
|
+
|
|
167
|
+
// include_permissions: (Permission | PermissionGroup)[];
|
|
168
|
+
// exclude_permissions: (Permission | PermissionGroup)[];
|
|
169
|
+
|
|
170
|
+
// domain: string;
|
|
171
|
+
// name: string;
|
|
172
|
+
|
|
173
|
+
// constructor(domain: string, name: string) {
|
|
174
|
+
// this.domain = domain;
|
|
175
|
+
// this.name = name;
|
|
176
|
+
|
|
177
|
+
// this.include_permissions = [];
|
|
178
|
+
// this.exclude_permissions = [];
|
|
179
|
+
// }
|
|
180
|
+
|
|
181
|
+
// hasIncludePermission(perm: Permission): boolean {
|
|
182
|
+
// return false;
|
|
183
|
+
// }
|
|
184
|
+
|
|
185
|
+
// hasExcludePermission(perm: Permission): boolean {
|
|
186
|
+
// return false;
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// hasPermission(perm: Permission): boolean {
|
|
190
|
+
// return this.hasIncludePermission(perm) && !this.hasExcludePermission(perm);
|
|
191
|
+
// }
|
|
192
|
+
// }
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
// const perm_root = Permission.newRoot('user-permission');
|
|
196
|
+
|
|
197
|
+
// const perm_crm = perm_root.child('CRM');
|
|
198
|
+
// const perm_crm_user = perm_crm.child('user');
|
|
199
|
+
|
|
200
|
+
// const perm_users_list = perm_crm_user.child('list');
|
|
201
|
+
// const perm_users_view = perm_crm_user.child('view');
|
|
202
|
+
// const perm_users_add = perm_crm_user.child('add');
|
|
203
|
+
// const perm_users_edit = perm_crm_user.child('edit');
|
|
204
|
+
// const perm_users_remove = perm_crm_user.child('remove');
|
|
205
|
+
|
|
206
|
+
// const User = {} as any;
|
|
207
|
+
|
|
208
|
+
// User.hasPermission = function (perm: Permission) {
|
|
209
|
+
// if (Permission.has(User.id, perm_root))
|
|
210
|
+
// return true;
|
|
211
|
+
|
|
212
|
+
// if (Permission.has(User.id, perm))
|
|
213
|
+
// return true;
|
|
214
|
+
|
|
215
|
+
// return false;
|
|
216
|
+
// };
|
|
217
|
+
|
|
218
|
+
// if (User.hasPermission(perm_users_list)) {
|
|
219
|
+
// //
|
|
220
|
+
// }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Generated, GeneratedAlways } from 'kysely';
|
|
2
|
+
|
|
3
|
+
export interface TablePermission {
|
|
4
|
+
id: Generated<number>
|
|
5
|
+
fk_id: number // fk, id к которому принадлежит право
|
|
6
|
+
name: string // fullName
|
|
7
|
+
created_at: GeneratedAlways<string>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TablePermissionGroup {
|
|
11
|
+
id: Generated<number>
|
|
12
|
+
created_at: GeneratedAlways<string>
|
|
13
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export * from './schema';
|
|
2
|
+
|
|
3
|
+
import { ORM } from '../../ORM';
|
|
4
|
+
|
|
5
|
+
import type { Kysely } from 'kysely';
|
|
6
|
+
import type { DBTablesByType } from '../../types';
|
|
7
|
+
import type { TableSetString } from './schema';
|
|
8
|
+
|
|
9
|
+
type DefaultKeySetString = 'default_set';
|
|
10
|
+
interface DefaultKyselySetString {
|
|
11
|
+
default_set: TableSetString
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class SetString extends ORM {
|
|
15
|
+
static async store_value_or_throw<
|
|
16
|
+
DB,
|
|
17
|
+
Domain extends DBTablesByType<DB, TableSetString> = DBTablesByType<DB, TableSetString>,
|
|
18
|
+
>(value: string, domain: Domain, db_builder: Kysely<DB>): Promise<number> {
|
|
19
|
+
const db = db_builder as unknown as Kysely<DefaultKyselySetString>;
|
|
20
|
+
const in_domain = domain as DefaultKeySetString;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
await db
|
|
24
|
+
.insertInto(in_domain)
|
|
25
|
+
.returning('id')
|
|
26
|
+
.values({
|
|
27
|
+
value,
|
|
28
|
+
})
|
|
29
|
+
.onConflict(oc => oc
|
|
30
|
+
// .doNothing() // Не возвращает id, если строка уже была в базе: https://sqlite.org/forum/info/6b14076446260538
|
|
31
|
+
.doUpdateSet(eb => ({
|
|
32
|
+
id: eb.ref('id'),
|
|
33
|
+
})),
|
|
34
|
+
)
|
|
35
|
+
.executeTakeFirstOrThrow()
|
|
36
|
+
).id;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static async try_store_value_or_throw<
|
|
40
|
+
DB,
|
|
41
|
+
Domain extends DBTablesByType<DB, TableSetString> = DBTablesByType<DB, TableSetString>,
|
|
42
|
+
>(value: string | undefined, domain: Domain, db_builder: Kysely<DB>): Promise<number | undefined> {
|
|
43
|
+
return value ? await this.store_value_or_throw(value, domain, db_builder) : undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
export * from './schema';
|
|
2
|
+
|
|
3
|
+
import { master_table } from '../../utils';
|
|
4
|
+
import { ORM } from '../../ORM';
|
|
5
|
+
|
|
6
|
+
import type { Kysely } from 'kysely';
|
|
7
|
+
import type { DBTablesByType } from '../../types';
|
|
8
|
+
import type { TableSettings } from './schema';
|
|
9
|
+
|
|
10
|
+
type DefaultKeyPermission = 'settings';
|
|
11
|
+
interface DefaultKyselyPermission {
|
|
12
|
+
settings: TableSettings
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SettingsStore {
|
|
16
|
+
getKV(key: string): Promise<string | undefined>
|
|
17
|
+
setKV(key: string, value: string): Promise<void>
|
|
18
|
+
hasKV(key: string): Promise<boolean>
|
|
19
|
+
unsetKV(key: string): Promise<void>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class SettingsStoreDB implements SettingsStore {
|
|
23
|
+
protected readonly db: Kysely<DefaultKyselyPermission>;
|
|
24
|
+
protected readonly domain: DefaultKeyPermission;
|
|
25
|
+
|
|
26
|
+
private constructor(db: any, domain: any) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
this.domain = domain;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static async create<
|
|
32
|
+
DB,
|
|
33
|
+
Domain extends DBTablesByType<DB, TableSettings>,
|
|
34
|
+
>(
|
|
35
|
+
db: Kysely<DB>,
|
|
36
|
+
domain: Domain,
|
|
37
|
+
) {
|
|
38
|
+
const master = await master_table(db);
|
|
39
|
+
const info = master.find(r => r.name == domain && r.type == 'table');
|
|
40
|
+
|
|
41
|
+
if (!info)
|
|
42
|
+
throw new Error(`Table ${domain} not found, can't create settings store`);
|
|
43
|
+
|
|
44
|
+
return new SettingsStoreDB(db, domain);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getKV(key: string): Promise<any> {
|
|
48
|
+
return (
|
|
49
|
+
await this.db
|
|
50
|
+
.selectFrom(this.domain)
|
|
51
|
+
.select('value')
|
|
52
|
+
.where('key', '=', key)
|
|
53
|
+
.executeTakeFirst()
|
|
54
|
+
)?.value;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async setKV(key: string, value: string): Promise<void> {
|
|
58
|
+
return void (
|
|
59
|
+
await this.db
|
|
60
|
+
.insertInto(this.domain)
|
|
61
|
+
.values({
|
|
62
|
+
key,
|
|
63
|
+
value,
|
|
64
|
+
})
|
|
65
|
+
.onConflict(oc => oc
|
|
66
|
+
.doUpdateSet({ value }))
|
|
67
|
+
.executeTakeFirst()
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async hasKV(key: string): Promise<boolean> {
|
|
72
|
+
return (
|
|
73
|
+
await this.db
|
|
74
|
+
.selectFrom(this.domain)
|
|
75
|
+
.select('id')
|
|
76
|
+
.where('key', '=', key)
|
|
77
|
+
.executeTakeFirst()
|
|
78
|
+
) != null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async unsetKV(key: string): Promise<void> {
|
|
82
|
+
return void (
|
|
83
|
+
await this.db
|
|
84
|
+
.deleteFrom(this.domain)
|
|
85
|
+
.where('key', '=', key)
|
|
86
|
+
.executeTakeFirst()
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
type DefaultsObject = {
|
|
92
|
+
[key: string]: any
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export class Settings<SettingsObject extends DefaultsObject> extends ORM {
|
|
96
|
+
protected readonly store: SettingsStore;
|
|
97
|
+
protected readonly defaults: SettingsObject;
|
|
98
|
+
|
|
99
|
+
private constructor(store: SettingsStore, defaults: any) {
|
|
100
|
+
super();
|
|
101
|
+
|
|
102
|
+
this.store = store;
|
|
103
|
+
this.defaults = defaults;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static new<
|
|
107
|
+
Defaults extends DefaultsObject,
|
|
108
|
+
>(options: {
|
|
109
|
+
store: SettingsStore
|
|
110
|
+
defaults: Defaults
|
|
111
|
+
}) {
|
|
112
|
+
return new Settings<Defaults>(options.store, options.defaults);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async get<K extends keyof SettingsObject>(key: K & string): Promise<SettingsObject[K]> {
|
|
116
|
+
const value = await this.store.getKV(key);
|
|
117
|
+
|
|
118
|
+
if (value !== undefined)
|
|
119
|
+
return JSON.parse(value);
|
|
120
|
+
|
|
121
|
+
return this.defaults[key];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async set<K extends keyof SettingsObject>(key: K & string, value: SettingsObject[K]): Promise<void> {
|
|
125
|
+
await this.store.setKV(key, JSON.stringify(value));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async unset<K extends keyof SettingsObject>(key: K & string): Promise<void> {
|
|
129
|
+
await this.store.unsetKV(key);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async has<K extends keyof SettingsObject>(key: K & string): Promise<boolean> {
|
|
133
|
+
return await this.store.hasKV(key);
|
|
134
|
+
}
|
|
135
|
+
}
|