![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
We consistently require controllers that have CRUD functionality (create, read, update and delete).
To avoid institutionalising ourselves, we define generic
versions of these methods here which we can then use to e.g. build a
controller that manages users. Such a controller would be created with
usersController = require('pavarotti').methodsFor(User)
, where User
is the
user model.
The methods we would like to build abstract versions of, are:
set
Create an item with the given params, or update the item with given id
with
the given params. The newly saved item is returned.
get
Get a single item by its id.
find
Get all items that match the criteria given, possibly paging and sorting the result.
remove
Delete a single item by its id.
We can customise these methods by passing in configuration options to the main
methodsFor
method, which constructs the CRUD controller. The options are:
beforeSet : Model |-> Model
bfunction called before the model is saved to the database. Is given the model that will be saved. The result is the final object saved to the database. An error stops the method.
Defaults to bf.identity
.
afterSet : Model |-> Model
bfunction called after the model has been saved to the database. Is given the
model that was saved. The result will be the output of the set
method. An
error stops the method.
Defaults to bf.identity
.
afterGet: : Model |-> Model
bfunction called after the model has been retrieved from the database. Is
given the model that was retrieved. The result will be the output of the
get
method. An error stops the method.
Defaults to bf.identity
.
beforeFind: : Params |-> Params
bfunction called at the beginning of the find
method. Is given the params to
the find
method. The result will be fed into the next stem of the find
method. An error stops the method.
Defaults to bf.identity
.
buildFindFilter : Params |-> FindFilter
bfunction that, given the params to the find
method, builds the object that
is given to mongoose to filter the model collection (the find()
filter). If
null, builds the find filter using properties that are in the filter
object
in the params.
Defaults to null
.
buildFindSort : Params |-> FindSort
bfunction that, given the params to the find
method, builds the object that
is given to mongoose to sort the model collection (the sort()
object). If
null, builds the sort filter using properties thare are in the sort
object
in the params such that e.g. { sort: { name: 'asc' } }
becomes
{ name: 1 }
.
Defaults to null
.
afterFind: `: { items: Model[], total: number, filteredTotal: number } |-> any
bfunction that, given the final result of the find
method (results, number
of total items and number of filtered items) returns some object that will be
the output of the find
method.
Defaults to bf.identity
.
_ = require 'underscore'
bf = require 'barefoot'
The CRUD controller methods are generated once from a single initialisation call
to methodsFor
. This method takes the model that the CRUD methods are for and a
variety of additional configuration methods that lets the consumer of this CRUD
controller customise each of the CRUD methods.
methodsFor = (model, config = {}) ->
config = _.defaults config,
beforeSet: bf.identity
afterSet: bf.identity
afterGet: bf.identity
beforeFind: bf.identity
buildFindFilter: null
buildFindSort: null
afterFind: bf.identity
crud = {}
We create and update with the single set
method. This performs an insert
operation if no id
is given, and an update operation is an id
is given. In
any case, the newly saved item is returned.
crud.set =
bf.chain -> [
bf.validate
_id: String
getOrCreate
config.beforeSet
save
config.afterSet
]
First, attempt to retrieve the item by its id. If there is none found then
create a new item. We use mongoose's set
method to apply the given params to
the fetched model.
getOrCreate = (params, done) ->
w = bf.errorWrapper done
model.findById params.id, w (item) ->
item ?= new model()
item.set params
done null, item
Now, we have a fully populated offer model. All that's left to do is save it!
save = (item, done) ->
item.save done
We can retrieve a single item by its id very simply. This method takes one
param, id
, and returns the item (or null if none exists).
crud.get =
bf.chain -> [
bf.validate
id: String
bf.select (p) -> p.id
_.bind model.findById, model
config.afterGet
]
We can search for items using a single super method that takes many different
filtering params (findFilterParams
) and sorting params (findSortParams
) and
retrieves a paginated list of items that match. The consumer of the CRUD API
helper is able to modify the mongo find()
object and sort()
object.
crud.find =
bf.chain -> [
bf.validate
_filter: Object
_sort: Object
_skip: Number
_limit: Number
config.beforeFind
bf.parallel [
config.buildFindFilter ? buildFilter
config.buildFindSort ? buildSort
bf.identity
]
runQuery
config.afterFind
]
The default buildFindFilter
just filters on the parameters given in
params.filter
.
buildFilter = (params, done) ->
done null, params.filter
The default buildFindSort
convers the params.sort
object given from e.g.
{prop: 'asc'}
to {prop: 1}
.
buildSort = (params, done) ->
sort = null
if params.sort?
sort = {}
for p, o of params.sort
if o == 'asc'
sort[p] = 1
else if o == 'desc'
sort[p] = -1
done null, sort
We require very flexible pagination, so running the query is a little tedious, though simple enough.
runQuery = ([filter, sort, params], done) ->
seq = bf.sequence done
filter ?= {}
sort ?= {}
total = 0
filteredTotal = 0
seq.then (next) ->
model.find().count seq.w (count) ->
total = count
next()
seq.then (next) ->
model.find(filter).count seq.w (count) ->
filteredTotal = count
next()
seq.then (next) ->
query = model.find(filter)
if params.skip?
query = query.skip(params.skip)
if params.limit?
query = query.limit(params.limit)
query.exec seq.w (items) ->
done null,
items: items
total: total
filteredTotal: filteredTotal
Deleting or removing an item is a simple method that retrieves an object by its
id
and then removes it if it exists. If no item with the given id
exists,
nothing happens.
crud.remove =
bf.chain -> [
bf.validate
id: String
_.bind model.remove, model
]
We must conclude the methodsFor
function we began to define.
return crud
And then export this function.
module.exports = {
methodsFor
}
FAQs
pavarotti creates CRUD controllers given a mongoose model
The npm package pavarotti receives a total of 1 weekly downloads. As such, pavarotti popularity was classified as not popular.
We found that pavarotti demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.