@objectql/driver-excel 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/EXAMPLE.md +198 -0
- package/LICENSE +21 -0
- package/README.md +653 -0
- package/dist/index.d.ts +215 -0
- package/dist/index.js +856 -0
- package/dist/index.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +37 -0
- package/src/index.ts +960 -0
- package/test/index.test.ts +566 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @objectql/driver-excel
|
|
2
|
+
|
|
3
|
+
## 0.2.0 - 2024-01-16
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **File Storage Modes**: New `fileStorageMode` configuration option
|
|
8
|
+
- `single-file` mode: All object types in one Excel file (default, existing behavior)
|
|
9
|
+
- `file-per-object` mode: Each object type in a separate Excel file
|
|
10
|
+
- Complete English documentation in README
|
|
11
|
+
- Additional tests for file-per-object mode (39 total tests now)
|
|
12
|
+
- Examples for both storage modes
|
|
13
|
+
|
|
14
|
+
### Improved
|
|
15
|
+
|
|
16
|
+
- Better documentation with comprehensive API reference
|
|
17
|
+
- Usage examples for common scenarios
|
|
18
|
+
- Performance benchmarks and optimization tips
|
|
19
|
+
- Detailed error handling guide
|
|
20
|
+
|
|
21
|
+
## 0.1.0 - 2024-01-16
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Initial release of Excel Driver for ObjectQL
|
|
26
|
+
- Full CRUD operations (create, read, update, delete)
|
|
27
|
+
- Query support with filters, sorting, and pagination
|
|
28
|
+
- Bulk operations (createMany, updateMany, deleteMany)
|
|
29
|
+
- Multiple worksheet support (one sheet per object type)
|
|
30
|
+
- Auto-save and manual save options
|
|
31
|
+
- File persistence with Excel (.xlsx) format
|
|
32
|
+
- Comprehensive test suite with 36 passing tests
|
|
33
|
+
- Complete documentation and examples
|
|
34
|
+
- TypeScript support with strict typing
|
|
35
|
+
- Compatible with @objectql/types Driver interface
|
|
36
|
+
|
|
37
|
+
### Security
|
|
38
|
+
|
|
39
|
+
- **IMPORTANT**: Uses ExcelJS (v4.4.0) instead of xlsx library to avoid known security vulnerabilities
|
|
40
|
+
- ExcelJS has no known CVEs and is actively maintained
|
|
41
|
+
- Secure against ReDoS (Regular Expression Denial of Service) attacks
|
|
42
|
+
- Protected from Prototype Pollution vulnerabilities
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
- ✅ Read from existing Excel files
|
|
47
|
+
- ✅ Write data back to Excel files
|
|
48
|
+
- ✅ Create new Excel files automatically
|
|
49
|
+
- ✅ Support for multiple object types (worksheets)
|
|
50
|
+
- ✅ Filter operators: =, !=, >, >=, <, <=, in, nin, contains, startswith, endswith, between
|
|
51
|
+
- ✅ Logical operators: AND, OR
|
|
52
|
+
- ✅ Sorting (ascending/descending)
|
|
53
|
+
- ✅ Pagination (skip/limit)
|
|
54
|
+
- ✅ Field projection
|
|
55
|
+
- ✅ Count and distinct queries
|
|
56
|
+
- ✅ Error handling with ObjectQLError
|
|
57
|
+
- ✅ Strict mode support
|
|
58
|
+
- ✅ Auto-generated IDs
|
|
59
|
+
- ✅ Timestamps (created_at, updated_at)
|
|
60
|
+
- ✅ Async/await API with factory pattern
|
|
61
|
+
|
|
62
|
+
### Dependencies
|
|
63
|
+
|
|
64
|
+
- exceljs@^4.4.0 - Secure Excel file read/write library (actively maintained, no known CVEs)
|
|
65
|
+
- @objectql/types@workspace:* - Core ObjectQL types
|
|
66
|
+
|
|
67
|
+
### API Changes
|
|
68
|
+
|
|
69
|
+
- Constructor requires async initialization via `ExcelDriver.create()` factory method
|
|
70
|
+
- All file I/O operations are properly async for better performance
|
package/EXAMPLE.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Excel Driver - Simple Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to use the Excel Driver for ObjectQL.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @objectql/driver-excel
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { ExcelDriver } from '@objectql/driver-excel';
|
|
15
|
+
|
|
16
|
+
// Initialize driver with Excel file
|
|
17
|
+
const driver = new ExcelDriver({
|
|
18
|
+
filePath: './data/mydata.xlsx',
|
|
19
|
+
createIfMissing: true,
|
|
20
|
+
autoSave: true
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Create records
|
|
24
|
+
const user1 = await driver.create('users', {
|
|
25
|
+
name: 'Alice Johnson',
|
|
26
|
+
email: 'alice@example.com',
|
|
27
|
+
role: 'admin',
|
|
28
|
+
age: 30
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const user2 = await driver.create('users', {
|
|
32
|
+
name: 'Bob Smith',
|
|
33
|
+
email: 'bob@example.com',
|
|
34
|
+
role: 'user',
|
|
35
|
+
age: 25
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Query records
|
|
39
|
+
const allUsers = await driver.find('users');
|
|
40
|
+
console.log('All users:', allUsers);
|
|
41
|
+
|
|
42
|
+
// Filter records
|
|
43
|
+
const admins = await driver.find('users', {
|
|
44
|
+
filters: [['role', '=', 'admin']]
|
|
45
|
+
});
|
|
46
|
+
console.log('Admin users:', admins);
|
|
47
|
+
|
|
48
|
+
// Sort and paginate
|
|
49
|
+
const sortedUsers = await driver.find('users', {
|
|
50
|
+
sort: [['age', 'desc']],
|
|
51
|
+
limit: 10
|
|
52
|
+
});
|
|
53
|
+
console.log('Sorted users:', sortedUsers);
|
|
54
|
+
|
|
55
|
+
// Update a record
|
|
56
|
+
await driver.update('users', user1.id, {
|
|
57
|
+
email: 'alice.new@example.com'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Delete a record
|
|
61
|
+
await driver.delete('users', user2.id);
|
|
62
|
+
|
|
63
|
+
// Count records
|
|
64
|
+
const count = await driver.count('users', {});
|
|
65
|
+
console.log('Total users:', count);
|
|
66
|
+
|
|
67
|
+
// Clean up
|
|
68
|
+
await driver.disconnect();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Advanced Features
|
|
72
|
+
|
|
73
|
+
### Multiple Object Types (Worksheets)
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Create products
|
|
77
|
+
await driver.create('products', {
|
|
78
|
+
name: 'Laptop',
|
|
79
|
+
price: 999.99,
|
|
80
|
+
category: 'Electronics'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Create orders
|
|
84
|
+
await driver.create('orders', {
|
|
85
|
+
userId: user1.id,
|
|
86
|
+
productId: 'product-123',
|
|
87
|
+
quantity: 2,
|
|
88
|
+
total: 1999.98
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Each object type is stored in its own worksheet
|
|
92
|
+
const products = await driver.find('products');
|
|
93
|
+
const orders = await driver.find('orders');
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Complex Filters
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// AND conditions
|
|
100
|
+
const results = await driver.find('users', {
|
|
101
|
+
filters: [
|
|
102
|
+
['age', '>', 18],
|
|
103
|
+
['role', '=', 'admin']
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// OR conditions
|
|
108
|
+
const results2 = await driver.find('users', {
|
|
109
|
+
filters: [
|
|
110
|
+
['role', '=', 'admin'],
|
|
111
|
+
'or',
|
|
112
|
+
['role', '=', 'moderator']
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Contains search
|
|
117
|
+
const searchResults = await driver.find('users', {
|
|
118
|
+
filters: [['name', 'contains', 'john']]
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Bulk Operations
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Create many
|
|
126
|
+
await driver.createMany('users', [
|
|
127
|
+
{ name: 'User 1', email: 'user1@example.com' },
|
|
128
|
+
{ name: 'User 2', email: 'user2@example.com' },
|
|
129
|
+
{ name: 'User 3', email: 'user3@example.com' }
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
// Update many
|
|
133
|
+
await driver.updateMany(
|
|
134
|
+
'users',
|
|
135
|
+
[['role', '=', 'user']],
|
|
136
|
+
{ role: 'member' }
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Delete many
|
|
140
|
+
await driver.deleteMany(
|
|
141
|
+
'users',
|
|
142
|
+
[['status', '=', 'inactive']]
|
|
143
|
+
);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Manual Save Control
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Disable auto-save for batch operations
|
|
150
|
+
const driver = new ExcelDriver({
|
|
151
|
+
filePath: './data/batch.xlsx',
|
|
152
|
+
autoSave: false
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Perform multiple operations
|
|
156
|
+
for (let i = 0; i < 1000; i++) {
|
|
157
|
+
await driver.create('records', { index: i });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Save once at the end
|
|
161
|
+
await driver.save();
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Excel File Structure
|
|
165
|
+
|
|
166
|
+
The Excel file will look like this:
|
|
167
|
+
|
|
168
|
+
**Sheet: users**
|
|
169
|
+
| id | name | email | role | age | created_at | updated_at |
|
|
170
|
+
|----|------|-------|------|-----|------------|------------|
|
|
171
|
+
| users-1234-1 | Alice Johnson | alice@example.com | admin | 30 | 2024-01-01T... | 2024-01-01T... |
|
|
172
|
+
| users-1234-2 | Bob Smith | bob@example.com | user | 25 | 2024-01-02T... | 2024-01-02T... |
|
|
173
|
+
|
|
174
|
+
**Sheet: products**
|
|
175
|
+
| id | name | price | category | created_at | updated_at |
|
|
176
|
+
|----|------|-------|----------|------------|------------|
|
|
177
|
+
| products-1234-1 | Laptop | 999.99 | Electronics | 2024-01-01T... | 2024-01-01T... |
|
|
178
|
+
|
|
179
|
+
## Use Cases
|
|
180
|
+
|
|
181
|
+
1. **Data Import/Export**: Import existing Excel data or export application data to Excel
|
|
182
|
+
2. **Prototyping**: Quick database for development without setting up a real database
|
|
183
|
+
3. **Reports**: Generate Excel reports from application data
|
|
184
|
+
4. **Data Migration**: Migrate data from Excel to other databases
|
|
185
|
+
5. **Small Projects**: Simple storage for projects with limited data needs
|
|
186
|
+
|
|
187
|
+
## Performance Considerations
|
|
188
|
+
|
|
189
|
+
- Best for datasets < 10,000 records per sheet
|
|
190
|
+
- All operations are in-memory (fast queries, but uses RAM)
|
|
191
|
+
- Auto-save writes to disk on every change (disable for batch operations)
|
|
192
|
+
- Not suitable for concurrent multi-process access
|
|
193
|
+
|
|
194
|
+
## Next Steps
|
|
195
|
+
|
|
196
|
+
- Explore the [full API documentation](../README.md)
|
|
197
|
+
- Check out other drivers: [SQL](../../sql), [MongoDB](../../mongo), [Memory](../../memory)
|
|
198
|
+
- Learn about [ObjectQL](../../../README.md)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ObjectQL Contributors (https://github.com/objectql)
|
|
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.
|