Skip to content

Commit 20781c2

Browse files
committed
initial commit
1 parent 509f36f commit 20781c2

File tree

12 files changed

+456
-0
lines changed

12 files changed

+456
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,5 @@ dist
134134
.yarn/build-state.yml
135135
.yarn/install-state.gz
136136
.pnp.*
137+
138+
test-results

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

browser.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
require('mongoose/lib/driver').set(require('./driver'));
4+
5+
const mongoose = require('mongoose/lib/mongoose');
6+
module.exports = mongoose;
7+
8+
if (typeof window !== 'undefined') {
9+
window.mongoose = mongoose;
10+
}

driver/index.js

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
'use strict';
2+
3+
const MongooseCollection = require('mongoose/lib/collection');
4+
const MongooseConnection = require('mongoose/lib/connection');
5+
6+
class Collection extends MongooseCollection {
7+
get collection() {
8+
return this;
9+
}
10+
11+
aggregate() {
12+
throw new Error('Database operations not supported in @mongoosejs/browser');
13+
}
14+
15+
bulkWrite() {
16+
throw new Error('Database operations not supported in @mongoosejs/browser');
17+
}
18+
19+
createIndex() {
20+
throw new Error('Database operations not supported in @mongoosejs/browser');
21+
}
22+
23+
countDocuments() {
24+
throw new Error('Database operations not supported in @mongoosejs/browser');
25+
}
26+
27+
deleteMany() {
28+
throw new Error('Database operations not supported in @mongoosejs/browser');
29+
}
30+
31+
deleteOne() {
32+
throw new Error('Database operations not supported in @mongoosejs/browser');
33+
}
34+
35+
distinct() {
36+
throw new Error('Database operations not supported in @mongoosejs/browser');
37+
}
38+
39+
dropIndex() {
40+
throw new Error('Database operations not supported in @mongoosejs/browser');
41+
}
42+
43+
estimatedDocumentCount() {
44+
throw new Error('Database operations not supported in @mongoosejs/browser');
45+
}
46+
47+
find() {
48+
throw new Error('Database operations not supported in @mongoosejs/browser');
49+
}
50+
51+
findOne() {
52+
throw new Error('Database operations not supported in @mongoosejs/browser');
53+
}
54+
55+
findOneAndDelete() {
56+
throw new Error('Database operations not supported in @mongoosejs/browser');
57+
}
58+
59+
findOneAndReplace() {
60+
throw new Error('Database operations not supported in @mongoosejs/browser');
61+
}
62+
63+
findOneAndUpdate() {
64+
throw new Error('Database operations not supported in @mongoosejs/browser');
65+
}
66+
67+
listIndexes() {
68+
throw new Error('Database operations not supported in @mongoosejs/browser');
69+
}
70+
71+
insertMany() {
72+
throw new Error('Database operations not supported in @mongoosejs/browser');
73+
}
74+
75+
insertOne() {
76+
throw new Error('Database operations not supported in @mongoosejs/browser');
77+
}
78+
79+
replaceOne() {
80+
throw new Error('Database operations not supported in @mongoosejs/browser');
81+
}
82+
83+
updateOne() {
84+
throw new Error('Database operations not supported in @mongoosejs/browser');
85+
}
86+
87+
updateMany() {
88+
throw new Error('Database operations not supported in @mongoosejs/browser');
89+
}
90+
};
91+
exports.Collection = Collection;
92+
93+
exports.Connection = class Connection extends MongooseConnection {
94+
collection(name, options) {
95+
if (!(name in this.collections)) {
96+
this.collections[name] = new Collection(name, this, options);
97+
}
98+
return super.collection(name, options);
99+
}
100+
101+
createCollection(name, options) {
102+
this.collection(name, options);
103+
}
104+
105+
async dropCollection(name) {
106+
delete this.collections[name];
107+
}
108+
109+
openUri() {
110+
throw new Error('Cannot call connect() in @mongoosejs/browser');
111+
}
112+
113+
asPromise() {
114+
return Promise.resolve(this);
115+
}
116+
117+
doClose(_force, cb) {
118+
if (cb) {
119+
cb(null);
120+
}
121+
return this;
122+
}
123+
124+
async dropDatabase() {
125+
this.collections = {};
126+
}
127+
};
128+
129+
exports.BulkWriteResult = function() {};

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./src/driver');

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"package": "@mongoosejs/browser",
3+
"version": "0.0.1",
4+
"private": false,
5+
"browser": "./dist/index.js",
6+
"scripts": {
7+
"build": "rm -rf ./dist/* && node scripts/build-browser.js",
8+
"postinstall": "playwright install-deps && playwright install chromium",
9+
"prepublish": "npm run build",
10+
"test:browser": "playwright test ./test/browser.test.js",
11+
"test:node": "mocha test/*.node.test.js"
12+
},
13+
"peerDependencies": {
14+
"mongoose": "8.x"
15+
},
16+
"devDependencies": {
17+
"@babel/core": "7.26.10",
18+
"@babel/preset-env": "7.26.9",
19+
"@playwright/test": "^1.52.0",
20+
"assert-browserify": "2.0.0",
21+
"babel-loader": "8.2.5",
22+
"buffer": "^5.6.0",
23+
"crypto-browserify": "3.12.1",
24+
"mocha": "^10.2.0",
25+
"mongoose": "git+https://github.com/Automattic/mongoose.git#9.0",
26+
"playwright": "1.49.1",
27+
"stream-browserify": "3.0.0",
28+
"webpack": "5.98.0"
29+
}
30+
}

scripts/build-browser.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const config = require('../webpack.config.js');
4+
const webpack = require('webpack');
5+
6+
const compiler = webpack(config);
7+
8+
console.log('Starting browser build...');
9+
compiler.run((err, stats) => {
10+
if (err) {
11+
console.err(stats.toString());
12+
console.err('Browser build unsuccessful.');
13+
process.exit(1);
14+
}
15+
console.log(stats.toString());
16+
console.log('Browser build successful.');
17+
process.exit(0);
18+
});

test/browser.node.test.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
'use strict';
2+
3+
/**
4+
* Module dependencies.
5+
*/
6+
7+
const assert = require('assert');
8+
const mongoose = require('../browser');
9+
const exec = require('child_process').exec;
10+
11+
/**
12+
* Test.
13+
*/
14+
describe('browser', function() {
15+
it('require() works with no other require calls (gh-5842)', function(done) {
16+
exec('node --eval "require(\'./browser\')"', done);
17+
});
18+
19+
it('using schema (gh-7170)', function(done) {
20+
exec('node --eval "const mongoose = require(\'./browser\'); new mongoose.Schema();"', done);
21+
});
22+
23+
it('document works (gh-4987)', function() {
24+
const schema = new mongoose.Schema({
25+
name: { type: String, required: true },
26+
quest: { type: String, match: /Holy Grail/i, required: true },
27+
favoriteColor: { type: String, enum: ['Red', 'Blue'], required: true }
28+
});
29+
30+
assert.doesNotThrow(function() {
31+
new mongoose.Document({}, schema);
32+
});
33+
});
34+
35+
it('document validation with arrays (gh-6175)', async function() {
36+
const Point = new mongoose.Schema({
37+
latitude: {
38+
type: Number,
39+
required: true,
40+
min: -90,
41+
max: 90
42+
},
43+
longitude: {
44+
type: Number,
45+
required: true,
46+
min: -180,
47+
max: 180
48+
}
49+
});
50+
51+
const schema = new mongoose.Schema({
52+
name: {
53+
type: String,
54+
required: true
55+
},
56+
vertices: {
57+
type: [Point],
58+
required: true
59+
}
60+
});
61+
62+
let test = new mongoose.Document({
63+
name: 'Test Polygon',
64+
vertices: [
65+
{
66+
latitude: -37.81902680201739,
67+
longitude: 144.9821037054062
68+
}
69+
]
70+
}, schema);
71+
72+
// Should not throw
73+
await test.validate();
74+
75+
test = new mongoose.Document({
76+
name: 'Test Polygon',
77+
vertices: [
78+
{
79+
latitude: -37.81902680201739
80+
}
81+
]
82+
}, schema);
83+
84+
const error = await test.validate().then(() => null, err => err);
85+
assert.ok(error.errors['vertices.0.longitude']);
86+
});
87+
88+
it('throws errors when using db operations', async function () {
89+
const TestModel = mongoose.model('Test', mongoose.Schema({ name: String }));
90+
const doc = new TestModel({ name: 'test' });
91+
await assert.rejects(doc.save(), /Database operations not supported in @mongoosejs\/browser/);
92+
93+
await assert.rejects(TestModel.aggregate([{ $match: {} }]), /Database operations not supported in @mongoosejs\/browser/);
94+
await assert.rejects(TestModel.create({ name: 'test' }), /Database operations not supported in @mongoosejs\/browser/);
95+
await assert.rejects(TestModel.deleteMany({ name: 'test' }), /Database operations not supported in @mongoosejs\/browser/);
96+
await assert.rejects(TestModel.deleteOne({ name: 'test' }), /Database operations not supported in @mongoosejs\/browser/);
97+
await assert.rejects(TestModel.find({ name: 'test' }), /Database operations not supported in @mongoosejs\/browser/);
98+
await assert.rejects(TestModel.findOne({ name: 'test' }), /Database operations not supported in @mongoosejs\/browser/);
99+
await assert.rejects(TestModel.updateMany({ name: 'test' }, { name: 'test2' }), /Database operations not supported in @mongoosejs\/browser/);
100+
await assert.rejects(TestModel.updateOne({ name: 'test' }, { name: 'test2' }), /Database operations not supported in @mongoosejs\/browser/);
101+
});
102+
});

test/browser.test.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const { test } = require('@playwright/test');
5+
6+
test('can create new schema without errors', async ({ page }) => {
7+
await page.addScriptTag({ path: './dist/mongoose.umd.js' });
8+
9+
const result = await page.evaluate(() => {
10+
const schema = new mongoose.Schema({ name: String });
11+
const TestModel = mongoose.model('Test', schema);
12+
const doc = new TestModel({ name: 'John' });
13+
return !doc.validateSync();
14+
});
15+
16+
assert.strictEqual(result, true);
17+
});
18+
19+
test('reports validation errors', async ({ page }) => {
20+
await page.addScriptTag({ path: './dist/mongoose.umd.js' });
21+
22+
const result = await page.evaluate(async () => {
23+
try {
24+
const schema = new mongoose.Schema({ name: { type: String, required: true } });
25+
const TestModel = mongoose.model('Test', schema);
26+
const doc = new TestModel();
27+
await doc.validate();
28+
} catch (error) {
29+
return error.message;
30+
}
31+
});
32+
33+
assert.strictEqual(result, 'Validation failed: name: Path `name` is required.');
34+
});
35+
36+
test('TestModel.findOne() throws an expected error', async ({ page }) => {
37+
await page.addScriptTag({ path: './dist/mongoose.umd.js' });
38+
39+
const result = await page.evaluate(async () => {
40+
try {
41+
const schema = new mongoose.Schema({ name: String });
42+
const TestModel = mongoose.model('Test', schema);
43+
await TestModel.findOne();
44+
return false;
45+
} catch (error) {
46+
return error.message;
47+
}
48+
});
49+
50+
assert.strictEqual(result, 'Database operations not supported in @mongoosejs/browser');
51+
});
52+
53+
test('TestModel.find() throws an expected error', async ({ page }) => {
54+
await page.addScriptTag({ path: './dist/mongoose.umd.js' });
55+
56+
const result = await page.evaluate(async () => {
57+
try {
58+
const schema = new mongoose.Schema({ name: String });
59+
const TestModel = mongoose.model('Test', schema);
60+
await TestModel.find();
61+
return false;
62+
} catch (error) {
63+
return error.message;
64+
}
65+
});
66+
67+
assert.strictEqual(result, 'Database operations not supported in @mongoosejs/browser');
68+
});
69+
70+
test('mongoose.connect() throws an expected error', async ({ page }) => {
71+
await page.addScriptTag({ path: './dist/mongoose.umd.js' });
72+
73+
const result = await page.evaluate(async () => {
74+
try {
75+
await mongoose.connect('mongodb://localhost:27017/test');
76+
return false;
77+
} catch (error) {
78+
return error.message;
79+
}
80+
});
81+
82+
assert.strictEqual(result, 'Cannot call connect() in @mongoosejs/browser');
83+
});

0 commit comments

Comments
 (0)