@neupgroup/mapper 1.6.1 → 1.7.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/dist/cli/create-migration.js +16 -16
- package/dist/errors.js +1 -1
- package/dist/fluent-mapper.d.ts +60 -38
- package/dist/fluent-mapper.js +231 -129
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -46,34 +46,34 @@ import { Mapper, TableMigrator } from '@neupgroup/mapper';
|
|
|
46
46
|
export const usesConnection = 'default';
|
|
47
47
|
|
|
48
48
|
export async function up() {
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const schema = Mapper.schema('${tableName}');
|
|
50
|
+
schema.useConnection(usesConnection);
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* CASE 1: CREATE
|
|
54
|
-
* Use this when defining a new
|
|
53
|
+
* CASE 1: CREATE SCHEMA (Requires .exec())
|
|
54
|
+
* Use this when defining a new schema. addColumn calls are batched.
|
|
55
55
|
*/
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
// await
|
|
56
|
+
// schema.addColumn('id').type('int').isPrimary().autoIncrement();
|
|
57
|
+
// schema.addColumn('name').type('string').notNull();
|
|
58
|
+
// await schema.exec();
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* CASE 2: ALTER
|
|
61
|
+
* CASE 2: ALTER SCHEMA (Queued actions)
|
|
62
62
|
* These methods are queued and only execute when you call .exec()
|
|
63
63
|
*/
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// await
|
|
64
|
+
// schema.dropColumn('old_field');
|
|
65
|
+
// schema.dropUnique('field_name');
|
|
66
|
+
// await schema.exec();
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export async function down() {
|
|
70
70
|
/**
|
|
71
|
-
* DROP
|
|
72
|
-
* This will drop the
|
|
71
|
+
* DROP SCHEMA (Immediate action)
|
|
72
|
+
* This will drop the schema from the DB and delete the local schema file.
|
|
73
73
|
*/
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
await
|
|
74
|
+
const schema = Mapper.schema('${tableName}');
|
|
75
|
+
schema.useConnection(usesConnection);
|
|
76
|
+
await schema.drop().exec();
|
|
77
77
|
}
|
|
78
78
|
`;
|
|
79
79
|
fs.writeFileSync(filePath, fileContent.trim());
|
package/dist/errors.js
CHANGED
|
@@ -40,7 +40,7 @@ export class SchemaExistingError extends MapperError {
|
|
|
40
40
|
}
|
|
41
41
|
export class SchemaMissingError extends MapperError {
|
|
42
42
|
constructor(name) {
|
|
43
|
-
super(`Unknown schema '${name}'.`, 'SCHEMA_UNKNOWN', `Ensure you have
|
|
43
|
+
super(`Unknown schema '${name}'.`, 'SCHEMA_UNKNOWN', `The schema '${name}' is not registered. Ensure you have run migrations, called 'Mapper.discover()', or defined it manually using 'Mapper.schema().create("${name}")'.`);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
export class SchemaConfigurationError extends MapperError {
|
package/dist/fluent-mapper.d.ts
CHANGED
|
@@ -4,9 +4,10 @@ export declare class FluentQueryBuilder {
|
|
|
4
4
|
private mapper;
|
|
5
5
|
private schemaName;
|
|
6
6
|
private query;
|
|
7
|
-
constructor(mapper: any, schemaName: string);
|
|
7
|
+
constructor(mapper: any, schemaName: string, connectionName?: string);
|
|
8
8
|
where(field: string, value: any, operator?: string): this;
|
|
9
9
|
whereComplex(raw: string): this;
|
|
10
|
+
whereRaw(raw: string): this;
|
|
10
11
|
limit(n: number): this;
|
|
11
12
|
offset(n: number): this;
|
|
12
13
|
to(update: Record<string, any>): this;
|
|
@@ -15,10 +16,32 @@ export declare class FluentQueryBuilder {
|
|
|
15
16
|
getOne(): Promise<Record<string, any> | null>;
|
|
16
17
|
add(data: Record<string, any>): Promise<any>;
|
|
17
18
|
insert(data: Record<string, any>): Promise<any>;
|
|
18
|
-
update(): Promise<void>;
|
|
19
|
+
update(data?: Record<string, any>): Promise<void>;
|
|
19
20
|
delete(): Promise<void>;
|
|
20
21
|
deleteOne(): Promise<void>;
|
|
21
|
-
updateOne(): Promise<void>;
|
|
22
|
+
updateOne(data?: Record<string, any>): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export declare class FluentSchemaBuilder {
|
|
25
|
+
private mapper;
|
|
26
|
+
private schemaName;
|
|
27
|
+
private _migrator?;
|
|
28
|
+
constructor(mapper: any, schemaName: string, connectionName?: string);
|
|
29
|
+
private getDef;
|
|
30
|
+
set fields(config: any);
|
|
31
|
+
structure(config: any): this;
|
|
32
|
+
collection(collectionName: string): this;
|
|
33
|
+
set insertableFields(val: string[]);
|
|
34
|
+
set updatableFields(val: string[]);
|
|
35
|
+
set deleteType(val: 'softDelete' | 'hardDelete');
|
|
36
|
+
set massDeleteAllowed(val: boolean);
|
|
37
|
+
set massEditAllowed(val: boolean);
|
|
38
|
+
get migrator(): TableMigrator;
|
|
39
|
+
useConnection(name: string): this;
|
|
40
|
+
addColumn(name: string): import("./migrator.js").ColumnBuilder;
|
|
41
|
+
selectColumn(name: string): import("./migrator.js").ColumnBuilder;
|
|
42
|
+
dropColumn(name: string): this;
|
|
43
|
+
drop(): this;
|
|
44
|
+
exec(): Promise<void>;
|
|
22
45
|
}
|
|
23
46
|
export declare class FluentConnectionBuilder {
|
|
24
47
|
private mapper;
|
|
@@ -30,24 +53,33 @@ export declare class FluentConnectionBuilder {
|
|
|
30
53
|
query(schemaName: string): FluentQueryBuilder;
|
|
31
54
|
useConnection(connectionName: string): FluentConnectionSelector;
|
|
32
55
|
}
|
|
33
|
-
export declare class
|
|
56
|
+
export declare class RawQueryBuilder {
|
|
34
57
|
private mapper;
|
|
35
|
-
private
|
|
36
|
-
private
|
|
37
|
-
constructor(mapper: any,
|
|
38
|
-
|
|
58
|
+
private sql;
|
|
59
|
+
private _bindings;
|
|
60
|
+
constructor(mapper: any, sql: string);
|
|
61
|
+
bind(bindings: any[] | any): this;
|
|
62
|
+
run(): Promise<any>;
|
|
39
63
|
}
|
|
40
|
-
export declare class
|
|
64
|
+
export declare class BaseQueryBuilder {
|
|
41
65
|
private mapper;
|
|
42
|
-
private
|
|
43
|
-
private
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
private target;
|
|
67
|
+
private queryBuilder;
|
|
68
|
+
private _select;
|
|
69
|
+
private _insertData?;
|
|
70
|
+
private _updateData?;
|
|
71
|
+
private _action;
|
|
72
|
+
constructor(mapper: any, target: string);
|
|
73
|
+
select(fields: string[]): this;
|
|
74
|
+
where(field: string, value: any, operator?: string): this;
|
|
75
|
+
whereRaw(raw: string): this;
|
|
76
|
+
limit(n: number): this;
|
|
77
|
+
offset(n: number): this;
|
|
78
|
+
insert(data: any): this;
|
|
79
|
+
update(data: any): this;
|
|
80
|
+
get(): Promise<any>;
|
|
81
|
+
getOne(): Promise<any>;
|
|
82
|
+
run(): Promise<any>;
|
|
51
83
|
}
|
|
52
84
|
export declare class FluentApiRequestBuilder {
|
|
53
85
|
private mapper;
|
|
@@ -70,10 +102,10 @@ export declare class FluentConnectionSelector {
|
|
|
70
102
|
private connectionName;
|
|
71
103
|
constructor(mapper: any, connectionName: string);
|
|
72
104
|
schema(schemaName: string): FluentSchemaBuilder;
|
|
105
|
+
schemas(schemaName: string): FluentSchemaBuilder;
|
|
73
106
|
query(schemaName: string): FluentQueryBuilder;
|
|
74
107
|
table(tableName: string): FluentQueryBuilder;
|
|
75
108
|
collection(collectionName: string): FluentQueryBuilder;
|
|
76
|
-
schemas(schemaName: string): FluentSchemaWrapper;
|
|
77
109
|
path(path: string): FluentApiRequestBuilder;
|
|
78
110
|
header(key: string | Record<string, string | string[]>, value?: string | string[]): FluentApiRequestBuilder;
|
|
79
111
|
headers(headers: Record<string, string> | any[]): FluentApiRequestBuilder;
|
|
@@ -87,7 +119,10 @@ export declare class FluentMapper {
|
|
|
87
119
|
private mapper;
|
|
88
120
|
constructor(mapper: any);
|
|
89
121
|
query(schemaName: string): FluentQueryBuilder;
|
|
122
|
+
schema(name: string): FluentSchemaBuilder;
|
|
90
123
|
table(name: string): FluentQueryBuilder;
|
|
124
|
+
raw(sql: string): RawQueryBuilder;
|
|
125
|
+
base(target: string): BaseQueryBuilder;
|
|
91
126
|
makeConnection(name: string, type: ConnectionType, config: Record<string, any>): FluentConnectionBuilder;
|
|
92
127
|
useConnection(connectionName: string): FluentConnectionSelector;
|
|
93
128
|
connection(connectionOrConfig: string | Record<string, any>): FluentConnectionSelector;
|
|
@@ -105,10 +140,14 @@ export declare class StaticMapper {
|
|
|
105
140
|
static makeConnection(name: string, type: ConnectionType, config: Record<string, any>): FluentConnectionBuilder;
|
|
106
141
|
static makeTempConnection(type: ConnectionType, config: Record<string, any>): FluentConnectionBuilder;
|
|
107
142
|
static query(schemaName: string): FluentQueryBuilder;
|
|
143
|
+
static schema(name: string): FluentSchemaBuilder;
|
|
144
|
+
static schema(): SchemaManagerWrapper;
|
|
108
145
|
static table(name: string): FluentQueryBuilder;
|
|
146
|
+
static raw(sql: string): RawQueryBuilder;
|
|
147
|
+
static base(target: string): BaseQueryBuilder;
|
|
109
148
|
static connection(connectionOrConfig: string | Record<string, any>): FluentConnectionSelector;
|
|
110
149
|
static useConnection(connectionName: string): FluentConnectionSelector;
|
|
111
|
-
static schemas(name?: string):
|
|
150
|
+
static schemas(name?: string): any;
|
|
112
151
|
static get(schemaName: string, filters?: Record<string, any>): Promise<Record<string, any>[]>;
|
|
113
152
|
static getOne(schemaName: string, filters?: Record<string, any>): Promise<Record<string, any> | null>;
|
|
114
153
|
static add(schemaName: string, data: Record<string, any>): Promise<any>;
|
|
@@ -120,27 +159,10 @@ export declare class StaticMapper {
|
|
|
120
159
|
}
|
|
121
160
|
export declare const Mapper: typeof StaticMapper;
|
|
122
161
|
export default Mapper;
|
|
123
|
-
export declare class FluentSchemaWrapper {
|
|
124
|
-
private manager;
|
|
125
|
-
private name;
|
|
126
|
-
private connectionName?;
|
|
127
|
-
constructor(manager: SchemaManager, name: string, connectionName?: string | undefined);
|
|
128
|
-
private getDef;
|
|
129
|
-
set fields(config: any);
|
|
130
|
-
set insertableFields(val: string[]);
|
|
131
|
-
set updatableFields(val: string[]);
|
|
132
|
-
set deleteType(val: 'softDelete' | 'hardDelete');
|
|
133
|
-
set massDeleteAllowed(val: boolean);
|
|
134
|
-
set massEditAllowed(val: boolean);
|
|
135
|
-
get(...fields: string[]): any;
|
|
136
|
-
limit(n: number): FluentQueryBuilder;
|
|
137
|
-
offset(n: number): FluentQueryBuilder;
|
|
138
|
-
insert(data: Record<string, any>): Promise<any>;
|
|
139
|
-
dropTable(): Promise<void>;
|
|
140
|
-
}
|
|
141
162
|
export declare class SchemaManagerWrapper {
|
|
142
163
|
private manager;
|
|
143
164
|
constructor(manager: SchemaManager);
|
|
144
165
|
table(name: string): TableMigrator;
|
|
166
|
+
schema(name: string): TableMigrator;
|
|
145
167
|
dropTable(name: string): Promise<void>;
|
|
146
168
|
}
|
package/dist/fluent-mapper.js
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { createMapper } from './mapper.js';
|
|
2
2
|
import { TableMigrator } from './migrator.js';
|
|
3
|
+
// DML Builder (Querying)
|
|
3
4
|
export class FluentQueryBuilder {
|
|
4
|
-
constructor(mapper, schemaName) {
|
|
5
|
+
constructor(mapper, schemaName, connectionName) {
|
|
5
6
|
this.mapper = mapper;
|
|
6
7
|
this.schemaName = schemaName;
|
|
7
|
-
|
|
8
|
+
try {
|
|
9
|
+
this.query = mapper.use(schemaName);
|
|
10
|
+
// Auto-update connection if provided override
|
|
11
|
+
if (connectionName) {
|
|
12
|
+
// We can't easily update the schema def from query builder purely,
|
|
13
|
+
// but the Use() call presumably set up the schemaQuery.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
// Auto-register schema if missing
|
|
18
|
+
mapper.getSchemaManager().create(schemaName).use({ connection: connectionName || 'default', collection: schemaName }).setStructure({});
|
|
19
|
+
this.query = mapper.use(schemaName);
|
|
20
|
+
}
|
|
8
21
|
}
|
|
9
22
|
where(field, value, operator) {
|
|
10
23
|
this.query.where(field, value, operator);
|
|
@@ -14,6 +27,9 @@ export class FluentQueryBuilder {
|
|
|
14
27
|
this.query.whereComplex(raw);
|
|
15
28
|
return this;
|
|
16
29
|
}
|
|
30
|
+
whereRaw(raw) {
|
|
31
|
+
return this.whereComplex(raw);
|
|
32
|
+
}
|
|
17
33
|
limit(n) {
|
|
18
34
|
this.query.limit(n);
|
|
19
35
|
return this;
|
|
@@ -26,22 +42,13 @@ export class FluentQueryBuilder {
|
|
|
26
42
|
this.query.to(update);
|
|
27
43
|
return this;
|
|
28
44
|
}
|
|
29
|
-
// If args provided, act as SELECT (projection) and return this.
|
|
30
|
-
// If no args, act as execute() (but this class is thenable so we can just return this if we want consistency,
|
|
31
|
-
// but existing API returns Promise directly. To check user intent:
|
|
32
|
-
// User: get('f1').limit(1).
|
|
33
|
-
// So get('f1') must return this.
|
|
34
45
|
get(...fields) {
|
|
35
46
|
if (fields.length > 0) {
|
|
36
|
-
// Apply field selection? SchemaQuery needs a way to filter fields.
|
|
37
|
-
// We'll add this capability to Field filtering in SchemaQuery or just use 'fields' option in buildOptions.
|
|
38
|
-
// For now, let's assume we can modify the query's field list.
|
|
39
47
|
this.query.selectFields(fields);
|
|
40
48
|
return this;
|
|
41
49
|
}
|
|
42
|
-
return this.query.get();
|
|
50
|
+
return this.query.get();
|
|
43
51
|
}
|
|
44
|
-
// Make the builder thenable
|
|
45
52
|
then(onfulfilled, onrejected) {
|
|
46
53
|
return this.query.get().then(onfulfilled, onrejected);
|
|
47
54
|
}
|
|
@@ -54,7 +61,10 @@ export class FluentQueryBuilder {
|
|
|
54
61
|
async insert(data) {
|
|
55
62
|
return this.add(data);
|
|
56
63
|
}
|
|
57
|
-
async update() {
|
|
64
|
+
async update(data) {
|
|
65
|
+
if (data) {
|
|
66
|
+
this.query.to(data);
|
|
67
|
+
}
|
|
58
68
|
return this.query.update();
|
|
59
69
|
}
|
|
60
70
|
async delete() {
|
|
@@ -63,10 +73,106 @@ export class FluentQueryBuilder {
|
|
|
63
73
|
async deleteOne() {
|
|
64
74
|
return this.query.deleteOne();
|
|
65
75
|
}
|
|
66
|
-
async updateOne() {
|
|
76
|
+
async updateOne(data) {
|
|
77
|
+
if (data) {
|
|
78
|
+
this.query.to(data);
|
|
79
|
+
}
|
|
67
80
|
return this.query.updateOne();
|
|
68
81
|
}
|
|
69
82
|
}
|
|
83
|
+
// DDL Builder (Migrations & Schema Definition)
|
|
84
|
+
export class FluentSchemaBuilder {
|
|
85
|
+
constructor(mapper, schemaName, connectionName) {
|
|
86
|
+
this.mapper = mapper;
|
|
87
|
+
this.schemaName = schemaName;
|
|
88
|
+
// Ensure schema exists for configuration
|
|
89
|
+
const manager = mapper.getSchemaManager();
|
|
90
|
+
const exists = manager.schemas.has(schemaName);
|
|
91
|
+
if (!exists) {
|
|
92
|
+
manager.create(schemaName).use({ connection: connectionName || 'default', collection: schemaName }).setStructure({});
|
|
93
|
+
}
|
|
94
|
+
// If connectionName provided, update it
|
|
95
|
+
if (connectionName) {
|
|
96
|
+
const def = this.getDef();
|
|
97
|
+
if (def)
|
|
98
|
+
def.connectionName = connectionName;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
getDef() {
|
|
102
|
+
return this.mapper.getSchemaManager().schemas.get(this.schemaName);
|
|
103
|
+
}
|
|
104
|
+
// Schema Configuration Proxies
|
|
105
|
+
set fields(config) {
|
|
106
|
+
const def = this.getDef();
|
|
107
|
+
if (def) {
|
|
108
|
+
const parsed = parseDescriptorStructure(config);
|
|
109
|
+
def.fields = parsed.fields;
|
|
110
|
+
def.fieldsMap = new Map();
|
|
111
|
+
def.fields.forEach((f) => def.fieldsMap.set(f.name, f));
|
|
112
|
+
def.allowUndefinedFields = parsed.allowUndefinedFields;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
structure(config) {
|
|
116
|
+
this.fields = config;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
collection(collectionName) {
|
|
120
|
+
const def = this.getDef();
|
|
121
|
+
if (def)
|
|
122
|
+
def.collectionName = collectionName;
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
set insertableFields(val) {
|
|
126
|
+
const def = this.getDef();
|
|
127
|
+
if (def)
|
|
128
|
+
def.insertableFields = val;
|
|
129
|
+
}
|
|
130
|
+
set updatableFields(val) {
|
|
131
|
+
const def = this.getDef();
|
|
132
|
+
if (def)
|
|
133
|
+
def.updatableFields = val;
|
|
134
|
+
}
|
|
135
|
+
set deleteType(val) {
|
|
136
|
+
const def = this.getDef();
|
|
137
|
+
if (def)
|
|
138
|
+
def.deleteType = val;
|
|
139
|
+
}
|
|
140
|
+
set massDeleteAllowed(val) {
|
|
141
|
+
const def = this.getDef();
|
|
142
|
+
if (def)
|
|
143
|
+
def.massDeleteAllowed = val;
|
|
144
|
+
}
|
|
145
|
+
set massEditAllowed(val) {
|
|
146
|
+
const def = this.getDef();
|
|
147
|
+
if (def)
|
|
148
|
+
def.massEditAllowed = val;
|
|
149
|
+
}
|
|
150
|
+
// Migration / DDL Methods
|
|
151
|
+
get migrator() {
|
|
152
|
+
if (!this._migrator) {
|
|
153
|
+
this._migrator = new TableMigrator(this.schemaName);
|
|
154
|
+
const def = this.getDef();
|
|
155
|
+
if (def === null || def === void 0 ? void 0 : def.connectionName) {
|
|
156
|
+
this._migrator.useConnection(def.connectionName);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return this._migrator;
|
|
160
|
+
}
|
|
161
|
+
useConnection(name) {
|
|
162
|
+
this.migrator.useConnection(name);
|
|
163
|
+
const def = this.getDef();
|
|
164
|
+
if (def)
|
|
165
|
+
def.connectionName = name;
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
addColumn(name) { return this.migrator.addColumn(name); }
|
|
169
|
+
selectColumn(name) { return this.migrator.selectColumn(name); }
|
|
170
|
+
dropColumn(name) { this.migrator.dropColumn(name); return this; }
|
|
171
|
+
drop() { this.migrator.drop(); return this; }
|
|
172
|
+
async exec() {
|
|
173
|
+
return this.migrator.exec();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
70
176
|
export class FluentConnectionBuilder {
|
|
71
177
|
constructor(mapper, connectionName, connectionType, config) {
|
|
72
178
|
this.mapper = mapper;
|
|
@@ -86,28 +192,94 @@ export class FluentConnectionBuilder {
|
|
|
86
192
|
return new FluentConnectionSelector(this.mapper, connectionName);
|
|
87
193
|
}
|
|
88
194
|
}
|
|
89
|
-
export class
|
|
90
|
-
constructor(mapper,
|
|
195
|
+
export class RawQueryBuilder {
|
|
196
|
+
constructor(mapper, sql) {
|
|
91
197
|
this.mapper = mapper;
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
198
|
+
this.sql = sql;
|
|
199
|
+
this._bindings = [];
|
|
94
200
|
}
|
|
95
|
-
|
|
96
|
-
|
|
201
|
+
bind(bindings) {
|
|
202
|
+
if (Array.isArray(bindings)) {
|
|
203
|
+
this._bindings = bindings;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
this._bindings = [bindings];
|
|
207
|
+
}
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
async run() {
|
|
211
|
+
// Find a default connection or use one if specified (not currently supported in raw() entry point args, defaulting to 'default')
|
|
212
|
+
// To support explicit connection for raw, we might need Mapper.connection('name').raw(...)
|
|
213
|
+
const connections = this.mapper.getConnections();
|
|
214
|
+
const conn = connections.get('default'); // Default fallback
|
|
215
|
+
if (!conn)
|
|
216
|
+
throw new Error("No default connection found for raw query.");
|
|
217
|
+
const adapter = connections.getAdapter(conn.name);
|
|
218
|
+
if (adapter && typeof adapter.query === 'function') {
|
|
219
|
+
return adapter.query(this.sql, this._bindings);
|
|
220
|
+
}
|
|
221
|
+
throw new Error(`Connection '${conn.name}' does not support raw queries.`);
|
|
97
222
|
}
|
|
98
223
|
}
|
|
99
|
-
export class
|
|
100
|
-
constructor(mapper,
|
|
224
|
+
export class BaseQueryBuilder {
|
|
225
|
+
constructor(mapper, target) {
|
|
101
226
|
this.mapper = mapper;
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
227
|
+
this.target = target;
|
|
228
|
+
this._select = [];
|
|
229
|
+
this._action = 'select';
|
|
230
|
+
this.queryBuilder = new FluentQueryBuilder(mapper, target);
|
|
231
|
+
}
|
|
232
|
+
select(fields) {
|
|
233
|
+
this._select = fields;
|
|
234
|
+
this._action = 'select';
|
|
235
|
+
return this;
|
|
105
236
|
}
|
|
106
|
-
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
237
|
+
where(field, value, operator) {
|
|
238
|
+
this.queryBuilder.where(field, value, operator);
|
|
239
|
+
return this;
|
|
240
|
+
}
|
|
241
|
+
whereRaw(raw) {
|
|
242
|
+
this.queryBuilder.whereRaw(raw);
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
limit(n) {
|
|
246
|
+
this.queryBuilder.limit(n);
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
offset(n) {
|
|
250
|
+
this.queryBuilder.offset(n);
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
insert(data) {
|
|
254
|
+
this._insertData = data;
|
|
255
|
+
this._action = 'insert';
|
|
256
|
+
return this;
|
|
257
|
+
}
|
|
258
|
+
update(data) {
|
|
259
|
+
this._updateData = data;
|
|
260
|
+
this._action = 'update';
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
async get() {
|
|
264
|
+
return this.queryBuilder.get(...this._select);
|
|
265
|
+
}
|
|
266
|
+
async getOne() {
|
|
267
|
+
// If select fields were provided, apply them first (though getOne usually fetches all or requires separate select handling in standard query)
|
|
268
|
+
// FluentQueryBuilder.getOne doesn't take args, but we can ensure fields are selected if underlying support exists.
|
|
269
|
+
// Current FluentQueryBuilder doesn't support select() state persistence easily without get() args.
|
|
270
|
+
// We'll proceed with getOne(). To support partial select on getOne, we might need to enhance FluentQueryBuilder or just fetch all.
|
|
271
|
+
// For now, delegating effectively:
|
|
272
|
+
return this.queryBuilder.getOne();
|
|
273
|
+
}
|
|
274
|
+
async run() {
|
|
275
|
+
if (this._action === 'insert') {
|
|
276
|
+
return this.queryBuilder.insert(this._insertData);
|
|
277
|
+
}
|
|
278
|
+
if (this._action === 'update') {
|
|
279
|
+
return this.queryBuilder.update(this._updateData);
|
|
280
|
+
}
|
|
281
|
+
// Fallback or other actions
|
|
282
|
+
return this.get();
|
|
111
283
|
}
|
|
112
284
|
}
|
|
113
285
|
export class FluentApiRequestBuilder {
|
|
@@ -192,8 +364,11 @@ export class FluentConnectionSelector {
|
|
|
192
364
|
schema(schemaName) {
|
|
193
365
|
return new FluentSchemaBuilder(this.mapper, schemaName, this.connectionName);
|
|
194
366
|
}
|
|
367
|
+
schemas(schemaName) {
|
|
368
|
+
return this.schema(schemaName);
|
|
369
|
+
}
|
|
195
370
|
query(schemaName) {
|
|
196
|
-
return new FluentQueryBuilder(this.mapper, schemaName);
|
|
371
|
+
return new FluentQueryBuilder(this.mapper, schemaName, this.connectionName);
|
|
197
372
|
}
|
|
198
373
|
table(tableName) {
|
|
199
374
|
return this.query(tableName);
|
|
@@ -201,9 +376,6 @@ export class FluentConnectionSelector {
|
|
|
201
376
|
collection(collectionName) {
|
|
202
377
|
return this.query(collectionName);
|
|
203
378
|
}
|
|
204
|
-
schemas(schemaName) {
|
|
205
|
-
return new FluentSchemaWrapper(this.mapper.getSchemaManager(), schemaName, this.connectionName);
|
|
206
|
-
}
|
|
207
379
|
// API Request methods
|
|
208
380
|
path(path) {
|
|
209
381
|
return new FluentApiRequestBuilder(this.mapper, this.connectionName, path);
|
|
@@ -237,9 +409,18 @@ export class FluentMapper {
|
|
|
237
409
|
query(schemaName) {
|
|
238
410
|
return new FluentQueryBuilder(this.mapper, schemaName);
|
|
239
411
|
}
|
|
412
|
+
schema(name) {
|
|
413
|
+
return new FluentSchemaBuilder(this.mapper, name);
|
|
414
|
+
}
|
|
240
415
|
table(name) {
|
|
241
416
|
return this.query(name);
|
|
242
417
|
}
|
|
418
|
+
raw(sql) {
|
|
419
|
+
return new RawQueryBuilder(this.mapper, sql);
|
|
420
|
+
}
|
|
421
|
+
base(target) {
|
|
422
|
+
return new BaseQueryBuilder(this.mapper, target);
|
|
423
|
+
}
|
|
243
424
|
makeConnection(name, type, config) {
|
|
244
425
|
return new FluentConnectionBuilder(this.mapper, name, type, config);
|
|
245
426
|
}
|
|
@@ -306,9 +487,20 @@ export class StaticMapper {
|
|
|
306
487
|
static query(schemaName) {
|
|
307
488
|
return StaticMapper.getFluentMapper().query(schemaName);
|
|
308
489
|
}
|
|
490
|
+
static schema(name) {
|
|
491
|
+
if (name)
|
|
492
|
+
return StaticMapper.getFluentMapper().schema(name);
|
|
493
|
+
return StaticMapper.schemas();
|
|
494
|
+
}
|
|
309
495
|
static table(name) {
|
|
310
496
|
return StaticMapper.query(name);
|
|
311
497
|
}
|
|
498
|
+
static raw(sql) {
|
|
499
|
+
return StaticMapper.getFluentMapper().raw(sql);
|
|
500
|
+
}
|
|
501
|
+
static base(target) {
|
|
502
|
+
return StaticMapper.getFluentMapper().base(target);
|
|
503
|
+
}
|
|
312
504
|
// New API
|
|
313
505
|
static connection(connectionOrConfig) {
|
|
314
506
|
return StaticMapper.getFluentMapper().connection(connectionOrConfig);
|
|
@@ -318,9 +510,8 @@ export class StaticMapper {
|
|
|
318
510
|
return StaticMapper.connection(connectionName);
|
|
319
511
|
}
|
|
320
512
|
static schemas(name) {
|
|
321
|
-
if (name)
|
|
322
|
-
return
|
|
323
|
-
}
|
|
513
|
+
if (name)
|
|
514
|
+
return StaticMapper.schema(name);
|
|
324
515
|
return new SchemaManagerWrapper(StaticMapper.getFluentMapper().mapper.getSchemaManager());
|
|
325
516
|
}
|
|
326
517
|
// Direct static methods
|
|
@@ -353,98 +544,6 @@ export class StaticMapper {
|
|
|
353
544
|
// Export a default instance for convenience
|
|
354
545
|
export const Mapper = StaticMapper;
|
|
355
546
|
export default Mapper;
|
|
356
|
-
export class FluentSchemaWrapper {
|
|
357
|
-
// builder unused
|
|
358
|
-
constructor(manager, name, connectionName) {
|
|
359
|
-
this.manager = manager;
|
|
360
|
-
this.name = name;
|
|
361
|
-
this.connectionName = connectionName;
|
|
362
|
-
// Ensure schema exists or create it?
|
|
363
|
-
// User pattern: Mapper.schemas('name').fields = ...
|
|
364
|
-
// So we likely need to create it if missing, or update it.
|
|
365
|
-
try {
|
|
366
|
-
this.manager.create(name).use({ connection: connectionName || 'default', collection: name }).setStructure({});
|
|
367
|
-
}
|
|
368
|
-
catch (e) {
|
|
369
|
-
// Ignore if exists, but maybe update connection if strictly provided?
|
|
370
|
-
// Use existing definition if available.
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
getDef() {
|
|
374
|
-
// Access private map from manager? Or expose a get method.
|
|
375
|
-
// Manager has .schemas map.
|
|
376
|
-
return this.manager.schemas.get(this.name);
|
|
377
|
-
}
|
|
378
|
-
set fields(config) {
|
|
379
|
-
// Update schema structure
|
|
380
|
-
const builder = new FluentSchemaBuilder(null, this.name, ''); // Dummy wrapper or use internal
|
|
381
|
-
// Easier: use Manager.create(name) returns SchemaBuilder which has setStructure.
|
|
382
|
-
// But if it exists, create() throws.
|
|
383
|
-
// We need 'update' or direct access.
|
|
384
|
-
// Let's hack: re-register or update def.
|
|
385
|
-
const def = this.getDef();
|
|
386
|
-
if (def) {
|
|
387
|
-
// Re-parse
|
|
388
|
-
const parsed = parseDescriptorStructure(config);
|
|
389
|
-
def.fields = parsed.fields;
|
|
390
|
-
def.fieldsMap = new Map();
|
|
391
|
-
def.fields.forEach((f) => def.fieldsMap.set(f.name, f));
|
|
392
|
-
def.allowUndefinedFields = parsed.allowUndefinedFields;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
set insertableFields(val) {
|
|
396
|
-
const def = this.getDef();
|
|
397
|
-
if (def)
|
|
398
|
-
def.insertableFields = val;
|
|
399
|
-
}
|
|
400
|
-
set updatableFields(val) {
|
|
401
|
-
const def = this.getDef();
|
|
402
|
-
if (def)
|
|
403
|
-
def.updatableFields = val;
|
|
404
|
-
}
|
|
405
|
-
set deleteType(val) {
|
|
406
|
-
const def = this.getDef();
|
|
407
|
-
if (def)
|
|
408
|
-
def.deleteType = val;
|
|
409
|
-
}
|
|
410
|
-
set massDeleteAllowed(val) {
|
|
411
|
-
const def = this.getDef();
|
|
412
|
-
if (def)
|
|
413
|
-
def.massDeleteAllowed = val;
|
|
414
|
-
}
|
|
415
|
-
set massEditAllowed(val) {
|
|
416
|
-
const def = this.getDef();
|
|
417
|
-
if (def)
|
|
418
|
-
def.massEditAllowed = val;
|
|
419
|
-
}
|
|
420
|
-
// Delegation to QueryBuilder
|
|
421
|
-
get(...fields) {
|
|
422
|
-
const q = new FluentQueryBuilder({ use: (n) => this.manager.use(n) }, this.name);
|
|
423
|
-
return q.get(...fields);
|
|
424
|
-
}
|
|
425
|
-
limit(n) {
|
|
426
|
-
const q = new FluentQueryBuilder({ use: (n) => this.manager.use(n) }, this.name);
|
|
427
|
-
return q.limit(n);
|
|
428
|
-
}
|
|
429
|
-
offset(n) {
|
|
430
|
-
const q = new FluentQueryBuilder({ use: (n) => this.manager.use(n) }, this.name);
|
|
431
|
-
return q.offset(n);
|
|
432
|
-
}
|
|
433
|
-
async insert(data) {
|
|
434
|
-
const q = new FluentQueryBuilder({
|
|
435
|
-
use: (n) => this.manager.use(n),
|
|
436
|
-
add: (n, d) => this.manager.use(n).add(d)
|
|
437
|
-
}, this.name);
|
|
438
|
-
return q.insert(data);
|
|
439
|
-
}
|
|
440
|
-
async dropTable() {
|
|
441
|
-
const migrator = new TableMigrator(this.name);
|
|
442
|
-
if (this.connectionName) {
|
|
443
|
-
migrator.useConnection(this.connectionName);
|
|
444
|
-
}
|
|
445
|
-
return migrator.drop().exec();
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
547
|
// Helper to access parseDescriptorStructure from index.ts if not exported?
|
|
449
548
|
// It is NOT exported. I need to export it or duplicate logic.
|
|
450
549
|
// I'll export it from index.ts.
|
|
@@ -457,6 +556,9 @@ export class SchemaManagerWrapper {
|
|
|
457
556
|
// This allows Mapper.schemas().table('name') to return a migrator
|
|
458
557
|
return new TableMigrator(name);
|
|
459
558
|
}
|
|
559
|
+
schema(name) {
|
|
560
|
+
return this.table(name);
|
|
561
|
+
}
|
|
460
562
|
async dropTable(name) {
|
|
461
563
|
return new TableMigrator(name).drop().exec();
|
|
462
564
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -127,8 +127,8 @@ export type { EnvDslConnections, NormalizedConnection } from './env.js';
|
|
|
127
127
|
export { documentationMd, markdownToHtml, getDocumentationHtml } from './docs.js';
|
|
128
128
|
export { Mapper, createMapper } from './mapper.js';
|
|
129
129
|
export { default } from './mapper.js';
|
|
130
|
-
export { StaticMapper } from './fluent-mapper.js';
|
|
131
|
-
export type { FluentQueryBuilder, FluentConnectionBuilder, FluentSchemaBuilder,
|
|
130
|
+
export { StaticMapper, RawQueryBuilder, BaseQueryBuilder } from './fluent-mapper.js';
|
|
131
|
+
export type { FluentQueryBuilder, FluentConnectionBuilder, FluentSchemaBuilder, FluentConnectionSelector, FluentMapper } from './fluent-mapper.js';
|
|
132
132
|
export { ConfigBasedMapper, ConfigLoader, createConfigMapper, getConfigMapper, createDefaultMapper } from './config.js';
|
|
133
133
|
export type { MapperConfig, ConnectionConfig, DatabaseConnectionConfig, ApiConnectionConfig, SqliteConnectionConfig, ConfigSchema } from './config.js';
|
|
134
134
|
export { MySQLAdapter, createMySQLAdapter, PostgreSQLAdapter, createPostgreSQLAdapter, MongoDBAdapter, createMongoDBAdapter, APIAdapter, createAPIAdapter, SQLiteAdapter, createSQLiteAdapter, createAdapter, createAdapterFromUrl, autoAttachAdapter } from './adapters/index.js';
|
package/dist/index.js
CHANGED
|
@@ -397,7 +397,7 @@ export { documentationMd, markdownToHtml, getDocumentationHtml } from './docs.js
|
|
|
397
397
|
export { Mapper, createMapper } from './mapper.js';
|
|
398
398
|
export { default } from './mapper.js';
|
|
399
399
|
// Export the new fluent/static API
|
|
400
|
-
export { StaticMapper } from './fluent-mapper.js';
|
|
400
|
+
export { StaticMapper, RawQueryBuilder, BaseQueryBuilder } from './fluent-mapper.js';
|
|
401
401
|
// Export the new config-based system
|
|
402
402
|
export { ConfigBasedMapper, ConfigLoader, createConfigMapper, getConfigMapper, createDefaultMapper } from './config.js';
|
|
403
403
|
// Export database adapters
|