softwarebrothers / adminjs-mongoose Goto Github PK
View Code? Open in Web Editor NEWMongoose adapter for AdminJS
License: MIT License
Mongoose adapter for AdminJS
License: MIT License
Right now, when using a filter for string type, the regex used only works for a single word, or for an exact full phrase match if using multiple words.
I think it's more useful if it does an AND when multiple words are inputted.
I have made a PR for this in case it's considered useful.
there should be at least those what we have in admin-bro core:
"strictNullChecks": true,
"strictPropertyInitialization": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"noImplicitThis": true,
Would be nice to have a button to clone a document / DB entry.
is that on the roadmap?
adminjs-mongoose/src/property.ts
Lines 72 to 80 in b35f89f
This part requires another update because the ref
in mongoose can be defined as string | Model<any> | ((this: any, doc: any) => string | Model<any>);
Right now this logic correctly handles ref: string | Model
but not the ref: () => string | Model
part
Line 77 should be updated to
if (typeof ref === 'function') return ref.modelName || ref().modelName
Lmk what you think
As shown in this example, mongoose supports virtual (computed) properties on objects. I've implemented an example resource (just like the first one in the mongoose docs) and I am not able to show the property in the frontend.
What do I miss? Are virtuals supported in admin-bro-mongoose
?
As far as I can tell this mongoose adapter does not include any support for Mongoose discriminators.
Is there a plan to add support for discriminators?
If not is there any interest in contributions towards adding support for discriminators?
The discriminator mapping (discriminatorKey) along with the property information for each discriminator type could be extracted from the Mongoose schema and stored on the Property
.
Once available in the adminjs frontend the full set of properties could be determined using the discriminatorKey value for a recored.
Hello, mongoose version 8 implemented some breaking changes which affected this package. Specifically in our case the deprecation of the findOneAndRemove method breaks all delete requests. I suspect there may be more. Version 8 has been release for nearly 2 months now and I think we should work on an update to support it.
More info here > https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md#800-rc0--2023-10-24
Version tried:
4.0.0
4.0.0-beta.4
"@adminjs/express": "^6.0.0",
"@adminjs/mongoose": "4.0.0",
"adminjs": "^7.1.0",
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "ESNext",
"noImplicitAny": true,
"moduleResolution": "node",
.....
}
}
Thanks in advance!
Edit: Added other companion module versions
I have a number of records in my collection; some have "Active" in status property and others have "Inactive".
In AdminJS frontend, when I filter status field to show me only "Active" status records, it returns both Active and Inactive. For Inactive status filter, it works fine.
I believe the reason could be in file "src/utils/convert-filter.ts", line number 19.
Link; https://github.com/SoftwareBrothers/adminjs-mongoose/blob/master/src/utils/convert-filter.ts#L19
It's searching a property using regex, which returns both Active and Inactive since both values contain "Active".
Is there any workaround we can do to make sure only either Active or Inactive records get returned by the list action?
Suppose there is following collection :
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const imageSchema = new Schema(
{
key: { type: String },
filePath: { type: String, default: '' }
},
{ timestamps: true }
);
imageSchema.pre('save', function (next) {
const data = this;
data.filePath = 'abc.com' + data.key;
return next();
});
const Image = mongoose.model('Images', imageSchema);
module.exports = Image;
As you can see her fields like filePath
, createdAt
and updatedAt
are auto generated field and shouldn't come in UI
Hello,
thank you for your work. I was wondering if your software works with plugins that encrypt the values of the DB such as mongoose-encryption or mongoose-field-encryption.
Since according to the European GDPR databases have to be encrypted such tools are becoming quite mandatory.
Thank you for the attention
Hey,
This package currently depends on vulnerable versions of flat(<5.0.1) which is vulnerable to prototype pollution. Can you please update it to higher version of flat.
When dealing with optional fields, adminjs-mongoose
doesn't unset
removed data.
Here's an example. I'm using io-ts to validate. Suppose I have the following codec:
export const ArticleCodec = t.intersection([
uuid: t.string,
title: t.string,
t.partial({
numberOfLike: NumberFromString, // This is because data is passed as a string
avgRating: NumberFromString,
}),
]);
export type ArticleType = t.TypeOf<typeof ArticleCodec>;
I also have the following mongoose schema:
export const ArticleSchema = new Schema<ArticleType>(
{
uuid: { type: String, required: true },
title: { type: String, required: true },
numberOfLike: Number,
avgRating: Number,
},
{ timestamps: true }
);
Lastly, I have the following resource:
const ArticleResource = (): ResourceWithOptions => ({
[...]
actions: {
edit: {
before: async (request) => {
const { method, payload } = request;
const unflattened = flat.unflatten(payload);
const validated = ArticleCodec.decode(unflattened);
if (validated._tag === "Left") {
[...]
}
return request;
[...]
Suppose I create an article and erroneously set numberOfLike
instead of avgRating
. I have the following document in MongoDB:
{
uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
title: "An amazing article",
numberOfLike: 4
}
When I edit the entity, the request I receive has the following payload:
"uuid": "e5436802-0e8f-428e-933f-7abc7d50b86c",
"title": "An amazing article",
"numberOfLike": "",
"avgRating": 4,
This data is then passed to the update function which sets all data not un-setting numberOfLike
.
Mongoose, also, converts the empty string to the number 0. So, the resulting document is the following:
{
uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
title: "An amazing article",
numberOfLike: 0,
avgRating: 4,
}
While I would expect this document:
{
uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
title: "An amazing article",
avgRating: 4
}
I've been able to get around this problem by deleting the original document e removing all empty strings from the request payload but... I wonder if it could be possible to unset
the optional values during the update.
Hi, I tried to start the adminJs library with mongodb and I got this error
This is the stack trace
Uncaught TypeError: Cannot read properties of undefined (reading 'split') at NavigationElement (navigation-element.tsx:30:29) at renderWithHooks (global.bundle.js:20510:19) at mountIndeterminateComponent (global.bundle.js:24274:14) at beginWork (global.bundle.js:25787:17) at HTMLUnknownElement.callCallback (global.bundle.js:8372:15) at Object.invokeGuardedCallbackDev (global.bundle.js:8421:17) at invokeGuardedCallback (global.bundle.js:8485:32) at beginWork$1 (global.bundle.js:31636:8) at performUnitOfWork (global.bundle.js:30742:13) at workLoopSync (global.bundle.js:30651:6)
Installed libraries and their versions
adminjs": "^6.8.7"
@adminjs/express": "^5.1.0"
@adminjs/sequelize": "^3.0.3"
The database mongodb
Thanks
For object Ids (especially references) and arrays empty strings are sent from the form. They should be converted to null
or (if possible) to some more intelligent fallback values, for instance default value which is set in Schema
const DriverSchema = new Schema({
phone: {
type: String,
required: true,
},
busId: {
type: Schema.Types.ObjectId,
ref: 'Bus',
default: null,
},
});
For this model it is sent { phone: '', busId: '' }
when trying to sent empty form. This gives error ...cannot cast '' to ObjectID
It is a common pattern to replace the "_id" field of mongoose by the given "id" virtual when calling toObject or toJSON on a mongoose model instance to have a clean and concise API output. Using admin-bro with admin-bro-mongoose, I tried to change the id field accordingly using isId
:
const adminBro = new AdminBro({
resources: [
{
resource: User,
options: {
listProperties: ['name', 'email', 'id', 'role'],
properties: {
id: {
isId: true, // <--- expect this to force adminBro to use this as the actual identifier
},
},
},
},
...
But it does not have an effect. I can not access any resource in show or edit mode or delete it via the action buttons as it fails finding the id field. It produces links like http://localhost:3000/admin/resources/User/records/show
missing the id path param. After further investigation, it seems like the "_id" attribute is a hard coded constant and I could not find out if using PropertyOptions will successfully overwrite it or not: https://github.com/SoftwareBrothers/admin-bro-mongoose/blob/master/src/property.ts
Please someone fix this issue or tell me how I can change the ID field using mongoose, as I don't want to output the "_id" field in my json outputs.
Installed libraries and their versions
Expected behavior
When setting isId: true
, I expect the field to be used as the identifier for accessing the show, edit and delete actions.
Hey, I use the $geoNear
feature in MongoDB, so I added a location property to the Place schema object and it looks that the admin has a problem with adding new entries.
When I programatically create a new entry to the database and check it in the admin, it works:
When I try to add a new place in the admin it doesn't work:
My schema model:
import mongoose from "mongoose";
const { Schema } = mongoose;
const schema = new Schema(
{
name: {
type: String,
required: true,
},
desc: {
type: String,
},
location: {
type: { type: String, default: "Point" },
coordinates: [Number],
},
categories: [
{
type: Schema.Types.ObjectId,
ref: "Category",
},
],
tags: [
{
type: Schema.Types.ObjectId,
ref: "Tag",
},
],
published: Boolean,
},
{ timestamps: true }
);
schema.index({ location: "2dsphere" });
const Place = mongoose.models.Place || mongoose.model("Place", schema);
export default Place;
I'd like to use your admin as it's nice. If you don't have time to fix it yourself, can you point me to the right place in the source code, so I can send a PR? :)
Describe the bug
(node:18614) DeprecationWarning: collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead
Installed libraries and their versions
"@admin-bro/express": "^3.1.0",
"@admin-bro/mongoose": "^1.1.0",
"admin-bro": "^3.4.0",
"admin-bro-expressjs": "^2.1.1",
"bcryptjs": "^2.4.3",
"chart.js": "^2.9.4",
"cloudinary": "^1.25.1",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"ejs": "^3.1.6",
"express": "^4.17.1",
"express-formidable": "^1.2.0",
"express-list-endpoints": "^5.0.0",
"express-session": "^1.17.1",
"json2csv": "^5.0.6",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.19",
"multer": "^1.4.2",
"multer-storage-cloudinary": "^4.0.0",
"nodemailer": "^6.5.0",
"query-to-mongo": "^0.10.1",
"react-chartjs-2": "^2.11.1",
"stripe": "^8.142.0",
"swagger-ui-express": "^4.1.6",
"tslib": "^2.1.0"
To Reproduce
Steps to reproduce the behavior:
AdminBroOptions with schema
const AdminBro = require("admin-bro");
const { buildAuthenticatedRouter } = require("@admin-bro/express");
const AdminBroMongoose = require("@admin-bro/mongoose");
const UserModel = require("../models/userModel");
const AdminBroOptions = require("./options");
AdminBro.registerAdapter(AdminBroMongoose);
const adminBro = new AdminBro(AdminBroOptions);
const adminRouter = buildAuthenticatedRouter(adminBro, {
cookieName: "admin-bro",
cookiePassword: "secret password",
authenticate: async (email, password) => {
const user = await UserModel.findByCredentials(email, password);
return user;
},
});
module.exports = adminRouter;
Desktop (please complete the following information if relevant):
Hey,
When updating a resource from admin panel, schema pre-hooks doesn't run.
However, when creating it, it runs perfectly.
This is the message at terminal in my express application,
(node:50219) DeprecationWarning: Mongoose: findOneAndUpdate()
and findOneAndDelete()
without the useFindAndModify
option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#-findandmodify-
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.