
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@knorcedger/backend-utils
Advanced tools
A comprehensive collection of utilities designed to simplify backend GraphQL and MongoDB development.
This package assumes that you use node 22.6 or newer that supports type stripping
npm install @knorcedger/backend-utils
Automatically generate GraphQL types from your Mongoose models.
transformModelToGraphQLTypes()Transforms a Mongoose model into GraphQL object and enum types.
import UserModel from './models/UserModel';
import { transformModelToGraphQLTypes } from '@knorcedger/backend-utils';
// Generate GraphQL types from your Mongoose model
export const { objectTypes, enumTypes } =
transformModelToGraphQLTypes(UserModel);
// Access the generated type
export const UserType = objectTypes.UserType;
Use options.omitFields to specify which model fields will be ignored.
const { enumTypes, objectTypes } = transformModelToGraphQLTypes(
MessageRuleModel,
{ omitFields: ['time'] }
);
createInputTypeFromOutputType()Converts an output GraphQL type to an input type for mutations.
import GuestAppPreferencesModel from './models/GuestAppPreferencesModel';
import {
createInputTypeFromOutputType,
transformModelToGraphQLTypes,
} from '@knorcedger/backend-utils';
// Generate GraphQL types from your model
export const { objectTypes } = transformModelToGraphQLTypes(
GuestAppPreferencesModel
);
// Get the output type
export const GuestAppPreferencesType = objectTypes.GuestAppPreferencesType;
// Create an input type from the output type
export const {
inputFields: GuestAppPreferencesInputFields,
inputType: GuestAppPreferencesInputType,
} = createInputTypeFromOutputType(GuestAppPreferencesType);
// Make email required in the input field
makeInputFieldRequired(ClientInputFields, 'email');
addFieldToType({
field: {
description: 'The client _id',
name: '_id', // Field name
// resolve: (source, args, context, info) => {
// return `Test value for client ID: ${source?._id ?? "unknown"}`;
// },
type: GraphQLObjectID, // Field type
// args: {} // Define arguments here if needed
},
type: ClientType, // The GraphQLObjectType to modify
});
removeFieldFromType({
fieldName: 'password', // the field to remove
type: ClientType, // The GraphQLObjectType to modify
});
createTypes()Creates a set of GraphQL types (output, input, and update) from field definitions.
import { createTypes, GraphQLString } from '@knorcedger/backend-utils';
const userTypes = createTypes('User', {
email: {
description: "The user's email address",
required: ['input', 'output'],
type: GraphQLString,
},
name: {
description: "The user's full name",
type: GraphQLString,
},
password: {
description: "The user's password (hashed)",
include: ['input'],
required: ['input'],
type: GraphQLString,
},
});
// Access the generated types
const { UserType, UserInputType, UserUpdateType } = userTypes;
Each field can be configured with the following properties:
type: The GraphQL type for this field (used when the same type applies to all variants).
type: GraphQLString;
distinctTypes: Define different types for input/output/update (used instead of type).
distinctTypes: {
input: GraphQLInputFileType,
output: GraphQLFileType,
update: GraphQLInputFileType
}
description: Optional field description that appears in GraphQL documentation.
description: "The user's profile picture";
include: Specifies which type variants should include this field (defaults to all).
include: ['input', 'output']; // Exclude from update type
required: Specifies in which type variants this field is required.
required: ['input']; // Field is required in input type but optional elsewhere
resolve: Custom resolver function for the field (only applied to output type).
resolve: (user, args, context) => {
return user.firstName + ' ' + user.lastName;
};
permission: Permission check for accessing field values.
'self': Only the user can access their own data'loggedin': Any authenticated user can access the fieldpermission: 'self'; // Only the user can see their own email
The function returns an object with six properties:
[Name]Type: The output GraphQL object type[Name]OutputFields: The fields object for the output type[Name]InputType: The input GraphQL object type for creating new objects[Name]InputFields: The fields object for the input type[Name]UpdateType: The input GraphQL object type for updating objects[Name]UpdateFields: The fields object for the update typeIntRangeType(min, max)Creates a GraphQL scalar that validates integers within a specified range.
import { IntRangeType } from '@knorcedger/backend-utils';
import { GraphQLObjectType, GraphQLSchema } from 'graphql';
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
fields: {
rating: { type: IntRangeType(1, 5) }, // Only accepts integers 1-5
},
name: 'Query',
}),
});
Extracts requested field names from a GraphQL resolver info object.
import { getRequestedFields } from '@knorcedger/backend-utils';
const resolvers = {
Query: {
getUser: (_, args, context, info) => {
const fields = getRequestedFields(info);
console.log('Requested fields:', fields); // ['id', 'name', 'email', etc.]
// Now you can optimize your database query based on requested fields
},
},
};
Intelligently populates MongoDB references based on GraphQL query fields
This function:
import { populate } from '@knorcedger/backend-utils';
const resolvers = {
Query: {
getPost: async (_, { id }, context, info) => {
const query = PostModel.findById(id);
return populate(query, info, ['author', 'comments']);
},
},
};
catchAppErrors()Prevents application crashes by catching uncaught exceptions and unhandled promise rejections.
import { catchAppErrors } from '@knorcedger/backend-utils';
// Add this at the end of your main application file
catchAppErrors();
Selectively copies properties from a source object based on a list of attribute names.
import { optionallyAddAttrs } from '@knorcedger/backend-utils';
const resolvers = {
Mutation: {
updateUser: async (_, { id, input }) => {
// Only update fields that were actually provided
const updates = optionallyAddAttrs(input, ['name', 'email', 'age']);
return UserModel.findByIdAndUpdate(id, updates, { new: true });
},
},
};
mongooseConnect()Connects to a MongoDB database using Mongoose with proper error handling.
import mongoose from 'mongoose';
import { mongooseConnect } from '@knorcedger/backend-utils';
// With default logging
await mongooseConnect(mongoose, 'mongodb://localhost:27017/mydatabase');
// With disabled logging
await mongooseConnect(mongoose, 'mongodb://localhost:27017/mydatabase', {
logging: false,
});
Inside the typescript folder there's a tsconfig.json that can be used to run typescript checks in the parent project.
Inside your package.json
"scripts": {
"typecheck": "cp node_modules/@knorcedger/backend-utils/tsconfig.json . && npx tsc --noEmit && rm -f tsconfig.json"
}
ISC
Contributions are welcome! Please feel free to submit a Pull Request.
FAQs
A collection of useful utils to use in your backend code
We found that @knorcedger/backend-utils demonstrated a healthy version release cadence and project activity because the last version was released less than 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
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.