@forestadmin/datasource-mongoose 1.0.0-beta.11 → 1.0.0-beta.14

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/collection.d.ts +11 -8
  3. package/dist/collection.js +124 -15
  4. package/dist/datasource.d.ts +6 -3
  5. package/dist/datasource.js +29 -12
  6. package/dist/index.d.ts +2 -1
  7. package/dist/index.js +3 -3
  8. package/dist/mongoose/schema.d.ts +21 -0
  9. package/dist/mongoose/schema.js +89 -0
  10. package/dist/types.d.ts +4 -0
  11. package/dist/types.js +3 -0
  12. package/dist/utils/helpers.d.ts +51 -0
  13. package/dist/utils/helpers.js +109 -0
  14. package/dist/utils/pipeline/filter.d.ts +18 -0
  15. package/dist/utils/pipeline/filter.js +160 -0
  16. package/dist/utils/pipeline/group.d.ts +15 -0
  17. package/dist/utils/pipeline/group.js +70 -0
  18. package/dist/utils/pipeline/lookup.d.ts +12 -0
  19. package/dist/utils/pipeline/lookup.js +49 -0
  20. package/dist/utils/pipeline/projection.d.ts +7 -0
  21. package/dist/utils/pipeline/projection.js +18 -0
  22. package/dist/utils/pipeline/reparent.d.ts +13 -0
  23. package/dist/utils/pipeline/reparent.js +71 -0
  24. package/dist/utils/pipeline/virtual-fields.d.ts +21 -0
  25. package/dist/utils/pipeline/virtual-fields.js +65 -0
  26. package/dist/utils/schema/fields.d.ts +18 -0
  27. package/dist/utils/schema/fields.js +110 -0
  28. package/dist/utils/{filter-operator-builder.d.ts → schema/filter-operators.d.ts} +2 -2
  29. package/dist/utils/schema/filter-operators.js +52 -0
  30. package/dist/utils/schema/relations.d.ts +19 -0
  31. package/dist/utils/schema/relations.js +75 -0
  32. package/package.json +3 -2
  33. package/dist/utils/filter-operator-builder.js +0 -57
  34. package/dist/utils/schema-fields-generator.d.ts +0 -13
  35. package/dist/utils/schema-fields-generator.js +0 -142
package/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ # @forestadmin/datasource-mongoose [1.0.0-beta.14](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.13...@forestadmin/datasource-mongoose@1.0.0-beta.14) (2022-08-23)
2
+
3
+
4
+
5
+
6
+
7
+ ### Dependencies
8
+
9
+ * **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.27
10
+
11
+ # @forestadmin/datasource-mongoose [1.0.0-beta.13](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.12...@forestadmin/datasource-mongoose@1.0.0-beta.13) (2022-06-16)
12
+
13
+
14
+ ### Features
15
+
16
+ * add support for mongoose datasource ([#339](https://github.com/ForestAdmin/agent-nodejs/issues/339)) ([5515286](https://github.com/ForestAdmin/agent-nodejs/commit/55152862dceff4714bf9b36ed6c138acdf8cb9e3))
17
+
18
+ # @forestadmin/datasource-mongoose [1.0.0-beta.12](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.11...@forestadmin/datasource-mongoose@1.0.0-beta.12) (2022-06-15)
19
+
20
+
21
+
22
+
23
+
24
+ ### Dependencies
25
+
26
+ * **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.26
27
+
1
28
  # @forestadmin/datasource-mongoose [1.0.0-beta.11](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-mongoose@1.0.0-beta.10...@forestadmin/datasource-mongoose@1.0.0-beta.11) (2022-06-15)
2
29
 
3
30
 
@@ -1,12 +1,15 @@
1
- import { AggregateResult, BaseCollection, DataSource, RecordData } from '@forestadmin/datasource-toolkit';
1
+ import { AggregateResult, Aggregation, BaseCollection, Caller, DataSource, Filter, PaginatedFilter, Projection, RecordData, TSchema } from '@forestadmin/datasource-toolkit';
2
2
  import { Model } from 'mongoose';
3
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[]>;
4
+ model: Model<RecordData>;
5
+ prefix: string;
6
+ ignoredFields: string[];
7
+ constructor(dataSource: DataSource, model: Model<RecordData>, prefix?: string, ignoredFields?: string[]);
8
+ create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
9
+ list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
10
+ update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
11
+ delete(caller: Caller, filter: Filter): Promise<void>;
12
+ aggregate(caller: Caller, filter: Filter, aggregation: Aggregation, limit?: number): Promise<AggregateResult<TSchema, string>[]>;
13
+ private buildBasePipeline;
11
14
  }
12
15
  //# sourceMappingURL=collection.d.ts.map
@@ -3,30 +3,139 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable @typescript-eslint/naming-convention */
7
+ /* eslint-disable no-underscore-dangle */
6
8
  const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
7
- const schema_fields_generator_1 = __importDefault(require("./utils/schema-fields-generator"));
9
+ const helpers_1 = require("./utils/helpers");
10
+ const fields_1 = __importDefault(require("./utils/schema/fields"));
11
+ const filter_1 = __importDefault(require("./utils/pipeline/filter"));
12
+ const group_1 = __importDefault(require("./utils/pipeline/group"));
13
+ const lookup_1 = __importDefault(require("./utils/pipeline/lookup"));
14
+ const schema_1 = __importDefault(require("./mongoose/schema"));
15
+ const projection_1 = __importDefault(require("./utils/pipeline/projection"));
16
+ const reparent_1 = __importDefault(require("./utils/pipeline/reparent"));
17
+ const virtual_fields_1 = __importDefault(require("./utils/pipeline/virtual-fields"));
8
18
  class MongooseCollection extends datasource_toolkit_1.BaseCollection {
9
- constructor(dataSource, model) {
10
- super(model.modelName, dataSource);
19
+ constructor(dataSource, model, prefix = null, ignoredFields = []) {
20
+ super(prefix ? (0, helpers_1.escape)(`${model.modelName}.${prefix}`) : model.modelName, dataSource);
11
21
  this.model = model;
22
+ this.prefix = prefix;
23
+ this.ignoredFields = ignoredFields;
12
24
  this.enableCount();
13
- this.addFields(schema_fields_generator_1.default.buildFieldsSchema(model));
25
+ this.addFields(fields_1.default.buildFieldsSchema(model, prefix, ignoredFields));
14
26
  }
15
- async create() {
16
- throw new Error('not implemented');
27
+ async create(caller, data) {
28
+ // If there is no prefix, we can delegate the work to mongoose directly.
29
+ if (!this.prefix) {
30
+ const { insertedIds } = await this.model.insertMany(data, { rawResult: true });
31
+ return data.map((record, index) => ({ _id: insertedIds[index], ...record }));
32
+ }
33
+ // Transform list of subrecords to a list of modifications that we'll apply to the root record.
34
+ const fieldName = this.prefix.substring(this.prefix.lastIndexOf('.') + 1);
35
+ const schema = schema_1.default.fromModel(this.model).getSubSchema(this.prefix);
36
+ const updates = new Map();
37
+ const results = [];
38
+ for (const record of data) {
39
+ const { _pid, ...rest } = record;
40
+ if (!_pid)
41
+ throw new datasource_toolkit_1.ValidationError('Trying to create a subrecord with no parent');
42
+ const [rootId, path] = (0, helpers_1.splitId)(`${_pid}.${fieldName}`);
43
+ if (!updates.has(rootId))
44
+ updates.set(rootId, { path, records: [] });
45
+ // unwrap 'content' on leafs
46
+ updates.get(rootId).records.push(schema.isLeaf ? rest.content : rest);
47
+ results.push({
48
+ _id: schema.isArray // arrays have indexes in their ids
49
+ ? `${rootId}.${path}.${updates.get(rootId).records.length - 1}`
50
+ : `${rootId}.${path}`,
51
+ ...record,
52
+ });
53
+ }
54
+ // Apply the modifications to the root document.
55
+ const promises = [...updates.entries()].map(async ([rootId, { path, records }]) => this.model.updateOne({ _id: rootId }, schema.isArray
56
+ ? { $push: { [path]: { $each: records, position: 0 } } }
57
+ : { $set: { [path]: records[0] } }, { rawResult: true }));
58
+ await Promise.all(promises);
59
+ return results;
17
60
  }
18
- async list() {
19
- throw new Error('not implemented');
61
+ async list(caller, filter, projection) {
62
+ const lookupProjection = projection.union(filter.conditionTree?.projection, filter.sort?.projection);
63
+ const records = await this.model.aggregate([
64
+ ...this.buildBasePipeline(filter, lookupProjection),
65
+ ...projection_1.default.project(projection),
66
+ ]);
67
+ return (0, helpers_1.replaceMongoTypes)(records);
20
68
  }
21
- async update() {
22
- throw new Error('not implemented');
69
+ async update(caller, filter, patch) {
70
+ const records = await this.list(caller, filter, new datasource_toolkit_1.Projection('_id'));
71
+ const ids = records.map(record => record._id);
72
+ if (!this.prefix) {
73
+ await this.model.updateMany({ _id: ids }, patch, { rawResult: true });
74
+ return;
75
+ }
76
+ // Clean patch
77
+ const schema = schema_1.default.fromModel(this.model).getSubSchema(this.prefix);
78
+ let cleanPatch = { ...patch };
79
+ delete cleanPatch._id; // Virtual field
80
+ delete cleanPatch._pid; // Ignore _pids: they should not be editable from the frontend.
81
+ if (Object.keys(cleanPatch).length === 0)
82
+ return;
83
+ if (schema.isLeaf)
84
+ cleanPatch = cleanPatch.content;
85
+ // Perform update
86
+ const idsByPath = (0, helpers_1.groupIdsByPath)(ids);
87
+ const promises = Object.entries(idsByPath).map(async ([path, rootIds]) => this.model.updateMany({ _id: rootIds }, { [path]: cleanPatch }, { rawResult: true }));
88
+ await Promise.all(promises);
23
89
  }
24
- async delete() {
25
- throw new Error('not implemented');
90
+ async delete(caller, filter) {
91
+ const records = await this.list(caller, filter, new datasource_toolkit_1.Projection('_id'));
92
+ const ids = records.map(record => record._id);
93
+ if (!this.prefix) {
94
+ await this.model.deleteMany({ _id: ids }, { rawResult: true });
95
+ return;
96
+ }
97
+ const schema = schema_1.default.fromModel(this.model).getSubSchema(this.prefix);
98
+ const idsByPath = (0, helpers_1.groupIdsByPath)(ids);
99
+ if (schema.isArray) {
100
+ for (const path of Object.keys(idsByPath).sort(helpers_1.compareIds).reverse()) {
101
+ const arrayPath = path.substring(0, path.lastIndexOf('.'));
102
+ const index = Number(path.substring(path.lastIndexOf('.') + 1));
103
+ // There is no update operator to pop items out of arrays at known positions
104
+ // => we use an aggregation pipeline in the update operation
105
+ // @see https://jira.mongodb.org/browse/SERVER-1014?focusedCommentId=2305681#comment-2305681
106
+ const newArrayValue = [
107
+ { $slice: [`$${arrayPath}`, index] },
108
+ { $slice: [`$${arrayPath}`, index + 1, { $size: `$${arrayPath}` }] },
109
+ ];
110
+ // When updating arrays, indexes will change with each request so we need to perform the
111
+ // request sequentially.
112
+ // eslint-disable-next-line no-await-in-loop
113
+ await this.model.collection.updateMany({ _id: { $in: idsByPath[path] } }, [{ $set: { [arrayPath]: { $concatArrays: newArrayValue } } }], {});
114
+ }
115
+ }
116
+ else {
117
+ const promises = Object.entries(idsByPath).map(([path, pathIds]) => this.model.collection.updateMany({ _id: { $in: pathIds } }, { $unset: { [path]: '' } }, {}));
118
+ await Promise.all(promises);
119
+ }
26
120
  }
27
- async aggregate() {
28
- throw new Error('not implemented');
121
+ async aggregate(caller, filter, aggregation, limit) {
122
+ const lookupProjection = aggregation.projection.union(filter.conditionTree?.projection);
123
+ const rows = await this.model.aggregate([
124
+ ...this.buildBasePipeline(filter, lookupProjection),
125
+ ...group_1.default.group(aggregation),
126
+ { $sort: { value: -1 } },
127
+ ...(limit ? [{ $limit: limit }] : []),
128
+ ]);
129
+ return (0, helpers_1.replaceMongoTypes)(rows);
130
+ }
131
+ buildBasePipeline(filter, lookupProjection) {
132
+ return [
133
+ ...reparent_1.default.reparent(this.model, this.prefix),
134
+ ...virtual_fields_1.default.addVirtual(this.model, this.prefix, this.ignoredFields, lookupProjection),
135
+ ...lookup_1.default.lookup(this.model, this.prefix, lookupProjection),
136
+ ...filter_1.default.filter(this.model, this.prefix, filter),
137
+ ];
29
138
  }
30
139
  }
31
140
  exports.default = MongooseCollection;
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBS3lDO0FBR3pDLDhGQUFvRTtBQUVwRSxNQUFxQixrQkFBbUIsU0FBUSxtQ0FBYztJQUc1RCxZQUFZLFVBQXNCLEVBQUUsS0FBd0I7UUFDMUQsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFFbkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsaUNBQXFCLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTTtRQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTO1FBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Q0FDRjtBQTlCRCxxQ0E4QkMifQ==
141
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEseURBQXlEO0FBQ3pELHlDQUF5QztBQUN6Qyx3RUFZeUM7QUFHekMsNkNBQWlHO0FBQ2pHLG1FQUFvRDtBQUNwRCxxRUFBc0Q7QUFDdEQsbUVBQW9EO0FBQ3BELHFFQUFzRDtBQUN0RCwrREFBK0M7QUFDL0MsNkVBQThEO0FBQzlELHlFQUEwRDtBQUMxRCxxRkFBcUU7QUFFckUsTUFBcUIsa0JBQW1CLFNBQVEsbUNBQWM7SUFLNUQsWUFDRSxVQUFzQixFQUN0QixLQUF3QixFQUN4QixTQUFpQixJQUFJLEVBQ3JCLGdCQUEwQixFQUFFO1FBRTVCLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUEsZ0JBQU0sRUFBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNyRixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUVuQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFjLEVBQUUsSUFBa0I7UUFDN0Msd0VBQXdFO1FBQ3hFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2hCLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFD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
@@ -1,9 +1,12 @@
1
1
  import { BaseDataSource } from '@forestadmin/datasource-toolkit';
2
2
  import { Connection } from 'mongoose';
3
+ import { MongooseOptions } from './types';
3
4
  import MongooseCollection from './collection';
4
5
  export default class MongooseDatasource extends BaseDataSource<MongooseCollection> {
5
- private connection;
6
- constructor(connection: Connection);
7
- protected createCollections(): void;
6
+ constructor(connection: Connection, options?: MongooseOptions);
7
+ /** Create all collections for a given model */
8
+ private addModel;
9
+ /** Get list of cuts for a given model */
10
+ private getCuts;
8
11
  }
9
12
  //# sourceMappingURL=datasource.d.ts.map
@@ -5,21 +5,38 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
7
7
  const collection_1 = __importDefault(require("./collection"));
8
- const schema_fields_generator_1 = __importDefault(require("./utils/schema-fields-generator"));
8
+ const schema_1 = __importDefault(require("./mongoose/schema"));
9
+ const relations_1 = __importDefault(require("./utils/schema/relations"));
9
10
  class MongooseDatasource extends datasource_toolkit_1.BaseDataSource {
10
- constructor(connection) {
11
+ constructor(connection, options = {}) {
11
12
  super();
12
- if (!connection)
13
- throw new Error('Invalid (null) Mongoose instance.');
14
- this.connection = connection;
15
- this.createCollections();
13
+ // Create collections (with only many to one relations).
14
+ for (const model of Object.values(connection.models)) {
15
+ this.addModel(model, this.getCuts(options, model));
16
+ }
17
+ // Add one-to-many, one-to-one and many-to-many relations.
18
+ relations_1.default.addImplicitRelations(this.collections);
16
19
  }
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);
20
+ /** Create all collections for a given model */
21
+ addModel(model, cuts, prefix = null) {
22
+ const ignore = [...new Set([...cuts.columns, ...Object.keys(cuts.relations)])];
23
+ this.addCollection(new collection_1.default(this, model, prefix, ignore));
24
+ for (const name of ignore) {
25
+ const subProjection = cuts.relations[name] ?? new datasource_toolkit_1.Projection();
26
+ const subPrefix = prefix ? `${prefix}.${name}` : name;
27
+ this.addModel(model, subProjection, subPrefix);
28
+ }
29
+ }
30
+ /** Get list of cuts for a given model */
31
+ getCuts(options, model) {
32
+ // A list was provided by the customer, use it.
33
+ if (options?.asModels?.[model.modelName]) {
34
+ return new datasource_toolkit_1.Projection(...options.asModels[model.modelName].map(item => item.replace(/\./g, ':')));
35
+ }
36
+ // When no cuts are provided, only cut on list of references
37
+ const schema = schema_1.default.fromModel(model);
38
+ return new datasource_toolkit_1.Projection(...Object.keys(schema.fields).filter(field => schema.fields[field]?.['[]']?.options?.ref));
22
39
  }
23
40
  }
24
41
  exports.default = MongooseDatasource;
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBQWlFO0FBR2pFLDhEQUE4QztBQUM5Qyw4RkFBb0U7QUFFcEUsTUFBcUIsa0JBQW1CLFNBQVEsbUNBQWtDO0lBR2hGLFlBQVksVUFBc0I7UUFDaEMsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsVUFBVTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUV0RSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUU3QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRVMsaUJBQWlCO1FBQ3pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLG9CQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO1FBQ0gsaUNBQXFCLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQW5CRCxxQ0FtQkMifQ==
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBQTZFO0FBSTdFLDhEQUE4QztBQUM5QywrREFBK0M7QUFDL0MseUVBQXlEO0FBRXpELE1BQXFCLGtCQUFtQixTQUFRLG1DQUFrQztJQUNoRixZQUFZLFVBQXNCLEVBQUUsVUFBMkIsRUFBRTtRQUMvRCxLQUFLLEVBQUUsQ0FBQztRQUVSLHdEQUF3RDtRQUN4RCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3BELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDcEQ7UUFFRCwwREFBMEQ7UUFDMUQsbUJBQWlCLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCwrQ0FBK0M7SUFDdkMsUUFBUSxDQUFDLEtBQXFCLEVBQUUsSUFBZ0IsRUFBRSxTQUFpQixJQUFJO1FBQzdFLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9FLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxvQkFBa0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBRXhFLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxFQUFFO1lBQ3pCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSwrQkFBVSxFQUFFLENBQUM7WUFDL0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3RELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFRCx5Q0FBeUM7SUFDakMsT0FBTyxDQUFDLE9BQXdCLEVBQUUsS0FBcUI7UUFDN0QsK0NBQStDO1FBQy9DLElBQUksT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUN4QyxPQUFPLElBQUksK0JBQVUsQ0FDbkIsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUMzRSxDQUFDO1NBQ0g7UUFFRCw0REFBNEQ7UUFDNUQsTUFBTSxNQUFNLEdBQUcsZ0JBQWMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFL0MsT0FBTyxJQUFJLCtCQUFVLENBQ25CLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FDMUYsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQTFDRCxxQ0EwQ0MifQ==
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Connection } from 'mongoose';
2
2
  import { DataSourceFactory } from '@forestadmin/datasource-toolkit';
3
+ import { MongooseOptions } from './types';
3
4
  export { default as MongooseCollection } from './collection';
4
5
  export { default as MongooseDatasource } from './datasource';
5
- export declare function createMongooseDataSource(connection: Connection): DataSourceFactory;
6
+ export declare function createMongooseDataSource(connection: Connection, options: MongooseOptions): DataSourceFactory;
6
7
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -9,8 +9,8 @@ var collection_1 = require("./collection");
9
9
  Object.defineProperty(exports, "MongooseCollection", { enumerable: true, get: function () { return __importDefault(collection_1).default; } });
10
10
  var datasource_2 = require("./datasource");
11
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);
12
+ function createMongooseDataSource(connection, options) {
13
+ return async () => new datasource_1.default(connection, options);
14
14
  }
15
15
  exports.createMongooseDataSource = createMongooseDataSource;
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsOERBQThDO0FBRTlDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBQ3RDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBRXRDLFNBQWdCLHdCQUF3QixDQUFDLFVBQXNCO0lBQzdELE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQyxJQUFJLG9CQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFGRCw0REFFQyJ9
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBSUEsOERBQThDO0FBRTlDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBQ3RDLDJDQUE2RDtBQUFwRCxpSUFBQSxPQUFPLE9BQXNCO0FBRXRDLFNBQWdCLHdCQUF3QixDQUN0QyxVQUFzQixFQUN0QixPQUF3QjtJQUV4QixPQUFPLEtBQUssSUFBSSxFQUFFLENBQUMsSUFBSSxvQkFBa0IsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDakUsQ0FBQztBQUxELDREQUtDIn0=
@@ -0,0 +1,21 @@
1
+ import { Model, SchemaType } from 'mongoose';
2
+ export declare type SchemaBranch = {
3
+ [key: string]: SchemaNode;
4
+ };
5
+ export declare type SchemaNode = SchemaType | SchemaBranch;
6
+ export default class MongooseSchema {
7
+ readonly isArray: boolean;
8
+ readonly isLeaf: boolean;
9
+ readonly fields: SchemaBranch;
10
+ private models;
11
+ static fromModel(model: Model<unknown>): MongooseSchema;
12
+ get schemaType(): SchemaType;
13
+ constructor(models: Record<string, Model<unknown>>, fields: SchemaBranch, isArray: boolean, isLeaf: boolean);
14
+ getSubSchema(path: string, withParent?: boolean): MongooseSchema;
15
+ /**
16
+ * Build a tree of SchemaType from a mongoose schema.
17
+ * This removes most complexity from using prefixes, nested schemas and array types
18
+ */
19
+ private static buildFields;
20
+ }
21
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable no-underscore-dangle */
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const mongoose_1 = require("mongoose");
6
+ const helpers_1 = require("../utils/helpers");
7
+ class MongooseSchema {
8
+ constructor(models, fields, isArray, isLeaf) {
9
+ this.models = models;
10
+ this.fields = fields;
11
+ this.isArray = isArray;
12
+ this.isLeaf = isLeaf;
13
+ }
14
+ static fromModel(model) {
15
+ return new MongooseSchema(model.db.models, this.buildFields(model.schema), false, false);
16
+ }
17
+ get schemaType() {
18
+ if (this.fields.content instanceof mongoose_1.SchemaType) {
19
+ return this.fields.content;
20
+ }
21
+ throw new Error(`Schema is not a leaf.`);
22
+ }
23
+ getSubSchema(path, withParent = false) {
24
+ // Terminating condition
25
+ if (path === null)
26
+ return this;
27
+ // General case: go down the tree
28
+ const dotIndex = path.indexOf('.');
29
+ const prefix = dotIndex === -1 ? path : path.substring(0, dotIndex);
30
+ const suffix = dotIndex === -1 ? null : path.substring(dotIndex + 1);
31
+ let isArray = false;
32
+ let isLeaf = false;
33
+ let child = this.fields[prefix];
34
+ // Traverse relations
35
+ if (prefix.endsWith('__manyToOne')) {
36
+ const foreignKeyName = prefix.substring(0, prefix.length - '__manyToOne'.length);
37
+ const relationName = this.fields[foreignKeyName].options.ref;
38
+ child = MongooseSchema.fromModel(this.models[relationName]).fields;
39
+ }
40
+ // Traverse arrays
41
+ if (child['[]']) {
42
+ child = child['[]'];
43
+ isArray = true;
44
+ }
45
+ // We ended up on a field => box it.
46
+ if (child instanceof mongoose_1.SchemaType) {
47
+ child = { content: child };
48
+ isLeaf = true;
49
+ }
50
+ // If we want parent to be included, re-add the rootSchema
51
+ if (withParent && !prefix.endsWith('__manyToOne')) {
52
+ const id = new mongoose_1.Schema.Types.String(prefix, {}, 'String');
53
+ child = { ...child, _id: id, _pid: this.fields._id, parent: this.fields };
54
+ }
55
+ return new MongooseSchema(this.models, child, isArray, isLeaf).getSubSchema(suffix, withParent);
56
+ }
57
+ /**
58
+ * Build a tree of SchemaType from a mongoose schema.
59
+ * This removes most complexity from using prefixes, nested schemas and array types
60
+ */
61
+ static buildFields(schema, level = 0) {
62
+ const paths = {};
63
+ for (const [name, field] of Object.entries(schema.paths)) {
64
+ // Exclude mixedFieldPattern $* and privateFieldPattern __
65
+ if (!name.startsWith('$*') && !name.includes('__') && (name !== '_id' || level === 0)) {
66
+ // Flatten nested schemas and arrays
67
+ if (field.constructor.name === 'SubdocumentPath') {
68
+ const subPaths = this.buildFields(field.schema, level + 1);
69
+ for (const [subName, subField] of Object.entries(subPaths))
70
+ (0, helpers_1.recursiveSet)(paths, `${name}.${subName}`, subField);
71
+ }
72
+ else if (field.constructor.name === 'DocumentArrayPath') {
73
+ const subPaths = this.buildFields(field.schema, level + 1);
74
+ for (const [subName, subField] of Object.entries(subPaths))
75
+ (0, helpers_1.recursiveSet)(paths, `${name}.[].${subName}`, subField);
76
+ }
77
+ else if (field.constructor.name === 'SchemaArray') {
78
+ (0, helpers_1.recursiveSet)(paths, `${name}.[]`, field.caster);
79
+ }
80
+ else {
81
+ (0, helpers_1.recursiveSet)(paths, name, field);
82
+ }
83
+ }
84
+ }
85
+ return paths;
86
+ }
87
+ }
88
+ exports.default = MongooseSchema;
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vbmdvb3NlL3NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUF5QztBQUN6Qyx1REFBdUQ7QUFDdkQsdUNBQXFEO0FBRXJELDhDQUFnRDtBQUtoRCxNQUFxQixjQUFjO0lBbUJqQyxZQUNFLE1BQXNDLEVBQ3RDLE1BQW9CLEVBQ3BCLE9BQWdCLEVBQ2hCLE1BQWU7UUFFZixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBdEJELE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBcUI7UUFDcEMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLFlBQVkscUJBQVUsRUFBRTtZQUM3QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBcUIsQ0FBQztTQUMxQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBY0QsWUFBWSxDQUFDLElBQVksRUFBRSxVQUFVLEdBQUcsS0FBSztRQUMzQyx3QkFBd0I7UUFDeEIsSUFBSSxJQUFJLEtBQUssSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRS9CLGlDQUFpQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25D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
@@ -0,0 +1,4 @@
1
+ export declare type MongooseOptions = {
2
+ asModels?: Record<string, string[]>;
3
+ };
4
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Replace dots by underscores.
3
+ *
4
+ * @example
5
+ * escape('a.b') == 'a_b'
6
+ */
7
+ export declare function escape(str: string): string;
8
+ /**
9
+ * Set a value in a plain object recursively
10
+ *
11
+ * @example
12
+ * const a = {};
13
+ * recursiveSet(a, 'field.subfield', 42);
14
+ * a == { field: { subfield: 42 } }
15
+ */
16
+ export declare function recursiveSet(target: any, path: string, value: unknown): void;
17
+ /**
18
+ * Compare two ids.
19
+ * This is useful to ensure we perform array operations in the right order.
20
+ *
21
+ * @example
22
+ * compareIds('a.20.a', 'a.1.b') => 1 (because 1 < 20)
23
+ * compareIds('a.0.a', 'b.1.b') => -1 (because 'a' < 'b')
24
+ */
25
+ export declare function compareIds(a: string, b: string): number;
26
+ /**
27
+ * Split the fake ids which are generated when using the `asModel` option into rootId + path.
28
+ *
29
+ * @example
30
+ * splitId('123.some.path.0.to.the.item) == [123, 'some.path.0.to.the.item]
31
+ */
32
+ export declare function splitId(id: string): [unknown, string];
33
+ /**
34
+ * Group the fake ids which are generated when using the `asModel` option by the path they are
35
+ * targeting to help performing requests.
36
+ *
37
+ * @example
38
+ * groupIdsByPath(['123.field', '456.field']) == { field: [123, 456] }
39
+ */
40
+ export declare function groupIdsByPath(ids: string[]): {
41
+ [path: string]: unknown[];
42
+ };
43
+ /**
44
+ * Replace ObjectId and Date instances in records by strings.
45
+ *
46
+ * @example
47
+ * replaceMongoTypes({_id: ObjectId('12312321313'), createdAt: Date() })
48
+ * == { _id: '12312321313', createdAt: '2010-01-01T00:00:00Z' }
49
+ */
50
+ export declare function replaceMongoTypes(records: any): any;
51
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.replaceMongoTypes = exports.groupIdsByPath = exports.splitId = exports.compareIds = exports.recursiveSet = exports.escape = void 0;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const mongoose_1 = require("mongoose");
6
+ /**
7
+ * Replace dots by underscores.
8
+ *
9
+ * @example
10
+ * escape('a.b') == 'a_b'
11
+ */
12
+ function escape(str) {
13
+ return str.replace(/\./g, '_');
14
+ }
15
+ exports.escape = escape;
16
+ /**
17
+ * Set a value in a plain object recursively
18
+ *
19
+ * @example
20
+ * const a = {};
21
+ * recursiveSet(a, 'field.subfield', 42);
22
+ * a == { field: { subfield: 42 } }
23
+ */
24
+ function recursiveSet(target, path, value) {
25
+ const index = path.indexOf('.');
26
+ if (index !== -1) {
27
+ const prefix = path.substring(0, index);
28
+ const suffix = path.substring(index + 1);
29
+ target[prefix] ?? (target[prefix] = {});
30
+ recursiveSet(target[prefix], suffix, value);
31
+ }
32
+ else {
33
+ target[path] = value;
34
+ }
35
+ }
36
+ exports.recursiveSet = recursiveSet;
37
+ /**
38
+ * Compare two ids.
39
+ * This is useful to ensure we perform array operations in the right order.
40
+ *
41
+ * @example
42
+ * compareIds('a.20.a', 'a.1.b') => 1 (because 1 < 20)
43
+ * compareIds('a.0.a', 'b.1.b') => -1 (because 'a' < 'b')
44
+ */
45
+ function compareIds(a, b) {
46
+ const isNumber = /^\d+$/;
47
+ const partsA = a.split('.');
48
+ const partsB = b.split('.');
49
+ const length = a.length < b.length ? a.length : b.length;
50
+ for (let i = 0; i < length; i += 1) {
51
+ if (partsA[i] !== partsB[i] && isNumber.test(partsA[i]) && isNumber.test(partsB[i]))
52
+ return Number(partsA[i]) - Number(partsB[i]);
53
+ if (partsA[i] < partsB[i])
54
+ return -1;
55
+ if (partsA[i] > partsB[i])
56
+ return 1;
57
+ }
58
+ if (partsA.length < partsB.length)
59
+ return -1;
60
+ if (partsA.length > partsB.length)
61
+ return 1;
62
+ return 0;
63
+ }
64
+ exports.compareIds = compareIds;
65
+ /**
66
+ * Split the fake ids which are generated when using the `asModel` option into rootId + path.
67
+ *
68
+ * @example
69
+ * splitId('123.some.path.0.to.the.item) == [123, 'some.path.0.to.the.item]
70
+ */
71
+ function splitId(id) {
72
+ const dotIndex = id.indexOf('.');
73
+ const rootId = id.substring(0, dotIndex);
74
+ const path = id.substring(dotIndex + 1);
75
+ // @fixme hack, we should never do that without looking at the schema
76
+ return (0, mongoose_1.isValidObjectId)(rootId)
77
+ ? [mongoose_1.Types.ObjectId.createFromHexString(rootId), path]
78
+ : [rootId, path];
79
+ }
80
+ exports.splitId = splitId;
81
+ /**
82
+ * Group the fake ids which are generated when using the `asModel` option by the path they are
83
+ * targeting to help performing requests.
84
+ *
85
+ * @example
86
+ * groupIdsByPath(['123.field', '456.field']) == { field: [123, 456] }
87
+ */
88
+ function groupIdsByPath(ids) {
89
+ const updates = {};
90
+ for (const id of ids) {
91
+ const [rootId, path] = splitId(id);
92
+ updates[path] ?? (updates[path] = []);
93
+ updates[path].push(rootId);
94
+ }
95
+ return updates;
96
+ }
97
+ exports.groupIdsByPath = groupIdsByPath;
98
+ /**
99
+ * Replace ObjectId and Date instances in records by strings.
100
+ *
101
+ * @example
102
+ * replaceMongoTypes({_id: ObjectId('12312321313'), createdAt: Date() })
103
+ * == { _id: '12312321313', createdAt: '2010-01-01T00:00:00Z' }
104
+ */
105
+ function replaceMongoTypes(records) {
106
+ return JSON.parse(JSON.stringify(records));
107
+ }
108
+ exports.replaceMongoTypes = replaceMongoTypes;
109
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUF1RDtBQUN2RCx1Q0FBa0Q7QUFFbEQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixNQUFNLENBQUMsR0FBVztJQUNoQyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFGRCx3QkFFQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixZQUFZLENBQUMsTUFBVyxFQUFFLElBQVksRUFBRSxLQUFjO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFaEMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLEVBQUU7UUFDaEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLE1BQU0sTUFBYixNQUFNLENBQUMsTUFBTSxJQUFNLEVBQUUsRUFBQztRQUV0QixZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztLQUM3QztTQUFNO1FBQ0wsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQztLQUN0QjtBQUNILENBQUM7QUFaRCxvQ0FZQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixVQUFVLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDN0MsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsTUFBTSxNQUFN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