@forestadmin/datasource-mongoose 1.0.0-beta.3
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 +26 -0
- package/dist/collection.d.ts +12 -0
- package/dist/collection.js +31 -0
- package/dist/datasource.d.ts +9 -0
- package/dist/datasource.js +25 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +16 -0
- package/dist/utils/filter-operator-builder.d.ts +9 -0
- package/dist/utils/filter-operator-builder.js +57 -0
- package/dist/utils/schema-fields-generator.d.ts +13 -0
- package/dist/utils/schema-fields-generator.js +142 -0
- package/package.json +30 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @forestadmin/datasource-mongoose [1.0.0-beta.3](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.2...@forestadmin/datasource-mongoose@1.0.0-beta.3) (2022-05-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### Dependencies
|
|
8
|
+
|
|
9
|
+
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.17
|
|
10
|
+
|
|
11
|
+
# @forestadmin/datasource-mongoose [1.0.0-beta.2](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.1...@forestadmin/datasource-mongoose@1.0.0-beta.2) (2022-05-23)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Dependencies
|
|
18
|
+
|
|
19
|
+
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.17
|
|
20
|
+
|
|
21
|
+
# @forestadmin/datasource-mongoose 1.0.0-beta.1 (2022-05-17)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
* **mongoose:** add schema generator ([#303](https://github.com/ForestAdmin/agent-nodejs/issues/303)) ([55fa26a](https://github.com/ForestAdmin/agent-nodejs/commit/55fa26a3d1c975c35bdab6a20655573ecaceb31e))
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AggregateResult, BaseCollection, DataSource, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Model } from 'mongoose';
|
|
3
|
+
export default class MongooseCollection extends BaseCollection {
|
|
4
|
+
private readonly model;
|
|
5
|
+
constructor(dataSource: DataSource, model: Model<RecordData>);
|
|
6
|
+
create(): Promise<RecordData[]>;
|
|
7
|
+
list(): Promise<RecordData[]>;
|
|
8
|
+
update(): Promise<void>;
|
|
9
|
+
delete(): Promise<void>;
|
|
10
|
+
aggregate(): Promise<AggregateResult[]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const schema_fields_generator_1 = __importDefault(require("./utils/schema-fields-generator"));
|
|
8
|
+
class MongooseCollection extends datasource_toolkit_1.BaseCollection {
|
|
9
|
+
constructor(dataSource, model) {
|
|
10
|
+
super(model.modelName, dataSource);
|
|
11
|
+
this.model = model;
|
|
12
|
+
this.addFields(schema_fields_generator_1.default.buildFieldsSchema(model));
|
|
13
|
+
}
|
|
14
|
+
async create() {
|
|
15
|
+
throw new Error('not implemented');
|
|
16
|
+
}
|
|
17
|
+
async list() {
|
|
18
|
+
throw new Error('not implemented');
|
|
19
|
+
}
|
|
20
|
+
async update() {
|
|
21
|
+
throw new Error('not implemented');
|
|
22
|
+
}
|
|
23
|
+
async delete() {
|
|
24
|
+
throw new Error('not implemented');
|
|
25
|
+
}
|
|
26
|
+
async aggregate() {
|
|
27
|
+
throw new Error('not implemented');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = MongooseCollection;
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBS3lDO0FBR3pDLDhGQUFvRTtBQUVwRSxNQUFxQixrQkFBbUIsU0FBUSxtQ0FBYztJQUc1RCxZQUFZLFVBQXNCLEVBQUUsS0FBd0I7UUFDMUQsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQ0FBcUIsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTTtRQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELEtBQUssQ0FBQyxNQUFNO1FBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTTtRQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFNBQVM7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBNUJELHFDQTRCQyJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseDataSource } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Connection } from 'mongoose';
|
|
3
|
+
import MongooseCollection from './collection';
|
|
4
|
+
export default class MongooseDatasource extends BaseDataSource<MongooseCollection> {
|
|
5
|
+
private connection;
|
|
6
|
+
constructor(connection: Connection);
|
|
7
|
+
protected createCollections(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=datasource.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_1 = __importDefault(require("./collection"));
|
|
8
|
+
const schema_fields_generator_1 = __importDefault(require("./utils/schema-fields-generator"));
|
|
9
|
+
class MongooseDatasource extends datasource_toolkit_1.BaseDataSource {
|
|
10
|
+
constructor(connection) {
|
|
11
|
+
super();
|
|
12
|
+
if (!connection)
|
|
13
|
+
throw new Error('Invalid (null) Mongoose instance.');
|
|
14
|
+
this.connection = connection;
|
|
15
|
+
this.createCollections();
|
|
16
|
+
}
|
|
17
|
+
createCollections() {
|
|
18
|
+
Object.values(this.connection.models).forEach(model => {
|
|
19
|
+
this.addCollection(new collection_1.default(this, model));
|
|
20
|
+
});
|
|
21
|
+
schema_fields_generator_1.default.addInverseRelationships(this.collections);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.default = MongooseDatasource;
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBQWlFO0FBR2pFLDhEQUE4QztBQUM5Qyw4RkFBb0U7QUFFcEUsTUFBcUIsa0JBQW1CLFNBQVEsbUNBQWtDO0lBR2hGLFlBQVksVUFBc0I7UUFDaEMsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsVUFBVTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUV0RSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUU3QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRVMsaUJBQWlCO1FBQ3pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLG9CQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO1FBQ0gsaUNBQXFCLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQW5CRCxxQ0FtQkMifQ==
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Connection } from 'mongoose';
|
|
2
|
+
import { DataSourceFactory } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
export { default as MongooseCollection } from './collection';
|
|
4
|
+
export { default as MongooseDatasource } from './datasource';
|
|
5
|
+
export declare function createMongooseDataSource(connection: Connection): DataSourceFactory;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createMongooseDataSource = exports.MongooseDatasource = exports.MongooseCollection = void 0;
|
|
7
|
+
const datasource_1 = __importDefault(require("./datasource"));
|
|
8
|
+
var collection_1 = require("./collection");
|
|
9
|
+
Object.defineProperty(exports, "MongooseCollection", { enumerable: true, get: function () { return __importDefault(collection_1).default; } });
|
|
10
|
+
var datasource_2 = require("./datasource");
|
|
11
|
+
Object.defineProperty(exports, "MongooseDatasource", { enumerable: true, get: function () { return __importDefault(datasource_2).default; } });
|
|
12
|
+
function createMongooseDataSource(connection) {
|
|
13
|
+
return async () => new datasource_1.default(connection);
|
|
14
|
+
}
|
|
15
|
+
exports.createMongooseDataSource = createMongooseDataSource;
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsOERBQThDO0FBRTlDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBQ3RDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBRXRDLFNBQWdCLHdCQUF3QixDQUFDLFVBQXNCO0lBQzdELE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQyxJQUFJLG9CQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFGRCw0REFFQyJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColumnType, Operator } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
export default class FilterOperatorBuilder {
|
|
3
|
+
static readonly defaultOperators: Partial<Operator[]>;
|
|
4
|
+
static readonly inOperators: Partial<Operator[]>;
|
|
5
|
+
static readonly stringOperators: Partial<Operator[]>;
|
|
6
|
+
static readonly comparisonOperators: Partial<Operator[]>;
|
|
7
|
+
static getSupportedOperators(type: ColumnType): Set<Operator>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=filter-operator-builder.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class FilterOperatorBuilder {
|
|
4
|
+
static getSupportedOperators(type) {
|
|
5
|
+
if (!(type instanceof Array) && type instanceof Object) {
|
|
6
|
+
return new Set(FilterOperatorBuilder.defaultOperators);
|
|
7
|
+
}
|
|
8
|
+
switch (type) {
|
|
9
|
+
case 'Boolean':
|
|
10
|
+
return new Set(FilterOperatorBuilder.defaultOperators);
|
|
11
|
+
case 'Date':
|
|
12
|
+
case 'Dateonly':
|
|
13
|
+
return new Set([
|
|
14
|
+
...FilterOperatorBuilder.defaultOperators,
|
|
15
|
+
...FilterOperatorBuilder.inOperators,
|
|
16
|
+
...FilterOperatorBuilder.comparisonOperators,
|
|
17
|
+
]);
|
|
18
|
+
case 'Enum':
|
|
19
|
+
return new Set([
|
|
20
|
+
...FilterOperatorBuilder.defaultOperators,
|
|
21
|
+
...FilterOperatorBuilder.inOperators,
|
|
22
|
+
]);
|
|
23
|
+
case 'Number':
|
|
24
|
+
return new Set([
|
|
25
|
+
...FilterOperatorBuilder.defaultOperators,
|
|
26
|
+
...FilterOperatorBuilder.inOperators,
|
|
27
|
+
...FilterOperatorBuilder.comparisonOperators,
|
|
28
|
+
]);
|
|
29
|
+
case 'String':
|
|
30
|
+
return new Set([
|
|
31
|
+
...FilterOperatorBuilder.defaultOperators,
|
|
32
|
+
...FilterOperatorBuilder.inOperators,
|
|
33
|
+
...FilterOperatorBuilder.stringOperators,
|
|
34
|
+
]);
|
|
35
|
+
case 'Uuid':
|
|
36
|
+
return new Set([
|
|
37
|
+
...FilterOperatorBuilder.defaultOperators,
|
|
38
|
+
...FilterOperatorBuilder.stringOperators,
|
|
39
|
+
]);
|
|
40
|
+
case 'Json':
|
|
41
|
+
return new Set(FilterOperatorBuilder.defaultOperators);
|
|
42
|
+
default:
|
|
43
|
+
return new Set();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.default = FilterOperatorBuilder;
|
|
48
|
+
FilterOperatorBuilder.defaultOperators = ['Equal', 'NotEqual', 'Present'];
|
|
49
|
+
FilterOperatorBuilder.inOperators = ['In', 'NotIn'];
|
|
50
|
+
FilterOperatorBuilder.stringOperators = [
|
|
51
|
+
'Like',
|
|
52
|
+
'NotContains',
|
|
53
|
+
'LongerThan',
|
|
54
|
+
'ShorterThan',
|
|
55
|
+
];
|
|
56
|
+
FilterOperatorBuilder.comparisonOperators = ['GreaterThan', 'LessThan'];
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLW9wZXJhdG9yLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvZmlsdGVyLW9wZXJhdG9yLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxNQUFxQixxQkFBcUI7SUFZeEMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLElBQWdCO1FBQzNDLElBQUksQ0FBQyxDQUFDLElBQUksWUFBWSxLQUFLLENBQUMsSUFBSSxJQUFJLFlBQVksTUFBTSxFQUFFO1lBQ3RELE9BQU8sSUFBSSxHQUFHLENBQVcscUJBQXFCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztTQUNsRTtRQUVELFFBQVEsSUFBSSxFQUFFO1lBQ1osS0FBSyxTQUFTO2dCQUNaLE9BQU8sSUFBSSxHQUFHLENBQVcscUJBQXFCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNuRSxLQUFLLE1BQU0sQ0FBQztZQUNaLEtBQUssVUFBVTtnQkFDYixPQUFPLElBQUksR0FBRyxDQUFXO29CQUN2QixHQUFHLHFCQUFxQixDQUFDLGdCQUFnQjtvQkFDekMsR0FBRyxxQkFBcUIsQ0FBQyxXQUFXO29CQUNwQyxHQUFHLHFCQUFxQixDQUFDLG1CQUFtQjtpQkFDN0MsQ0FBQyxDQUFDO1lBQ0wsS0FBSyxNQUFNO2dCQUNULE9BQU8sSUFBSSxHQUFHLENBQVc7b0JBQ3ZCLEdBQUcscUJBQXFCLENBQUMsZ0JBQWdCO29CQUN6QyxHQUFHLHFCQUFxQixDQUFDLFdBQVc7aUJBQ3JDLENBQUMsQ0FBQztZQUNMLEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksR0FBRyxDQUFXO29CQUN2QixHQUFHLHFCQUFxQixDQUFDLGdCQUFnQjtvQkFDekMsR0FBRyxxQkFBcUIsQ0FBQyxXQUFXO29CQUNwQyxHQUFHLHFCQUFxQixDQUFDLG1CQUFtQjtpQkFDN0MsQ0FBQyxDQUFDO1lBQ0wsS0FBSyxRQUFRO2dCQUNYLE9BQU8sSUFBSSxHQUFHLENBQVc7b0JBQ3ZCLEdBQUcscUJBQXFCLENBQUMsZ0JBQWdCO29CQUN6QyxHQUFHLHFCQUFxQixDQUFDLFdBQVc7b0JBQ3BDLEdBQUcscUJBQXFCLENBQUMsZUFBZTtpQkFDekMsQ0FBQyxDQUFDO1lBQ0wsS0FBSyxNQUFNO2dCQUNULE9BQU8sSUFBSSxHQUFHLENBQVc7b0JBQ3ZCLEdBQUcscUJBQXFCLENBQUMsZ0JBQWdCO29CQUN6QyxHQUFHLHFCQUFxQixDQUFDLGVBQWU7aUJBQ3pDLENBQUMsQ0FBQztZQUNMLEtBQUssTUFBTTtnQkFDVCxPQUFPLElBQUksR0FBRyxDQUFXLHFCQUFxQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbkU7Z0JBQ0UsT0FBTyxJQUFJLEdBQUcsRUFBWSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQzs7QUF0REgsd0NBdURDO0FBdERpQixzQ0FBZ0IsR0FBd0IsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3pFLGlDQUFXLEdBQXdCLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ25ELHFDQUFlLEdBQXdCO0lBQ3JELE1BQU07SUFDTixhQUFhO0lBQ2IsWUFBWTtJQUNaLGFBQWE7Q0FDZCxDQUFDO0FBRWMseUNBQW1CLEdBQXdCLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDIn0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CollectionSchema, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Model } from 'mongoose';
|
|
3
|
+
import MongooseCollection from '../collection';
|
|
4
|
+
export default class SchemaFieldsGenerator {
|
|
5
|
+
static addInverseRelationships(collections: MongooseCollection[]): void;
|
|
6
|
+
static buildFieldsSchema(model: Model<RecordData>): CollectionSchema['fields'];
|
|
7
|
+
private static getColumnType;
|
|
8
|
+
private static buildColumnSchema;
|
|
9
|
+
private static getEnumValues;
|
|
10
|
+
private static getColumnTypeFromNested;
|
|
11
|
+
private static getColumnTypeFromNestedPath;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=schema-fields-generator.d.ts.map
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const filter_operator_builder_1 = __importDefault(require("./filter-operator-builder"));
|
|
7
|
+
class SchemaFieldsGenerator {
|
|
8
|
+
static addInverseRelationships(collections) {
|
|
9
|
+
collections.forEach(collection => {
|
|
10
|
+
Object.values(collection.schema.fields).forEach(fieldSchema => {
|
|
11
|
+
if (fieldSchema.type === 'ManyToOne') {
|
|
12
|
+
const foreignCollection = collections.find(c => c.name === fieldSchema.foreignCollection);
|
|
13
|
+
if (!foreignCollection) {
|
|
14
|
+
throw new Error(`The collection '${fieldSchema.foreignCollection}' does not exist`);
|
|
15
|
+
}
|
|
16
|
+
const field = `${foreignCollection.name}__${fieldSchema.foreignKey}__oneToMany`;
|
|
17
|
+
foreignCollection.schema.fields[field] = {
|
|
18
|
+
foreignCollection: collection.name,
|
|
19
|
+
originKey: fieldSchema.foreignKey,
|
|
20
|
+
originKeyTarget: '_id',
|
|
21
|
+
type: 'OneToMany',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
static buildFieldsSchema(model) {
|
|
28
|
+
const schemaFields = {};
|
|
29
|
+
Object.entries(model.schema.paths).forEach(([fieldName, field]) => {
|
|
30
|
+
const mixedFieldPattern = '$*';
|
|
31
|
+
const privateFieldPattern = '__';
|
|
32
|
+
if (fieldName.startsWith(privateFieldPattern) || fieldName.includes(mixedFieldPattern)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (field.options.ref) {
|
|
36
|
+
schemaFields[`${fieldName}_manyToOne`] = {
|
|
37
|
+
type: 'ManyToOne',
|
|
38
|
+
foreignCollection: field.options.ref,
|
|
39
|
+
foreignKey: field.path,
|
|
40
|
+
foreignKeyTarget: '_id',
|
|
41
|
+
};
|
|
42
|
+
schemaFields[fieldName] = SchemaFieldsGenerator.buildColumnSchema(field, 'String');
|
|
43
|
+
}
|
|
44
|
+
schemaFields[field.path.split('.').shift()] = SchemaFieldsGenerator.buildColumnSchema(field, SchemaFieldsGenerator.getColumnType(field.instance, field));
|
|
45
|
+
});
|
|
46
|
+
return schemaFields;
|
|
47
|
+
}
|
|
48
|
+
static getColumnType(instance, field) {
|
|
49
|
+
if (field.path.includes('.')) {
|
|
50
|
+
const fieldPath = field.path.split('.');
|
|
51
|
+
fieldPath.shift();
|
|
52
|
+
field.path = fieldPath[fieldPath.length - 1];
|
|
53
|
+
return SchemaFieldsGenerator.getColumnTypeFromNestedPath(fieldPath, field);
|
|
54
|
+
}
|
|
55
|
+
const potentialEnumValues = this.getEnumValues(field);
|
|
56
|
+
if (potentialEnumValues) {
|
|
57
|
+
if (potentialEnumValues.some(value => !(typeof value === 'string'))) {
|
|
58
|
+
throw new Error('Enum support only String values');
|
|
59
|
+
}
|
|
60
|
+
return 'Enum';
|
|
61
|
+
}
|
|
62
|
+
switch (instance) {
|
|
63
|
+
case 'Array':
|
|
64
|
+
return [
|
|
65
|
+
SchemaFieldsGenerator.getColumnType(field.schema ? 'Embedded' : field.caster.instance, field.schema ? field : field.caster),
|
|
66
|
+
];
|
|
67
|
+
case 'String':
|
|
68
|
+
case 'ObjectID':
|
|
69
|
+
case 'Buffer':
|
|
70
|
+
case 'Decimal128':
|
|
71
|
+
return 'String';
|
|
72
|
+
case 'Number':
|
|
73
|
+
return 'Number';
|
|
74
|
+
case 'Date':
|
|
75
|
+
return 'Date';
|
|
76
|
+
case 'Boolean':
|
|
77
|
+
return 'Boolean';
|
|
78
|
+
case 'Map':
|
|
79
|
+
case 'Mixed':
|
|
80
|
+
return 'Json';
|
|
81
|
+
case 'Embedded':
|
|
82
|
+
default:
|
|
83
|
+
return SchemaFieldsGenerator.getColumnTypeFromNested(field);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
static buildColumnSchema(field, columnType) {
|
|
87
|
+
return {
|
|
88
|
+
columnType,
|
|
89
|
+
filterOperators: filter_operator_builder_1.default.getSupportedOperators(columnType),
|
|
90
|
+
defaultValue: field.options?.default,
|
|
91
|
+
enumValues: this.getEnumValues(field),
|
|
92
|
+
isPrimaryKey: field.path === '_id',
|
|
93
|
+
isReadOnly: !!field.options?.immutable,
|
|
94
|
+
isSortable: !(columnType instanceof Object || columnType === 'Json'),
|
|
95
|
+
type: 'Column',
|
|
96
|
+
validation: field.isRequired ? [{ operator: 'Present' }] : null,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
static getEnumValues(field) {
|
|
100
|
+
return field.options?.enum instanceof Array ? field.options.enum : field.options?.enum?.values;
|
|
101
|
+
}
|
|
102
|
+
static getColumnTypeFromNested(field) {
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
const { singleNestedPaths } = field.schema;
|
|
106
|
+
const paths = Object.keys(singleNestedPaths).length > 0 ? singleNestedPaths : field.schema.paths;
|
|
107
|
+
return Object.entries(paths).reduce((columnType, [fieldPath, fieldSchema]) => {
|
|
108
|
+
return SchemaFieldsGenerator.getColumnTypeFromNestedPath(fieldPath.split('.'), fieldSchema, columnType);
|
|
109
|
+
}, {});
|
|
110
|
+
}
|
|
111
|
+
static getColumnTypeFromNestedPath(fieldPath, field, columnType = {}) {
|
|
112
|
+
let previousPath;
|
|
113
|
+
fieldPath.forEach((fieldName, index) => {
|
|
114
|
+
if (fieldName === '_id') {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (index !== fieldPath.length - 1) {
|
|
118
|
+
if (previousPath) {
|
|
119
|
+
if (!previousPath[fieldName]) {
|
|
120
|
+
previousPath[fieldName] = {};
|
|
121
|
+
}
|
|
122
|
+
previousPath = previousPath[fieldName];
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
if (!columnType[fieldName]) {
|
|
126
|
+
columnType[fieldName] = {};
|
|
127
|
+
}
|
|
128
|
+
previousPath = columnType[fieldName];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
if (!previousPath) {
|
|
133
|
+
previousPath = columnType;
|
|
134
|
+
}
|
|
135
|
+
previousPath[fieldName] = SchemaFieldsGenerator.getColumnType(field.instance, field);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return columnType;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.default = SchemaFieldsGenerator;
|
|
142
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWZpZWxkcy1nZW5lcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2NoZW1hLWZpZWxkcy1nZW5lcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFVQSx3RkFBOEQ7QUFHOUQsTUFBcUIscUJBQXFCO0lBQ3hDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxXQUFpQztRQUM5RCxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQzVELElBQUksV0FBVyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7b0JBQ3BDLE1BQU0saUJBQWlCLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBRTFGLElBQUksQ0FBQyxpQkFBaUIsRUFBRTt3QkFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsV0FBVyxDQUFDLGlCQUFpQixrQkFBa0IsQ0FBQyxDQUFDO3FCQUNyRjtvQkFFRCxNQUFNLEtBQUssR0FBRyxHQUFHLGlCQUFpQixDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsVUFBVSxhQUFhLENBQUM7b0JBQ2hGLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUc7d0JBQ3ZDLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxJQUFJO3dCQUNsQyxTQUFTLEVBQUUsV0FBVyxDQUFDLFVBQVU7d0JBQ2pDLGVBQWUsRUFBRSxLQUFLO3dCQUN0QixJQUFJLEVBQUUsV0FBVztxQkFDbEIsQ0FBQztpQkFDSDtZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxD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
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forestadmin/datasource-mongoose",
|
|
3
|
+
"version": "1.0.0-beta.3",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"license": "GPL-3.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ForestAdmin/agent-nodejs.git",
|
|
12
|
+
"directory": "packages/datasource-mongoose"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/**/*.js",
|
|
16
|
+
"dist/**/*.d.ts"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@forestadmin/datasource-toolkit": "1.0.0-beta.17",
|
|
20
|
+
"mongoose": "^6.3.2"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"build:watch": "tsc --watch",
|
|
26
|
+
"clean": "rm -rf coverage dist",
|
|
27
|
+
"lint": "eslint src test",
|
|
28
|
+
"test": "jest"
|
|
29
|
+
}
|
|
30
|
+
}
|