@gl-life/gl-life-database 1.0.0 → 1.1.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/API.md +249 -1
- package/README.md +67 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cache/index.d.ts +0 -4
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/invalidation.d.ts +0 -156
- package/dist/cache/invalidation.d.ts.map +0 -1
- package/dist/cache/kv-cache.d.ts +0 -79
- package/dist/cache/kv-cache.d.ts.map +0 -1
- package/dist/cache/memory-cache.d.ts +0 -68
- package/dist/cache/memory-cache.d.ts.map +0 -1
- package/dist/cloudforge/d1-adapter.d.ts +0 -67
- package/dist/cloudforge/d1-adapter.d.ts.map +0 -1
- package/dist/cloudforge/do-storage.d.ts +0 -51
- package/dist/cloudforge/do-storage.d.ts.map +0 -1
- package/dist/cloudforge/index.d.ts +0 -4
- package/dist/cloudforge/index.d.ts.map +0 -1
- package/dist/cloudforge/r2-backup.d.ts +0 -38
- package/dist/cloudforge/r2-backup.d.ts.map +0 -1
- package/dist/connection/index.d.ts +0 -2
- package/dist/connection/index.d.ts.map +0 -1
- package/dist/connection/manager.d.ts +0 -54
- package/dist/connection/manager.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/migration/index.d.ts +0 -4
- package/dist/migration/index.d.ts.map +0 -1
- package/dist/migration/loader.d.ts +0 -88
- package/dist/migration/loader.d.ts.map +0 -1
- package/dist/migration/runner.d.ts +0 -91
- package/dist/migration/runner.d.ts.map +0 -1
- package/dist/migration/seeder.d.ts +0 -95
- package/dist/migration/seeder.d.ts.map +0 -1
- package/dist/query/builder.d.ts +0 -47
- package/dist/query/builder.d.ts.map +0 -1
- package/dist/query/index.d.ts +0 -3
- package/dist/query/index.d.ts.map +0 -1
- package/dist/query/raw.d.ts +0 -92
- package/dist/query/raw.d.ts.map +0 -1
- package/dist/tenant/context.d.ts +0 -52
- package/dist/tenant/context.d.ts.map +0 -1
- package/dist/tenant/index.d.ts +0 -4
- package/dist/tenant/index.d.ts.map +0 -1
- package/dist/tenant/query-wrapper.d.ts +0 -96
- package/dist/tenant/query-wrapper.d.ts.map +0 -1
- package/dist/tenant/schema-manager.d.ts +0 -185
- package/dist/tenant/schema-manager.d.ts.map +0 -1
- package/dist/transaction/index.d.ts +0 -2
- package/dist/transaction/index.d.ts.map +0 -1
- package/dist/transaction/transaction.d.ts +0 -51
- package/dist/transaction/transaction.d.ts.map +0 -1
- package/dist/types/cache.d.ts +0 -214
- package/dist/types/cache.d.ts.map +0 -1
- package/dist/types/cloudforge.d.ts +0 -753
- package/dist/types/cloudforge.d.ts.map +0 -1
- package/dist/types/connection.d.ts +0 -91
- package/dist/types/connection.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -10
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/migration.d.ts +0 -225
- package/dist/types/migration.d.ts.map +0 -1
- package/dist/types/plugin.d.ts +0 -432
- package/dist/types/plugin.d.ts.map +0 -1
- package/dist/types/query-builder.d.ts +0 -217
- package/dist/types/query-builder.d.ts.map +0 -1
- package/dist/types/seed.d.ts +0 -187
- package/dist/types/seed.d.ts.map +0 -1
- package/dist/types/tenant.d.ts +0 -140
- package/dist/types/tenant.d.ts.map +0 -1
- package/dist/types/transaction.d.ts +0 -144
- package/dist/types/transaction.d.ts.map +0 -1
package/API.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @gl-life/gl-life-database API Reference
|
|
2
2
|
|
|
3
|
-
**Version**: 1.
|
|
3
|
+
**Version**: 1.1.0
|
|
4
4
|
**Package**: `@gl-life/gl-life-database`
|
|
5
5
|
**License**: Apache-2.0
|
|
6
6
|
**Homepage**: https://gl.life
|
|
@@ -805,6 +805,254 @@ Rollback migrations.
|
|
|
805
805
|
|
|
806
806
|
---
|
|
807
807
|
|
|
808
|
+
## Flex Table System
|
|
809
|
+
|
|
810
|
+
The Flex Table System provides dynamic schema capabilities without ALTER TABLE operations. From `gl-life-data`.
|
|
811
|
+
|
|
812
|
+
### MetaDataService
|
|
813
|
+
|
|
814
|
+
Manages metadata mappings between logical and physical field names.
|
|
815
|
+
|
|
816
|
+
#### Constructor
|
|
817
|
+
|
|
818
|
+
```typescript
|
|
819
|
+
class MetaDataService {
|
|
820
|
+
constructor(dbPath: string);
|
|
821
|
+
}
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
**Parameters**:
|
|
825
|
+
- `dbPath: string` - Path to SQLite database containing metadata
|
|
826
|
+
|
|
827
|
+
#### Methods
|
|
828
|
+
|
|
829
|
+
##### createMapping()
|
|
830
|
+
|
|
831
|
+
```typescript
|
|
832
|
+
createMapping(input: CreateMappingInput): Promise<MetadataSelect>
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
Creates a new metadata mapping, automatically assigning the next available physical field.
|
|
836
|
+
|
|
837
|
+
**Parameters**:
|
|
838
|
+
```typescript
|
|
839
|
+
interface CreateMappingInput {
|
|
840
|
+
tableName: string;
|
|
841
|
+
logicalFieldName: string;
|
|
842
|
+
dataType: 'string' | 'int' | 'decimal' | 'date' | 'boolean' | 'text' | 'datetime' | 'float' | 'bigint' | 'uuid';
|
|
843
|
+
isRequired?: boolean;
|
|
844
|
+
defaultValue?: string | null;
|
|
845
|
+
validationRules?: ValidationRules;
|
|
846
|
+
description?: string;
|
|
847
|
+
displayOrder?: number;
|
|
848
|
+
isIndexed?: boolean;
|
|
849
|
+
isUnique?: boolean;
|
|
850
|
+
foreignKeyRef?: string | null;
|
|
851
|
+
createdBy?: string;
|
|
852
|
+
}
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
**Returns**: `Promise<MetadataSelect>` - Created metadata entry
|
|
856
|
+
|
|
857
|
+
**Example**:
|
|
858
|
+
```typescript
|
|
859
|
+
const metaDataService = new MetaDataService('./database.db');
|
|
860
|
+
|
|
861
|
+
await metaDataService.createMapping({
|
|
862
|
+
tableName: 'products',
|
|
863
|
+
logicalFieldName: 'productName',
|
|
864
|
+
dataType: 'string', // Will map to string_field_1
|
|
865
|
+
isRequired: true,
|
|
866
|
+
description: 'Product name'
|
|
867
|
+
});
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
##### getMappingByLogicalField()
|
|
871
|
+
|
|
872
|
+
```typescript
|
|
873
|
+
getMappingByLogicalField(tableName: string, logicalFieldName: string): MetadataSelect | null
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Parameters**:
|
|
877
|
+
- `tableName: string` - Entity table name
|
|
878
|
+
- `logicalFieldName: string` - Logical field name to look up
|
|
879
|
+
|
|
880
|
+
**Returns**: `MetadataSelect | null` - Metadata entry or null if not found
|
|
881
|
+
|
|
882
|
+
##### getTableMappings()
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
885
|
+
getTableMappings(tableName: string): MetadataSelect[]
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
**Parameters**:
|
|
889
|
+
- `tableName: string` - Entity table name
|
|
890
|
+
|
|
891
|
+
**Returns**: `MetadataSelect[]` - All metadata mappings for the table
|
|
892
|
+
|
|
893
|
+
### Using Flex Tables with TypeSafeQueryBuilder
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
import { TypeSafeQueryBuilder, Logger } from '@gl-life/gl-life-database';
|
|
897
|
+
import { MetaDataService } from 'gl-life-data';
|
|
898
|
+
|
|
899
|
+
const logger = new Logger({ level: 'info' });
|
|
900
|
+
const metaDataService = new MetaDataService('./database.db');
|
|
901
|
+
|
|
902
|
+
// Create mappings
|
|
903
|
+
await metaDataService.createMapping({
|
|
904
|
+
tableName: 'products',
|
|
905
|
+
logicalFieldName: 'name',
|
|
906
|
+
dataType: 'string' // Maps to string_field_1
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
await metaDataService.createMapping({
|
|
910
|
+
tableName: 'products',
|
|
911
|
+
logicalFieldName: 'price',
|
|
912
|
+
dataType: 'decimal' // Maps to decimal_field_1
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
// Query using logical field names
|
|
916
|
+
const builder = new TypeSafeQueryBuilder('products', metaDataService, logger);
|
|
917
|
+
const sql = builder
|
|
918
|
+
.select(['name', 'price']) // Logical names
|
|
919
|
+
.where('price', '>', 100)
|
|
920
|
+
.toSQL();
|
|
921
|
+
|
|
922
|
+
// Generates: SELECT string_field_1, decimal_field_1
|
|
923
|
+
// FROM flex_table
|
|
924
|
+
// WHERE decimal_field_1 > ?
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
### Flex Table Schema
|
|
928
|
+
|
|
929
|
+
Universal schema for all Flex tables:
|
|
930
|
+
|
|
931
|
+
```sql
|
|
932
|
+
CREATE TABLE flex_table (
|
|
933
|
+
id TEXT PRIMARY KEY,
|
|
934
|
+
tenant_id TEXT,
|
|
935
|
+
|
|
936
|
+
-- String fields (10 slots)
|
|
937
|
+
string_field_1 TEXT,
|
|
938
|
+
string_field_2 TEXT,
|
|
939
|
+
string_field_3 TEXT,
|
|
940
|
+
...
|
|
941
|
+
string_field_10 TEXT,
|
|
942
|
+
|
|
943
|
+
-- Integer fields (10 slots)
|
|
944
|
+
int_field_1 INTEGER,
|
|
945
|
+
int_field_2 INTEGER,
|
|
946
|
+
...
|
|
947
|
+
int_field_10 INTEGER,
|
|
948
|
+
|
|
949
|
+
-- Decimal fields (10 slots)
|
|
950
|
+
decimal_field_1 REAL,
|
|
951
|
+
...
|
|
952
|
+
decimal_field_10 REAL,
|
|
953
|
+
|
|
954
|
+
-- Date fields (10 slots)
|
|
955
|
+
date_field_1 TEXT,
|
|
956
|
+
...
|
|
957
|
+
date_field_10 TEXT,
|
|
958
|
+
|
|
959
|
+
-- Boolean fields (10 slots)
|
|
960
|
+
boolean_field_1 INTEGER,
|
|
961
|
+
...
|
|
962
|
+
boolean_field_10 INTEGER,
|
|
963
|
+
|
|
964
|
+
-- Text fields (10 slots)
|
|
965
|
+
text_field_1 TEXT,
|
|
966
|
+
...
|
|
967
|
+
text_field_10 TEXT,
|
|
968
|
+
|
|
969
|
+
-- Additional field types (10 slots each):
|
|
970
|
+
-- datetime_field_1 through datetime_field_10
|
|
971
|
+
-- float_field_1 through float_field_10
|
|
972
|
+
-- bigint_field_1 through bigint_field_10
|
|
973
|
+
-- uuid_field_1 through uuid_field_10
|
|
974
|
+
|
|
975
|
+
-- Overflow for extra fields
|
|
976
|
+
json_data TEXT,
|
|
977
|
+
|
|
978
|
+
-- Timestamps
|
|
979
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
980
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
981
|
+
);
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
### Metadata Table Schema
|
|
985
|
+
|
|
986
|
+
```sql
|
|
987
|
+
CREATE TABLE metadata (
|
|
988
|
+
id TEXT PRIMARY KEY,
|
|
989
|
+
tenant_id TEXT, -- NULL for shared, or specific tenant ID
|
|
990
|
+
table_name TEXT NOT NULL,
|
|
991
|
+
logical_field_name TEXT NOT NULL,
|
|
992
|
+
physical_column_name TEXT NOT NULL,
|
|
993
|
+
data_type TEXT NOT NULL,
|
|
994
|
+
is_required INTEGER NOT NULL DEFAULT 0,
|
|
995
|
+
default_value TEXT,
|
|
996
|
+
validation_rules TEXT, -- JSON
|
|
997
|
+
description TEXT,
|
|
998
|
+
display_order INTEGER,
|
|
999
|
+
is_indexed INTEGER NOT NULL DEFAULT 0,
|
|
1000
|
+
is_unique INTEGER NOT NULL DEFAULT 0,
|
|
1001
|
+
foreign_key_ref TEXT,
|
|
1002
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
1003
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
1004
|
+
created_by TEXT,
|
|
1005
|
+
updated_by TEXT,
|
|
1006
|
+
UNIQUE(tenant_id, table_name, logical_field_name),
|
|
1007
|
+
UNIQUE(tenant_id, table_name, physical_column_name)
|
|
1008
|
+
);
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
### Flex Tables + Multi-Tenancy
|
|
1012
|
+
|
|
1013
|
+
Combine Flex tables with multi-tenancy for per-tenant custom fields:
|
|
1014
|
+
|
|
1015
|
+
```typescript
|
|
1016
|
+
// Shared field for all tenants
|
|
1017
|
+
await metaDataService.createMapping({
|
|
1018
|
+
tableName: 'products',
|
|
1019
|
+
logicalFieldName: 'name',
|
|
1020
|
+
dataType: 'string'
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
// Tenant-specific field (Tenant A only)
|
|
1024
|
+
await connection.execute(`
|
|
1025
|
+
INSERT INTO metadata (
|
|
1026
|
+
id, tenant_id, table_name, logical_field_name,
|
|
1027
|
+
physical_column_name, data_type
|
|
1028
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
1029
|
+
`, [
|
|
1030
|
+
'tenantA_products_warranty',
|
|
1031
|
+
'tenant-A',
|
|
1032
|
+
'products',
|
|
1033
|
+
'warrantyMonths',
|
|
1034
|
+
'int_field_1', // Tenant A uses int_field_1
|
|
1035
|
+
'int'
|
|
1036
|
+
]);
|
|
1037
|
+
|
|
1038
|
+
// Tenant-specific field (Tenant B only)
|
|
1039
|
+
await connection.execute(`
|
|
1040
|
+
INSERT INTO metadata (
|
|
1041
|
+
id, tenant_id, table_name, logical_field_name,
|
|
1042
|
+
physical_column_name, data_type
|
|
1043
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
1044
|
+
`, [
|
|
1045
|
+
'tenantB_products_size',
|
|
1046
|
+
'tenant-B',
|
|
1047
|
+
'products',
|
|
1048
|
+
'size',
|
|
1049
|
+
'string_field_2', // Tenant B uses string_field_2
|
|
1050
|
+
'string'
|
|
1051
|
+
]);
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
---
|
|
1055
|
+
|
|
808
1056
|
## CloudForge Adapters
|
|
809
1057
|
|
|
810
1058
|
### D1Adapter
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Enhanced gl-life-data wrapper with CloudForge features - Type-safe database abst
|
|
|
9
9
|
### Key Features
|
|
10
10
|
|
|
11
11
|
- 🗄️ **Type-Safe Query Builder** - Fluent API with full TypeScript support extending gl-life-data
|
|
12
|
+
- 🔀 **Flex Table System** - Dynamic schema without ALTER TABLE, metadata-driven field mapping
|
|
12
13
|
- 👥 **Multi-Tenancy** - Built-in tenant isolation with Row-Level Security (RLS)
|
|
13
14
|
- ⚡ **Caching Layer** - High-performance query result caching with memory and Cloudflare KV backends
|
|
14
15
|
- 🔄 **Migrations** - Version-controlled database migrations with rollback support
|
|
@@ -180,6 +181,72 @@ export default {
|
|
|
180
181
|
};
|
|
181
182
|
```
|
|
182
183
|
|
|
184
|
+
### Flex Table System
|
|
185
|
+
|
|
186
|
+
The Flex Table System is a powerful feature from gl-life-data that provides dynamic schema capabilities without ALTER TABLE operations. Perfect for multi-tenant SaaS applications where each tenant needs custom fields.
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { TypeSafeQueryBuilder, Logger } from '@gl-life/gl-life-database';
|
|
190
|
+
import { MetaDataService } from 'gl-life-data';
|
|
191
|
+
|
|
192
|
+
// Initialize metadata service
|
|
193
|
+
const metaDataService = new MetaDataService('./database.db');
|
|
194
|
+
|
|
195
|
+
// Create metadata mapping: logical field → physical column
|
|
196
|
+
await metaDataService.createMapping({
|
|
197
|
+
tableName: 'products',
|
|
198
|
+
logicalFieldName: 'productName',
|
|
199
|
+
dataType: 'string', // Maps to string_field_1
|
|
200
|
+
isRequired: true,
|
|
201
|
+
description: 'Product name'
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
await metaDataService.createMapping({
|
|
205
|
+
tableName: 'products',
|
|
206
|
+
logicalFieldName: 'price',
|
|
207
|
+
dataType: 'decimal', // Maps to decimal_field_1
|
|
208
|
+
isRequired: true
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Query using logical field names
|
|
212
|
+
const builder = new TypeSafeQueryBuilder('products', metaDataService, logger);
|
|
213
|
+
const sql = builder
|
|
214
|
+
.select(['productName', 'price']) // Uses logical names
|
|
215
|
+
.where('price', '>', 100)
|
|
216
|
+
.toSQL();
|
|
217
|
+
// Generates: SELECT string_field_1, decimal_field_1 FROM flex_table WHERE decimal_field_1 > ?
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Key Benefits:**
|
|
221
|
+
- **Universal Schema**: All tables use same physical structure (string_field_1, int_field_1, etc.)
|
|
222
|
+
- **No ALTER TABLE**: Add fields by creating metadata entries
|
|
223
|
+
- **Type Safety**: 10 fields per data type (string, int, decimal, date, boolean, text, datetime, float, bigint, uuid)
|
|
224
|
+
- **Multi-Tenant Ready**: Different tenants can have different custom fields
|
|
225
|
+
- **Query Transparency**: Use logical field names, metadata handles physical mapping
|
|
226
|
+
|
|
227
|
+
**Flex Table Schema:**
|
|
228
|
+
```sql
|
|
229
|
+
CREATE TABLE flex_table (
|
|
230
|
+
id TEXT PRIMARY KEY,
|
|
231
|
+
tenant_id TEXT,
|
|
232
|
+
-- 10 string fields
|
|
233
|
+
string_field_1 TEXT,
|
|
234
|
+
string_field_2 TEXT,
|
|
235
|
+
...
|
|
236
|
+
string_field_10 TEXT,
|
|
237
|
+
-- 10 int fields
|
|
238
|
+
int_field_1 INTEGER,
|
|
239
|
+
...
|
|
240
|
+
int_field_10 INTEGER,
|
|
241
|
+
-- Plus: decimal, date, boolean, text, datetime, float, bigint, uuid fields
|
|
242
|
+
json_data TEXT, -- Overflow for extra fields
|
|
243
|
+
created_at TEXT,
|
|
244
|
+
updated_at TEXT
|
|
245
|
+
);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
See [examples/06-flex-tables.ts](./examples/06-flex-tables.ts) and [examples/07-flex-with-multi-tenancy.ts](./examples/07-flex-with-multi-tenancy.ts) for complete workflows.
|
|
249
|
+
|
|
183
250
|
## Usage
|
|
184
251
|
|
|
185
252
|
### Query Builder
|