craft-native 0.0.37
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.md +21 -0
- package/README.md +424 -0
- package/bin/cli.ts +937 -0
- package/dist/api/android-advanced.d.ts +737 -0
- package/dist/api/android-advanced.d.ts.map +1 -0
- package/dist/api/app.d.ts +432 -0
- package/dist/api/app.d.ts.map +1 -0
- package/dist/api/clipboard.d.ts +85 -0
- package/dist/api/clipboard.d.ts.map +1 -0
- package/dist/api/crypto.d.ts +79 -0
- package/dist/api/crypto.d.ts.map +1 -0
- package/dist/api/db.d.ts +427 -0
- package/dist/api/db.d.ts.map +1 -0
- package/dist/api/dialog.d.ts +141 -0
- package/dist/api/dialog.d.ts.map +1 -0
- package/dist/api/fs.d.ts +131 -0
- package/dist/api/fs.d.ts.map +1 -0
- package/dist/api/http.d.ts +196 -0
- package/dist/api/http.d.ts.map +1 -0
- package/dist/api/index.d.ts +38 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/ios-advanced.d.ts +833 -0
- package/dist/api/ios-advanced.d.ts.map +1 -0
- package/dist/api/macos-advanced.d.ts +721 -0
- package/dist/api/macos-advanced.d.ts.map +1 -0
- package/dist/api/media.d.ts +233 -0
- package/dist/api/media.d.ts.map +1 -0
- package/dist/api/mobile.d.ts +658 -0
- package/dist/api/mobile.d.ts.map +1 -0
- package/dist/api/process.d.ts +168 -0
- package/dist/api/process.d.ts.map +1 -0
- package/dist/api/sidebar.d.ts +125 -0
- package/dist/api/sidebar.d.ts.map +1 -0
- package/dist/api/tray.d.ts +410 -0
- package/dist/api/tray.d.ts.map +1 -0
- package/dist/api/window.d.ts +462 -0
- package/dist/api/window.d.ts.map +1 -0
- package/dist/api/windows-advanced.d.ts +719 -0
- package/dist/api/windows-advanced.d.ts.map +1 -0
- package/dist/assets/index.d.ts +69 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/binary-resolver.d.ts +39 -0
- package/dist/binary-resolver.d.ts.map +1 -0
- package/dist/bridge/android.d.ts +574 -0
- package/dist/bridge/android.d.ts.map +1 -0
- package/dist/bridge/core.d.ts +474 -0
- package/dist/bridge/core.d.ts.map +1 -0
- package/dist/bridge/ids.d.ts +18 -0
- package/dist/bridge/ids.d.ts.map +1 -0
- package/dist/bridge/ios.d.ts +528 -0
- package/dist/bridge/ios.d.ts.map +1 -0
- package/dist/bridge/webkit-pending.d.ts +50 -0
- package/dist/bridge/webkit-pending.d.ts.map +1 -0
- package/dist/build/bundle-optimizer.d.ts +69 -0
- package/dist/build/bundle-optimizer.d.ts.map +1 -0
- package/dist/components/index.d.ts +719 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/native.d.ts +728 -0
- package/dist/components/native.d.ts.map +1 -0
- package/dist/components/sidebar.d.ts +458 -0
- package/dist/components/sidebar.d.ts.map +1 -0
- package/dist/dev/devtools.d.ts +118 -0
- package/dist/dev/devtools.d.ts.map +1 -0
- package/dist/dev/error-overlay.d.ts +73 -0
- package/dist/dev/error-overlay.d.ts.map +1 -0
- package/dist/dev/hot-reload.d.ts +127 -0
- package/dist/dev/hot-reload.d.ts.map +1 -0
- package/dist/index.cjs +10253 -0
- package/dist/index.d.cts +59 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10240 -0
- package/dist/logging/index.d.ts +152 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/optimizations/index.d.ts +232 -0
- package/dist/optimizations/index.d.ts.map +1 -0
- package/dist/package.d.ts +90 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/performance/runtime.d.ts +230 -0
- package/dist/performance/runtime.d.ts.map +1 -0
- package/dist/performance/startup.d.ts +223 -0
- package/dist/performance/startup.d.ts.map +1 -0
- package/dist/plugins/index.d.ts +114 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/security/index.d.ts +268 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/signing/index.d.ts +104 -0
- package/dist/signing/index.d.ts.map +1 -0
- package/dist/styles/headwind.d.ts +222 -0
- package/dist/styles/headwind.d.ts.map +1 -0
- package/dist/styles/index.d.ts +31 -0
- package/dist/styles/index.d.ts.map +1 -0
- package/dist/styles/sidebar-templates.d.ts +77 -0
- package/dist/styles/sidebar-templates.d.ts.map +1 -0
- package/dist/styles/sidebars.d.ts +194 -0
- package/dist/styles/sidebars.d.ts.map +1 -0
- package/dist/types.d.ts +1555 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/updater/index.d.ts +164 -0
- package/dist/updater/index.d.ts.map +1 -0
- package/dist/utils/audio.d.ts +40 -0
- package/dist/utils/audio.d.ts.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/native.d.ts +27 -0
- package/dist/utils/native.d.ts.map +1 -0
- package/dist/utils/react.d.ts +157 -0
- package/dist/utils/react.d.ts.map +1 -0
- package/dist/utils/storage.d.ts +35 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/svelte.d.ts +187 -0
- package/dist/utils/svelte.d.ts.map +1 -0
- package/dist/utils/timer.d.ts +57 -0
- package/dist/utils/timer.d.ts.map +1 -0
- package/dist/utils/vue.d.ts +157 -0
- package/dist/utils/vue.d.ts.map +1 -0
- package/package.json +78 -0
package/dist/api/db.d.ts
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Craft Database API
|
|
3
|
+
* @description Provides SQLite database access through the Craft bridge.
|
|
4
|
+
* Includes transaction support, table management, and a key-value store abstraction.
|
|
5
|
+
* @module @craft-native/api/db
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { openDatabase, KeyValueStore } from '@craft-native/api/db'
|
|
10
|
+
*
|
|
11
|
+
* // Open a database
|
|
12
|
+
* const myDb = await openDatabase('myapp.db')
|
|
13
|
+
*
|
|
14
|
+
* // Create a table
|
|
15
|
+
* await myDb.createTable('users', [
|
|
16
|
+
* { name: 'id', type: 'INTEGER', primaryKey: true, autoIncrement: true },
|
|
17
|
+
* { name: 'name', type: 'TEXT', notNull: true },
|
|
18
|
+
* { name: 'email', type: 'TEXT', unique: true }
|
|
19
|
+
* ])
|
|
20
|
+
*
|
|
21
|
+
* // Insert data
|
|
22
|
+
* await myDb.execute('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com'])
|
|
23
|
+
*
|
|
24
|
+
* // Query data
|
|
25
|
+
* const users = await myDb.query('SELECT * FROM users')
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import { EventEmitter } from 'events';
|
|
29
|
+
import type { CraftDatabaseAPI } from '../types';
|
|
30
|
+
/**
|
|
31
|
+
* Global emitter for `db:execute` audit events. Subscribe to log every SQL
|
|
32
|
+
* statement that goes through the SDK. The event payload is `{ name, sql,
|
|
33
|
+
* paramsCount, readOnly }` — params themselves are not included by default
|
|
34
|
+
* to avoid leaking secrets to logs.
|
|
35
|
+
*
|
|
36
|
+
* `setMaxListeners(0)` lifts the default 10-listener cap: analytics, the
|
|
37
|
+
* dev overlay, and tests routinely subscribe in parallel and the cap
|
|
38
|
+
* triggered spurious "MaxListenersExceeded" warnings without indicating
|
|
39
|
+
* an actual leak.
|
|
40
|
+
*/
|
|
41
|
+
export declare const dbAudit: EventEmitter;
|
|
42
|
+
/**
|
|
43
|
+
* Validate a SQL identifier (table or column name) to prevent SQL injection
|
|
44
|
+
* and runaway identifiers. Only allows alphanumeric characters and
|
|
45
|
+
* underscores, with a length cap.
|
|
46
|
+
*
|
|
47
|
+
* @param name The identifier to validate.
|
|
48
|
+
* @param kind Human-readable label for error messages (`'table'` /
|
|
49
|
+
* `'column'` / `'index'` …). Defaults to `'identifier'`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function validateIdentifier(name: string, kind?: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Back-compat alias for {@link validateIdentifier} when validating a table
|
|
54
|
+
* name. Existing call sites that say `validateTableName(...)` keep working.
|
|
55
|
+
*/
|
|
56
|
+
export declare function validateTableName(name: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Encode a SQL literal for safe inclusion in a `DEFAULT` clause. Strings
|
|
59
|
+
* have their single quotes doubled per the SQL standard. Numbers are
|
|
60
|
+
* emitted verbatim (after `Number.isFinite` check). `null`/`undefined`
|
|
61
|
+
* become `NULL`. Booleans become `0`/`1`. Anything else throws — DEFAULT
|
|
62
|
+
* with a JSON object/array would silently misencode.
|
|
63
|
+
*/
|
|
64
|
+
export declare function encodeDefaultLiteral(value: unknown): string;
|
|
65
|
+
/**
|
|
66
|
+
* Low-level database API implementation.
|
|
67
|
+
* Uses native SQLite through the Craft bridge.
|
|
68
|
+
* For most use cases, prefer the {@link Database} class or {@link KeyValueStore}.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* import { db } from '@craft-native/api/db'
|
|
73
|
+
*
|
|
74
|
+
* // Execute a statement
|
|
75
|
+
* await db.execute('CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT)')
|
|
76
|
+
*
|
|
77
|
+
* // Query data
|
|
78
|
+
* const results = await db.query('SELECT * FROM settings WHERE key = ?', ['theme'])
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare const db: CraftDatabaseAPI;
|
|
82
|
+
/**
|
|
83
|
+
* Create or open a SQLite database.
|
|
84
|
+
*
|
|
85
|
+
* @param name - Database name (will be stored as `{name}.sqlite` in app data directory)
|
|
86
|
+
* @returns Promise resolving to Database instance
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const myDb = await openDatabase('myapp')
|
|
91
|
+
*
|
|
92
|
+
* // Database will be created at app data directory as 'myapp.sqlite'
|
|
93
|
+
* await myDb.createTable('notes', [
|
|
94
|
+
* { name: 'id', type: 'INTEGER', primaryKey: true, autoIncrement: true },
|
|
95
|
+
* { name: 'title', type: 'TEXT', notNull: true },
|
|
96
|
+
* { name: 'content', type: 'TEXT' },
|
|
97
|
+
* { name: 'created_at', type: 'INTEGER', default: Date.now() }
|
|
98
|
+
* ])
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare function openDatabase(name: string): Promise<Database>;
|
|
102
|
+
/**
|
|
103
|
+
* Open a database in read-only mode. `execute()` on the returned instance
|
|
104
|
+
* rejects DDL/DML statements (`INSERT`, `UPDATE`, `DELETE`, `DROP`, etc.).
|
|
105
|
+
* Use this for analytics / reporting code paths where there is no reason
|
|
106
|
+
* for a SQL bug to be able to mutate state.
|
|
107
|
+
*/
|
|
108
|
+
export declare function openDatabaseReadOnly(name: string): Promise<Database>;
|
|
109
|
+
/**
|
|
110
|
+
* SQLite database wrapper with extended functionality.
|
|
111
|
+
* Provides table management, transactions, and query helpers.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const db = new Database('myapp')
|
|
116
|
+
* await db.open()
|
|
117
|
+
*
|
|
118
|
+
* // Create table with schema
|
|
119
|
+
* await db.createTable('tasks', [
|
|
120
|
+
* { name: 'id', type: 'INTEGER', primaryKey: true, autoIncrement: true },
|
|
121
|
+
* { name: 'title', type: 'TEXT', notNull: true },
|
|
122
|
+
* { name: 'completed', type: 'INTEGER', default: 0 }
|
|
123
|
+
* ])
|
|
124
|
+
*
|
|
125
|
+
* // Insert and get ID
|
|
126
|
+
* const result = await db.execute('INSERT INTO tasks (title) VALUES (?)', ['Buy groceries'])
|
|
127
|
+
* console.log('Created task with ID:', result.lastInsertId)
|
|
128
|
+
*
|
|
129
|
+
* // Query with type safety
|
|
130
|
+
* interface Task { id: number; title: string; completed: number }
|
|
131
|
+
* const tasks = await db.query<Task>('SELECT * FROM tasks')
|
|
132
|
+
*
|
|
133
|
+
* // Get single row
|
|
134
|
+
* const task = await db.get<Task>('SELECT * FROM tasks WHERE id = ?', [1])
|
|
135
|
+
*
|
|
136
|
+
* // Transaction helper
|
|
137
|
+
* await db.transaction(async () => {
|
|
138
|
+
* await db.execute('UPDATE tasks SET completed = 1 WHERE id = ?', [1])
|
|
139
|
+
* await db.execute('INSERT INTO activity_log (action) VALUES (?)', ['completed_task'])
|
|
140
|
+
* })
|
|
141
|
+
*
|
|
142
|
+
* await db.close()
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export declare class Database {
|
|
146
|
+
private name;
|
|
147
|
+
private isOpen;
|
|
148
|
+
private readOnly;
|
|
149
|
+
/** True while a `db.transaction(...)` callback is on the stack. Set
|
|
150
|
+
* before `BEGIN TRANSACTION` and cleared in the finally arm. Used to
|
|
151
|
+
* make the inevitable mistake of calling `beginTransaction()` inside
|
|
152
|
+
* `transaction()` (or vice versa) fail fast with a clear error. */
|
|
153
|
+
private _inTransactionHelper;
|
|
154
|
+
/**
|
|
155
|
+
* Create a new Database instance.
|
|
156
|
+
*
|
|
157
|
+
* @param name - Database name
|
|
158
|
+
* @param options.readOnly - When true, `execute()` rejects DDL/DML
|
|
159
|
+
* statements (anything that would mutate the schema or data).
|
|
160
|
+
* `query()` is unaffected. Defaults to false.
|
|
161
|
+
*/
|
|
162
|
+
constructor(name: string, options?: {
|
|
163
|
+
readOnly?: boolean;
|
|
164
|
+
});
|
|
165
|
+
/** Whether this Database refuses mutating statements. */
|
|
166
|
+
isReadOnly(): boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Open the database connection.
|
|
169
|
+
* Called automatically on first query if not explicitly opened.
|
|
170
|
+
*
|
|
171
|
+
* @returns Promise that resolves when connection is established
|
|
172
|
+
* @throws {Error} If not running in Craft environment
|
|
173
|
+
*/
|
|
174
|
+
open(): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Close the database connection.
|
|
177
|
+
* Should be called when done with the database to free resources.
|
|
178
|
+
*
|
|
179
|
+
* @returns Promise that resolves when connection is closed
|
|
180
|
+
*/
|
|
181
|
+
close(): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Execute a SQL statement and get result metadata.
|
|
184
|
+
*
|
|
185
|
+
* @param sql - SQL statement to execute
|
|
186
|
+
* @param params - Optional parameters for prepared statement
|
|
187
|
+
* @returns Promise resolving to ExecuteResult with rowsAffected and lastInsertId
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const result = await db.execute(
|
|
192
|
+
* 'INSERT INTO users (name, email) VALUES (?, ?)',
|
|
193
|
+
* ['John', 'john@example.com']
|
|
194
|
+
* )
|
|
195
|
+
* console.log(`Inserted user with ID: ${result.lastInsertId}`)
|
|
196
|
+
* console.log(`Rows affected: ${result.rowsAffected}`)
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
|
|
200
|
+
/**
|
|
201
|
+
* Execute a query and return all matching rows.
|
|
202
|
+
*
|
|
203
|
+
* @typeParam T - Type of result rows
|
|
204
|
+
* @param sql - SQL SELECT statement
|
|
205
|
+
* @param params - Optional parameters for prepared statement
|
|
206
|
+
* @returns Promise resolving to array of typed results
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* interface User {
|
|
211
|
+
* id: number
|
|
212
|
+
* name: string
|
|
213
|
+
* email: string
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
* const users = await db.query<User>('SELECT * FROM users WHERE active = ?', [1])
|
|
217
|
+
* users.forEach(user => console.log(user.name))
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
221
|
+
/**
|
|
222
|
+
* Execute a query and return the first matching row.
|
|
223
|
+
*
|
|
224
|
+
* @typeParam T - Type of result row
|
|
225
|
+
* @param sql - SQL SELECT statement
|
|
226
|
+
* @param params - Optional parameters for prepared statement
|
|
227
|
+
* @returns Promise resolving to first row or null if no matches
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* const user = await db.get<User>('SELECT * FROM users WHERE id = ?', [1])
|
|
232
|
+
* if (user) {
|
|
233
|
+
* console.log(`Found user: ${user.name}`)
|
|
234
|
+
* }
|
|
235
|
+
else {
|
|
236
|
+
* console.log('User not found')
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
get<T = unknown>(sql: string, params?: unknown[]): Promise<T | null>;
|
|
241
|
+
/**
|
|
242
|
+
* Execute a function within a transaction.
|
|
243
|
+
* Automatically commits on success, rolls back on error.
|
|
244
|
+
*
|
|
245
|
+
* NOTE: this method drives the transaction by emitting raw SQL
|
|
246
|
+
* (`BEGIN TRANSACTION` / `COMMIT` / `ROLLBACK`). The connection-level
|
|
247
|
+
* helpers `db.beginTransaction()` / `db.commit()` / `db.rollback()` use
|
|
248
|
+
* a separate native handler. Don't mix the two on the same connection —
|
|
249
|
+
* pick one style per code path. See `docs/db-transactions.md`.
|
|
250
|
+
*
|
|
251
|
+
* @typeParam T - Return type of transaction function
|
|
252
|
+
* @param fn - Async function containing database operations
|
|
253
|
+
* @returns Promise resolving to function's return value
|
|
254
|
+
* @throws Re-throws any error after rolling back
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* const orderId = await db.transaction(async () => {
|
|
259
|
+
* const orderResult = await db.execute(
|
|
260
|
+
* 'INSERT INTO orders (user_id, total) VALUES (?, ?)',
|
|
261
|
+
* [userId, total]
|
|
262
|
+
* )
|
|
263
|
+
*
|
|
264
|
+
* for (const item of items) {
|
|
265
|
+
* await db.execute(
|
|
266
|
+
* 'INSERT INTO order_items (order_id, product_id, quantity) VALUES (?, ?, ?)',
|
|
267
|
+
* [orderResult.lastInsertId, item.productId, item.quantity]
|
|
268
|
+
* )
|
|
269
|
+
* }
|
|
270
|
+
*
|
|
271
|
+
* return orderResult.lastInsertId
|
|
272
|
+
* })
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
276
|
+
/**
|
|
277
|
+
* Create a table with the specified schema.
|
|
278
|
+
* Uses CREATE TABLE IF NOT EXISTS, so safe to call multiple times.
|
|
279
|
+
*
|
|
280
|
+
* @param tableName - Name of the table to create
|
|
281
|
+
* @param columns - Array of column definitions
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* await db.createTable('products', [
|
|
286
|
+
* { name: 'id', type: 'INTEGER', primaryKey: true, autoIncrement: true },
|
|
287
|
+
* { name: 'name', type: 'TEXT', notNull: true },
|
|
288
|
+
* { name: 'price', type: 'REAL', notNull: true },
|
|
289
|
+
* { name: 'category', type: 'TEXT' },
|
|
290
|
+
* { name: 'in_stock', type: 'INTEGER', default: 1 }
|
|
291
|
+
* ])
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
createTable(tableName: string, columns: TableColumn[]): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Drop a table if it exists.
|
|
297
|
+
*
|
|
298
|
+
* @param tableName - Name of the table to drop
|
|
299
|
+
*/
|
|
300
|
+
dropTable(tableName: string): Promise<void>;
|
|
301
|
+
/**
|
|
302
|
+
* Check if a table exists in the database.
|
|
303
|
+
*
|
|
304
|
+
* @param tableName - Name of the table to check
|
|
305
|
+
* @returns Promise resolving to true if table exists
|
|
306
|
+
*/
|
|
307
|
+
tableExists(tableName: string): Promise<boolean>;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Result of an execute operation.
|
|
311
|
+
*/
|
|
312
|
+
export interface ExecuteResult {
|
|
313
|
+
/** Number of rows affected by the operation */
|
|
314
|
+
rowsAffected: number;
|
|
315
|
+
/** ID of the last inserted row (for INSERT operations) */
|
|
316
|
+
lastInsertId: number;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Column definition for createTable.
|
|
320
|
+
*/
|
|
321
|
+
export interface TableColumn {
|
|
322
|
+
/** Column name */
|
|
323
|
+
name: string;
|
|
324
|
+
/** SQLite data type */
|
|
325
|
+
type: 'TEXT' | 'INTEGER' | 'REAL' | 'BLOB' | 'NULL';
|
|
326
|
+
/** Mark as primary key */
|
|
327
|
+
primaryKey?: boolean;
|
|
328
|
+
/** Enable auto-increment (INTEGER PRIMARY KEY only) */
|
|
329
|
+
autoIncrement?: boolean;
|
|
330
|
+
/** Disallow NULL values */
|
|
331
|
+
notNull?: boolean;
|
|
332
|
+
/** Require unique values */
|
|
333
|
+
unique?: boolean;
|
|
334
|
+
/** Default value for column */
|
|
335
|
+
default?: unknown;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Simple key-value store backed by SQLite.
|
|
339
|
+
* Useful for settings, preferences, and cached data.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```typescript
|
|
343
|
+
* const db = await openDatabase('settings')
|
|
344
|
+
* const store = new KeyValueStore(db)
|
|
345
|
+
* await store.init()
|
|
346
|
+
*
|
|
347
|
+
* // Store values (automatically JSON serialized)
|
|
348
|
+
* await store.set('theme', 'dark')
|
|
349
|
+
* await store.set('user', { name: 'John', premium: true })
|
|
350
|
+
* await store.set('recentFiles', ['/doc1.txt', '/doc2.txt'])
|
|
351
|
+
*
|
|
352
|
+
* // Retrieve values
|
|
353
|
+
* const theme = await store.get<string>('theme') // 'dark'
|
|
354
|
+
* const user = await store.get<{ name: string; premium: boolean }>('user')
|
|
355
|
+
*
|
|
356
|
+
* // Check existence
|
|
357
|
+
* if (await store.has('lastSync')) {
|
|
358
|
+
* const lastSync = await store.get<number>('lastSync')
|
|
359
|
+
* }
|
|
360
|
+
*
|
|
361
|
+
* // List all keys
|
|
362
|
+
* const allKeys = await store.keys()
|
|
363
|
+
*
|
|
364
|
+
* // Delete and clear
|
|
365
|
+
* await store.delete('tempData')
|
|
366
|
+
* await store.clear() // Remove all entries
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
export declare class KeyValueStore {
|
|
370
|
+
private db;
|
|
371
|
+
private tableName;
|
|
372
|
+
/**
|
|
373
|
+
* Create a new KeyValueStore.
|
|
374
|
+
*
|
|
375
|
+
* @param db - Database instance to use
|
|
376
|
+
* @param tableName - Table name for storage (default: 'kv_store')
|
|
377
|
+
*/
|
|
378
|
+
constructor(db: Database, tableName?: string);
|
|
379
|
+
/**
|
|
380
|
+
* Initialize the key-value store table.
|
|
381
|
+
* Must be called before using other methods.
|
|
382
|
+
*/
|
|
383
|
+
init(): Promise<void>;
|
|
384
|
+
/**
|
|
385
|
+
* Get a value by key.
|
|
386
|
+
* Returns null if key doesn't exist.
|
|
387
|
+
*
|
|
388
|
+
* @typeParam T - Expected type of the value
|
|
389
|
+
* @param key - Key to retrieve
|
|
390
|
+
* @returns Promise resolving to value or null
|
|
391
|
+
*/
|
|
392
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
393
|
+
/**
|
|
394
|
+
* Set a value for a key.
|
|
395
|
+
* Creates new entry or updates existing one.
|
|
396
|
+
* Values are automatically JSON serialized.
|
|
397
|
+
*
|
|
398
|
+
* @param key - Key to set
|
|
399
|
+
* @param value - Value to store (will be JSON serialized)
|
|
400
|
+
*/
|
|
401
|
+
set(key: string, value: unknown): Promise<void>;
|
|
402
|
+
/**
|
|
403
|
+
* Delete a key from the store.
|
|
404
|
+
*
|
|
405
|
+
* @param key - Key to delete
|
|
406
|
+
*/
|
|
407
|
+
delete(key: string): Promise<void>;
|
|
408
|
+
/**
|
|
409
|
+
* Check if a key exists.
|
|
410
|
+
*
|
|
411
|
+
* @param key - Key to check
|
|
412
|
+
* @returns Promise resolving to true if key exists
|
|
413
|
+
*/
|
|
414
|
+
has(key: string): Promise<boolean>;
|
|
415
|
+
/**
|
|
416
|
+
* Get all keys in the store.
|
|
417
|
+
*
|
|
418
|
+
* @returns Promise resolving to array of keys
|
|
419
|
+
*/
|
|
420
|
+
keys(): Promise<string[]>;
|
|
421
|
+
/**
|
|
422
|
+
* Clear all entries from the store.
|
|
423
|
+
*/
|
|
424
|
+
clear(): Promise<void>;
|
|
425
|
+
}
|
|
426
|
+
export default db;
|
|
427
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/api/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Craft Dialog API
|
|
3
|
+
* Native file pickers and alert dialogs
|
|
4
|
+
* @module @craft-native/api/dialog
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* File filter for open/save dialogs
|
|
8
|
+
*/
|
|
9
|
+
export interface FileFilter {
|
|
10
|
+
/** Filter display name (e.g., "Images") */
|
|
11
|
+
name: string;
|
|
12
|
+
/** File extensions without dots (e.g., ["png", "jpg", "gif"]) */
|
|
13
|
+
extensions: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Options for open file dialog
|
|
17
|
+
*/
|
|
18
|
+
export interface OpenDialogOptions {
|
|
19
|
+
/** Dialog title */
|
|
20
|
+
title?: string;
|
|
21
|
+
/** Default path to open */
|
|
22
|
+
defaultPath?: string;
|
|
23
|
+
/** File filters */
|
|
24
|
+
filters?: FileFilter[];
|
|
25
|
+
/** Allow selecting multiple files */
|
|
26
|
+
multiple?: boolean;
|
|
27
|
+
/** Allow selecting directories */
|
|
28
|
+
directory?: boolean;
|
|
29
|
+
/** Show hidden files */
|
|
30
|
+
showHiddenFiles?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for save file dialog
|
|
34
|
+
*/
|
|
35
|
+
export interface SaveDialogOptions {
|
|
36
|
+
/** Dialog title */
|
|
37
|
+
title?: string;
|
|
38
|
+
/** Default path to save */
|
|
39
|
+
defaultPath?: string;
|
|
40
|
+
/** Default file name */
|
|
41
|
+
defaultName?: string;
|
|
42
|
+
/** File filters */
|
|
43
|
+
filters?: FileFilter[];
|
|
44
|
+
/** Show hidden files */
|
|
45
|
+
showHiddenFiles?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Alert dialog style
|
|
49
|
+
*/
|
|
50
|
+
export type AlertStyle = 'info' | 'warning' | 'critical';
|
|
51
|
+
/**
|
|
52
|
+
* Options for alert dialog
|
|
53
|
+
*/
|
|
54
|
+
export interface AlertOptions {
|
|
55
|
+
/** Dialog title (main message) */
|
|
56
|
+
title: string;
|
|
57
|
+
/** Dialog message (secondary text) */
|
|
58
|
+
message?: string;
|
|
59
|
+
/** Alert style */
|
|
60
|
+
style?: AlertStyle;
|
|
61
|
+
/** Custom button labels */
|
|
62
|
+
buttons?: string[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Options for confirm dialog
|
|
66
|
+
*/
|
|
67
|
+
export interface ConfirmOptions {
|
|
68
|
+
/** Dialog title (main message) */
|
|
69
|
+
title: string;
|
|
70
|
+
/** Dialog message (secondary text) */
|
|
71
|
+
message?: string;
|
|
72
|
+
/** OK button label */
|
|
73
|
+
okLabel?: string;
|
|
74
|
+
/** Cancel button label */
|
|
75
|
+
cancelLabel?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Result from open dialog
|
|
79
|
+
*/
|
|
80
|
+
export interface OpenDialogResult {
|
|
81
|
+
/** Whether a file was selected (not cancelled) */
|
|
82
|
+
canceled: boolean;
|
|
83
|
+
/** Selected file paths */
|
|
84
|
+
filePaths: string[];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Result from save dialog
|
|
88
|
+
*/
|
|
89
|
+
export interface SaveDialogResult {
|
|
90
|
+
/** Whether save was cancelled */
|
|
91
|
+
canceled: boolean;
|
|
92
|
+
/** Selected file path */
|
|
93
|
+
filePath?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Show open file dialog
|
|
97
|
+
* @param options Dialog options
|
|
98
|
+
* @returns Selected file path(s)
|
|
99
|
+
*/
|
|
100
|
+
export declare function openFile(options?: OpenDialogOptions): Promise<OpenDialogResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Show open folder dialog
|
|
103
|
+
* @param options Dialog options
|
|
104
|
+
* @returns Selected folder path
|
|
105
|
+
*/
|
|
106
|
+
export declare function openFolder(options?: Omit<OpenDialogOptions, 'multiple' | 'directory'>): Promise<OpenDialogResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Show save file dialog
|
|
109
|
+
* @param options Dialog options
|
|
110
|
+
* @returns Selected save path
|
|
111
|
+
*/
|
|
112
|
+
export declare function saveFile(options?: SaveDialogOptions): Promise<SaveDialogResult>;
|
|
113
|
+
/**
|
|
114
|
+
* Show alert dialog
|
|
115
|
+
* @param options Alert options or just a message string
|
|
116
|
+
* @returns Button index that was clicked
|
|
117
|
+
*/
|
|
118
|
+
export declare function showAlert(options: AlertOptions | string): Promise<number>;
|
|
119
|
+
/**
|
|
120
|
+
* Show confirm dialog with OK/Cancel buttons
|
|
121
|
+
* @param options Confirm options or just a message string
|
|
122
|
+
* @returns true if OK was clicked, false if cancelled
|
|
123
|
+
*/
|
|
124
|
+
export declare function showConfirm(options: ConfirmOptions | string): Promise<boolean>;
|
|
125
|
+
/**
|
|
126
|
+
* Show prompt dialog with text input
|
|
127
|
+
* @param title Dialog title
|
|
128
|
+
* @param defaultValue Default input value
|
|
129
|
+
* @returns User input or null if cancelled
|
|
130
|
+
*/
|
|
131
|
+
export declare function showPrompt(title: string, defaultValue?: string): Promise<string | null>;
|
|
132
|
+
export declare const dialog: {
|
|
133
|
+
openFile: typeof openFile;
|
|
134
|
+
openFolder: typeof openFolder;
|
|
135
|
+
saveFile: typeof saveFile;
|
|
136
|
+
showAlert: typeof showAlert;
|
|
137
|
+
showConfirm: typeof showConfirm;
|
|
138
|
+
showPrompt: typeof showPrompt;
|
|
139
|
+
};
|
|
140
|
+
export default dialog;
|
|
141
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/api/dialog.ts"],"names":[],"mappings":"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"}
|