Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
@arnoldtkl/feathers-knex
Advanced tools
A service plugin for KnexJS a query builder for PostgreSQL, MySQL and SQLite3
A database adapter for KnexJS, an SQL query builder for Postgres, MSSQL, MySQL, MariaDB, SQLite3, and Oracle.
npm install --save mysql knex feathers-knex
Important:
feathers-knex
implements the Feathers Common database adapter API and querying syntax.
Note: You also need to install the database driver for the DB you want to use.
service(options)
Returns a new service instance initialized with the given options.
const knex = require('knex');
const service = require('feathers-knex');
const db = knex({
client: 'sqlite3',
connection: {
filename: './db.sqlite'
}
});
// Create the schema
db.schema.createTable('messages', table => {
table.increments('id');
table.string('text');
});
app.use('/messages', service({
Model: db,
name: 'messages'
}));
app.use('/messages', service({ Model, name, id, events, paginate }));
Options:
Model
(required) - The KnexJS database instancename
(required) - The name of the tableschema
(optional) - The name of the schema table prefix (example: schema.table
)id
(optional, default: 'id'
) - The name of the id field property.events
(optional) - A list of custom service events sent by this servicepaginate
(optional) - A pagination object containing a default
and max
page sizemulti
(optional) - Allow create
with arrays and update
and remove
with id
null
to change multiple items. Can be true
for all methods or an array of allowed methods (e.g. [ 'remove', 'create' ]
)whitelist
(optional) - A list of additional query parameters to allow (e..g [ '$regex', '$geoNear' ]
). Default is the supported operators
adapter.createQuery(query)
Returns a KnexJS query with the common filter criteria (without pagination) applied.
When making a service method call, params
can contain an knex
property which allows to modify the options used to run the KnexJS query. See customizing the query for an example.
Here's a complete example of a Feathers server with a messages
SQLite service. We are using the Knex schema builder and SQLite as the database.
$ npm install @feathersjs/feathers @feathersjs/errors @feathersjs/express @feathersjs/socketio feathers-knex knex sqlite3
In app.js
:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
const service = require('feathers-knex');
const knex = require('knex');
const db = knex({
client: 'sqlite3',
connection: {
filename: './db.sqlite'
}
});
// Create a feathers instance.
const app = express(feathers());
// Turn on JSON parser for REST services
app.use(express.json());
// Turn on URL-encoded parser for REST services
app.use(express.urlencoded({ extended: true }));
// Enable REST services
app.configure(express.rest());
// Enable Socket.io services
app.configure(socketio());
// Create Knex Feathers service with a default page size of 2 items
// and a maximum size of 4
app.use('/messages', service({
Model: db,
name: 'messages',
paginate: {
default: 2,
max: 4
}
}))
app.use(express.errorHandler());
// Clean up our data. This is optional and is here
// because of our integration tests
db.schema.dropTableIfExists('messages').then(() => {
console.log('Dropped messages table');
// Initialize your table
return db.schema.createTable('messages', table => {
console.log('Creating messages table');
table.increments('id');
table.string('text');
});
}).then(() => {
// Create a dummy Message
app.service('messages').create({
text: 'Message created on server'
}).then(message => console.log('Created message', message));
});
// Start the server.
const port = 3030;
app.listen(port, () => {
console.log(`Feathers server listening on port ${port}`);
});
Run the example with node app
and go to localhost:3030/messages.
In addition to the common querying mechanism, this adapter also supports:
Find all records that match all of the given criteria. The following query retrieves all messages that have foo and bar attributes as true.
app.service('messages').find({
query: {
$and: [
{foo: true},
{bar: true}
]
}
});
Through the REST API:
/messages?$and[][foo]=true&$and[][bar]=true
Find all records where the value matches the given string pattern. The following query retrieves all messages that start with Hello
:
app.service('messages').find({
query: {
text: {
$like: 'Hello%'
}
}
});
Through the REST API:
/messages?text[$like]=Hello%
The opposite of $like
; resulting in an SQL condition similar to this: WHERE some_field NOT LIKE 'X'
app.service('messages').find({
query: {
text: {
$notlike: '%bar'
}
}
});
Through the REST API:
/messages?text[$notlike]=%bar
For PostgreSQL only, the keywork $ilike can be used instead of $like to make the match case insensitive. The following query retrieves all messages that start with hello
(case insensitive):
app.service('messages').find({
query: {
text: {
$ilike: 'hello%'
}
}
});
Through the REST API:
/messages?text[$ilike]=hello%
The Knex adapter comes with three hooks that allows to run service method calls in a transaction. They can be used as application wide (app.hooks.js
) hooks or per service like this:
// A common hooks file
const { hooks } = require('feathers-knex');
const { transaction } = hooks;
module.exports = {
before: {
all: [ transaction.start() ],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
after: {
all: [ transaction.end() ],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [ transaction.rollback() ],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
To use the transactions feature, you must ensure that the three hooks (start, end and rollback) are being used.
At the start of any request, a new transaction will be started. All the changes made during the request to the services that are using the feathers-knex
will use the transaction. At the end of the request, if sucessful, the changes will be commited. If an error occurs, the changes will be forfeit, all the creates
, patches
, updates
and deletes
are not going to be commited.
The object that contains transaction
is stored in the params.transaction
of each request.
Important: If you call another Knex service within a hook and want to share the transaction you will have to pass
context.params.transaction
in the parameters of the service call.
In a find
call, params.knex
can be passed a KnexJS query (without pagination) to customize the find results.
Combined with .createQuery({ query: {...} })
, which returns a new KnexJS query with the common filter criteria applied, this can be used to create more complex queries. The best way to customize the query is in a before hook for find
.
app.service('messages').hooks({
before: {
find(context) {
const query = context.service.createQuery(context.params);
// do something with query here
query.orderBy('name', 'desc');
context.params.knex = query;
return context;
}
}
});
For using knex's migration CLI, we need to make the configuration available by the CLI. We can do that by providing a knexfile.js
(OR knexfile.ts
when using TypeScript) in the root folder with the following contents:
knexfile.js
const app = require('./src/app')
module.exports = app.get('postgres')
OR
knexfile.ts
import app from './src/app';
module.exports = app.get('postgres');
You will need to replace the postgres
part with the adapter you are using. You will also need to add a migrations
key to your feathersjs config under your database adapter. Optionally, add a seeds
key if you will be using seeds.
// src/config/default.json
...
"postgres": {
"client": "pg",
"connection": "postgres://user:password@localhost:5432/database",
"migrations": {
"tableName": "knex_migrations"
},
"seeds": {
"directory": "../src/seeds"
}
}
Then, by running: knex migrate:make create-users
, a migrations
directory will be created, with the new migration.
As of version 4.0.0 feathers-knex
only throws Feathers Errors with the message. On the server, the original error can be retrieved through a secure symbol via error[require('feathers-knex').ERROR]
const { ERROR } = require('feathers-knex');
try {
await knexService.doSomething();
} catch(error) {
// error is a FeathersError with just the message
// Safely retrieve the Knex error
const knexError = error[ERROR];
}
Copyright (c) 2019
Licensed under the MIT license.
FAQs
A service plugin for KnexJS a query builder for PostgreSQL, MySQL and SQLite3
The npm package @arnoldtkl/feathers-knex receives a total of 2 weekly downloads. As such, @arnoldtkl/feathers-knex popularity was classified as not popular.
We found that @arnoldtkl/feathers-knex 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
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.