speedly
v1.3.0
Published
**Overview**
Readme
Overview
- Project:
speedly— a lightweight express utility framework that bundles auth middlewares, database model handlers, file uploader helpers, request validators, API documentation loader and small utilities to speed up building REST APIs. - Entry point exports:
auth,db,uploader,validator,models,modules,utils,document(see below for details and examples).
Quick Start
- Install: add the project to your workspace or import the package in your service.
- Basic server skeleton:
import express from 'express'
import { auth, db, uploader, validator, models, modules, utils, document } from './src'
const app = express();
app.use(express.json());
// Mount example module router
app.use('/api/translation', modules.translation);
// Swagger docs (served at /docs)
document(app, require('path').join(process.cwd(), 'src/modules'));
app.listen(3000);Exports Reference
auth
- Type: default export (object)
- Purpose: Provides simple express middlewares for access control. Each function returns an Express middleware that inspects the request using a configurable
customValidator(fromgetConfig('auth')) and either allows, forbids or rejects the request. - API:
auth.user()→ middleware that enforces auseraccess type.auth.admin(config?)→ middleware for admin access. Optionally pass{ permission }to require a specific admin permission (the middleware names themselves include the permission, e.g.auth:admin:PERM).auth.any()→ middleware that accepts any authenticated-type logic configured by thecustomValidator.
- Notes:
authreads default options fromgetConfig('auth'). ThecustomValidatorshould return truthy to allow or falsy to forbid;nullis treated as unauthorized.
db
- Type: default export (factory function)
- Purpose: Creates Express middlewares that operate on a Mongoose model (or other model loaded from the
modelspath). Designed to simplify CRUD endpoints by composing handler builders like.find(),.create(),.findByIdAndUpdate(), etc. - How to use: call
db(collectionName, config?)to get a model handler factory, then chain action methods and use the returned function as an Express middleware. - Common methods returned by
db('collection'):.find(match = {}).create(body = {}).updateOne(match, body).updateMany(match, body).deleteOne(match).deleteMany(match).findOne(match).findOneAndUpdate(match, body).aggregate(pipeline).findById(id).findByIdAndUpdate(id, body).findByIdAndDelete(id)
- Query behavior: The produced middleware reads query params like
search,filters,sort,page,limit, andselectto modify results. Pagination behaviour can be controlled viagetConfig('db')(e.g.,pagination.quantity,pagination.detailed). - Config: second argument allows overriding
{ path, type: 'internal'|'external', message }. Whentypeisinternalthe loader resolves models relative to the library; whenexternalit resolves from the host app andconfigs.path. - Example:
// GET /api/translation -> finds translations
app.get('/api/translation', db('translation', { type: 'internal' }).find());
// POST /api/translation -> create translation documents
app.post('/api/translation', db('translation', { type: 'internal' }).create());uploader
- Type: default export (factory)
- Purpose: Provides file uploading middlewares built on
multerand convenience helpers that optionally save media metadata to amediacollection. - Signature:
uploader(destination = '/image', config?)returns an object with methods{ single, array, fields, any, none }which are wrappers around multer handlers. - Config options (defaults obtained from
getConfig('uploader')):saveInDb(boolean) — whether to persist metadata in amediacollectionprefix(string) — prefix for saved filenameslimit(number) — max upload size in MBformat(RegExp) — allowed file extensionspath(string) — base path to save files (default../../../publicin library defaults)
- Returned helpers:
single(fieldName)— middleware saving a single file and setting the file URL intoreq.body[fieldName]. IfsaveInDbis true it will store a doc inmediaand setreq.mediaId.array(fieldName, maxCount)— accept multiple files and set an array of URLs intoreq.body[fieldName].fields(fieldsArray)— accept mixed fields (multer-style field definitions).any()andnone()— passthrough multer helpers.
- Example:
app.post('/upload', uploader('/images').single('photo'), (req,res) => {
res.json({ url: req.body.photo });
});validator
- Type: default export (generic factory)
- Purpose: A small wrapper around
yupto validatereq.body,req.params, andreq.query. On failure it forwards an error object tonext()withstatus: 405and a message. - Signature:
validator({ body?: yup.Schema, params?: yup.Schema, query?: yup.Schema })returns an ExpressRequestHandler. - Behavior: strips unknown fields, assigns validated values back to
req.body,req.params, andreq.query. The created middleware is annotated with__validationSchema(used by automatic documentation generator). - Example:
import * as yup from 'yup';
const schema = { body: yup.object({ text: yup.string().required() }) };
app.post('/translate', validator(schema), handler);models
- Type: object containing Mongoose models
- Currently included:
translation— Mongoose model with fields{ text: String, lang: String, translatedText: String }and timestamps.
- Purpose: Direct access to low-level models for custom operations (e.g., prefetch, caching or complex queries).
modules
- Type: object of
express.Routerinstances keyed by module name - Included:
translation— router defined insrc/modules/translation/translation.routes.tswith routes:GET /→db('translation', {type:'internal'}).find()POST /→ guarded by a simple bodyauthcheck inside the route and thencreate()PUT /:id→auth.admin()+validator(...)+findByIdAndUpdate()
- Mounting:
app.use('/api/translation', modules.translation)
utils
- Type: object of helper utilities
- Included:
translator— a small translation helper that attempts multiple external translation providers and caches successful translations to thetranslationmodel. Signature:translator(text = 'unspecified text', lang = 'fa') => Promise<string>.
- Behavior: Normalizes text, looks up local cache (
translationmodel), attempts external services (a worker proxy and optionallyone-api), writes the result to DB, and returns the translated text. Falls back to the formatted original text on failure.
document
- Type: default export (function)
- Purpose: Scans
src/modulesrouters and mounts a Swagger UI at/docswith automatically generated OpenAPI paths and basic security scheme. - Signature:
document(app: Express, baseDir?: string)—baseDirdefaults topath.join(process.cwd(), 'src/module')in the loader. Use a correct path to your modules folder (e.g.,path.join(process.cwd(), 'src/modules')). - What it detects: routes, http methods,
yupvalidation schemas (to document request bodies), and auth middlewares (to add security hints and descriptions).
Configuration & Environment
- Use
getConfig(key)(internal) to supply runtime options forauth,db,uploader, andtranslateproviders. Typical environment keys used by the modules:JWT_KEY(used by auth-related configs)DB_URL(database connection string if using external db config)one_api_token(optional token for the alternate translator provider)
Examples
- Mounting everything in a small app:
import express from 'express';
import { modules, document } from './src';
import path from 'path';
const app = express();
app.use(express.json());
app.use('/api/translation', modules.translation);
document(app, path.join(process.cwd(), 'src/modules'));
app.listen(3000);Developer Notes
dbmiddleware attaches pagination,searchandfiltersbehavior usingreq.query. Usetype: 'internal'when you want the model path resolved inside the package, orexternalto resolve from the consumer app.validatorattaches__validationSchemato middlewares whichdocumentuses to generate OpenAPI schemas.uploaderwrites files to disk under the configuredpathand returns public URLs prefixed with/static.
If you'd like, I can also:
- add usage examples/tests around each exported function
- add API reference tables per-method for
dbhandlers - generate a small example express app under
examples/using these exports
