
Research
/Security News
DuckDB npm Account Compromised in Continuing Supply Chain Attack
Ongoing npm supply chain attack spreads to DuckDB: multiple packages compromised with the same wallet-drainer malware.
BirchTree is mainly a helper library for knexjs. It takes an instance of knex and adds two helper functions: grow and nest. These functions make it easy to get nested objects as results when running join queries.
BirchTree is also a repository library built on knexjs. It provides base Repo
and Model
classes that can be extended to create a basic model system.
npm install --save birchtree
BirchTree is written in typescript and should just work. You can import the type for birchtree like this
import { BirchTree } from 'birchtree'
import birchtree from 'birchtree';
import * as Knex from 'knex';
const knex = Knex({
client: 'mysql',
debug: false,
connection,
pool
});
const birch = birchtree(knex);
const songs = 'albums:songs';
const author = 'albums:songs:author';
const select = await birch.grow('artists', 'albums', `songs AS ${songs}`, `authors AS ${author}`);
const results = await birch('users')
.select(select)
.leftJoin('albums', 'albums.artist_id', 'artists.id')
.leftJoin(`songs AS ${songs}`, `${songs}.album_id`, `albums.id`)
.leftJoin(`authors as ${author}`, `${author}.id`, `${songs}.author_id`)
.where('artists.id', '=', 1);
const nestedResults = birch.nest(results);
Results will look like
[{
id: 1,
name: 'The Beatles',
albums: [{
id: 1,
name: 'Rubber Soul',
songs: [{
id: 1,
name: 'Drive My Car',
author: {
id: 2,
name: 'Paul McCartney'
}
}, {
id: 2,
name: 'Norwegian Wood (This Bird has Flown)',
author: {
id: 1,
name: 'John Lennon'
}
}]
}, {
id: 2,
name: 'Revolver',
songs: [{
id: 3,
name: 'Taxman',
author: {
id: 3,
name: 'George Harrison'
}
}, {
id: 4,
name: 'Eleanor Rigby',
author: {
id: 2,
name: 'Paul McCartney'
}
}]
}]
}]
There are some important things to note from the example.
:
Asynchronous: Takes any number of table names with or without aliases as arguments and returns an array for knex's select function that will make sure columns don't get overwritten. It will select every column in each table given.
Takes the results from a select query and nests them using treeize
import { default as birchtree, BirchTree, Repo, Model } from 'birchtree';
// let's just pretend we set knex up
const birch = birchtree(knex);
// let's make a user repo
const userRepo = new UserRepo(birch);
class User extends Model {
static tableName = 'users';
private id: number;
private email: string;
private username: string;
constructor(props) {
super();
Object.assign(this, props);
}
toJSON() {
return {
id: this.id,
email: this.email,
username: this.username
}
}
}
class UserRepo extends Repo<User> {
constructor(birch) {
super(User, birch);
}
async findDuplicate(user: User, trx: BirchTree.Transaction) {
return this.createQuery(trx)
.where({ email: user.email })
.orWhere({ username: user.username });
}
}
static tableName
property equal to the name of the corresponding database tabletoJSON
function. This function is used to get the object to persist in repo.create
, repo.update
and repo.save
id
propertysuper
in the constructorthis.birch
in extended reposconst user = new User({
email: 'fry@gmail.com',
username: 'fry'
});
await userRepo.create(user);
user.username = 'bender';
await userRepo.update(user);
user.email = 'bender@gmail.com';
await userRepo.save(user);
const leela = new User({
email: 'leela@gmail.com',
username: 'leela'
});
await userRepo.save(leela);
const bender = await userRepo.findOneById(user.id);
const benderAndLeela = await userRepo.findByIds([bender.id, leela.id]);
await userRepo.exterminate(bender);
const leelaAgain = await userRepo.findOne({ email: 'leela@gmail.com' });
const leelaAsAnArray = await userRepo.find({ email: 'leela@gmail.com' });
This returns a birchtree/knex querybuilder.
const results = await userRepo.createQuery().where('email', '=', 'bender@gmail.com');
birch.transaction(trx => {
const bender = await userRepo.findOne({ username: 'bender' }, trx);
bender.username = 'coilette';
await userRepo.save(bender, trx);
const leela = await userRepo.createQuery(trx).where({ username: 'leela' });
leela.username = 'Turanga';
await userRepo.save(leela, trx);
return [ bender, leela ];
})
.then(results => console.log(results))
.catch(err => console.error(err));
FAQs
Repository system and helper functions for knexjs
The npm package birchtree receives a total of 4 weekly downloads. As such, birchtree popularity was classified as not popular.
We found that birchtree 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.
Research
/Security News
Ongoing npm supply chain attack spreads to DuckDB: multiple packages compromised with the same wallet-drainer malware.
Security News
The MCP Steering Committee has launched the official MCP Registry in preview, a central hub for discovering and publishing MCP servers.
Product
Socket’s new Pull Request Stories give security teams clear visibility into dependency risks and outcomes across scanned pull requests.