Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-6627): add TS support to encrypted schemas #15213

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
4a79a88
feat: `useConnection(connection)` function
IslandRhythms Aug 12, 2024
3a9afe6
more assertions
IslandRhythms Aug 20, 2024
e87d506
feat(model): complete useConnection()
vkarpov15 Oct 26, 2024
96b5726
Merge branch '8.8' into IslandRhythms/use-connection
vkarpov15 Oct 26, 2024
1ccf38e
temp
aditi-khare-mongoDB Nov 19, 2024
aeda36b
temp
aditi-khare-mongoDB Nov 20, 2024
e5d8cad
temp 2
aditi-khare-mongoDB Nov 20, 2024
a041206
test
aditi-khare-mongoDB Nov 21, 2024
0c978a2
edit
aditi-khare-mongoDB Nov 21, 2024
f8cbb9a
removed errors
aditi-khare-mongoDB Nov 21, 2024
2fa3417
on push
aditi-khare-mongoDB Nov 21, 2024
c71d3c2
test
aditi-khare-mongoDB Nov 21, 2024
e6facfe
path
aditi-khare-mongoDB Nov 21, 2024
06f9758
path
aditi-khare-mongoDB Nov 21, 2024
86f7874
path
aditi-khare-mongoDB Nov 21, 2024
7a30734
path
aditi-khare-mongoDB Nov 21, 2024
b39c754
fixed
aditi-khare-mongoDB Nov 22, 2024
ccb726e
typo
aditi-khare-mongoDB Nov 22, 2024
b0a1c3c
install mocha
aditi-khare-mongoDB Nov 22, 2024
6198ade
fixed?
aditi-khare-mongoDB Nov 22, 2024
a135e79
fix tests
aditi-khare-mongoDB Nov 22, 2024
ca25868
run tests
aditi-khare-mongoDB Nov 22, 2024
270d151
ready for rereview
aditi-khare-mongoDB Nov 25, 2024
69dbda6
ready for rereview 2
aditi-khare-mongoDB Nov 25, 2024
3ce14a4
typo
aditi-khare-mongoDB Nov 25, 2024
eac708f
ready for review
aditi-khare-mongoDB Dec 10, 2024
f38366b
change to two files for local testing
aditi-khare-mongoDB Dec 10, 2024
62d18d8
fixed deps
aditi-khare-mongoDB Dec 10, 2024
40858d4
requested changes
aditi-khare-mongoDB Dec 11, 2024
d6044e7
fix
aditi-khare-mongoDB Dec 11, 2024
03407f6
types(document): make sure `toObject()` and `toJSON()` apply versionK…
vkarpov15 Dec 15, 2024
8cd67ef
fix(model): throw error if calling `create()` with multiple docs in a…
vkarpov15 Dec 15, 2024
9a6aeff
Update test/types/document.test.ts
vkarpov15 Dec 16, 2024
5a99d52
Merge branch 'master' into vkarpov15/gh-15091
vkarpov15 Dec 16, 2024
7a6f744
fix tests
vkarpov15 Dec 16, 2024
eebe0ff
fix tests
vkarpov15 Dec 16, 2024
2d51c10
fix tests
vkarpov15 Dec 16, 2024
f8844bb
Merge pull request #15097 from Automattic/vkarpov15/gh-15077
vkarpov15 Dec 16, 2024
b7191c4
Merge pull request #15100 from Automattic/vkarpov15/gh-15091
vkarpov15 Dec 16, 2024
0440c52
Merge branch 'master' into 8.10
vkarpov15 Dec 18, 2024
8f05374
Merge pull request #14802 from Automattic/IslandRhythms/use-connection
vkarpov15 Dec 18, 2024
08f4c23
fix wording
aditi-khare-mongoDB Dec 18, 2024
da4eb75
fix(populate): handle hydrating deeply nested populated docs undernea…
vkarpov15 Dec 23, 2024
1098636
change all occurences of encrypted-cluster to data
aditi-khare-mongoDB Dec 26, 2024
5a04290
fix(model): handle nested conventional populate with hydratedPopulate…
vkarpov15 Dec 26, 2024
955cedf
remove extra gha call - use local script instead
aditi-khare-mongoDB Dec 27, 2024
acacc7a
Update test/model.hydrate.test.js
vkarpov15 Dec 30, 2024
79de0ff
Update test/model.hydrate.test.js
vkarpov15 Dec 30, 2024
c90e6da
Merge branch 'master' into 8.10
vkarpov15 Dec 30, 2024
a8fc5cd
Merge pull request #15130 from Automattic/vkarpov15/gh-15110
vkarpov15 Dec 30, 2024
60c5c7f
Merge branch 'master' into 8.10
vkarpov15 Jan 2, 2025
29b3936
feat(connection): support Connection.prototype.aggregate() for db-lev…
vkarpov15 Jan 2, 2025
4c6e324
fix tests
vkarpov15 Jan 2, 2025
2ebcc9e
refactor: remove need for aggregate() import
vkarpov15 Jan 2, 2025
563fe5d
fix tests and lint
vkarpov15 Jan 2, 2025
4d4bd00
fix(model): skip createCollection() in syncIndexes() if autoCreate: f…
vkarpov15 Jan 3, 2025
306fced
fix tests
vkarpov15 Jan 3, 2025
57237a9
Merge pull request #15153 from Automattic/vkarpov15/gh-15118
vkarpov15 Jan 3, 2025
911ba54
Merge pull request #15155 from Automattic/vkarpov15/autocreate-syncin…
vkarpov15 Jan 4, 2025
03343ad
Merge branch 'master' into 8.10
vkarpov15 Jan 4, 2025
3203fe1
feat(model): add insertOne() function to insert a single doc
vkarpov15 Jan 6, 2025
e519ac3
types: add Model.insertOne() to types
vkarpov15 Jan 6, 2025
fc0ee9f
feat(document): support schematype-level transform option
vkarpov15 Jan 6, 2025
97adaac
chore(eslintrc): set "ecmaVersion: 2022"
hasezoey Jan 8, 2025
43cb76b
Update lib/model.js
vkarpov15 Jan 8, 2025
439ec4d
style: improve docs and var naming re: code review comments
vkarpov15 Jan 8, 2025
12e8431
Merge pull request #15162 from Automattic/vkarpov15/gh-14843
vkarpov15 Jan 8, 2025
08113ef
style: fix lint and code review comments
vkarpov15 Jan 8, 2025
933a283
chore: pin exact versions of typescript-eslint to hopefully fix tests
vkarpov15 Jan 8, 2025
7cac003
Merge pull request #15163 from Automattic/vkarpov15/gh-15084
vkarpov15 Jan 8, 2025
81e1bbb
Merge pull request #15165 from hasezoey/eslintEcma
vkarpov15 Jan 8, 2025
62ab149
Merge branch 'master' into 8.10
vkarpov15 Jan 9, 2025
9800153
feat(schema): introduce basic jsonSchema() method to convert Mongoose…
vkarpov15 Jan 9, 2025
464107c
most of Val's comments addressed
aditi-khare-mongoDB Jan 9, 2025
06ffdea
comments addressed
aditi-khare-mongoDB Jan 9, 2025
7abbbcc
change version to avert N-API bug
aditi-khare-mongoDB Jan 10, 2025
45b20f0
feat(model): make `syncIndexes()` not call `createIndex()` on indexes…
vkarpov15 Jan 10, 2025
dcca5ca
Merge branch 'master' into 8.10
vkarpov15 Jan 10, 2025
ee8bf75
Merge branch '8.10' into vkarpov15/sync-indexes-tocreate
vkarpov15 Jan 10, 2025
67a30e7
Merge pull request #15175 from Automattic/vkarpov15/sync-indexes-tocr…
vkarpov15 Jan 11, 2025
815a907
Merge branch '8.10' into vkarpov15/gh-11162
vkarpov15 Jan 13, 2025
942911c
fix(schema): WIP array and document array support for jsonSchema()
vkarpov15 Jan 13, 2025
cf1f3b3
fix(schema): support primitive arrays and arrays of arrays in JSONschema
vkarpov15 Jan 13, 2025
d0e8d57
fix(schema): test jsonSchema() output with AJV
vkarpov15 Jan 13, 2025
e8a35c3
fix(schema): map support for jsonSchema()
vkarpov15 Jan 13, 2025
eff58ce
test: add test case for map of arrays, implementation still WIP
vkarpov15 Jan 15, 2025
da6d7e1
add separate setup npm command
aditi-khare-mongoDB Jan 15, 2025
42a7b5e
Merge branch 'master' into NODE-6505/ci-setup
aditi-khare-mongoDB Jan 15, 2025
47759f8
chore: use Deno 2.1 in tests
vkarpov15 Jan 15, 2025
556ea45
explicitly set type: commonjs for Deno
vkarpov15 Jan 15, 2025
cf34a9f
fix: handle maps of arrays
vkarpov15 Jan 15, 2025
553b29c
test: expand map jsonSchema tests
vkarpov15 Jan 15, 2025
5a056c3
Merge pull request #15183 from Automattic/vkarpov15/deno-upgrade
vkarpov15 Jan 16, 2025
9a89b46
Update lib/schema.js
vkarpov15 Jan 16, 2025
cc9f288
fix(collection): avoid buffering if creating a collection during a co…
vkarpov15 Jan 17, 2025
92103a2
Merge branch 'master' into 8.10
vkarpov15 Jan 17, 2025
149f0f5
Merge branch '8.10' into vkarpov15/gh-11162
vkarpov15 Jan 17, 2025
402bbec
add Buffer and UUID, add link to JSON schema docs, add additional tes…
vkarpov15 Jan 17, 2025
fd6022b
style: fix lint
vkarpov15 Jan 17, 2025
879443d
fix tests
vkarpov15 Jan 17, 2025
00a2778
refactor(schema): move logic for converting SchemaType to JSON schema…
vkarpov15 Jan 20, 2025
34bc2d1
Merge branch 'master' into 8.10
vkarpov15 Jan 20, 2025
efbef97
Merge branch '8.10' into vkarpov15/gh-11162
vkarpov15 Jan 20, 2025
e893399
fix: rename jsonSchema -> toJSONSchema for consistency
vkarpov15 Jan 20, 2025
57b48f9
types: add toJSONSchema to typescript types
vkarpov15 Jan 20, 2025
62e9447
Merge pull request #15184 from Automattic/vkarpov15/gh-11162
vkarpov15 Jan 20, 2025
d8c9d6c
Merge pull request #15139 from mongodb-js/NODE-6505/ci-setup
vkarpov15 Jan 20, 2025
3e4ba3f
Merge pull request #15187 from Automattic/vkarpov15/gh-14971
vkarpov15 Jan 20, 2025
d02dfc4
changes
baileympearson Jan 23, 2025
4402f80
Update lib/encryptionUtils.js
baileympearson Jan 23, 2025
a6a51bd
Update test/encrypted_schema.test.js
baileympearson Jan 23, 2025
7fa6616
src code changes
aditi-khare-mongoDB Jan 29, 2025
616ce14
tests added
aditi-khare-mongoDB Jan 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ module.exports = {
'**/docs/js/native.js',
'!.*',
'node_modules',
'.git'
'.git',
'data',
'.config'
],
overrides: [
{
Expand Down Expand Up @@ -104,7 +106,7 @@ module.exports = {
// 'markdown'
],
parserOptions: {
ecmaVersion: 2020
ecmaVersion: 2022
},
env: {
node: true,
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/encryption-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Encryption Tests

on:
push:
branches: ['master']
pull_request:
branches: [ 'master' ]
workflow_dispatch: {}

permissions:
contents: write
pull-requests: write
id-token: write

jobs:
run-tests:
permissions:
# required for all workflows
security-events: write
id-token: write
contents: write
runs-on: ubuntu-latest
name: Encryption tests
env:
FORCE_COLOR: true
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- name: Setup node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
with:
node-version: 22
- name: Install Dependencies
run: npm install
- name: Install mongodb-client-encryption
run: npm install mongodb-client-encryption
- name: Setup Tests
run: npm run setup-test-encryption
- name: Run Tests
run: npm run test-encryption
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: v1.37.x
deno-version: v2.1.x
- run: deno --version
- run: npm install
- name: Run Deno tests
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@ examples/ecommerce-netlify-functions/.netlify/state.json

notes.md
list.out

data
*.pid
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ If you have a question about Mongoose (not a bug report) please post it to eithe
* execute `npm run test-tsd` to run the typescript tests
* execute `npm run ts-benchmark` to run the typescript benchmark "performance test" for a single time.
* execute `npm run ts-benchmark-watch` to run the typescript benchmark "performance test" while watching changes on types folder. Note: Make sure to commit all changes before executing this command.
* in order to run tests that require an cluster with encryption locally, run `npm run setup-test-encryption` followed by `npm run test-encryption`. Alternatively, you can start an encrypted cluster using the `scripts/configure-cluster-with-encryption.sh` file.
* These scripts can take a few minutes to run.
* To change an encryption configuration, it is recommended to follow these steps:
* Edit the variables in `scripts/configure-cluster-with-encryption.sh` with your desired configuration.
* Restart your shell.
* Delete the `data/` directory if it exists.
* Finally, run the configuration script.

## Documentation

Expand Down
38 changes: 38 additions & 0 deletions docs/field-level-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,41 @@ With the above connection, if you create a model named 'Test' that uses the 'tes
const Model = mongoose.model('Test', mongoose.Schema({ name: String }));
await Model.create({ name: 'super secret' });
```

## Automatic FLE in Mongoose

Mongoose supports the declaration of encrypted schemas - schemas that, when connected to a model, utilize MongoDB's Client Side
Field Level Encryption or Queryable Encryption under the hood. Mongoose automatically generates either an `encryptedFieldsMap` or a
`schemaMap` when instantiating a MongoClient and encrypts fields on write and decrypts fields on reads.

### Encryption types

MongoDB has two different automatic encryption implementations: client side field level encryption (CSFLE) and queryable encryption (QE).
See [choosing an in-use encryption approach](https://www.mongodb.com/docs/v7.3/core/queryable-encryption/about-qe-csfle/#choosing-an-in-use-encryption-approach).

### Declaring Encrypted Schemas

The following schema declares two properties, `name` and `ssn`. `ssn` is encrypted using queryable encryption, and
is configured for equality queries:

```javascript
const encryptedUserSchema = new Schema({
name: String,
ssn: {
type: String,
// 1
encrypt: {
keyId: '<uuid string of key id>',
queries: 'equality'
}
}
// 2
}, { encryptionType: 'queryableEncryption' });
```

To declare a field as encrypted, you must:

1. Annotate the field with encryption metadata in the schema definition
2. Choose an encryption type for the schema and configure the schema for the encryption type

Not all schematypes are supported for CSFLE and QE. For an overview of valid schema types, refer to MongoDB's documentation.
25 changes: 21 additions & 4 deletions lib/aggregate.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const getConstructorName = require('./helpers/getConstructorName');
const prepareDiscriminatorPipeline = require('./helpers/aggregate/prepareDiscriminatorPipeline');
const stringifyFunctionOperators = require('./helpers/aggregate/stringifyFunctionOperators');
const utils = require('./utils');
const { modelSymbol } = require('./helpers/symbols');
const read = Query.prototype.read;
const readConcern = Query.prototype.readConcern;

Expand Down Expand Up @@ -46,13 +47,17 @@ const validRedactStringValues = new Set(['$$DESCEND', '$$PRUNE', '$$KEEP']);
* @see MongoDB https://www.mongodb.com/docs/manual/applications/aggregation/
* @see driver https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#aggregate
* @param {Array} [pipeline] aggregation pipeline as an array of objects
* @param {Model} [model] the model to use with this aggregate.
* @param {Model|Connection} [modelOrConn] the model or connection to use with this aggregate.
* @api public
*/

function Aggregate(pipeline, model) {
function Aggregate(pipeline, modelOrConn) {
this._pipeline = [];
this._model = model;
if (modelOrConn == null || modelOrConn[modelSymbol]) {
this._model = modelOrConn;
} else {
this._connection = modelOrConn;
}
this.options = {};

if (arguments.length === 1 && Array.isArray(pipeline)) {
Expand Down Expand Up @@ -1029,12 +1034,24 @@ Aggregate.prototype.pipeline = function() {
*/

Aggregate.prototype.exec = async function exec() {
if (!this._model) {
if (!this._model && !this._connection) {
throw new Error('Aggregate not bound to any Model');
}
if (typeof arguments[0] === 'function') {
throw new MongooseError('Aggregate.prototype.exec() no longer accepts a callback');
}

if (this._connection) {
if (!this._pipeline.length) {
throw new MongooseError('Aggregate has empty pipeline');
}

this._optionsForExec();

const cursor = await this._connection.client.db().aggregate(this._pipeline, this.options);
return await cursor.toArray();
}

const model = this._model;
const collection = this._model.collection;

Expand Down
2 changes: 1 addition & 1 deletion lib/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function Collection(name, conn, opts) {
this.collectionName = name;
this.conn = conn;
this.queue = [];
this.buffer = true;
this.buffer = !conn?._hasOpened;
this.emitter = new EventEmitter();

if (STATES.connected === this.conn.readyState) {
Expand Down
12 changes: 12 additions & 0 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,18 @@ Connection.prototype.syncIndexes = async function syncIndexes(options = {}) {
* @api public
*/

/**
* Runs a [db-level aggregate()](https://www.mongodb.com/docs/manual/reference/method/db.aggregate/) on this connection's underlying `db`
*
* @method aggregate
* @memberOf Connection
* @param {Array} pipeline
* @param {Object} [options]
* @param {Boolean} [options.cursor=false] If true, make the Aggregate resolve to a Mongoose AggregationCursor rather than an array
* @return {Aggregate} Aggregation wrapper
* @api public
*/

/**
* Removes the database connection with the given name created with with `useDb()`.
*
Expand Down
8 changes: 7 additions & 1 deletion lib/cursor/aggregationCursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,17 @@ function AggregationCursor(agg) {
this.cursor = null;
this.agg = agg;
this._transforms = [];
const connection = agg._connection;
const model = agg._model;
delete agg.options.cursor.useMongooseAggCursor;
this._mongooseOptions = {};

_init(model, this, agg);
if (connection) {
this.cursor = connection.db.aggregate(agg._pipeline, agg.options || {});
setImmediate(() => this.emit('cursor', this.cursor));
} else {
_init(model, this, agg);
}
}

util.inherits(AggregationCursor, Readable);
Expand Down
17 changes: 9 additions & 8 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -807,8 +807,8 @@ function init(self, obj, doc, opts, prefix) {
reason: e
}));
}
} else if (opts.hydratedPopulatedDocs) {
doc[i] = schemaType.cast(value, self, true);
} else if (schemaType && opts.hydratedPopulatedDocs) {
doc[i] = schemaType.cast(value, self, true, undefined, { hydratedPopulatedDocs: true });

if (doc[i] && doc[i].$__ && doc[i].$__.wasPopulated) {
self.$populated(path, doc[i].$__.wasPopulated.value, doc[i].$__.wasPopulated.options);
Expand Down Expand Up @@ -4256,24 +4256,25 @@ function applySchemaTypeTransforms(self, json) {

for (const path of paths) {
const schematype = schema.paths[path];
if (typeof schematype.options.transform === 'function') {
const topLevelTransformFunction = schematype.options.transform ?? schematype.constructor?.defaultOptions?.transform;
const embeddedSchemaTypeTransformFunction = schematype.$embeddedSchemaType?.options?.transform
?? schematype.$embeddedSchemaType?.constructor?.defaultOptions?.transform;
if (typeof topLevelTransformFunction === 'function') {
const val = self.$get(path);
if (val === undefined) {
continue;
}
const transformedValue = schematype.options.transform.call(self, val);
const transformedValue = topLevelTransformFunction.call(self, val);
throwErrorIfPromise(path, transformedValue);
utils.setValue(path, transformedValue, json);
} else if (schematype.$embeddedSchemaType != null &&
typeof schematype.$embeddedSchemaType.options.transform === 'function') {
} else if (typeof embeddedSchemaTypeTransformFunction === 'function') {
const val = self.$get(path);
if (val === undefined) {
continue;
}
const vals = [].concat(val);
const transform = schematype.$embeddedSchemaType.options.transform;
for (let i = 0; i < vals.length; ++i) {
const transformedValue = transform.call(self, vals[i]);
const transformedValue = embeddedSchemaTypeTransformFunction.call(self, vals[i]);
vals[i] = transformedValue;
throwErrorIfPromise(path, transformedValue);
}
Expand Down
11 changes: 11 additions & 0 deletions lib/drivers/node-mongodb-native/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ NativeConnection.prototype.useDb = function(name, options) {
return newConn;
};

/**
* Runs a [db-level aggregate()](https://www.mongodb.com/docs/manual/reference/method/db.aggregate/) on this connection's underlying `db`
*
* @param {Array} pipeline
* @param {Object} [options]
*/

NativeConnection.prototype.aggregate = function aggregate(pipeline, options) {
return new this.base.Aggregate(null, this).append(pipeline).option(options ?? {});
};

/**
* Removes the database connection with the given name created with `useDb()`.
*
Expand Down
72 changes: 72 additions & 0 deletions lib/encryptionUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';

const schemaTypes = require('./schema/index.js');
const SchemaBigInt = require('./schema/bigint');
const SchemaBoolean = require('./schema/boolean');
const SchemaBuffer = require('./schema/buffer');
const SchemaDate = require('./schema/date');
const SchemaDecimal128 = require('./schema/decimal128');
const SchemaDouble = require('./schema/double');
const SchemaInt32 = require('./schema/int32');
const SchemaObjectId = require('./schema/objectId');
const SchemaString = require('./schema/string');

/**
* Given a schema and a path to a field in the schema, this returns the
* BSON type of the field, if it can be determined. This method specifically
* **only** handles BSON types that are used for CSFLE and QE - any other
* BSON types will return `null`. (example: MinKey and MaxKey).
*
* @param {import('.').Schema} schema
* @param {string} path
* @returns {string}
*/
function inferBSONType(schema, path) {
const type = schema.path(path);

if (type instanceof SchemaString) {
return 'string';
}

if (type instanceof SchemaInt32) {
return 'int';
}

if (type instanceof SchemaBigInt) {
return 'long';
}

if (type instanceof SchemaBoolean) {
return 'bool';
}

if (type instanceof SchemaDate) {
return 'date';
}

if (type instanceof SchemaBuffer) {
return 'binData';
}

if (type instanceof SchemaObjectId) {
return 'objectId';
}

if (type instanceof SchemaDecimal128) {
return 'decimal';
}

if (type instanceof SchemaDouble) {
return 'double';
}

if (type instanceof schemaTypes.Array) {
return 'array';
}

return null;
}

module.exports = {
inferBSONType
};
24 changes: 24 additions & 0 deletions lib/helpers/createJSONSchemaTypeDefinition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

/**
* Handles creating `{ type: 'object' }` vs `{ bsonType: 'object' }` vs `{ bsonType: ['object', 'null'] }`
*
* @param {String} type
* @param {String} bsonType
* @param {Boolean} useBsonType
* @param {Boolean} isRequired
*/

module.exports = function createJSONSchemaTypeArray(type, bsonType, useBsonType, isRequired) {
if (useBsonType) {
if (isRequired) {
return { bsonType };
}
return { bsonType: [bsonType, 'null'] };
} else {
if (isRequired) {
return { type };
}
return { type: [type, 'null'] };
}
};
Loading
Loading