Hello,
I freshly updated my project from v4 to v7 (recreated a fresh project and reimported my code as it got way to hard xD)
However, as I prefer typescript, my models/routes are in typescript and… I have a bit of a problem…
Based on this documentation, regarding the models part: https://docs.forestadmin.com/woodshop/how-tos/translate-your-app-into-typescript#how-it-works
As we can see, you give an example that seems to be v5/v6:
const mongoose = require('mongoose');
const schema = mongoose.Schema({
'firstName': String,
'lastName': Date,
}, {
timestamps: false,
});
module.exports = mongoose.model('users', schema, 'users');
This is easely translatable into typescript with the following:
import { Schema, Document, model} from 'mongoose';
interface IUser extends Document {
firstName: string;
lastName: string;
}
const schema = new Schema({
'firstName': String,
'lastName': Boolean,
}, {
timestamps: false,
});
export default model<IUser>('users', schema, 'users');
However, in v7 (example reproducible by creating a fresh new project), the base model in js will look like so:
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (mongoose, Mongoose) => {
// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = Mongoose.Schema({
'firstName': String,
'lastName': Boolean,
}, {
timestamps: false,
});
return mongoose.model('users', schema, 'users');
};
And… if you translate it into typescript, from my point of view, it should give something like this:
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
import {Document, Schema} from "mongoose";
export interface IUser extends Document {
firstName: string,
lastName: boolean,
}
// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = new Schema({
'firstName': String,
'lastName': Boolean,
}, {
timestamps: false,
});
//// Not sure about this
// export const collection = mongoose.model<IUser>('users', schema, 'Users');
module.exports = (mongoose, Mongoose) => {
return mongoose.model('users', schema, 'users');
};
And here the problème starts… if I want to get a record by ID, then new RecordGetter(...)
will do the job. However, when I want to import/findOne it doesn’t work… Either the default exports doesn’t have .findOne(...)
method, either I try to export my collection/model manually:
export const collection = mongoose.model<IUser>('users', schema, 'Users');
and then import it like import {collection as usersCollection} from '../models/users.ts'
but then, I get:
(node:252) UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘findOne’ of undefined
I really have no idea how to deal with that situation… I think first that I am missing something, of course, but I do feel as a second point that the documentation is obosolete and doesn’t show a croncret working example for the v7 when trying to make advanced queries from routes like shown at this link: https://docs.forestadmin.com/documentation/reference-guide/routes/override-a-route#changing-forest-admins-behavior
Of course, assessors as RecordGetter, RecordUpdater, etc are good, but sometimes, updateMany, findOne, etc can do advanced stuff you know, so it’s good to keep their way of uses explained through your documentation
Expected behavior
From my routes/users.ts
, I want to (for some reason) query my collection (... from '../models/users.ts'
) using operation such as:
- findOne(…)
- updateMany(…)
- etc
instead of using RecordGetter, RecordRemover, etc
Actual behavior
I can’t find the way to access such operation from the default function exported or the collection itself using a Typescript approach
Failure Logs
- When exporting the collection as above:
import {collection as usersCollection} from "../models/users";
// ...
function foo() : IUser {
// ...
usersCollection.findOne({...})...
}
(node:252) UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘findOne’ of undefined
- When trying to access the default export’s findOne() method:
import * as users from "../models/users";
// ...
users.findOne(...)
TS2339: Property ‘findOne’ does not exist on type ‘typeof import(“C:/Workspace/…/models/users”)’.
- When trying to import as stated in the doc (https://docs.forestadmin.com/documentation/reference-guide/routes/override-a-route#changing-forest-admins-behavior):
const { users} = require('../models');
// ...
const recordGetter = new RecordGetter(users);
TS2305: Module ‘“…/models”’ has no exported member ‘users’.
Context
Please provide any relevant information about your setup.
package.json
{
"name": "project-backoffice",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node ./dist/server.js",
"legacy-start": "node server.js",
"build": "tsc",
"start-dev": "tsc-watch --project ./tsconfig.json --noClear --onSuccess \"nodemon --watch ./dist ./dist/server.js\""
},
"dependencies": {
"@types/express": "^4.17.11",
"@types/forest-express-mongoose": "^7.5.0",
"@types/mongoose": "^5.10.5",
"@types/node": "^15.3.0",
"axios": "^0.21.1",
"body-parser": "1.19.0",
"chalk": "~4.1.1",
"cookie-parser": "1.4.5",
"cors": "2.8.5",
"debug": "~4.3.1",
"dotenv": "~9.0.2",
"express": "~4.17.1",
"express-jwt": "6.0.0",
"forest-express-mongoose": "^7.6.0",
"mongoose": "~5.12.9",
"morgan": "1.10.0",
"nodemon": "^2.0.7",
"require-all": "^3.0.0",
"tsc-watch": "^4.2.9",
"typescript": "^4.2.4"
}
}
PS: IMPORTANT NOTES
/models/index.js conversion into typescript has issues
File example: https://docs.forestadmin.com/documentation/how-tos/maintain/upgrade-notes-sql-mongodb/upgrade-to-v7#models-index
- First, it can’t work as
const db = {}
doesn’t have any ofobjectMapping
orconnections
defined, so the two of them must be added manually. - Second, theline
.filter((file) => file.indexOf('.') !== 0 && file !== 'index.js')
doesn’t work properly and loads .js.map files which creates some errors… The way to fix it is simply to replace the line by.filter((file) => !file.includes('.map') && file.indexOf('.') !== 0 && file !== 'index.js'
/models/*.js generation has empty schema
- I don’t know if it’s the expected behavior, but, using latest NPM lumber version (as of today), when the models files gets created, they all have empty schema, is it normal? Only the timestamp part is present:
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (mongoose, Mongoose) => {
// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = Mongoose.Schema({
}, {
timestamps: false,
});
return mongoose.model('users', schema, 'users');
};
FOREST_AUTH_SECRET if I loose this variable, do I have a way to retrieve it?
- I had an issue (fully my mistake) where I removed the project, but not the right one… As the
.env
file is not versionned… I had a little bit of a hard time retrieving it from another computer. When I recreated it manually, I was missing this auth secret and couldn’t find the way to get it from ForestAdmin dashboard
express-jwt version 6 support instead of v5.3.1 (at project generation)
- I know it’s a known and resolved issue (Forest Admin keeps asking me to repeat my password to unlock my data but says it is wrong, even after resetting it) but it could be greate if, in addition of supporting it directly at project creation, you could have some improvement in your Upgrade to v7 by mentioning this “algorithm” value part as a “warning” or “information” (within your documentation)
PLEASE ADD FULL TYPESCRIPT GENERATION
I know, it’s a lot of work and you guys are doing really great, to be honest, I have a lot of respect for your work, your product, your reactivity etc. However, I big point which is missing is that you don’t have a full typescript version of your product and, even when you try to convert everything into typescript, you run into errors with stuff such as Liana, so please, put it on your roadmap, I am sure it would give you a lot of precious points!!
Thank you so much and sorry for that big post!
Hope to hear from you soon!
Best,
Max