commandkit 1.0.0-dev.20250702020504 → 1.0.0-dev.20250702033548
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/dist/{CommandKit-BZVEqKzs.js → CommandKit-DkPVD3wV.js} +2 -2
- package/dist/{CommandKit-BZVEqKzs.js.map → CommandKit-DkPVD3wV.js.map} +1 -1
- package/dist/CommandKit.js +2 -2
- package/dist/analytics/analytics-engine.js +2 -2
- package/dist/analytics/utils.js +2 -2
- package/dist/app/commands/AppCommandRunner.js +2 -2
- package/dist/app/commands/Context.js +2 -2
- package/dist/app/handlers/AppCommandHandler.js +2 -2
- package/dist/app/handlers/AppEventsHandler.js +2 -2
- package/dist/app/index.js +2 -2
- package/dist/app/register/CommandRegistrar.js +2 -2
- package/dist/{app-process-kobgJPMW.js → app-process-CMtPJoA5.js} +2 -2
- package/dist/{app-process-kobgJPMW.js.map → app-process-CMtPJoA5.js.map} +1 -1
- package/dist/{build-CI-WOwAi.js → build--FBgqYjI.js} +4 -4
- package/dist/{build-CI-WOwAi.js.map → build--FBgqYjI.js.map} +1 -1
- package/dist/cli/app-process.js +2 -2
- package/dist/cli/build.js +4 -4
- package/dist/cli/common.js +1 -1
- package/dist/cli/development.js +5 -5
- package/dist/cli/generators.js +1 -1
- package/dist/cli/information.js +1 -1
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.js +3 -3
- package/dist/cli/production.d.ts +2 -2
- package/dist/cli/production.js +5 -5
- package/dist/cli/type-checker.js +2 -2
- package/dist/{common-DUta5JO9.js → common-Cx8Kw8DO.js} +5 -3
- package/dist/common-Cx8Kw8DO.js.map +1 -0
- package/dist/components/index.js +2 -2
- package/dist/components/v1/button/Button.js +2 -2
- package/dist/components/v1/button/ButtonKit.js +2 -2
- package/dist/components/v1/modal/Modal.js +2 -2
- package/dist/components/v1/modal/ModalKit.js +2 -2
- package/dist/components/v1/select-menu/ChannelSelectMenuKit.js +2 -2
- package/dist/components/v1/select-menu/MentionableSelectMenuKit.js +2 -2
- package/dist/components/v1/select-menu/RoleSelectMenuKit.js +2 -2
- package/dist/components/v1/select-menu/SelectMenu.js +2 -2
- package/dist/components/v1/select-menu/StringSelectMenuKit.js +2 -2
- package/dist/components/v1/select-menu/UserSelectMenuKit.js +2 -2
- package/dist/config/config.js +2 -2
- package/dist/config/default.js +2 -2
- package/dist/config/loader.js +2 -2
- package/dist/context/async-context.js +2 -2
- package/dist/context/environment.js +2 -2
- package/dist/{feature-flags-IU-pT6k_.js → feature-flags-DJcINI5E.js} +2 -2
- package/dist/{feature-flags-IU-pT6k_.js.map → feature-flags-DJcINI5E.js.map} +1 -1
- package/dist/flags/feature-flags.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/{init-D3mhxEzo.js → init-DeoDd5cK.js} +3 -3
- package/dist/{init-D3mhxEzo.js.map → init-DeoDd5cK.js.map} +1 -1
- package/dist/{init-BbVFAxJw.d.ts → init-DsaK1AfD.d.ts} +3 -3
- package/dist/kv/kv.d.ts +321 -0
- package/dist/kv/kv.js +428 -0
- package/dist/kv/kv.js.map +1 -0
- package/dist/logger/DefaultLogger.js +2 -2
- package/dist/logger/Logger.js +2 -2
- package/dist/plugins/index.js +2 -2
- package/dist/plugins/plugin-runtime/CommandKitPluginRuntime.js +2 -2
- package/dist/plugins/plugin-runtime/CompilerPluginRuntime.js +2 -2
- package/dist/plugins/plugin-runtime/builtin/CommonDirectiveTransformer.js +2 -2
- package/dist/plugins/plugin-runtime/builtin/MacroPlugin.js +2 -2
- package/dist/{type-checker-BhbQMKkv.js → type-checker-BATr8TiL.js} +2 -2
- package/dist/{type-checker-BhbQMKkv.js.map → type-checker-BATr8TiL.js.map} +1 -1
- package/dist/utils/colors.d.ts +2 -2
- package/dist/utils/dev-hooks.js +2 -2
- package/dist/utils/utilities.js +2 -2
- package/dist/{version-RmiVh92c.js → version-PfJROmx1.js} +2 -2
- package/dist/{version-RmiVh92c.js.map → version-PfJROmx1.js.map} +1 -1
- package/dist/version.js +1 -1
- package/kv.cjs +6 -0
- package/kv.d.ts +1 -0
- package/package.json +10 -3
- package/dist/common-DUta5JO9.js.map +0 -1
package/dist/kv/kv.js
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
const require_chunk = require('../chunk-nOFOJqeH.js');
|
|
2
|
+
const node_sqlite = require_chunk.__toESM(require("node:sqlite"));
|
|
3
|
+
|
|
4
|
+
//#region src/kv/kv.ts
|
|
5
|
+
/**
|
|
6
|
+
* A key-value store implementation using SQLite
|
|
7
|
+
*
|
|
8
|
+
* This class provides a simple, persistent key-value storage solution
|
|
9
|
+
* with support for namespaces, automatic cleanup, iteration, and expiration.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const kv = new KV('data.db');
|
|
14
|
+
* kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));
|
|
15
|
+
* const user = JSON.parse(kv.get('user:123') || '{}');
|
|
16
|
+
*
|
|
17
|
+
* // Using namespaces
|
|
18
|
+
* const userKv = kv.namespace('users');
|
|
19
|
+
* userKv.set('123', JSON.stringify({ name: 'John' }));
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
var KV = class KV {
|
|
23
|
+
db;
|
|
24
|
+
statements = {};
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new KV store instance
|
|
27
|
+
*
|
|
28
|
+
* @param path - Database file path, buffer, URL, or existing DatabaseSync instance
|
|
29
|
+
* @param options - Configuration options for the KV store
|
|
30
|
+
*/
|
|
31
|
+
constructor(path, options = {
|
|
32
|
+
enableWAL: true,
|
|
33
|
+
namespace: "commandkit_kv"
|
|
34
|
+
}) {
|
|
35
|
+
this.options = options;
|
|
36
|
+
this.db = path instanceof node_sqlite.DatabaseSync ? path : new node_sqlite.DatabaseSync(path, { open: true });
|
|
37
|
+
if (options.enableWAL) this.db.exec(`PRAGMA journal_mode = WAL;`);
|
|
38
|
+
this.db.prepare(`
|
|
39
|
+
CREATE TABLE IF NOT EXISTS ? (
|
|
40
|
+
key TEXT PRIMARY KEY,
|
|
41
|
+
value TEXT,
|
|
42
|
+
expires_at INTEGER
|
|
43
|
+
)
|
|
44
|
+
`).run(options.namespace ?? "commandkit_kv");
|
|
45
|
+
this.statements = {
|
|
46
|
+
get: this.db.prepare(`SELECT value, expires_at FROM ? WHERE key = ?`),
|
|
47
|
+
set: this.db.prepare(`INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`),
|
|
48
|
+
setex: this.db.prepare(`INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`),
|
|
49
|
+
delete: this.db.prepare(`DELETE FROM ? WHERE key = ?`),
|
|
50
|
+
has: this.db.prepare(`SELECT COUNT(*) FROM ? WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`),
|
|
51
|
+
keys: this.db.prepare(`SELECT key FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
|
|
52
|
+
values: this.db.prepare(`SELECT value FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
|
|
53
|
+
clear: this.db.prepare(`DELETE FROM ?`),
|
|
54
|
+
count: this.db.prepare(`SELECT COUNT(*) FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
|
|
55
|
+
all: this.db.prepare(`SELECT key, value FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
|
|
56
|
+
expire: this.db.prepare(`UPDATE ? SET expires_at = ? WHERE key = ?`),
|
|
57
|
+
ttl: this.db.prepare(`SELECT expires_at FROM ? WHERE key = ?`),
|
|
58
|
+
namespaces: this.db.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`),
|
|
59
|
+
begin: this.db.prepare(`BEGIN TRANSACTION`),
|
|
60
|
+
commit: this.db.prepare(`COMMIT`),
|
|
61
|
+
rollback: this.db.prepare(`ROLLBACK`)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Gets the current timestamp in milliseconds
|
|
66
|
+
*/
|
|
67
|
+
getCurrentTime() {
|
|
68
|
+
return Date.now();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Checks if the database connection is open
|
|
72
|
+
*
|
|
73
|
+
* @returns `true` if the database is open, `false` otherwise
|
|
74
|
+
*/
|
|
75
|
+
isOpen() {
|
|
76
|
+
return this.db.isOpen;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Gets the underlying SQLite database instance
|
|
80
|
+
*
|
|
81
|
+
* @returns The DatabaseSync instance
|
|
82
|
+
*/
|
|
83
|
+
getDatabase() {
|
|
84
|
+
return this.db;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Closes the database connection
|
|
88
|
+
*/
|
|
89
|
+
close() {
|
|
90
|
+
if (this.db.isOpen) this.db.close();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Disposable implementation - closes the database when disposed
|
|
94
|
+
*/
|
|
95
|
+
[Symbol.dispose]() {
|
|
96
|
+
this.close();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* AsyncDisposable implementation - closes the database when disposed
|
|
100
|
+
*/
|
|
101
|
+
async [Symbol.asyncDispose]() {
|
|
102
|
+
this.close();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Retrieves a value by key
|
|
106
|
+
*
|
|
107
|
+
* @param key - The key to retrieve
|
|
108
|
+
* @returns The value associated with the key, or `undefined` if not found or expired
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const value = kv.get('my-key');
|
|
113
|
+
* if (value) {
|
|
114
|
+
* console.log('Found:', value);
|
|
115
|
+
* }
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
get(key) {
|
|
119
|
+
const result = this.statements.get.get(this.getCurrentNamespace(), key);
|
|
120
|
+
if (!result) return void 0;
|
|
121
|
+
if (result.expires_at && Number(result.expires_at) <= this.getCurrentTime()) {
|
|
122
|
+
this.delete(key);
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
return result.value;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Sets a key-value pair
|
|
129
|
+
*
|
|
130
|
+
* @param key - The key to set
|
|
131
|
+
* @param value - The value to associate with the key
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* kv.set('user:123', JSON.stringify({ name: 'John' }));
|
|
136
|
+
* kv.set('counter', '42');
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
set(key, value) {
|
|
140
|
+
this.statements.set.run(this.getCurrentNamespace(), key, value, null);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Sets a key-value pair with expiration
|
|
144
|
+
*
|
|
145
|
+
* @param key - The key to set
|
|
146
|
+
* @param value - The value to associate with the key
|
|
147
|
+
* @param ttl - Time to live in milliseconds
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* // Set with 1 hour expiration
|
|
152
|
+
* kv.setex('session:123', 'user_data', 60 * 60 * 1000);
|
|
153
|
+
*
|
|
154
|
+
* // Set with 5 minutes expiration
|
|
155
|
+
* kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
setex(key, value, ttl) {
|
|
159
|
+
const expiresAt = this.getCurrentTime() + ttl;
|
|
160
|
+
this.statements.setex.run(this.getCurrentNamespace(), key, value, expiresAt);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Sets expiration for an existing key
|
|
164
|
+
*
|
|
165
|
+
* @param key - The key to set expiration for
|
|
166
|
+
* @param ttl - Time to live in milliseconds
|
|
167
|
+
* @returns `true` if the key exists and expiration was set, `false` otherwise
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* kv.set('user:123', 'user_data');
|
|
172
|
+
*
|
|
173
|
+
* // Set 30 minute expiration
|
|
174
|
+
* if (kv.expire('user:123', 30 * 60 * 1000)) {
|
|
175
|
+
* console.log('Expiration set successfully');
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
expire(key, ttl) {
|
|
180
|
+
if (!this.has(key)) return false;
|
|
181
|
+
const expiresAt = this.getCurrentTime() + ttl;
|
|
182
|
+
this.statements.expire.run(this.getCurrentNamespace(), expiresAt, key);
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Gets the time to live for a key
|
|
187
|
+
*
|
|
188
|
+
* @param key - The key to check
|
|
189
|
+
* @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const ttl = kv.ttl('user:123');
|
|
194
|
+
* if (ttl > 0) {
|
|
195
|
+
* console.log(`Key expires in ${ttl}ms`);
|
|
196
|
+
* } else if (ttl === -2) {
|
|
197
|
+
* console.log('Key has no expiration');
|
|
198
|
+
* } else {
|
|
199
|
+
* console.log('Key does not exist');
|
|
200
|
+
* }
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
ttl(key) {
|
|
204
|
+
const result = this.statements.ttl.get(this.getCurrentNamespace(), key);
|
|
205
|
+
if (!result) return -1;
|
|
206
|
+
if (!result.expires_at) return -2;
|
|
207
|
+
const remaining = Number(result.expires_at) - this.getCurrentTime();
|
|
208
|
+
return remaining > 0 ? remaining : -1;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Deletes a key-value pair
|
|
212
|
+
*
|
|
213
|
+
* @param key - The key to delete
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* kv.delete('user:123');
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
delete(key) {
|
|
221
|
+
this.statements.delete.run(this.getCurrentNamespace(), key);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Checks if a key exists and is not expired
|
|
225
|
+
*
|
|
226
|
+
* @param key - The key to check
|
|
227
|
+
* @returns `true` if the key exists and is not expired, `false` otherwise
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* if (kv.has('user:123')) {
|
|
232
|
+
* console.log('User exists and is not expired');
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
has(key) {
|
|
237
|
+
const result = this.statements.has.get(this.getCurrentNamespace(), key, this.getCurrentTime());
|
|
238
|
+
return (result === null || result === void 0 ? void 0 : result.count) !== void 0 && result.count !== null && Number(result.count) > 0;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Gets all keys in the current namespace (excluding expired keys)
|
|
242
|
+
*
|
|
243
|
+
* @returns Array of all non-expired keys
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* const keys = kv.keys();
|
|
248
|
+
* console.log('All keys:', keys);
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
keys() {
|
|
252
|
+
const result = this.statements.keys.all(this.getCurrentNamespace(), this.getCurrentTime());
|
|
253
|
+
return result.map((row) => row.key);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Gets all values in the current namespace (excluding expired keys)
|
|
257
|
+
*
|
|
258
|
+
* @returns Array of all non-expired values
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const values = kv.values();
|
|
263
|
+
* console.log('All values:', values);
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
values() {
|
|
267
|
+
const result = this.statements.values.all(this.getCurrentNamespace(), this.getCurrentTime());
|
|
268
|
+
return result.map((row) => row.value);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Gets the total number of key-value pairs in the current namespace (excluding expired keys)
|
|
272
|
+
*
|
|
273
|
+
* @returns The count of non-expired key-value pairs
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```typescript
|
|
277
|
+
* const count = kv.count();
|
|
278
|
+
* console.log(`Total entries: ${count}`);
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
count() {
|
|
282
|
+
const result = this.statements.count.get(this.getCurrentNamespace(), this.getCurrentTime());
|
|
283
|
+
return Number((result === null || result === void 0 ? void 0 : result.count) ?? 0);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Removes all key-value pairs from the current namespace
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* kv.clear(); // Removes all entries in current namespace
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
clear() {
|
|
294
|
+
this.statements.clear.run(this.getCurrentNamespace());
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Gets all key-value pairs as an object (excluding expired keys)
|
|
298
|
+
*
|
|
299
|
+
* @returns Object with all non-expired key-value pairs
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const all = kv.all();
|
|
304
|
+
* console.log('All entries:', all);
|
|
305
|
+
* // Output: { 'key1': 'value1', 'key2': 'value2' }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
all() {
|
|
309
|
+
const result = this.statements.all.all(this.getCurrentNamespace(), this.getCurrentTime());
|
|
310
|
+
return Object.fromEntries(result.map((row) => [row.key, row.value]));
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Gets all available namespaces (tables) in the database
|
|
314
|
+
*
|
|
315
|
+
* @returns Array of namespace names
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* const namespaces = kv.namespaces();
|
|
320
|
+
* console.log('Available namespaces:', namespaces);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
namespaces() {
|
|
324
|
+
const result = this.statements.namespaces.all();
|
|
325
|
+
return result.map((row) => row.name);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Gets the current namespace name
|
|
329
|
+
*
|
|
330
|
+
* @returns The current namespace string
|
|
331
|
+
*/
|
|
332
|
+
getCurrentNamespace() {
|
|
333
|
+
return this.options.namespace ?? "commandkit_kv";
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Creates a new KV instance with a different namespace
|
|
337
|
+
*
|
|
338
|
+
* @param namespace - The namespace to use for the new instance
|
|
339
|
+
* @returns A new KV instance with the specified namespace
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```typescript
|
|
343
|
+
* const userKv = kv.namespace('users');
|
|
344
|
+
* const configKv = kv.namespace('config');
|
|
345
|
+
*
|
|
346
|
+
* userKv.set('123', 'John Doe');
|
|
347
|
+
* configKv.set('theme', 'dark');
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
namespace(namespace) {
|
|
351
|
+
return new KV(this.db, {
|
|
352
|
+
enableWAL: this.options.enableWAL,
|
|
353
|
+
namespace
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Iterator implementation for iterating over all non-expired key-value pairs
|
|
358
|
+
*
|
|
359
|
+
* @returns Iterator yielding [key, value] tuples
|
|
360
|
+
*
|
|
361
|
+
* @example
|
|
362
|
+
* ```typescript
|
|
363
|
+
* for (const [key, value] of kv) {
|
|
364
|
+
* console.log(`${key}: ${value}`);
|
|
365
|
+
* }
|
|
366
|
+
*
|
|
367
|
+
* // Or using spread operator
|
|
368
|
+
* const entries = [...kv];
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
*[Symbol.iterator]() {
|
|
372
|
+
const result = this.statements.all.iterate(this.getCurrentNamespace(), this.getCurrentTime());
|
|
373
|
+
for (const row of result) yield [row.key, row.value];
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Executes a function within a transaction
|
|
377
|
+
*
|
|
378
|
+
* @param fn - Function to execute within the transaction (can be async)
|
|
379
|
+
* @returns The result of the function
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```typescript
|
|
383
|
+
* // Synchronous transaction
|
|
384
|
+
* kv.transaction(() => {
|
|
385
|
+
* kv.set('user:123', JSON.stringify({ name: 'John' }));
|
|
386
|
+
* kv.set('user:456', JSON.stringify({ name: 'Jane' }));
|
|
387
|
+
* // If any operation fails, all changes are rolled back
|
|
388
|
+
* });
|
|
389
|
+
*
|
|
390
|
+
* // Async transaction
|
|
391
|
+
* await kv.transaction(async () => {
|
|
392
|
+
* kv.set('user:123', JSON.stringify({ name: 'John' }));
|
|
393
|
+
* await someAsyncOperation();
|
|
394
|
+
* kv.set('user:456', JSON.stringify({ name: 'Jane' }));
|
|
395
|
+
* // If any operation fails, all changes are rolled back
|
|
396
|
+
* });
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
async transaction(fn) {
|
|
400
|
+
try {
|
|
401
|
+
this.statements.begin.run();
|
|
402
|
+
const result = await fn();
|
|
403
|
+
this.statements.commit.run();
|
|
404
|
+
return result;
|
|
405
|
+
} catch (error) {
|
|
406
|
+
this.statements.rollback.run();
|
|
407
|
+
throw error;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* Opens a new KV instance
|
|
413
|
+
*
|
|
414
|
+
* @param path - Database file path, buffer, URL, or existing DatabaseSync instance
|
|
415
|
+
* @param options - Configuration options for the KV store
|
|
416
|
+
* @returns A new KV instance
|
|
417
|
+
*/
|
|
418
|
+
function openKV(path = "commandkit_kv.db", options = {
|
|
419
|
+
enableWAL: true,
|
|
420
|
+
namespace: "commandkit_kv"
|
|
421
|
+
}) {
|
|
422
|
+
return new KV(path, options);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
//#endregion
|
|
426
|
+
exports.KV = KV;
|
|
427
|
+
exports.openKV = openKV;
|
|
428
|
+
//# sourceMappingURL=kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.js","names":[],"sources":["../../src/kv/kv.ts"],"sourcesContent":["import { DatabaseSync, StatementSync } from 'node:sqlite';\n\n/**\n * Configuration options for the KV store\n */\nexport interface KvOptions {\n /** Enable Write-Ahead Logging for better performance and durability */\n enableWAL?: boolean;\n /** Namespace for the key-value store table */\n namespace?: string;\n}\n\n/**\n * A key-value store implementation using SQLite\n *\n * This class provides a simple, persistent key-value storage solution\n * with support for namespaces, automatic cleanup, iteration, and expiration.\n *\n * @example\n * ```typescript\n * const kv = new KV('data.db');\n * kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));\n * const user = JSON.parse(kv.get('user:123') || '{}');\n *\n * // Using namespaces\n * const userKv = kv.namespace('users');\n * userKv.set('123', JSON.stringify({ name: 'John' }));\n * ```\n */\nexport class KV implements Disposable, AsyncDisposable {\n private db: DatabaseSync;\n private statements: Record<string, StatementSync> = {};\n\n /**\n * Creates a new KV store instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n */\n public constructor(\n path: string | Buffer | URL | DatabaseSync,\n private options: KvOptions = {\n enableWAL: true,\n namespace: 'commandkit_kv',\n },\n ) {\n this.db =\n path instanceof DatabaseSync\n ? path\n : new DatabaseSync(path, { open: true });\n\n if (options.enableWAL) {\n this.db.exec(/* sql */ `PRAGMA journal_mode = WAL;`);\n }\n\n this.db\n .prepare(\n /* sql */ `\n CREATE TABLE IF NOT EXISTS ? (\n key TEXT PRIMARY KEY,\n value TEXT,\n expires_at INTEGER\n )\n `,\n )\n .run(options.namespace ?? 'commandkit_kv');\n\n this.statements = {\n get: this.db.prepare(\n /* sql */ `SELECT value, expires_at FROM ? WHERE key = ?`,\n ),\n set: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n setex: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n delete: this.db.prepare(/* sql */ `DELETE FROM ? WHERE key = ?`),\n has: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ? WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`,\n ),\n keys: this.db.prepare(\n /* sql */ `SELECT key FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n values: this.db.prepare(\n /* sql */ `SELECT value FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n clear: this.db.prepare(/* sql */ `DELETE FROM ?`),\n count: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n all: this.db.prepare(\n /* sql */ `SELECT key, value FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n expire: this.db.prepare(\n /* sql */ `UPDATE ? SET expires_at = ? WHERE key = ?`,\n ),\n ttl: this.db.prepare(/* sql */ `SELECT expires_at FROM ? WHERE key = ?`),\n namespaces: this.db.prepare(\n /* sql */ `SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`,\n ),\n begin: this.db.prepare(/* sql */ `BEGIN TRANSACTION`),\n commit: this.db.prepare(/* sql */ `COMMIT`),\n rollback: this.db.prepare(/* sql */ `ROLLBACK`),\n };\n }\n\n /**\n * Gets the current timestamp in milliseconds\n */\n private getCurrentTime(): number {\n return Date.now();\n }\n\n /**\n * Checks if the database connection is open\n *\n * @returns `true` if the database is open, `false` otherwise\n */\n public isOpen(): boolean {\n return this.db.isOpen;\n }\n\n /**\n * Gets the underlying SQLite database instance\n *\n * @returns The DatabaseSync instance\n */\n public getDatabase(): DatabaseSync {\n return this.db;\n }\n\n /**\n * Closes the database connection\n */\n public close(): void {\n if (this.db.isOpen) this.db.close();\n }\n\n /**\n * Disposable implementation - closes the database when disposed\n */\n public [Symbol.dispose]() {\n this.close();\n }\n\n /**\n * AsyncDisposable implementation - closes the database when disposed\n */\n public async [Symbol.asyncDispose]() {\n this.close();\n }\n\n /**\n * Retrieves a value by key\n *\n * @param key - The key to retrieve\n * @returns The value associated with the key, or `undefined` if not found or expired\n *\n * @example\n * ```typescript\n * const value = kv.get('my-key');\n * if (value) {\n * console.log('Found:', value);\n * }\n * ```\n */\n public get(key: string): string | undefined {\n const result = this.statements.get.get(this.getCurrentNamespace(), key);\n\n if (!result) return undefined;\n\n // Check if the key has expired\n if (\n result.expires_at &&\n Number(result.expires_at) <= this.getCurrentTime()\n ) {\n this.delete(key);\n return undefined;\n }\n\n return result.value as string;\n }\n\n /**\n * Sets a key-value pair\n *\n * @param key - The key to set\n * @param value - The value to associate with the key\n *\n * @example\n * ```typescript\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * kv.set('counter', '42');\n * ```\n */\n public set(key: string, value: string): void {\n this.statements.set.run(this.getCurrentNamespace(), key, value, null);\n }\n\n /**\n * Sets a key-value pair with expiration\n *\n * @param key - The key to set\n * @param value - The value to associate with the key\n * @param ttl - Time to live in milliseconds\n *\n * @example\n * ```typescript\n * // Set with 1 hour expiration\n * kv.setex('session:123', 'user_data', 60 * 60 * 1000);\n *\n * // Set with 5 minutes expiration\n * kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);\n * ```\n */\n public setex(key: string, value: string, ttl: number): void {\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.setex.run(\n this.getCurrentNamespace(),\n key,\n value,\n expiresAt,\n );\n }\n\n /**\n * Sets expiration for an existing key\n *\n * @param key - The key to set expiration for\n * @param ttl - Time to live in milliseconds\n * @returns `true` if the key exists and expiration was set, `false` otherwise\n *\n * @example\n * ```typescript\n * kv.set('user:123', 'user_data');\n *\n * // Set 30 minute expiration\n * if (kv.expire('user:123', 30 * 60 * 1000)) {\n * console.log('Expiration set successfully');\n * }\n * ```\n */\n public expire(key: string, ttl: number): boolean {\n if (!this.has(key)) return false;\n\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.expire.run(this.getCurrentNamespace(), expiresAt, key);\n return true;\n }\n\n /**\n * Gets the time to live for a key\n *\n * @param key - The key to check\n * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration\n *\n * @example\n * ```typescript\n * const ttl = kv.ttl('user:123');\n * if (ttl > 0) {\n * console.log(`Key expires in ${ttl}ms`);\n * } else if (ttl === -2) {\n * console.log('Key has no expiration');\n * } else {\n * console.log('Key does not exist');\n * }\n * ```\n */\n public ttl(key: string): number {\n const result = this.statements.ttl.get(this.getCurrentNamespace(), key);\n\n if (!result) return -1; // Key doesn't exist\n\n if (!result.expires_at) return -2; // No expiration\n\n const remaining = Number(result.expires_at) - this.getCurrentTime();\n return remaining > 0 ? remaining : -1; // Expired or doesn't exist\n }\n\n /**\n * Deletes a key-value pair\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * kv.delete('user:123');\n * ```\n */\n public delete(key: string): void {\n this.statements.delete.run(this.getCurrentNamespace(), key);\n }\n\n /**\n * Checks if a key exists and is not expired\n *\n * @param key - The key to check\n * @returns `true` if the key exists and is not expired, `false` otherwise\n *\n * @example\n * ```typescript\n * if (kv.has('user:123')) {\n * console.log('User exists and is not expired');\n * }\n * ```\n */\n public has(key: string): boolean {\n const result = this.statements.has.get(\n this.getCurrentNamespace(),\n key,\n this.getCurrentTime(),\n );\n\n return (\n result?.count !== undefined &&\n result.count !== null &&\n Number(result.count) > 0\n );\n }\n\n /**\n * Gets all keys in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired keys\n *\n * @example\n * ```typescript\n * const keys = kv.keys();\n * console.log('All keys:', keys);\n * ```\n */\n public keys(): string[] {\n const result = this.statements.keys.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return result.map((row) => row.key as string);\n }\n\n /**\n * Gets all values in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired values\n *\n * @example\n * ```typescript\n * const values = kv.values();\n * console.log('All values:', values);\n * ```\n */\n public values(): string[] {\n const result = this.statements.values.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return result.map((row) => row.value as string);\n }\n\n /**\n * Gets the total number of key-value pairs in the current namespace (excluding expired keys)\n *\n * @returns The count of non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const count = kv.count();\n * console.log(`Total entries: ${count}`);\n * ```\n */\n public count(): number {\n const result = this.statements.count.get(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return Number(result?.count ?? 0);\n }\n\n /**\n * Removes all key-value pairs from the current namespace\n *\n * @example\n * ```typescript\n * kv.clear(); // Removes all entries in current namespace\n * ```\n */\n public clear(): void {\n this.statements.clear.run(this.getCurrentNamespace());\n }\n\n /**\n * Gets all key-value pairs as an object (excluding expired keys)\n *\n * @returns Object with all non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const all = kv.all();\n * console.log('All entries:', all);\n * // Output: { 'key1': 'value1', 'key2': 'value2' }\n * ```\n */\n public all(): Record<string, string> {\n const result = this.statements.all.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return Object.fromEntries(\n result.map((row) => [row.key as string, row.value as string]),\n );\n }\n\n /**\n * Gets all available namespaces (tables) in the database\n *\n * @returns Array of namespace names\n *\n * @example\n * ```typescript\n * const namespaces = kv.namespaces();\n * console.log('Available namespaces:', namespaces);\n * ```\n */\n public namespaces(): string[] {\n const result = this.statements.namespaces.all();\n\n return result.map((row) => row.name as string);\n }\n\n /**\n * Gets the current namespace name\n *\n * @returns The current namespace string\n */\n public getCurrentNamespace(): string {\n return this.options.namespace ?? 'commandkit_kv';\n }\n\n /**\n * Creates a new KV instance with a different namespace\n *\n * @param namespace - The namespace to use for the new instance\n * @returns A new KV instance with the specified namespace\n *\n * @example\n * ```typescript\n * const userKv = kv.namespace('users');\n * const configKv = kv.namespace('config');\n *\n * userKv.set('123', 'John Doe');\n * configKv.set('theme', 'dark');\n * ```\n */\n public namespace(namespace: string): KV {\n return new KV(this.db, {\n enableWAL: this.options.enableWAL,\n namespace,\n });\n }\n\n /**\n * Iterator implementation for iterating over all non-expired key-value pairs\n *\n * @returns Iterator yielding [key, value] tuples\n *\n * @example\n * ```typescript\n * for (const [key, value] of kv) {\n * console.log(`${key}: ${value}`);\n * }\n *\n * // Or using spread operator\n * const entries = [...kv];\n * ```\n */\n public *[Symbol.iterator](): Iterator<[string, string]> {\n const result = this.statements.all.iterate(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n for (const row of result) {\n yield [row.key as string, row.value as string];\n }\n }\n\n /**\n * Executes a function within a transaction\n *\n * @param fn - Function to execute within the transaction (can be async)\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * // Synchronous transaction\n * kv.transaction(() => {\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * kv.set('user:456', JSON.stringify({ name: 'Jane' }));\n * // If any operation fails, all changes are rolled back\n * });\n *\n * // Async transaction\n * await kv.transaction(async () => {\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * await someAsyncOperation();\n * kv.set('user:456', JSON.stringify({ name: 'Jane' }));\n * // If any operation fails, all changes are rolled back\n * });\n * ```\n */\n public async transaction<T>(fn: () => T | Promise<T>): Promise<T> {\n try {\n // Begin transaction\n this.statements.begin.run();\n\n // Execute the function\n const result = await fn();\n\n // Commit transaction\n this.statements.commit.run();\n\n return result;\n } catch (error) {\n // Rollback transaction on error\n this.statements.rollback.run();\n throw error;\n }\n }\n}\n\n/**\n * Opens a new KV instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n * @returns A new KV instance\n */\nexport function openKV(\n path: string | Buffer | URL | DatabaseSync = 'commandkit_kv.db',\n options: KvOptions = { enableWAL: true, namespace: 'commandkit_kv' },\n): KV {\n return new KV(path, options);\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../common-CcfjYnPG.js');
|
|
6
6
|
require('../common-vnMIelAE.js');
|
|
7
7
|
require('../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../router-wA3kFzES.js');
|
|
32
|
-
require('../common-
|
|
32
|
+
require('../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../store-CyzliDXj.js');
|
|
35
35
|
|
package/dist/logger/Logger.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../common-CcfjYnPG.js');
|
|
6
6
|
require('../common-vnMIelAE.js');
|
|
7
7
|
require('../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../router-wA3kFzES.js');
|
|
32
|
-
require('../common-
|
|
32
|
+
require('../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../store-CyzliDXj.js');
|
|
35
35
|
|
package/dist/plugins/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../common-CcfjYnPG.js');
|
|
6
6
|
require('../common-vnMIelAE.js');
|
|
7
7
|
require('../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../router-wA3kFzES.js');
|
|
32
|
-
require('../common-
|
|
32
|
+
require('../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../store-CyzliDXj.js');
|
|
35
35
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../../common-CcfjYnPG.js');
|
|
6
6
|
require('../../common-vnMIelAE.js');
|
|
7
7
|
require('../../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../../router-wA3kFzES.js');
|
|
32
|
-
require('../../common-
|
|
32
|
+
require('../../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../../store-CyzliDXj.js');
|
|
35
35
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../../common-CcfjYnPG.js');
|
|
6
6
|
require('../../common-vnMIelAE.js');
|
|
7
7
|
require('../../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../../router-wA3kFzES.js');
|
|
32
|
-
require('../../common-
|
|
32
|
+
require('../../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../../store-CyzliDXj.js');
|
|
35
35
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../../../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../../../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../../../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../../../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../../../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../../../common-CcfjYnPG.js');
|
|
6
6
|
require('../../../common-vnMIelAE.js');
|
|
7
7
|
require('../../../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../../../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../../../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../../../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../../../router-wA3kFzES.js');
|
|
32
|
-
require('../../../common-
|
|
32
|
+
require('../../../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../../../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../../../store-CyzliDXj.js');
|
|
35
35
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('../../../colors-Cd4Oz-r-.js');
|
|
2
2
|
require('../../../ActionRow-CmTHbo2t.js');
|
|
3
3
|
require('../../../error-codes-DXOuid4c.js');
|
|
4
|
-
const require_CommandKit = require('../../../CommandKit-
|
|
4
|
+
const require_CommandKit = require('../../../CommandKit-DkPVD3wV.js');
|
|
5
5
|
require('../../../common-CcfjYnPG.js');
|
|
6
6
|
require('../../../common-vnMIelAE.js');
|
|
7
7
|
require('../../../container-DCjIgp-B.js');
|
|
@@ -29,7 +29,7 @@ require('../../../MessageCommandParser-CUZrGknY.js');
|
|
|
29
29
|
require('../../../CommandsRouter-Bs9UuowL.js');
|
|
30
30
|
require('../../../EventsRouter-B7oifgM6.js');
|
|
31
31
|
require('../../../router-wA3kFzES.js');
|
|
32
|
-
require('../../../common-
|
|
32
|
+
require('../../../common-Cx8Kw8DO.js');
|
|
33
33
|
require('../../../CommandKitEventsChannel-BSdcgY3Q.js');
|
|
34
34
|
require('../../../store-CyzliDXj.js');
|
|
35
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-nOFOJqeH.js');
|
|
2
2
|
const require_colors = require('./colors-Cd4Oz-r-.js');
|
|
3
|
-
const require_common = require('./common-
|
|
3
|
+
const require_common = require('./common-Cx8Kw8DO.js');
|
|
4
4
|
const node_fs = require_chunk.__toESM(require("node:fs"));
|
|
5
5
|
const node_path = require_chunk.__toESM(require("node:path"));
|
|
6
6
|
|
|
@@ -85,4 +85,4 @@ Object.defineProperty(exports, 'performTypeCheck', {
|
|
|
85
85
|
return performTypeCheck;
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
//# sourceMappingURL=type-checker-
|
|
88
|
+
//# sourceMappingURL=type-checker-BATr8TiL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-checker-
|
|
1
|
+
{"version":3,"file":"type-checker-BATr8TiL.js","names":[],"sources":["../src/cli/type-checker.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { loadTypeScript } from './common';\nimport { join, relative } from 'node:path';\nimport colors from '../utils/colors';\n\nconst TS_NOT_FOUND_ERR = `TypeScript must be installed in order to use the type checker. Please install it using \\`npm install typescript\\` or \\`yarn add typescript\\``;\n\n/**\n * Formats a TypeScript diagnostic message in a pretty, readable format\n * @private\n * @internal\n */\nfunction formatDiagnostic(\n ts: typeof import('typescript'),\n diagnostic: import('typescript').Diagnostic,\n cwd: string,\n): string {\n const messageText = ts.flattenDiagnosticMessageText(\n diagnostic.messageText,\n '\\n',\n );\n\n if (!diagnostic.file) {\n return `${colors.red('error')}: ${messageText}`;\n }\n\n const { line, character } = ts.getLineAndCharacterOfPosition(\n diagnostic.file,\n diagnostic.start!,\n );\n const fileName = relative(cwd, diagnostic.file.fileName);\n const position = `${line + 1}:${character + 1}`;\n const errorCode = diagnostic.code ? `TS${diagnostic.code}` : '';\n\n // Format the error message nicely\n return [\n `${colors.bold(colors.cyan(fileName))}:${colors.bold(colors.yellow(position))} - ${colors.red('error')} ${colors.gray(errorCode)}`,\n `${messageText}`,\n ].join('\\n');\n}\n\n/**\n * Performs a type check on the project using TypeScript.\n * @param path The project root or cwd\n * @private\n * @internal\n */\nexport async function performTypeCheck(path: string) {\n const tsconfigPath = join(path, 'tsconfig.json');\n\n if (!existsSync(tsconfigPath)) return;\n\n const ts = await loadTypeScript(TS_NOT_FOUND_ERR);\n\n // Format host for error reporting\n const formatHost = {\n getCanonicalFileName: (path: string) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n };\n\n // Read tsconfig.json\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.error(\n colors.red(\n `Error reading tsconfig.json: ${ts.formatDiagnostic(configFile.error, formatHost)}`,\n ),\n );\n process.exit(1);\n }\n\n // Parse the config file\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n path,\n );\n\n // Force noEmit to true as we only want type checking\n parsedConfig.options.noEmit = true;\n\n // Create a program\n const program = ts.createProgram({\n rootNames: parsedConfig.fileNames,\n options: parsedConfig.options,\n projectReferences: parsedConfig.projectReferences,\n });\n\n // Get the diagnostics\n const diagnostics = [\n ...program.getOptionsDiagnostics(),\n ...program.getGlobalDiagnostics(),\n ...program.getSyntacticDiagnostics(),\n ...program.getSemanticDiagnostics(),\n ];\n\n // Report any errors\n if (diagnostics.length > 0) {\n console.log('');\n console.error(\n colors.bold(\n colors.red('Type checking failed with the following errors:'),\n ),\n );\n console.log('');\n\n // Group diagnostics by file for better readability\n const byFile = new Map<string, import('typescript').Diagnostic[]>();\n\n for (const diagnostic of diagnostics) {\n const fileName = diagnostic.file ? diagnostic.file.fileName : 'Global';\n if (!byFile.has(fileName)) {\n byFile.set(fileName, []);\n }\n byFile.get(fileName)!.push(diagnostic);\n }\n\n // Pretty-print each diagnostic\n const totalErrors = diagnostics.length;\n let counter = 0;\n\n for (const [_, fileDiags] of byFile) {\n for (const diagnostic of fileDiags) {\n counter++;\n console.log(formatDiagnostic(ts, diagnostic, path));\n // Add separator between errors for better readability, except for the last one\n if (counter < totalErrors) {\n console.log('');\n }\n }\n }\n\n console.log('');\n console.error(\n colors.bold(\n colors.red(`Found ${totalErrors} error${totalErrors > 1 ? 's' : ''}`),\n ),\n );\n console.log('');\n\n process.exit(1);\n }\n\n console.log(colors.green('✓ Type checking completed successfully.'));\n}\n"],"mappings":";;;;;;;AAKA,MAAM,oBAAoB;;;;;;AAO1B,SAAS,iBACT,IACA,YACA,KACS;CACP,MAAM,cAAc,GAAG,6BACrB,WAAW,aACX,KACD;AAED,MAAK,WAAW,KACd,SAAQ,EAAE,8BAAO,IAAI,QAAQ,CAAC,IAAI,YAAY;CAGhD,MAAM,EAAE,MAAM,WAAW,GAAG,GAAG,8BAC7B,WAAW,MACX,WAAW,MACZ;CACD,MAAM,WAAW,wBAAS,KAAK,WAAW,KAAK,SAAS;CACxD,MAAM,YAAY,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE;CAC9C,MAAM,YAAY,WAAW,QAAQ,IAAI,WAAW,KAAK,IAAI;AAG7D,QAAO,EACN,EAAE,8BAAO,KAAK,8BAAO,KAAK,SAAS,CAAC,CAAC,GAAG,8BAAO,KAAK,8BAAO,OAAO,SAAS,CAAC,CAAC,KAAK,8BAAO,IAAI,QAAQ,CAAC,GAAG,8BAAO,KAAK,UAAU,CAAC,IAChI,EAAE,YAAY,CAAE,EACjB,KAAK,KAAK;AACZ;;;;;;;AAQA,eAAsB,iBAAiB,MAAc;CACnD,MAAM,eAAe,oBAAK,MAAM,gBAAgB;AAEhD,MAAK,wBAAW,aAAa,CAAE;CAE/B,MAAM,KAAK,MAAM,8BAAe,iBAAiB;CAGjD,MAAM,aAAa;EACjB,sBAAsB,CAAC,WAAiB;EACxC,qBAAqB,GAAG,IAAI;EAC5B,YAAY,MAAM,GAAG,IAAI;CAC1B;CAGD,MAAM,aAAa,GAAG,eAAe,cAAc,GAAG,IAAI,SAAS;AAEnE,KAAI,WAAW,OAAO;AACpB,UAAQ,MACN,8BAAO,KACJ,+BAA+B,GAAG,iBAAiB,WAAW,OAAO,WAAW,CAAC,EACnF,CACF;AACD,UAAQ,KAAK,EAAE;CACjB;CAGA,MAAM,eAAe,GAAG,2BACtB,WAAW,QACX,GAAG,KACH,KACD;AAGD,cAAa,QAAQ,SAAS;CAG9B,MAAM,UAAU,GAAG,cAAc;EAC/B,WAAW,aAAa;EACxB,SAAS,aAAa;EACtB,mBAAmB,aAAa;CACjC,EAAC;CAGF,MAAM,cAAc;EACpB,GAAG,QAAQ,uBAAuB;EAClC,GAAG,QAAQ,sBAAsB;EACjC,GAAG,QAAQ,yBAAyB;EACpC,GAAG,QAAQ,wBAAwB;CAAC;AAIpC,KAAI,YAAY,SAAS,GAAG;AAC1B,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,IAAI,kDAAkD,CAC9D,CACF;AACD,UAAQ,IAAI,GAAG;EAGf,MAAM,yBAAS,IAAI;AAEnB,OAAK,MAAM,cAAc,aAAa;GACpC,MAAM,WAAW,WAAW,OAAO,WAAW,KAAK,WAAW;AAC9D,QAAK,OAAO,IAAI,SAAS,CACvB,QAAO,IAAI,UAAU,CAAE,EAAC;AAE1B,UAAO,IAAI,SAAS,CAAE,KAAK,WAAW;EACxC;EAGA,MAAM,cAAc,YAAY;EAChC,IAAI,UAAU;AAEd,OAAK,MAAM,CAAC,GAAG,UAAU,IAAI,OAC3B,MAAK,MAAM,cAAc,WAAW;AAClC;AACA,WAAQ,IAAI,iBAAiB,IAAI,YAAY,KAAK,CAAC;AAEnD,OAAI,UAAU,YACZ,SAAQ,IAAI,GAAG;EAEnB;AAGF,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,KAAK,QAAQ,YAAY,QAAQ,cAAc,IAAI,MAAM,GAAG,EAAE,CACtE,CACF;AACD,UAAQ,IAAI,GAAG;AAEf,UAAQ,KAAK,EAAE;CACjB;AAEA,SAAQ,IAAI,8BAAO,MAAM,0CAA0C,CAAC;AACtE"}
|
package/dist/utils/colors.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as picocolors_types6 from "picocolors/types";
|
|
2
2
|
|
|
3
3
|
//#region src/utils/colors.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: picocolors_types6.Colors;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
7
7
|
//# sourceMappingURL=colors.d.ts.map
|