@ank1015/llm-sdk-adapters 0.0.1
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/file-keys.d.ts +68 -0
- package/dist/file-keys.d.ts.map +1 -0
- package/dist/file-keys.js +243 -0
- package/dist/file-keys.js.map +1 -0
- package/dist/file-sessions.d.ts +55 -0
- package/dist/file-sessions.d.ts.map +1 -0
- package/dist/file-sessions.js +376 -0
- package/dist/file-sessions.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/keys-ui.d.ts +30 -0
- package/dist/keys-ui.d.ts.map +1 -0
- package/dist/keys-ui.js +603 -0
- package/dist/keys-ui.js.map +1 -0
- package/dist/memory-keys.d.ts +20 -0
- package/dist/memory-keys.d.ts.map +1 -0
- package/dist/memory-keys.js +57 -0
- package/dist/memory-keys.js.map +1 -0
- package/dist/memory-sessions.d.ts +34 -0
- package/dist/memory-sessions.d.ts.map +1 -0
- package/dist/memory-sessions.js +236 -0
- package/dist/memory-sessions.js.map +1 -0
- package/dist/memory-usage.d.ts +18 -0
- package/dist/memory-usage.d.ts.map +1 -0
- package/dist/memory-usage.js +123 -0
- package/dist/memory-usage.js.map +1 -0
- package/dist/sqlite-usage.d.ts +36 -0
- package/dist/sqlite-usage.d.ts.map +1 -0
- package/dist/sqlite-usage.js +344 -0
- package/dist/sqlite-usage.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based Keys Adapter
|
|
3
|
+
*
|
|
4
|
+
* Stores encrypted API keys in ~/.llm/global/keys/
|
|
5
|
+
* Uses AES-256-GCM encryption with machine-specific key derivation.
|
|
6
|
+
*/
|
|
7
|
+
import type { KeysAdapter, Api } from '@ank1015/llm-types';
|
|
8
|
+
/**
|
|
9
|
+
* File-based implementation of KeysAdapter.
|
|
10
|
+
* Stores encrypted API keys in the filesystem.
|
|
11
|
+
*/
|
|
12
|
+
export declare class FileKeysAdapter implements KeysAdapter {
|
|
13
|
+
private keysDir;
|
|
14
|
+
private saltFile;
|
|
15
|
+
constructor(keysDir?: string);
|
|
16
|
+
/**
|
|
17
|
+
* Ensure the keys directory exists.
|
|
18
|
+
*/
|
|
19
|
+
private ensureKeysDir;
|
|
20
|
+
/**
|
|
21
|
+
* Get or create the encryption salt.
|
|
22
|
+
*/
|
|
23
|
+
private getSalt;
|
|
24
|
+
/**
|
|
25
|
+
* Derive encryption key from machine-specific data.
|
|
26
|
+
*/
|
|
27
|
+
private deriveKey;
|
|
28
|
+
/**
|
|
29
|
+
* Encrypt a string value.
|
|
30
|
+
*/
|
|
31
|
+
private encrypt;
|
|
32
|
+
/**
|
|
33
|
+
* Decrypt a string value.
|
|
34
|
+
*/
|
|
35
|
+
private decrypt;
|
|
36
|
+
/**
|
|
37
|
+
* Get the file path for a provider's key.
|
|
38
|
+
*/
|
|
39
|
+
private getKeyPath;
|
|
40
|
+
/**
|
|
41
|
+
* Get the file path for a provider's credential bundle.
|
|
42
|
+
*/
|
|
43
|
+
private getCredentialsPath;
|
|
44
|
+
/**
|
|
45
|
+
* Read an encrypted string file and decrypt it.
|
|
46
|
+
*/
|
|
47
|
+
private readDecryptedFile;
|
|
48
|
+
/**
|
|
49
|
+
* Write encrypted string data to disk.
|
|
50
|
+
*/
|
|
51
|
+
private writeEncryptedFile;
|
|
52
|
+
get(api: Api): Promise<string | undefined>;
|
|
53
|
+
getCredentials(api: Api): Promise<Record<string, string> | undefined>;
|
|
54
|
+
set(api: Api, key: string): Promise<void>;
|
|
55
|
+
setCredentials(api: Api, credentials: Record<string, string>): Promise<void>;
|
|
56
|
+
delete(api: Api): Promise<boolean>;
|
|
57
|
+
deleteCredentials(api: Api): Promise<boolean>;
|
|
58
|
+
list(): Promise<Api[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Get the keys directory path.
|
|
61
|
+
*/
|
|
62
|
+
getKeysDir(): string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a FileKeysAdapter with the default directory.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createFileKeysAdapter(keysDir?: string): FileKeysAdapter;
|
|
68
|
+
//# sourceMappingURL=file-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-keys.d.ts","sourceRoot":"","sources":["../src/file-keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAuC3D;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,GAAE,MAAyB;IAK9C;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,OAAO;IAUf;;OAEG;IACH,OAAO,CAAC,SAAS;IAMjB;;OAEG;IACH,OAAO,CAAC,OAAO;IAcf;;OAEG;IACH,OAAO,CAAC,OAAO;IAqBf;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAMpB,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAY1C,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IA0BrE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5E,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBlC,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7C,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAa5B;;OAEG;IACH,UAAU,IAAI,MAAM;CAGrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe,CAEvE"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based Keys Adapter
|
|
3
|
+
*
|
|
4
|
+
* Stores encrypted API keys in ~/.llm/global/keys/
|
|
5
|
+
* Uses AES-256-GCM encryption with machine-specific key derivation.
|
|
6
|
+
*/
|
|
7
|
+
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'node:crypto';
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { KnownApis, PathTraversalError } from '@ank1015/llm-types';
|
|
12
|
+
/** Directory for storing encrypted keys */
|
|
13
|
+
const DEFAULT_KEYS_DIR = join(homedir(), '.llm', 'global', 'keys');
|
|
14
|
+
/** Encryption algorithm */
|
|
15
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
16
|
+
function normalizeCredentials(api, credentials) {
|
|
17
|
+
const normalized = { ...credentials };
|
|
18
|
+
if (api === 'codex') {
|
|
19
|
+
const accountId = normalized['chatgpt-account-id'] ??
|
|
20
|
+
normalized.chatgptAccountId ??
|
|
21
|
+
normalized.accountId ??
|
|
22
|
+
normalized.account_id;
|
|
23
|
+
if (accountId) {
|
|
24
|
+
normalized['chatgpt-account-id'] = accountId;
|
|
25
|
+
}
|
|
26
|
+
const apiKey = normalized.apiKey ?? normalized.access_token ?? normalized.accessToken;
|
|
27
|
+
if (apiKey) {
|
|
28
|
+
normalized.apiKey = apiKey;
|
|
29
|
+
}
|
|
30
|
+
delete normalized.chatgptAccountId;
|
|
31
|
+
delete normalized.accountId;
|
|
32
|
+
delete normalized.account_id;
|
|
33
|
+
delete normalized.access_token;
|
|
34
|
+
delete normalized.accessToken;
|
|
35
|
+
}
|
|
36
|
+
return normalized;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* File-based implementation of KeysAdapter.
|
|
40
|
+
* Stores encrypted API keys in the filesystem.
|
|
41
|
+
*/
|
|
42
|
+
export class FileKeysAdapter {
|
|
43
|
+
keysDir;
|
|
44
|
+
saltFile;
|
|
45
|
+
constructor(keysDir = DEFAULT_KEYS_DIR) {
|
|
46
|
+
this.keysDir = keysDir;
|
|
47
|
+
this.saltFile = join(keysDir, '.salt');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Ensure the keys directory exists.
|
|
51
|
+
*/
|
|
52
|
+
ensureKeysDir() {
|
|
53
|
+
if (!existsSync(this.keysDir)) {
|
|
54
|
+
mkdirSync(this.keysDir, { recursive: true });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get or create the encryption salt.
|
|
59
|
+
*/
|
|
60
|
+
getSalt() {
|
|
61
|
+
this.ensureKeysDir();
|
|
62
|
+
if (existsSync(this.saltFile)) {
|
|
63
|
+
return readFileSync(this.saltFile);
|
|
64
|
+
}
|
|
65
|
+
const salt = randomBytes(32);
|
|
66
|
+
writeFileSync(this.saltFile, salt);
|
|
67
|
+
return salt;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Derive encryption key from machine-specific data.
|
|
71
|
+
*/
|
|
72
|
+
deriveKey() {
|
|
73
|
+
const salt = this.getSalt();
|
|
74
|
+
const machineId = `${homedir()}-llm-keys`;
|
|
75
|
+
return scryptSync(machineId, salt, 32);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Encrypt a string value.
|
|
79
|
+
*/
|
|
80
|
+
encrypt(plaintext) {
|
|
81
|
+
const key = this.deriveKey();
|
|
82
|
+
const iv = randomBytes(16);
|
|
83
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
84
|
+
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
85
|
+
encrypted += cipher.final('hex');
|
|
86
|
+
const authTag = cipher.getAuthTag();
|
|
87
|
+
// Format: iv:authTag:encrypted
|
|
88
|
+
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Decrypt a string value.
|
|
92
|
+
*/
|
|
93
|
+
decrypt(ciphertext) {
|
|
94
|
+
const key = this.deriveKey();
|
|
95
|
+
const parts = ciphertext.split(':');
|
|
96
|
+
if (parts.length !== 3) {
|
|
97
|
+
throw new Error('Invalid encrypted data format');
|
|
98
|
+
}
|
|
99
|
+
const [ivHex, authTagHex, encrypted] = parts;
|
|
100
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
101
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
102
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
103
|
+
decipher.setAuthTag(authTag);
|
|
104
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
105
|
+
decrypted += decipher.final('utf8');
|
|
106
|
+
return decrypted;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the file path for a provider's key.
|
|
110
|
+
*/
|
|
111
|
+
getKeyPath(api) {
|
|
112
|
+
const apiStr = String(api);
|
|
113
|
+
if (apiStr.includes('..') || apiStr.includes('/') || apiStr.includes('\\')) {
|
|
114
|
+
throw new PathTraversalError(apiStr);
|
|
115
|
+
}
|
|
116
|
+
return join(this.keysDir, `${apiStr}.key`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the file path for a provider's credential bundle.
|
|
120
|
+
*/
|
|
121
|
+
getCredentialsPath(api) {
|
|
122
|
+
const apiStr = String(api);
|
|
123
|
+
if (apiStr.includes('..') || apiStr.includes('/') || apiStr.includes('\\')) {
|
|
124
|
+
throw new PathTraversalError(apiStr);
|
|
125
|
+
}
|
|
126
|
+
return join(this.keysDir, `${apiStr}.credentials`);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Read an encrypted string file and decrypt it.
|
|
130
|
+
*/
|
|
131
|
+
readDecryptedFile(path) {
|
|
132
|
+
if (!existsSync(path))
|
|
133
|
+
return undefined;
|
|
134
|
+
try {
|
|
135
|
+
const encrypted = readFileSync(path, 'utf8');
|
|
136
|
+
return this.decrypt(encrypted);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Write encrypted string data to disk.
|
|
144
|
+
*/
|
|
145
|
+
writeEncryptedFile(path, plaintext) {
|
|
146
|
+
this.ensureKeysDir();
|
|
147
|
+
const encrypted = this.encrypt(plaintext);
|
|
148
|
+
writeFileSync(path, encrypted, 'utf8');
|
|
149
|
+
}
|
|
150
|
+
async get(api) {
|
|
151
|
+
// Prefer apiKey from credentials bundle when present.
|
|
152
|
+
const credentials = await this.getCredentials(api);
|
|
153
|
+
const bundledApiKey = credentials?.apiKey;
|
|
154
|
+
if (bundledApiKey) {
|
|
155
|
+
return bundledApiKey;
|
|
156
|
+
}
|
|
157
|
+
// Fallback to legacy single-key storage.
|
|
158
|
+
return this.readDecryptedFile(this.getKeyPath(api));
|
|
159
|
+
}
|
|
160
|
+
async getCredentials(api) {
|
|
161
|
+
const credentialsRaw = this.readDecryptedFile(this.getCredentialsPath(api));
|
|
162
|
+
if (credentialsRaw) {
|
|
163
|
+
try {
|
|
164
|
+
const parsed = JSON.parse(credentialsRaw);
|
|
165
|
+
if (!parsed || typeof parsed !== 'object')
|
|
166
|
+
return undefined;
|
|
167
|
+
const credentials = {};
|
|
168
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
169
|
+
if (typeof value === 'string' && value) {
|
|
170
|
+
credentials[key] = value;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const normalized = normalizeCredentials(api, credentials);
|
|
174
|
+
return Object.keys(normalized).length > 0 ? normalized : undefined;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Corrupted credentials bundle
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Backwards-compatible fallback for legacy single-key storage.
|
|
182
|
+
const apiKey = this.readDecryptedFile(this.getKeyPath(api));
|
|
183
|
+
if (!apiKey)
|
|
184
|
+
return undefined;
|
|
185
|
+
return { apiKey };
|
|
186
|
+
}
|
|
187
|
+
async set(api, key) {
|
|
188
|
+
// Keep legacy path for compatibility with existing consumers/tools.
|
|
189
|
+
this.writeEncryptedFile(this.getKeyPath(api), key);
|
|
190
|
+
// Keep credentials bundle in sync when present.
|
|
191
|
+
const existing = (await this.getCredentials(api)) ?? {};
|
|
192
|
+
const updated = { ...existing, apiKey: key };
|
|
193
|
+
this.writeEncryptedFile(this.getCredentialsPath(api), JSON.stringify(updated));
|
|
194
|
+
}
|
|
195
|
+
async setCredentials(api, credentials) {
|
|
196
|
+
const normalized = normalizeCredentials(api, credentials);
|
|
197
|
+
this.writeEncryptedFile(this.getCredentialsPath(api), JSON.stringify(normalized));
|
|
198
|
+
// Keep legacy single-key path in sync when apiKey is provided.
|
|
199
|
+
if (normalized.apiKey !== undefined) {
|
|
200
|
+
this.writeEncryptedFile(this.getKeyPath(api), normalized.apiKey);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async delete(api) {
|
|
204
|
+
const keyPath = this.getKeyPath(api);
|
|
205
|
+
const credentialsPath = this.getCredentialsPath(api);
|
|
206
|
+
let deleted = false;
|
|
207
|
+
if (existsSync(keyPath)) {
|
|
208
|
+
unlinkSync(keyPath);
|
|
209
|
+
deleted = true;
|
|
210
|
+
}
|
|
211
|
+
if (existsSync(credentialsPath)) {
|
|
212
|
+
unlinkSync(credentialsPath);
|
|
213
|
+
deleted = true;
|
|
214
|
+
}
|
|
215
|
+
return deleted;
|
|
216
|
+
}
|
|
217
|
+
async deleteCredentials(api) {
|
|
218
|
+
return this.delete(api);
|
|
219
|
+
}
|
|
220
|
+
async list() {
|
|
221
|
+
this.ensureKeysDir();
|
|
222
|
+
const providers = [];
|
|
223
|
+
for (const api of KnownApis) {
|
|
224
|
+
if (existsSync(this.getKeyPath(api)) || existsSync(this.getCredentialsPath(api))) {
|
|
225
|
+
providers.push(api);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return providers;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get the keys directory path.
|
|
232
|
+
*/
|
|
233
|
+
getKeysDir() {
|
|
234
|
+
return this.keysDir;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create a FileKeysAdapter with the default directory.
|
|
239
|
+
*/
|
|
240
|
+
export function createFileKeysAdapter(keysDir) {
|
|
241
|
+
return new FileKeysAdapter(keysDir);
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=file-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-keys.js","sourceRoot":"","sources":["../src/file-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based Sessions Adapter
|
|
3
|
+
*
|
|
4
|
+
* Stores sessions as JSONL files in ~/.llm/sessions/<projectName>/<path>/<sessionId>.jsonl
|
|
5
|
+
* Sessions are tree structures with branching support.
|
|
6
|
+
*/
|
|
7
|
+
import type { AppendCustomInput, AppendMessageInput, CreateSessionInput, SessionLocation, SessionsAdapter, BranchInfo, CustomNode, MessageNode, Session, SessionHeader, SessionNode, SessionSummary } from '@ank1015/llm-types';
|
|
8
|
+
/**
|
|
9
|
+
* File-based implementation of SessionsAdapter.
|
|
10
|
+
*/
|
|
11
|
+
export declare class FileSessionsAdapter implements SessionsAdapter {
|
|
12
|
+
private baseDir;
|
|
13
|
+
constructor(baseDir?: string);
|
|
14
|
+
/**
|
|
15
|
+
* Get the full directory path for a project/path combination.
|
|
16
|
+
*/
|
|
17
|
+
private getSessionDir;
|
|
18
|
+
/**
|
|
19
|
+
* Get the full file path for a session.
|
|
20
|
+
*/
|
|
21
|
+
private getSessionFilePath;
|
|
22
|
+
/**
|
|
23
|
+
* Ensure a directory exists.
|
|
24
|
+
*/
|
|
25
|
+
private ensureDir;
|
|
26
|
+
createSession(input: CreateSessionInput): Promise<{
|
|
27
|
+
sessionId: string;
|
|
28
|
+
header: SessionHeader;
|
|
29
|
+
}>;
|
|
30
|
+
getSession(location: SessionLocation): Promise<Session | undefined>;
|
|
31
|
+
deleteSession(location: SessionLocation): Promise<boolean>;
|
|
32
|
+
updateSessionName(location: SessionLocation, sessionName: string): Promise<SessionHeader | undefined>;
|
|
33
|
+
listSessions(projectName: string, path?: string): Promise<SessionSummary[]>;
|
|
34
|
+
listProjects(): Promise<string[]>;
|
|
35
|
+
appendMessage(input: AppendMessageInput): Promise<{
|
|
36
|
+
sessionId: string;
|
|
37
|
+
node: MessageNode;
|
|
38
|
+
}>;
|
|
39
|
+
appendCustom(input: AppendCustomInput): Promise<CustomNode | undefined>;
|
|
40
|
+
getBranches(location: SessionLocation): Promise<BranchInfo[] | undefined>;
|
|
41
|
+
getBranchHistory(location: SessionLocation, branch: string): Promise<SessionNode[] | undefined>;
|
|
42
|
+
getNode(location: SessionLocation, nodeId: string): Promise<SessionNode | undefined>;
|
|
43
|
+
getLatestNode(location: SessionLocation, branch?: string): Promise<SessionNode | undefined>;
|
|
44
|
+
getMessages(location: SessionLocation, branch?: string): Promise<MessageNode[] | undefined>;
|
|
45
|
+
searchSessions(projectName: string, query: string, path?: string): Promise<SessionSummary[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the base directory for sessions.
|
|
48
|
+
*/
|
|
49
|
+
getSessionsBaseDir(): string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a FileSessionsAdapter with the default base directory.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createFileSessionsAdapter(baseDir?: string): FileSessionsAdapter;
|
|
55
|
+
//# sourceMappingURL=file-sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-sessions.d.ts","sourceRoot":"","sources":["../src/file-sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,EACX,OAAO,EACP,aAAa,EACb,WAAW,EACX,cAAc,EACf,MAAM,oBAAoB,CAAC;AAwD5B;;GAEG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAkC;IAIvD;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,SAAS;IAMX,aAAa,CACjB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,CAAC;IAsBlD,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IA0BnE,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAY1D,iBAAiB,CACrB,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IA4B/B,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgD/E,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAUjC,aAAa,CACjB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAsD9C,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IA4BvE,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC;IA+CzE,gBAAgB,CACpB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAuC/B,OAAO,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAUpF,aAAa,CACjB,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAe7B,WAAW,CACf,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAgB/B,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,MAAW,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC;IAO5B;;OAEG;IACH,kBAAkB,IAAI,MAAM;CAG7B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAE/E"}
|