mongodb-js / mongoose-autopopulate

Always populate() certain fields in your mongoose schemas
Apache License 2.0
221 stars 36 forks source link

Unable to initiate Autopopulate on Schema.plugin() #107

Closed DigitalVortex92 closed 1 year ago

DigitalVortex92 commented 1 year ago

When attempting to call Schema.plugin(<mongoose-autopopulate here>), the code fails at line 225 of the index.js. Based on the section it's in, it looks like it's relevant to the change made for 0.17.1 regarding recursive schemas.

/home/XX/XX/node_modules/mongoose-autopopulate/index.js:225
  if (schemaStack.has(schema)) {
                  ^

TypeError: Cannot read properties of undefined (reading 'has')
    at eachPathRecursive (/home/XX/XX/node_modules/mongoose-autopopulate/index.js:225:19)
    at /home/XX/XX/node_modules/mongoose-autopopulate/index.js:240:11
    at Schema.eachPath (/home/XX/XX/node_modules/mongoose/lib/schema.js:1414:5)
    at eachPathRecursive (/home/XX/XX/node_modules/mongoose-autopopulate/index.js:233:10)
    at getPathsToPopulate (/home/XX/XX/node_modules/mongoose-autopopulate/index.js:154:3)
    at autopopulatePlugin (/home/XX/XX/node_modules/mongoose-autopopulate/index.js:4:27)
    at Schema.plugin (/home/XX/XX/node_modules/mongoose/lib/schema.js:1814:3)
    at file:///home/XX/XX/modules/db.js:388:17
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)

Digging into the file, it seems either an intentional passing of schemaStack was left out of the call to eachPathRecursive on line 240, or it was left out by accident.

if (schemaType.schema) {
  eachPathRecursive(schemaType.schema, handler, path, schemaStack);

  if (schemaType.schema.discriminators != null) {
    for (const discriminatorName of Object.keys(schemaType.schema.discriminators)) {
 ---->eachPathRecursive(schemaType.schema.discriminators[discriminatorName], handler, path);
    }
  }
} else if (schemaType.$isMongooseArray && schemaType.$embeddedSchemaType.$isMongooseArray) {
  while (schemaType != null && schemaType.$isMongooseArray && !schemaType.$isMongooseDocumentArray) {
    schemaType = schemaType.$embeddedSchemaType;
  }
  if (schemaType != null && schemaType.$isMongooseDocumentArray) {
    eachPathRecursive(schemaType.schema, handler, path, schemaStack);

    if (schemaType.schema.discriminators != null) {
      for (const discriminatorName of Object.keys(schemaType.schema.discriminators)) {
        eachPathRecursive(schemaType.schema.discriminators[discriminatorName], handler, path, schemaStack);
      }
    }
  }
}

Not really sure to be honest as I haven't looked to much into it. I can simply add the passing of schemaStack as a parameter to that call to fix the issue, but I'm not sure if that defeats the purpose of the recursive fix.

Edit: Apparently it has to do with the fact that I am using discriminators. I'm blind and can't read the code I'm reporting an issue with apparently :)

I'm not able to paste my direct code here, but essentially:

const schema = new mongoose.Schema({
    Time: Number
}, { discriminatorKey: 'Type', _id: false });
schema.discriminator('SomeText', new Schema({
    SomeField: Number
});
(it will fail here) schema.plugin(require('mongoose-autopopulate'));
vkarpov15 commented 1 year ago

I'm unable to repro, the following script works fine:

const mongoose = require('mongoose');

const mongooseAutoPopulate = require('mongoose-autopopulate');

const testSchema = new mongoose.Schema({
  Time: Number,
}, { discriminatorKey: 'Type', _id: false });

testSchema.discriminator('SomeText', new mongoose.Schema({
  SomeField: Number
}));

testSchema.plugin(mongooseAutoPopulate);

console.log('done');

Do you have some sort of polyfill for WeakMaps? What does new WeakMap() return in your environment?

vkarpov15 commented 1 year ago

Fixed in v1.0.1 along with #113