Create flexible REST endpoints and controllers from Sequelize models in your Express app

Overview

Build Status Dependency Status

Finale

Create flexible REST endpoints and controllers from Sequelize models in your Express or Restify app.

This project aims to be a Sequelize 4.x and 5.x compatible version of Epilogue.

Installation

npm install finale-rest

Getting Started

var Sequelize = require('sequelize'),
    finale = require('finale-rest'),
    http = require('http');

// Define your models
var database = new Sequelize('database', 'root', 'password');
var User = database.define('User', {
  username: Sequelize.STRING,
  birthday: Sequelize.DATE
});

// Initialize server
var server, app;
if (process.env.USE_RESTIFY) {
  var restify = require('restify');
  var corsMiddleware = require('restify-cors-middleware');
  
  app = server = restify.createServer()
  var cors = corsMiddleware({
    preflightMaxAge: 5, // Optional
    origins: ['*'], // Should whitelist actual domains in production
    allowHeaders: ['Authorization', 'API-Token', 'Content-Range'], //Content-range has size info on lists
    exposeHeaders: ['Authorization', 'API-Token-Expiry', 'Content-Range']
  })

  server.pre(cors.preflight)
  server.use(cors.actual)

  server.use(restify.plugins.queryParser()); //{mapParams: true}
  server.use(restify.plugins.bodyParser());  //{mapParams: true, mapFiles: true}
  server.use(restify.plugins.acceptParser(server.acceptable));
} else {
  var express = require('express'),
      bodyParser = require('body-parser');

  var app = express();
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  server = http.createServer(app);
}

// Initialize finale
finale.initialize({
  app: app,
  sequelize: database
});

// Create REST resource
var userResource = finale.resource({
  model: User,
  endpoints: ['/users', '/users/:id']
});

// Create database and listen
database
  .sync({ force: true })
  .then(function() {
    server.listen(function() {
      var host = server.address().address,
          port = server.address().port;

      console.log('listening at http://%s:%s', host, port);
    });
  });

Migrate from Epilogue

Finale is built to be a drop-in replacement for Epilogue that supports Sequelize 4.x.x

const epilogue = require('epilogue')
epilogue.initialize(...)

// change to

const finale = require('finale-rest')
finale.initialize(...)

Controllers and endpoints

On the server we now have the following controllers and endpoints:

Controller Endpoint Description
userResource.create POST /users Create a user
userResource.list GET /users Get a listing of users
userResource.read GET /users/:id Get details about a user
userResource.update PUT /users/:id Update a user
userResource.delete DELETE /users/:id Delete a user

Customize behavior

Of course it's likely that we'll want more flexibility. Our users resource has properties for each of the controller actions. Controller actions in turn have hooks for setting and overriding behavior at each step of the request. We have these milestones to work with: start, auth, fetch, data, write, send, and complete.

var ForbiddenError = require('finale-rest').Errors.ForbiddenError;

// disallow deletes on users
userResource.delete.auth(function(req, res, context) {
    throw new ForbiddenError("can't delete a user");
    // optionally:
    // return context.error(403, "can't delete a user");
})

We can set behavior for milestones directly as above, or we can add functionality before and after milestones too:

// check the cache first
userResource.list.fetch.before(function(req, res, context) {
	var instance = cache.get(context.criteria);

	if (instance) {
		// keep a reference to the instance and skip the fetch
		context.instance = instance;
		return context.skip;
	} else {
		// cache miss; we continue on
		return context.continue;
	}
})

Milestones can also be defined in a declarative fashion, and used as middleware with any resource. For example:

// my-middleware.js
module.exports = {
  create: {
    fetch: function(req, res, context) {
      // manipulate the fetch call
      return context.continue;
    }
  },
  list: {
    write: {
      before: function(req, res, context) {
        // modify data before writing list data
        return context.continue;
      },
      action: function(req, res, context) {
        // change behavior of actually writing the data
        return context.continue;
      },
      after: function(req, res, context) {
        // set some sort of flag after writing list data
        return context.continue;
      }
    }
  }
};

// my-app.js
var finale = require('finale-rest'),
    restMiddleware = require('my-middleware');

finale.initialize({
    app: app,
    sequelize: sequelize
});

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id']
});

userResource.use(restMiddleware);

Finale middleware also supports bundling in extra resource configuration by specifying an "extraConfiguration" member of the middleware like so:

// my-middleware.js
module.exports = {
  extraConfiguration: function(resource) {
    // support delete for plural form of a resource
    var app = resource.app;
    app.del(resource.endpoints.plural, function(req, res) {
      resource.controllers.delete._control(req, res);
    });
  }
};

To show an error and halt execution of milestone functions you can throw an error:

var ForbiddenError = require('finale-rest').Errors.ForbiddenError;

before: function(req, res, context) {
    return authenticate.then(function(authed) {
        if(!authed) throw new ForbiddenError();

        return context.continue;
    });
}

REST API

Listing resources support filtering, searching, sorting, and pagination as described below.

Filtering

Add query parameters named after fields to limit results.

$ curl http://localhost/users?name=James+Conrad

HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "name": "James Conrad",
    "email": "[email protected]"
  }
]

If your query specifies associations to be included – whether via a model scope (see below), manipulation of Finale's Context object in a custom Milestone handler, or simply by default in your Finale resource definition – your query parameters can reference fields on the joined models, e.g.

$ curl http://localhost/users?group.type=vip

Filtering using scope

Use scope to add additional filtering (More about scopes in sequelize - http://docs.sequelizejs.com/en/latest/docs/scopes/).

  // Define scope in model
  ...
  scope: {
    verified: {
      where : {
        email_verified: true
        phone_verified: true
      }  
    }
  }
$ curl http://localhost/users?scope=verified

HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "name": "James Conrad",
    "email": "[email protected]"
    "email_verified": true,
    "phone_verified": true
  }
]

Search

Use the q parameter to perform a substring search across all fields.

$ curl http://localhost/users?q=james

HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "name": "James Conrad",
    "email": "[email protected]"
  }, {
    "name": "Jim Huntington",
    "email": "[email protected]"
  }
]

Search behavior can be customized to change the parameter used for searching, as well as which attributes are included in the search, like so:

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    search: {
      param: 'searchOnlyUsernames',
      attributes: [ 'username' ]
    }
});

This would restrict substring searches to the username attribute of the User model, and the search parameter would be 'searchOnlyUsernames':

$ curl http://localhost/users?searchOnlyUsernames=james

By default, the substring search is performed using a {field} LIKE '%{query}%' pattern. However, this behavior can be customized by specifying a search operator. Valid operators include: Op.like (default), Op.iLike, Op.notLike, Op.notILike, Op.ne, Op.eq, Op.not, Op.gte, Op.gt, Op.lte, Op.lt. All "*like" operators can only be used against Sequelize.STRING or Sequelize.TEXT fields. For instance:

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    search: {
      operator: Sequelize.Op.gt,
      attributes: [ 'age' ]
    }
});

When querying against a Sequelize.BOOLEAN field, you'll need to use the Op.eq operator. You can also add multiple search parameters by passing the search key an array of objects:

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    search: [
      {operator: Sequelize.Op.eq, param: 'emailVerified', attributes: [ 'email_verified' ]},
      {param: 'searchOnlyUsernames', attributes: [ 'username' ]}
    ] 
});

Sorting

Specify the sort parameter to sort results. Values are field names, optionally preceded by a - to indicate descending order. Multiple sort values may be separated by ,.

$ curl http://localhost/users?sort=-name

HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "name": "Jim Huntington",
    "email": "[email protected]"
  }, {
    "name": "James Conrad",
    "email": "[email protected]"
  }
]

Sort behavior can be customized to change the parameter used for sorting, as well as which attributes are allowed to be used for sorting like so:

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    sort: {
      param: 'orderby',
      attributes: [ 'username' ]
    }
});

This would restrict sorting to only the username attribute of the User model, and the sort parameter would be 'orderby':

$ curl http://localhost/users?orderby=username

Default sort criteria can be defined with the default attribute. The expected format for default sort criteria is exactly the same as if it was proceeding the sort parameter in the URL.

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    sort: {
      default: '-email,username'
    }
});

With this configuration, these two calls would result in the same data:

$ curl http://localhost/users
$ curl http://localhost/users?sort=-email,username

Note that the sort parameter in the URL will override your default criteria.

By default all attributes defined on the model are allowed to be sorted on. Sorting on a attribute not allowed will cause a 400 error to be returned with errors in the format:

$ curl http://localhost/users?sortby=invalid,-otherinvalid,valid

HTTP/1.1 400 BAD REQUEST
Content-Type: application/json

{
  "message": "Sorting not allowed on given attributes",
  "errors": ["invalid", "otherinvalid"]
}

Pagination

List routes support pagination via offset or page and count query parameters. Find metadata about pagination and number of results in the Content-Range response header. Pagination defaults to a default of 100 results per page, and a maximum of 1000 results per page.

# get the third page of results
$ curl http://localhost/users?offset=200&count=100

HTTP/1.1 200 OK
Content-Type: application/json
Content-Range: items 200-299/3230

[
  { "name": "James Conrad", ... },
  ...
]

Alternatively, you can specify that pagination is disabled for a given resource by passing false to the pagination property like so:

var userResource = finale.resource({
    model: User,
    endpoints: ['/users', '/users/:id'],
    pagination: false
});

add_to_children on create and update action

For create and update actions, you can provide an add_to_children object to the context. The attributes of add_to_children will be added to all nested child objects sent in the request, overriding any values in the body. This is useful, for example, to inject common attributes from a session, like created_by_user_id or updated_by_user_id, to all children objects in the create body, without having to specify which ones they are specifically. Note: For doing this for top level writes and updates, you can simply specify context.attributes values. add_to_children is just for nested children objects.

finaleResource["create"].write.before(function(req:Request,res:Response,context:any) { 
    let loggedInUserId =  authManager.getLoggedInUserId(req);
    context.add_to_children = {
      updated_by_user_id :  loggedInUserId,
      created_by_user_id :  loggedInUserId
    }
    return context.continue;
  });
}

finaleResource["update"].write.before(function(req:Request,res:Response,context:any) { 
    let loggedInUserId =  authManager.getLoggedInUserId(req);
    context.add_to_children = {
      updated_by_user_id :  loggedInUserId
    }
    return context.continue;
  });
}


This currently is only supported for one level of nesting. It is not recursive.

Deep vs Shallow Payloads

By default, associations are included in read and list payloads. For list and read queries, you can set a shallow boolean on the context to indicate if you want it to include association child objects or not.

userResource["list"].fetch.before(function(req:Request,res:Response,context:any) { 
    context.shallow = true;
    return context.continue;
});

For finer-grain control over which children are included on a per-query basis, you can set context.shallow to true, and also leverage a children query parameter with a pipe-delimited list of associated children to include. children only works if shallow is set to true. The names used in the children query parameter are the as association names when setting up your sequelize models, or the default created by sequelize.

UserModel.belongsToMany(UserGroupModel), { through: UserGroupRelModel,foreignKey: "user_id" });
UserModel.belongsTo(OrganizationModel), { as: "PrimaryOrganization", foreignKey: "primary_organization_id" });
UserModel.belongsToMany(FooModel), { through: FooRelModel,foreignKey: "user_id" });
...
GET /user/?children=UserGroups|PrimaryOrganization

Finale API

initialize()

Set defaults and give finale a reference to your express app. Send the following parameters:

app

A reference to the Express application

base

Prefix to prepend to resource endpoints

updateMethod

HTTP method to use for update routes, one of POST, PUT, or PATCH

resource()

Create a resource and CRUD actions given a Sequelize model and endpoints. Accepts these parameters:

model

Reference to a Sequelize model

endpoints

Specify endpoints as an array with two sinatra-style URL paths in plural and singular form (e.g., ['/users', '/users/:id']).

actions

Create only the specified list of actions for the resource. Options include create, list, read, update, and delete. Defaults to all.

excludeAttributes

Explicitly remove the specified list of attributes from read and list operations

Milestones & Context

Check out the Milestone docs for information on lifecycle hooks that can be used with finale resources, and how to run custom code at various points during a request.

Protecting Finale REST Endpoints

To protect an endpoint, you must use milestones.

In order to protect and endpoint (for example, to require that only a logged in user or user with the appropriate security token can access a resource) you need to use the appropriate milestone hooks.

Below is an example of how to do this with standard Express middleware, which is commonly used to protect resources. Note that the callback functions required by Finale milestones look similar to express middleware, but the third argument (context) is different.

Suppose you have this resource:

var userResource = rest.resource({
    model: User
});

To protect all endpoints, we'll use userResource.all.auth, a hook used to authorize the endpoint before any operation (create, list, etc). Suppose also we have an express middlware function called authorize(req, res, done). This authorize function might for example be a passport strategy such as passport('local').

To authorize the endpoint, you would do this:

userResource.all.auth(function (req, res, context) {
  return new Promise(function(resolve, reject) {
    authorize(req, res, function (arg) {
      if (arg) {
        // Middleware function returned an error; this means the operation
        // should not be authorized.
        res.status(401).send({message: "Unauthorized"});
        resolve(context.stop);
      } else {
        resolve(context.continue);
      }
  });
})

In this code, note that userResource.all.auth is simply reusing the express middleware to do whatever authorization checking your code requires. We are passing a custom done function to the middleware, which resolves a promise as either context.stop or context.continue, indicating to finale whether or not to proceed. Note that in the case where the transaction isn't authorized, finale won't proceed, so it is your responsibility to send a response back to the client.

Protecting sub-resources

When models have assocations between them, to achieve the nested endpoints a la /user/1/UserGroups, finale creates sub-resources. Remember to set authorizations on those sub-resources as well. To get the sub-resources for a particular resource, you can use the string array subResourceNames attribute on the resource. Each name is also the name of an attribute on the resource.

userResource.all.auth(function (req, res, context) {
...
});

for(sub_resource_name in userResource.subResourceNames) {
    userResource[sub_resource_name].all.auth(function (req, res, context) {
      ...
    });
}

Further Information on Protecting Endpoints

The milestone documentation provides many other hooks for finer-grained operations, i.e. permitting all users to list but only some users to delete can be implemented by using the same approach described above, with different milestones.

Tests, Docker, OS X

The test suite requires use of Dtrace, which can be problematic on MacOS/OS X, which limits use of Dtrace. The base Dockerfile can be used to run tests.

docker build -t finale_test ./
docker run finale_test

Note: good errors happen, so stacktraces in the output are not necessarily indicative of a problem.

License

Copyright (C) 2012-2015 David Chester Copyright (C) 2014-2015 Matt Broadstone Copyright (C) 2017 Tom Juszczyk

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Getting shallow data instead of nested data

    Getting shallow data instead of nested data

    I had been looking for a way to just get shallow results (i.e. not the eagerly loaded results that contain nested children objects), and the only way I could figure out to do it was to add a "shallow" flag in the list and read controllers that, if true, skips the includes. Thought this might be useful to others.

    opened by bcolthurst 13
  • Missing use of transactions

    Missing use of transactions

    I'd like to start a discussion (with my vote for yes) on if we would like Finale to support the use of transactions, either by default or by optional configuration.

    My use-case:
    I have a Person model, which uses the standard Finale/Sequelize setup. On my Person Sequelize model, I have some after hooks that are defined to publish AWS SNS messages enforming other systems of the updates. If the SNS messages are not published (which would only happen if SNS is down, or if our credentials/setup of it was incorrect), I'd like the whole operation to fail, and rollback. These SNS Publishes have to be on the Sequelize model not the Finale model, in order for the rollbacks to be transactional, as well as to support updates that didn't come from Finale defined routes.

    Problem Sequelize Managed Transactions will handle the above use-case out of the box (http://docs.sequelizejs.com/manual/tutorial/transactions.html#managed-transaction-auto-callback-) but only if you use the transactions, which Finale does not currently have the capability to do so. So errors thrown in the after hooks on my models have no impact on the update. Whereas if I create a set of routes to call the same functionality with a transaction, the errors thrown in the after hooks have the desired effect of triggering the Sequelize auto-rollback feature.

    Discussion

    • My main question is if others think this would be helpful for them as well, and if there is any down-side?

    If people are interested, then I'm happy to discuss at exactly which step the transaction would be created, and how it would be passed in.

    Thanks.

    opened by Tmassery 6
  • multiple scope support

    multiple scope support

    feature

    I want to use multiple scope that is supported by sequelize. ?scope=scope1,scope2...&and-more-query

    you can transform above request this sequelize code. sequelize.models['name'].scope('scope1').scope('scope2')

    workaround.

    now I use milestone.

    
    const multipleScopeMilestone = {
      list: {
        fetch: {
          before: function (req, res, context) {
            if (req.query.scope) {
              this.model = this.model.scope('defaultScope').scope(req.query.scope.split(','));
              delete req.query.scope;
            }
            return context.continue;
          }
        }
      }
    }
    
    opened by hiradimir 5
  • Tests failing: search included model field doesn't work on restify

    Tests failing: search included model field doesn't work on restify

    Hey my recent PR has a test that fails for restify. I noticed that providing a search query like ?model.includedmodel=value allows searching for fields in included models, but apparently that isn't true for restify.

    In list.js, in the section to search for extraSearchCriteria, the param key would either be model or model.includedmodel depending on if you're using restify or not. This is due to the way Restify parses the req.query. With Restify the query would be an object with the shape of

    { model: { includedmodel: 'value' } }

    and without Restify it will be

    { model.indludedmodel: 'value' }

    So I think there's a question here of if this type of search query should be allowed or encouraged at all. For now I'll put up a PR to disable the test for Restify.

    opened by drama-ostrich 4
  • Sort search and group for fields on included models

    Sort search and group for fields on included models

    This fixes 3 Issues for list.js I've run into while dealing with included/associated models in a resource. I've tried to isolate these 3 problems in tests but the behavior changes based on if the resource has options.subQuery = true/false set and if the associations between models are one-to-many or many-to-many. Ideally I'm looking to be able to sort, search, and group by fields on included models at the same time.

    1. Group By breaks pagination

    Current Version

    If you use a group command (my test example is context.options.group = ['users.id']) then the sequelize findAndCountAll() method returns a list of grouped counts instead of one count number.

    Change

    If options.group is set then split the find and count into two queries.

    2. Sort by field on associated model

    Current Version

    Sorting by a field on an included model doesn't work. Sequelize uses the wrong table name for the nested field when generating SQL

    Change

    I use a Sequelize.literal() in the sort if the field path has a period in it.

    3. Search with "LIKE" on a associated resource

    Current Version

    If you want to search for a field on an associated resource you have the following options

    1. Use the name of the field as the url param. My example is ?profile.nickname=name
    2. Specify a search object on the resource definition to choose your own param name. If you choose this method you need to use the Sequelize.Op.eq operator, otherwise the search is picked up as a stringOperator in list.js:115 and throws an error because the path to the included model isn't a sequelize.STRING

    Change

    I exclude search keys with a period in the serach for stringOperators to allow using Sequelize.Op.like in the search definition in the resource

    Note: the field name in the search definition still requires the dollars around the field e.g. $profile.nickname$

    opened by drama-ostrich 4
  • How to use AND in search ?

    How to use AND in search ?

    I'm looking to do something like localhost:8080/api/v0/media?campaign_id=7&name=09. Which should result in every media with campaign_id == 7 and where the name contains "09" (%09%)..

    But i'm not able to find how to do it with "epilogue".. when i log the sequelize call i get : image

    What i'm looking to get is :

    where: {
        campaign_id: 7,
        name: {
            $like: "%09%"
        }
    }
    
    opened by jbeaudoin11 4
  • Instance removed from context on DELETE

    Instance removed from context on DELETE

    For DELETES, in this line https://github.com/tommybananas/finale/blob/master/lib/Controllers/delete.js#L23 the instance is removed from the context, which greatly limits what can be done in hooks after write.

    A temp solution I have is backing up the instance in another hook, but this seems to be limiting. Sequelize destroy hooks still retain the instance in memory so that hooks can use information on the newly deleted instance.

    The use case here is pretty common, creating an event from the event. Another common use case would be calling a third party service, like S3 to delete related blob items.

    Could we either 1) Remove that line 2) Move the instance to something like context.deletedInstance?

    help wanted good first issue 
    opened by awm33 3
  • associations: subResourceName is set by association.as if available

    associations: subResourceName is set by association.as if available

    I think it makes sense to be able to decide what the subResourceName of an association is. For instance, imagine that I have:

    var Person = sequelize.define('person', { name: { type: DataTypes.STRING } }),
        Course = sequelize.define('course', { name: { type: DataTypes.STRING } });
    Course.hasMany(Person, {as: 'students'});
    Course.hasOne(Person, { as: 'teacher' });
    rest.resource({model: Course, 
        endpoints: ['/courses', '/courses/:id'], 
        associations: true});
    

    Under the current logic, the association Resources are named according to the model name, inflected for the number of the association. I think with my example here, we would get /courses/:id/person and /courses/:id/people/. Intuitively, though, it seems like we have gone to the trouble of naming the association in the model, and so we should get routes like /courses/:id/students/ and /courses/:id/teacher.

    This patch checks the association.as field before setting the subResourceName.

    opened by wroberts 3
  • Filtering/sorting by association fields

    Filtering/sorting by association fields

    hi is there any way to filter/sort by association fields?

    I have a Project model with FK to User as project manager. I have turned on associations in sequelize and finale but now I want to be able to select all projects with project manager last name being XXXX.

    It is achievable via sequelize so I assume it should be somehow possible with epilogue as well? My resources are defined like that:

    
    var resources = Object.keys(app.get('models'));
    resources.pop();
    
    resources.forEach(function (resource) {
       var res = finale.resource({
       model: app.get('models')[resource],
       endpoints: ['/' + resource, '/' + resource + '/:id'],
       associations: true,
     });
    });
    

    where models are sequelize models

    opened by gibonu 3
  • Authentication

    Authentication

    Hey, good work at this library. I'm using it and it works well.

    About authentication, I realized the params of .auth hook are different of passport params, as I couldnt make

    //myHooksAsMiddleware.js
    module.exports = {
        create: {
              auth: myCustomPassportAuth
        },
        list: {},
        update: {},
        delete: {},
        read: {}
    };
    

    because the 3rd param of myCustomPassportAuth middleware is a next, but finale-rest .auth has a 3rd param that is an object that contains the next function. So I had to change to

    //myHooksAsMiddleware.js
    module.exports = {
        create: {
              auth: (req, res, context) => myCustomPassportAuth(req, res, context.continue)
        },
        list: {},
        update: {},
        delete: {},
        read: {}
    };
    

    Does have some different aproach to do this authentication?

    opened by lfernando-silva 3
  • TypeError: restify.queryParser is not a function

    TypeError: restify.queryParser is not a function

    Code like this: var restify = require('restify'); app = server = restify.createServer() app.use(restify.queryParser()); app.use(restify.bodyParser());

    get an error :

    app.use(restify.queryParser()); ^

    TypeError: restify.queryParser is not a function at Object. (/Users/xxxxxxx/sequelize/finale.js:34:17) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Function.Module.runMain (module.js:676:10) at startup (bootstrap_node.js:187:16) at bootstrap_node.js:608:3

    opened by anuxs 3
  • Bump validator and sequelize

    Bump validator and sequelize

    Bumps validator to 13.7.0 and updates ancestor dependency sequelize. These dependencies need to be updated together.

    Updates validator from 10.11.0 to 13.7.0

    Release notes

    Sourced from validator's releases.

    13.7.0

    13.7.0

    New Features

    Fixes and Enhancements

    New and Improved Locales

    ... (truncated)

    Changelog

    Sourced from validator's changelog.

    13.7.0

    New Features

    New Features

    Fixes and Enhancements

    New and Improved Locales

    ... (truncated)

    Commits
    • 47ee5ad 13.7.0
    • 496fc8b fix(rtrim): remove regex to prevent ReDOS attack (#1738)
    • 45901ec Merge pull request #1851 from validatorjs/chore/fix-merge-conflicts
    • 83cb7f8 chore: merge conflict clean-up
    • f17e220 feat(isMobilePhone): add El Salvador es-SV locale
    • 5b06703 feat(isMobilePhone): add Palestine ar-PS locale
    • a3faa83 feat(isMobilePhone): add Botswana en-BW locale
    • 26605f9 feat(isMobilePhone): add Turkmenistan tk-TM
    • 0e5d5d4 feat(isMobilePhone): add Guyana en-GY locale
    • f7ff349 feat(isMobilePhone): add Frech Polynesia fr-PF locale
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by profnandaa, a new releaser for validator since your current version.


    Updates sequelize from 4.44.4 to 6.25.2

    Release notes

    Sourced from sequelize's releases.

    v6.25.2

    6.25.2 (2022-10-15)

    Bug Fixes

    • types: fix TS 4.9 excessive depth error on InferAttributes (v6) (#15135) (851daaf)

    v6.25.1

    6.25.1 (2022-10-13)

    Bug Fixes

    • types: expose legacy "types" folder in export alias ( #15123) (9dd93b8)

    v6.25.0

    6.25.0 (2022-10-11)

    Features

    • oracle: add support for dialectOptions.connectString (#15042) (06ad05d)

    v6.24.0

    6.24.0 (2022-10-04)

    Features

    • snowflake: Add support for QueryGenerator#tableExistsQuery (#15087) (a44772e)

    v6.23.2

    6.23.2 (2022-09-27)

    Bug Fixes

    • postgres: add custom order direction to subQuery ordering with minified alias (#15056) (7203b66)

    v6.23.1

    6.23.1 (2022-09-22)

    Bug Fixes

    v6.23.0

    6.23.0 (2022-09-17)

    ... (truncated)

    Commits
    • 851daaf fix(types): fix TS 4.9 excessive depth error on InferAttributes (v6) (#15135)
    • 9dd93b8 fix(types): expose legacy "types" folder in export alias ( #15123)
    • 06ad05d feat(oracle): add support for dialectOptions.connectString (#15042)
    • a44772e feat(snowflake): Add support for QueryGenerator#tableExistsQuery (#15087)
    • 55051d0 docs: add missing ssl options for sequelize instance (v6) (#15049)
    • 5c88734 docs(model): Added paranoid option for Model.BelongsToMany.through (#15065)
    • 7203b66 fix(postgres): add custom order direction to subQuery ordering with minified ...
    • 5f621d7 fix(oracle): add support for Oracle DB 18c CI (#15016)
    • 3468378 feat(types): add typescript 4.8 compatibility (#14990)
    • 1da6657 fix(types): missing type for oracle dialect in v6 (#14992)
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by sdepold, a new releaser for sequelize since your current version.


    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump minimist, handlebars, mkdirp and mocha

    Bump minimist, handlebars, mkdirp and mocha

    Bumps minimist to 1.2.7 and updates ancestor dependencies minimist, handlebars, mkdirp and mocha. These dependencies need to be updated together.

    Updates minimist from 0.0.8 to 1.2.7

    Changelog

    Sourced from minimist's changelog.

    v1.2.7 - 2022-10-10

    Commits

    • [meta] add auto-changelog 0ebf4eb
    • [actions] add reusable workflows e115b63
    • [eslint] add eslint; rules to enable later are warnings f58745b
    • [Dev Deps] switch from covert to nyc ab03356
    • [readme] rename and add badges 236f4a0
    • [meta] create FUNDING.yml; add funding in package.json 783a49b
    • [meta] use npmignore to autogenerate an npmignore file f81ece6
    • Only apps should have lockfiles 56cad44
    • [Dev Deps] update covert, tape; remove unnecessary tap 49c5f9f
    • [Tests] add aud in posttest 228ae93
    • [meta] add safe-publish-latest 01fc23f
    • [meta] update repo URLs 6b164c7

    v1.2.6 - 2022-03-21

    Commits

    • test from prototype pollution PR bc8ecee
    • isConstructorOrProto adapted from PR c2b9819
    • security notice for additional prototype pollution issue ef88b93

    v1.2.5 - 2020-03-12

    v1.2.4 - 2020-03-11

    Commits

    • security notice 4cf1354
    • additional test for constructor prototype pollution 1043d21

    v1.2.3 - 2020-03-10

    Commits

    • more failing proto pollution tests 13c01a5
    • even more aggressive checks for protocol pollution 38a4d1c

    v1.2.2 - 2020-03-10

    Commits

    ... (truncated)

    Commits
    • c590d75 v1.2.7
    • 0ebf4eb [meta] add auto-changelog
    • e115b63 [actions] add reusable workflows
    • 01fc23f [meta] add safe-publish-latest
    • f58745b [eslint] add eslint; rules to enable later are warnings
    • 228ae93 [Tests] add aud in posttest
    • 236f4a0 [readme] rename and add badges
    • ab03356 [Dev Deps] switch from covert to nyc
    • 49c5f9f [Dev Deps] update covert, tape; remove unnecessary tap
    • 783a49b [meta] create FUNDING.yml; add funding in package.json
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by ljharb, a new releaser for minimist since your current version.


    Updates handlebars from 4.5.3 to 4.7.7

    Changelog

    Sourced from handlebars's changelog.

    v4.7.7 - February 15th, 2021

    • fix weird error in integration tests - eb860c0
    • fix: check prototype property access in strict-mode (#1736) - b6d3de7
    • fix: escape property names in compat mode (#1736) - f058970
    • refactor: In spec tests, use expectTemplate over equals and shouldThrow (#1683) - 77825f8
    • chore: start testing on Node.js 12 and 13 - 3789a30

    (POSSIBLY) BREAKING CHANGES:

    • the changes from version 4.6.0 now also apply in when using the compile-option "strict: true". Access to prototype properties is forbidden completely by default, specific properties or methods can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build.

    That is why we only bump the patch version despite mentioning breaking changes.

    Commits

    v4.7.6 - April 3rd, 2020

    Chore/Housekeeping:

    Compatibility notes:

    • Restored Node.js compatibility

    Commits

    v4.7.5 - April 2nd, 2020

    Chore/Housekeeping:

    • Node.js version support has been changed to v6+ Reverted in 4.7.6

    Compatibility notes:

    • Node.js < v6 is no longer supported Reverted in 4.7.6

    Commits

    v4.7.4 - April 1st, 2020

    Chore/Housekeeping:

    Compatibility notes:

    ... (truncated)

    Commits

    Updates mkdirp from 0.5.1 to 0.5.6

    Commits
    Maintainer changes

    This version was pushed to npm by isaacs, a new releaser for mkdirp since your current version.


    Updates mocha from 5.2.0 to 10.1.0

    Release notes

    Sourced from mocha's releases.

    v10.1.0

    10.1.0 / 2022-10-16

    :tada: Enhancements

    :nut_and_bolt: Other

    v10.0.0

    10.0.0 / 2022-05-01

    :boom: Breaking Changes

    :nut_and_bolt: Other

    Also thanks to @​ea2305 and @​SukkaW for improvements to our documentation.

    v9.2.2

    9.2.2 / 2022-03-11

    Please also note our announcements.

    :bug: Fixes

    ... (truncated)

    Changelog

    Sourced from mocha's changelog.

    10.1.0 / 2022-10-16

    :tada: Enhancements

    :nut_and_bolt: Other

    10.0.0 / 2022-05-01

    :boom: Breaking Changes

    :nut_and_bolt: Other

    Also thanks to @​ea2305 and @​SukkaW for improvements to our documentation.

    9.2.2 / 2022-03-11

    :bug: Fixes

    :nut_and_bolt: Other

    ... (truncated)

    Commits
    • 5f96d51 build(v10.1.0): release
    • ed74f16 build(v10.1.0): update CHANGELOG
    • 51d4746 chore(devDeps): update 'ESLint' to v8 (#4926)
    • 4e06a6f fix(browser): increase contrast for replay buttons (#4912)
    • 41567df Support prefers-color-scheme: dark (#4896)
    • 61b4b92 fix the regular expression for function clean in utils.js (#4770)
    • 77c18d2 chore: use standard 'Promise.allSettled' instead of polyfill (#4905)
    • 84b2f84 chore(ci): upgrade GH actions to latest versions (#4899)
    • 023f548 build(v10.0.0): release
    • 62b1566 build(v10.0.0): update CHANGELOG
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by juergba, a new releaser for mocha since your current version.


    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump handlebars from 4.5.3 to 4.7.7

    Bump handlebars from 4.5.3 to 4.7.7

    Bumps handlebars from 4.5.3 to 4.7.7.

    Changelog

    Sourced from handlebars's changelog.

    v4.7.7 - February 15th, 2021

    • fix weird error in integration tests - eb860c0
    • fix: check prototype property access in strict-mode (#1736) - b6d3de7
    • fix: escape property names in compat mode (#1736) - f058970
    • refactor: In spec tests, use expectTemplate over equals and shouldThrow (#1683) - 77825f8
    • chore: start testing on Node.js 12 and 13 - 3789a30

    (POSSIBLY) BREAKING CHANGES:

    • the changes from version 4.6.0 now also apply in when using the compile-option "strict: true". Access to prototype properties is forbidden completely by default, specific properties or methods can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build.

    That is why we only bump the patch version despite mentioning breaking changes.

    Commits

    v4.7.6 - April 3rd, 2020

    Chore/Housekeeping:

    Compatibility notes:

    • Restored Node.js compatibility

    Commits

    v4.7.5 - April 2nd, 2020

    Chore/Housekeeping:

    • Node.js version support has been changed to v6+ Reverted in 4.7.6

    Compatibility notes:

    • Node.js < v6 is no longer supported Reverted in 4.7.6

    Commits

    v4.7.4 - April 1st, 2020

    Chore/Housekeeping:

    Compatibility notes:

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • After updating a foreign key, the result data does not include the updated data

    After updating a foreign key, the result data does not include the updated data

    Suppose you have 2 tables: cars and brands and each car has an association to brand

    After updating a car's brand (setting brandId), and if the brand model is associated in the finale resource() method, the result will show the updated brandId value but the brand object on the model will still show the previous value.

    Let's say we have a car that looks like this: { id: 3, name: 'First car', brandId: 7 } When we fetch it, it includes the brand: { id: 3, name: 'First car', brandId: 7, Brand: { id: 7, name: 'Oldsmobile' } }

    Now, if we update brandId to 4, the result will be: { id: 3, name: 'First car', brandId: 4, Brand: { id: 7, name: 'Oldsmobile' } }

    The Brand associated object still shows the old data until the next fetch.

    opened by danieldilly 0
  • Throws 400 when ssl is set to true in sequelize config

    Throws 400 when ssl is set to true in sequelize config

    I just tried it with two different sets of sequelize config. I got an error when ssl is set to true (required for postgres databases managed by heroku or digital ocean app platform)

    opened by drixie 1
Releases(1.0.6)
Owner
Tom Juszczyk
Web and Mobile Engineer
Tom Juszczyk
A javascript REST ORM that is offline and real-time capable

Rekord Rekord is an ORM - a way to define properties and relationships - that interacts with local storage, a RESTful service, and a real-time service

Rekord 177 Oct 18, 2022
:rocket: One command to generate REST APIs for any MySql Database.

Xmysql : One command to generate REST APIs for any MySql database Why this ? Generating REST APIs for a MySql database which does not follow conventio

null 129 Dec 30, 2022
Social-Feeds-APIs - REST APIs to build social media sites.

express4.17.1-in-docker EXPRESS 4.17 SPA IMPORTANT NOTES: 1. Make sure you follow the steps mentioned under "PROJECT START STEPS" and ensure that the

Patel Rohan 1 Jan 3, 2022
🦁 REST API for the NestJS + Next.js Todo application

Create new NestJS project $ npm i -g @nestjs/cli $ npm i -g yarn $ nest new api-lesson # set strict true in tsconfig.json Install packages # install

Udemy course repositories by Kazu T+ 21 Jan 4, 2023
EasyStory REST API made with Nest.js & TypeORM.

Easy Story REST API ?? “EasyStory” is a web platform whose content is published by its users. With "EasyStory" you can publish your own stories or tal

null 2 Sep 13, 2022
Explore, create and deploy your SQLite databases right from your browser. Quick and easy, no installation required.

SQLighter (under development, alpha code) SQLighter is a database explorer born for SQLite that helps you design and deploy your application database

sqlighter 11 Sep 20, 2022
Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture, inspired by Hapi and Express.

Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture, inspired by Hapi and Express.

Jared Hanson 5 Oct 11, 2022
A back-end server aplication created using node.js, express and mongodb.

Course Material and FAQ for my Complete Node.js, Express and MongoDB Bootcamp This repo contains starter files and the finished project files for all

Pablo César Jiménez villeda 1 Jan 4, 2022
Nodeparse - A lightweight, vanilla replacement for Express framework when parsing the HTTP body's data or parsing the URL parameters and queries with NodeJS.

nodeparse A lightweight, vanilla replacement for Express framework when parsing the HTTP body's data or parsing the URL parameters and queries with No

Trần Quang Kha 1 Jan 8, 2022
NodeJS,express and mysql starter project

Node-express-mysql-starterproject NodeJS,express and mysql starter project Start with cloning the repo & Run npm i to download all the dependecies Aft

Nermine slimane 16 Dec 11, 2022
Código desenvolvido na mentoria do Hiring Coders utilizando Express e GraphQL

hiringcoders-graphql Código desenvolvido na mentoria do Hiring Coders utilizando Express e GraphQL Contribuições A ideia do repositório é continuar si

Daniel Mitre 37 Dec 29, 2022
Repository with various templates using nest ( express )

A progressive Node.js framework for building efficient and scalable server-side applications. Description Nest framework TypeScript starter repository

Douglas Ramirez 2 Nov 27, 2022
Create Node.js app that is packed with best practices AND strive for simplicity

Generate a Node.js app that is packed with best practices AND simplicty in mind. Based on our repo Node.js best practices (77,000 stars) ❣️ Alpha stag

null 674 Dec 31, 2022
Senior Design Project. Water intake tracker. Software for the communication to bottle and app. Software for app and database

WaterMate Senior Design Project. Water intake tracker to provide everyone with an easy to use water tracking system that can be integrated with your f

null 3 Nov 10, 2021
The Wholesome App. A project that allows you to upload images directly to MongoDB Atlas into your collection, a faster cloud database.

The Wholesome App. A project that allows you to upload images directly to MongoDB Atlas into your collection, a faster cloud database. To upload your cute and wholesome images.

Gourav Singh Rawat 2 Jul 17, 2022
around nestjs, with prisma and some graphql lib,write less code,create power api

介绍 这是一个 prisma + nestjs + graphql 的集成示例 对于开发者来说,特别是使用 graphql 的时候,只需要写非常少量的代码即可完成数据的各种操作,同时也支持接口透传。 开发&部署 本地开发 npm run start:dev swagger 地址:http://loc

芋头 26 Nov 24, 2022
Allows the DAO to manage Saber pools and for anyone to create new pools without permission

Saber Pools Program Allows the DAO to manage Saber pools and for anyone to create new pools without permission. Setup Instructions Running tests Insta

Saber 7 Sep 4, 2022
It is a Discord bot whose goal is to make it easier for server owners to create a so-called Staff/Mode Application

Application Bot MeCodes Application Bot It is a Discord bot whose goal is to make it easier for server owners to create a so-called administration sub

null 26 Dec 12, 2022
StashQL is a light-weight, open-source npm package that improves the speed of your GraphQL queries in your application.

Table of Contents What is StashQL? Install Getting Started Queries Mutations refillCache clearRelatedFields Logging The Team What is StashQL? StashQL

OSLabs Beta 67 Sep 30, 2022