@copypatch/storage-sqlite 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Efe Arabacı
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @copypatch/storage-sqlite
2
+
3
+ SQLite persistence for CopyPatch v2. The adapter implements the asynchronous
4
+ `CopyPatchPersistence` contract while using transactional, synchronous SQLite
5
+ operations internally.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @copypatch/core @copypatch/storage-sqlite better-sqlite3
11
+ ```
12
+
13
+ Node.js 20 or newer is required.
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createSQLitePersistence } from '@copypatch/storage-sqlite';
19
+
20
+ const persistence = createSQLitePersistence('./data/copypatch.sqlite');
21
+ await persistence.migrate();
22
+
23
+ try {
24
+ const snapshot = await persistence.readPublished('en');
25
+ console.log(snapshot);
26
+ } finally {
27
+ persistence.close();
28
+ }
29
+ ```
30
+
31
+ The factory also accepts `{ filename, busyTimeoutMs }`. Call `migrate()` before
32
+ the first operation on a new database. Migrations are versioned and idempotent.
33
+
34
+ Content mutations use atomic compare-and-swap checks against both published
35
+ and draft revisions. Sessions and rate limits are stored in SQLite so they
36
+ survive process restarts. Session callers must pass cryptographic token hashes;
37
+ the adapter never accepts or derives raw session tokens.
38
+
39
+ ## Exports
40
+
41
+ - `createSQLitePersistence(filenameOrOptions)`
42
+ - `SQLitePersistence`
43
+ - `SQLitePersistenceOptions`
44
+
45
+ CopyPatch is ESM-only. See the
46
+ [CopyPatch repository](https://github.com/Woffluon/CopyPatch) for complete API
47
+ documentation and examples.
@@ -0,0 +1,35 @@
1
+ import type { CopyPatchPersistence, DiscardDraftsCommand, DiscardDraftsResult, EditorSnapshot, PersistenceHealth, PersistenceMutationResult, PublishDraftsCommand, PublishDraftsResult, RateLimitDecision, RateLimitInput, SaveDraftsCommand, SaveDraftsResult, SessionTouch, StoredSession } from '@copypatch/core';
2
+ export interface SQLitePersistenceOptions {
3
+ filename: string;
4
+ busyTimeoutMs?: number;
5
+ }
6
+ export declare class SQLitePersistence implements CopyPatchPersistence {
7
+ private readonly sqlite;
8
+ private closed;
9
+ constructor(filenameOrOptions: string | SQLitePersistenceOptions);
10
+ migrate(): Promise<void>;
11
+ health(): Promise<PersistenceHealth>;
12
+ readPublished(locale: string): Promise<{
13
+ revision: number;
14
+ content: Record<string, string>;
15
+ }>;
16
+ readEditor(locale: string): Promise<EditorSnapshot>;
17
+ saveDrafts(command: SaveDraftsCommand): Promise<PersistenceMutationResult<SaveDraftsResult>>;
18
+ publishDrafts(command: PublishDraftsCommand): Promise<PersistenceMutationResult<PublishDraftsResult>>;
19
+ discardDrafts(command: DiscardDraftsCommand): Promise<PersistenceMutationResult<DiscardDraftsResult>>;
20
+ createSession(session: StoredSession): Promise<void>;
21
+ readSession(tokenHash: string): Promise<StoredSession | null>;
22
+ touchSession(tokenHash: string, update: SessionTouch): Promise<StoredSession | null>;
23
+ deleteSession(tokenHash: string): Promise<void>;
24
+ consumeRateLimit(input: RateLimitInput): Promise<RateLimitDecision>;
25
+ close(): void;
26
+ private editorSnapshot;
27
+ private readState;
28
+ private writeState;
29
+ private revisionsMatch;
30
+ private sessionFromRow;
31
+ private positiveInteger;
32
+ private assertOpen;
33
+ }
34
+ export declare function createSQLitePersistence(filenameOrOptions: string | SQLitePersistenceOptions): SQLitePersistence;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC;AAKzB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA6BD,qBAAa,iBAAkB,YAAW,oBAAoB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,iBAAiB,EAAE,MAAM,GAAG,wBAAwB;IAqB1D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDxB,MAAM,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAcpC,aAAa,CAAC,MAAM,EAAE,MAAM;;;;IAkB5B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAKnD,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;IAwB5F,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,yBAAyB,CAAC,mBAAmB,CAAC,CAAC;IA2BrG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,yBAAyB,CAAC,mBAAmB,CAAC,CAAC;IAyBrG,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBpD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAW7D,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAiBpF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0BzE,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,UAAU;CAGnB;AAED,wBAAgB,uBAAuB,CACrC,iBAAiB,EAAE,MAAM,GAAG,wBAAwB,GACnD,iBAAiB,CAEnB"}
package/dist/index.js ADDED
@@ -0,0 +1,337 @@
1
+ import Database from 'better-sqlite3';
2
+ import { chmodSync, existsSync, mkdirSync } from 'node:fs';
3
+ import { dirname, resolve } from 'node:path';
4
+ const SCHEMA_VERSION = 1;
5
+ const SHA256_HEX = /^[a-f0-9]{64}$/;
6
+ export class SQLitePersistence {
7
+ sqlite;
8
+ closed = false;
9
+ constructor(filenameOrOptions) {
10
+ const options = typeof filenameOrOptions === 'string'
11
+ ? { filename: filenameOrOptions }
12
+ : filenameOrOptions;
13
+ if (!options.filename)
14
+ throw new TypeError('A SQLite filename is required.');
15
+ const filename = resolve(options.filename);
16
+ const directory = dirname(filename);
17
+ if (!existsSync(directory))
18
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
19
+ this.sqlite = new Database(filename);
20
+ this.sqlite.pragma(`busy_timeout = ${this.positiveInteger(options.busyTimeoutMs ?? 5_000, 'busyTimeoutMs')}`);
21
+ this.sqlite.pragma('journal_mode = WAL');
22
+ this.sqlite.pragma('synchronous = NORMAL');
23
+ this.sqlite.pragma('foreign_keys = ON');
24
+ try {
25
+ chmodSync(filename, 0o600);
26
+ }
27
+ catch {
28
+ // Windows and some mounted filesystems do not expose POSIX file modes.
29
+ }
30
+ }
31
+ async migrate() {
32
+ this.assertOpen();
33
+ const current = this.sqlite.pragma('user_version', { simple: true });
34
+ if (current > SCHEMA_VERSION) {
35
+ throw new Error(`SQLite schema version ${current} is newer than supported version ${SCHEMA_VERSION}.`);
36
+ }
37
+ if (current === SCHEMA_VERSION)
38
+ return;
39
+ const managedTables = this.sqlite.prepare(`
40
+ SELECT name FROM sqlite_master
41
+ WHERE type = 'table' AND name IN ('content_state', 'content_entries', 'sessions', 'rate_limits')
42
+ `).pluck().all();
43
+ if (managedTables.length > 0) {
44
+ throw new Error('An unversioned or CopyPatch v1 database was detected. CopyPatch v1 data migration is not supported; configure a new v2 database.');
45
+ }
46
+ this.sqlite.transaction(() => {
47
+ this.sqlite.exec(`
48
+ CREATE TABLE IF NOT EXISTS content_state (
49
+ locale TEXT PRIMARY KEY,
50
+ published_revision INTEGER NOT NULL CHECK (published_revision >= 1),
51
+ draft_revision INTEGER NOT NULL CHECK (draft_revision >= 1)
52
+ );
53
+
54
+ CREATE TABLE IF NOT EXISTS content_entries (
55
+ locale TEXT NOT NULL,
56
+ content_key TEXT NOT NULL,
57
+ published_text TEXT,
58
+ draft_text TEXT,
59
+ PRIMARY KEY (locale, content_key)
60
+ ) WITHOUT ROWID;
61
+
62
+ CREATE TABLE IF NOT EXISTS sessions (
63
+ token_hash TEXT PRIMARY KEY,
64
+ csrf_token_hash TEXT NOT NULL,
65
+ subject TEXT NOT NULL,
66
+ roles_json TEXT NOT NULL,
67
+ created_at INTEGER NOT NULL,
68
+ last_seen_at INTEGER NOT NULL,
69
+ idle_expires_at INTEGER NOT NULL,
70
+ absolute_expires_at INTEGER NOT NULL
71
+ ) WITHOUT ROWID;
72
+
73
+ CREATE TABLE IF NOT EXISTS rate_limits (
74
+ key_hash TEXT PRIMARY KEY,
75
+ count INTEGER NOT NULL CHECK (count >= 1),
76
+ reset_at INTEGER NOT NULL
77
+ ) WITHOUT ROWID;
78
+
79
+ PRAGMA user_version = 1;
80
+ `);
81
+ }).immediate();
82
+ }
83
+ async health() {
84
+ try {
85
+ this.assertOpen();
86
+ const version = this.sqlite.pragma('user_version', { simple: true });
87
+ if (version !== SCHEMA_VERSION) {
88
+ return { ok: false, message: `SQLite schema version is ${version}; expected ${SCHEMA_VERSION}.` };
89
+ }
90
+ this.sqlite.prepare('SELECT 1 FROM content_state LIMIT 1').get();
91
+ return { ok: true };
92
+ }
93
+ catch (error) {
94
+ return { ok: false, message: error instanceof Error ? error.message : 'SQLite health check failed.' };
95
+ }
96
+ }
97
+ async readPublished(locale) {
98
+ this.assertOpen();
99
+ return this.sqlite.transaction((value) => {
100
+ const state = this.readState(value);
101
+ const rows = this.sqlite.prepare(`
102
+ SELECT content_key, published_text, draft_text
103
+ FROM content_entries
104
+ WHERE locale = ? AND published_text IS NOT NULL
105
+ ORDER BY content_key
106
+ `).all(value);
107
+ const content = {};
108
+ for (const row of rows) {
109
+ if (row.published_text !== null)
110
+ content[row.content_key] = row.published_text;
111
+ }
112
+ return { revision: state.publishedRevision, content };
113
+ }).deferred(locale);
114
+ }
115
+ async readEditor(locale) {
116
+ this.assertOpen();
117
+ return this.sqlite.transaction((value) => this.editorSnapshot(value)).deferred(locale);
118
+ }
119
+ async saveDrafts(command) {
120
+ this.assertOpen();
121
+ return this.sqlite.transaction((input) => {
122
+ const current = this.editorSnapshot(input.locale);
123
+ if (!this.revisionsMatch(current, input.expectedPublishedRevision, input.expectedDraftRevision)) {
124
+ return { status: 'conflict', latest: current };
125
+ }
126
+ const write = this.sqlite.prepare(`
127
+ INSERT INTO content_entries (locale, content_key, published_text, draft_text)
128
+ VALUES (?, ?, NULL, ?)
129
+ ON CONFLICT (locale, content_key) DO UPDATE SET draft_text = excluded.draft_text
130
+ `);
131
+ for (const change of input.changes)
132
+ write.run(input.locale, change.key, change.text);
133
+ const draftRevision = current.draftRevision + 1;
134
+ this.writeState(input.locale, current.publishedRevision, draftRevision);
135
+ return {
136
+ status: 'ok',
137
+ value: { publishedRevision: current.publishedRevision, draftRevision },
138
+ };
139
+ }).immediate(command);
140
+ }
141
+ async publishDrafts(command) {
142
+ this.assertOpen();
143
+ return this.sqlite.transaction((input) => {
144
+ const current = this.editorSnapshot(input.locale);
145
+ if (!this.revisionsMatch(current, input.expectedPublishedRevision, input.expectedDraftRevision)) {
146
+ return { status: 'conflict', latest: current };
147
+ }
148
+ const promotedCount = this.sqlite.prepare(`
149
+ SELECT count(*) FROM content_entries WHERE locale = ? AND draft_text IS NOT NULL
150
+ `).pluck().get(input.locale);
151
+ this.sqlite.prepare(`
152
+ UPDATE content_entries
153
+ SET published_text = draft_text, draft_text = NULL
154
+ WHERE locale = ? AND draft_text IS NOT NULL
155
+ `).run(input.locale);
156
+ const publishedRevision = current.publishedRevision + 1;
157
+ const draftRevision = current.draftRevision + 1;
158
+ this.writeState(input.locale, publishedRevision, draftRevision);
159
+ return {
160
+ status: 'ok',
161
+ value: { publishedRevision, draftRevision, promotedCount },
162
+ };
163
+ }).immediate(command);
164
+ }
165
+ async discardDrafts(command) {
166
+ this.assertOpen();
167
+ return this.sqlite.transaction((input) => {
168
+ const current = this.editorSnapshot(input.locale);
169
+ if (!this.revisionsMatch(current, input.expectedPublishedRevision, input.expectedDraftRevision)) {
170
+ return { status: 'conflict', latest: current };
171
+ }
172
+ const discardedCount = this.sqlite.prepare(`
173
+ SELECT count(*) FROM content_entries WHERE locale = ? AND draft_text IS NOT NULL
174
+ `).pluck().get(input.locale);
175
+ this.sqlite.prepare(`
176
+ UPDATE content_entries SET draft_text = NULL
177
+ WHERE locale = ? AND draft_text IS NOT NULL
178
+ `).run(input.locale);
179
+ const draftRevision = current.draftRevision + 1;
180
+ this.writeState(input.locale, current.publishedRevision, draftRevision);
181
+ return {
182
+ status: 'ok',
183
+ value: { publishedRevision: current.publishedRevision, draftRevision, discardedCount },
184
+ };
185
+ }).immediate(command);
186
+ }
187
+ async createSession(session) {
188
+ this.assertOpen();
189
+ assertHash('tokenHash', session.tokenHash);
190
+ assertHash('csrfTokenHash', session.csrfTokenHash);
191
+ this.sqlite.prepare(`
192
+ INSERT INTO sessions (
193
+ token_hash, csrf_token_hash, subject, roles_json, created_at,
194
+ last_seen_at, idle_expires_at, absolute_expires_at
195
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
196
+ `).run(session.tokenHash, session.csrfTokenHash, session.subject, JSON.stringify(session.roles), session.createdAt, session.lastSeenAt, session.idleExpiresAt, session.absoluteExpiresAt);
197
+ }
198
+ async readSession(tokenHash) {
199
+ this.assertOpen();
200
+ assertHash('tokenHash', tokenHash);
201
+ const row = this.sqlite.prepare(`
202
+ SELECT token_hash, csrf_token_hash, subject, roles_json, created_at,
203
+ last_seen_at, idle_expires_at, absolute_expires_at
204
+ FROM sessions WHERE token_hash = ?
205
+ `).get(tokenHash);
206
+ return row ? this.sessionFromRow(row) : null;
207
+ }
208
+ async touchSession(tokenHash, update) {
209
+ this.assertOpen();
210
+ assertHash('tokenHash', tokenHash);
211
+ if (update.csrfTokenHash !== undefined)
212
+ assertHash('csrfTokenHash', update.csrfTokenHash);
213
+ const result = update.csrfTokenHash === undefined
214
+ ? this.sqlite.prepare(`
215
+ UPDATE sessions SET last_seen_at = ?, idle_expires_at = ? WHERE token_hash = ?
216
+ `).run(update.lastSeenAt, update.idleExpiresAt, tokenHash)
217
+ : this.sqlite.prepare(`
218
+ UPDATE sessions
219
+ SET last_seen_at = ?, idle_expires_at = ?, csrf_token_hash = ?
220
+ WHERE token_hash = ?
221
+ `).run(update.lastSeenAt, update.idleExpiresAt, update.csrfTokenHash, tokenHash);
222
+ if (result.changes === 0)
223
+ return null;
224
+ return this.readSession(tokenHash);
225
+ }
226
+ async deleteSession(tokenHash) {
227
+ this.assertOpen();
228
+ assertHash('tokenHash', tokenHash);
229
+ this.sqlite.prepare('DELETE FROM sessions WHERE token_hash = ?').run(tokenHash);
230
+ }
231
+ async consumeRateLimit(input) {
232
+ this.assertOpen();
233
+ assertHash('keyHash', input.keyHash);
234
+ this.positiveInteger(input.limit, 'limit');
235
+ this.positiveInteger(input.windowMs, 'windowMs');
236
+ if (!Number.isSafeInteger(input.now))
237
+ throw new TypeError('now must be a safe integer.');
238
+ return this.sqlite.transaction((value) => {
239
+ const current = this.sqlite.prepare(`
240
+ SELECT count, reset_at FROM rate_limits WHERE key_hash = ?
241
+ `).get(value.keyHash);
242
+ const reset = current === undefined || current.reset_at <= value.now;
243
+ const count = reset ? 1 : current.count + 1;
244
+ const resetAt = reset ? value.now + value.windowMs : current.reset_at;
245
+ this.sqlite.prepare(`
246
+ INSERT INTO rate_limits (key_hash, count, reset_at) VALUES (?, ?, ?)
247
+ ON CONFLICT (key_hash) DO UPDATE SET count = excluded.count, reset_at = excluded.reset_at
248
+ `).run(value.keyHash, count, resetAt);
249
+ return {
250
+ allowed: count <= value.limit,
251
+ remaining: Math.max(0, value.limit - count),
252
+ resetAt,
253
+ };
254
+ }).immediate(input);
255
+ }
256
+ close() {
257
+ if (this.closed)
258
+ return;
259
+ this.sqlite.close();
260
+ this.closed = true;
261
+ }
262
+ editorSnapshot(locale) {
263
+ const state = this.readState(locale);
264
+ const rows = this.sqlite.prepare(`
265
+ SELECT content_key, published_text, draft_text
266
+ FROM content_entries
267
+ WHERE locale = ?
268
+ ORDER BY content_key
269
+ `).all(locale);
270
+ const published = {};
271
+ const drafts = {};
272
+ for (const row of rows) {
273
+ if (row.published_text !== null)
274
+ published[row.content_key] = row.published_text;
275
+ if (row.draft_text !== null)
276
+ drafts[row.content_key] = row.draft_text;
277
+ }
278
+ return {
279
+ locale,
280
+ publishedRevision: state.publishedRevision,
281
+ draftRevision: state.draftRevision,
282
+ publishingMode: 'draft',
283
+ published,
284
+ drafts,
285
+ };
286
+ }
287
+ readState(locale) {
288
+ const row = this.sqlite.prepare(`
289
+ SELECT published_revision, draft_revision FROM content_state WHERE locale = ?
290
+ `).get(locale);
291
+ return row
292
+ ? { publishedRevision: row.published_revision, draftRevision: row.draft_revision }
293
+ : { publishedRevision: 1, draftRevision: 1 };
294
+ }
295
+ writeState(locale, publishedRevision, draftRevision) {
296
+ this.sqlite.prepare(`
297
+ INSERT INTO content_state (locale, published_revision, draft_revision)
298
+ VALUES (?, ?, ?)
299
+ ON CONFLICT (locale) DO UPDATE SET
300
+ published_revision = excluded.published_revision,
301
+ draft_revision = excluded.draft_revision
302
+ `).run(locale, publishedRevision, draftRevision);
303
+ }
304
+ revisionsMatch(snapshot, publishedRevision, draftRevision) {
305
+ return snapshot.publishedRevision === publishedRevision && snapshot.draftRevision === draftRevision;
306
+ }
307
+ sessionFromRow(row) {
308
+ const roles = JSON.parse(row.roles_json);
309
+ return {
310
+ tokenHash: row.token_hash,
311
+ csrfTokenHash: row.csrf_token_hash,
312
+ subject: row.subject,
313
+ roles,
314
+ createdAt: row.created_at,
315
+ lastSeenAt: row.last_seen_at,
316
+ idleExpiresAt: row.idle_expires_at,
317
+ absoluteExpiresAt: row.absolute_expires_at,
318
+ };
319
+ }
320
+ positiveInteger(value, name) {
321
+ if (!Number.isSafeInteger(value) || value < 1)
322
+ throw new TypeError(`${name} must be a positive safe integer.`);
323
+ return value;
324
+ }
325
+ assertOpen() {
326
+ if (this.closed)
327
+ throw new Error('SQLite persistence is closed.');
328
+ }
329
+ }
330
+ export function createSQLitePersistence(filenameOrOptions) {
331
+ return new SQLitePersistence(filenameOrOptions);
332
+ }
333
+ function assertHash(name, value) {
334
+ if (!SHA256_HEX.test(value))
335
+ throw new TypeError(`${name} must be a lowercase SHA-256 hex digest.`);
336
+ }
337
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkB7C,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAkCpC,MAAM,OAAO,iBAAiB;IACX,MAAM,CAAoB;IACnC,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,iBAAoD;QAC9D,MAAM,OAAO,GAAG,OAAO,iBAAiB,KAAK,QAAQ;YACnD,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE;YACjC,CAAC,CAAC,iBAAiB,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;QAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEnF,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,aAAa,IAAI,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;QAC9G,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;QACzE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;QAC/E,IAAI,OAAO,GAAG,cAAc,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,oCAAoC,cAAc,GAAG,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,OAAO,KAAK,cAAc;YAAE,OAAO;QAEvC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;KAGzC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,EAAc,CAAC;QAC7B,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,kIAAkI,CAAC,CAAC;QACtJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;YAC/E,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;gBAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,4BAA4B,OAAO,cAAc,cAAc,GAAG,EAAE,CAAC;YACpG,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,EAAE,CAAC;YACjE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,EAAE,CAAC;QACxG,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAa,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;OAKhC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAsB,CAAC;YACnC,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,GAAG,CAAC,cAAc,KAAK,IAAI;oBAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC;YACjF,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,iBAAiB,EAAE,OAAO,EAAE,CAAC;QACxD,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjG,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA0B;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAwB,EAA+C,EAAE;YACvG,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAChG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACjD,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;OAIjC,CAAC,CAAC;YACH,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO;gBAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAErF,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YACxE,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,aAAa,EAAE;aACvE,CAAC;QACJ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAA6B;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAA2B,EAAkD,EAAE;YAC7G,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAChG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACjD,CAAC;YAED,MAAM,aAAa,GAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;OAE1C,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;OAInB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAErB,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,GAAG,CAAC,CAAC;YACxD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAChE,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE;aAC3D,CAAC;QACJ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAA6B;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAA2B,EAAkD,EAAE;YAC7G,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAChG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACjD,CAAC;YAED,MAAM,cAAc,GAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;OAE3C,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;OAGnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAErB,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YACxE,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE;aACvF,CAAC;QACJ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAsB;QACxC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3C,UAAU,CAAC,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;KAKnB,CAAC,CAAC,GAAG,CACJ,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,OAAO,EACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAC7B,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,iBAAiB,CAC1B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAiB;QACjC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;KAI/B,CAAC,CAAC,GAAG,CAAC,SAAS,CAA2B,CAAC;QAC5C,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAiB,EAAE,MAAoB;QACxD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACnC,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS;YAAE,UAAU,CAAC,eAAe,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,KAAK,SAAS;YAC/C,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;SAEnB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;SAInB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACrF,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,KAAqB;QAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAC;QAEzF,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAqB,EAAqB,EAAE;YAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;OAEnC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAA6B,CAAC;YAClD,MAAM,KAAK,GAAG,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC;YACrE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;OAGnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK;gBAC7B,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC3C,OAAO;aACR,CAAC;QACJ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAEO,cAAc,CAAC,MAAc;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;KAKhC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAsB,CAAC;QACpC,MAAM,SAAS,GAA2B,EAAE,CAAC;QAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,cAAc,KAAK,IAAI;gBAAE,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC;YACjF,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;QACxE,CAAC;QACD,OAAO;YACL,MAAM;YACN,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,OAAO;YACvB,SAAS;YACT,MAAM;SACP,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,MAAc;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;KAE/B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAgC,CAAC;QAC9C,OAAO,GAAG;YACR,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,kBAAkB,EAAE,aAAa,EAAE,GAAG,CAAC,cAAc,EAAE;YAClF,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACjD,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,iBAAyB,EAAE,aAAqB;QACjF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;KAMnB,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACnD,CAAC;IAEO,cAAc,CAAC,QAAwB,EAAE,iBAAyB,EAAE,aAAqB;QAC/F,OAAO,QAAQ,CAAC,iBAAiB,KAAK,iBAAiB,IAAI,QAAQ,CAAC,aAAa,KAAK,aAAa,CAAC;IACtG,CAAC;IAEO,cAAc,CAAC,GAAe;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAA2B,CAAC;QACnE,OAAO;YACL,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,aAAa,EAAE,GAAG,CAAC,eAAe;YAClC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK;YACL,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,UAAU,EAAE,GAAG,CAAC,YAAY;YAC5B,aAAa,EAAE,GAAG,CAAC,eAAe;YAClC,iBAAiB,EAAE,GAAG,CAAC,mBAAmB;SAC3C,CAAC;IACJ,CAAC;IAEO,eAAe,CAAC,KAAa,EAAE,IAAY;QACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,mCAAmC,CAAC,CAAC;QAC/G,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACpE,CAAC;CACF;AAED,MAAM,UAAU,uBAAuB,CACrC,iBAAoD;IAEpD,OAAO,IAAI,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,KAAa;IAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,0CAA0C,CAAC,CAAC;AACtG,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@copypatch/storage-sqlite",
3
+ "version": "2.0.0",
4
+ "description": "SQLite persistence adapter for CopyPatch",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "homepage": "https://copypatch.vercel.app",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Woffluon/CopyPatch.git",
11
+ "directory": "packages/storage-sqlite"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Woffluon/CopyPatch/issues"
15
+ },
16
+ "keywords": [
17
+ "copypatch",
18
+ "sqlite",
19
+ "persistence",
20
+ "content-editing"
21
+ ],
22
+ "main": "./dist/index.js",
23
+ "module": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "default": "./dist/index.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "engines": {
36
+ "node": ">=20.0.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "registry": "https://registry.npmjs.org/"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -b tsconfig.json",
44
+ "typecheck": "tsc --noEmit",
45
+ "test": "vitest run --root ../.. packages/storage-sqlite/tests/storage-sqlite.test.ts",
46
+ "test:coverage": "vitest run --root ../.. --coverage packages/storage-sqlite/tests/storage-sqlite.test.ts",
47
+ "clean": "rm -rf dist"
48
+ },
49
+ "dependencies": {
50
+ "@copypatch/core": "2.0.0",
51
+ "better-sqlite3": "^11.8.1"
52
+ },
53
+ "devDependencies": {
54
+ "@types/better-sqlite3": "^7.6.12",
55
+ "@types/node": "^24.0.0",
56
+ "typescript": "^5.8.0",
57
+ "vitest": "^3.2.7"
58
+ }
59
+ }