Skip to content

green_dot

Security and DX focused NodeJs backend framework

npx green_dot@latest generate

🧭 Back/Front Type-safe API route declarations, shared models
🔒 Unified model definitions and security configuration
🔌 Powerful plugin system (Managed Login, ApiKey Login…) (BETA)
🪄 File generation to generate project, databases, apps, models…so you get up and running in no time 🗃️ MongoDB integration with all the way type safety (others database drivers coming soon)
👨‍💻 DX and intellisense friendly
🏗️ Generate it’s own SDK to use in frontend, get your backend data without await, useEffects or state management: (Eg: const result = $.useQuery.myApiRoute())
⚡ Fully cached in frontend via TanStack Query
📦 VSCode / Cursor Plugin

API route declaration

Generate a new api route with npx green_dot generate and configure it:

getUserByEmailCustom.api.ts
export const
const getUserByEmailCustom: void
getUserByEmailCustom
=
function svc(config: {
for: [string | {
role: string;
hasValidatedEmail: boolean;
}];
main(ctx: {
_id: string;
role: "appUser";
}, body: {
email: string;
}): any;
rateLimiter: string;
output: any;
}): void
svc
({
for: [string | {
role: string;
hasValidatedEmail: boolean;
}]
for
: [
'customRole',
{
role: string
role
: 'user',
hasValidatedEmail: boolean
hasValidatedEmail
: true }
],
input: {
email: any;
}
input
: {
email: any
email
:
any
_
.
any
email
().
any
required
(),
},
output: any

Type output for security and backend / frontend type safety

output
:
any
_
.
any
model
('myDbName', 'user'),
rateLimiter: string

Custom rate limiter for this route

rateLimiter
: '10/min',
...
any
async
function main(ctx: {
_id: string;
role: "appUser";
}, body: {
email: string;
}): any
main
(
ctx: {
_id: string;
role: "appUser";
}
ctx
, { email }) {
email: string
// No need to worry about security here, this db call will automatically apply
// mask and filter depending on user perm (see below)
return await
ctx: {
_id: string;
role: "appUser";
}
ctx
.
any
db
.
any
user
.
any
getOne
({
email: string
email
})
},
})

Note: the above will auto generate a route on POST myDomain.com/get-user-by-email-custom based on the const value. You can modify this by adding a route and method config



In frontend, everything is well typed: you just have to import the generated SDK and use it like:

import {
import $
const $: {
getUserByEmailCustom(): Promise<User>;
useQuery: {
getUserByEmailCustom(): User;
};
}
$
} from '@my-company/user-app-sdk'
const
const user: User
user
= await
import $
const $: {
getUserByEmailCustom(): Promise<User>;
useQuery: {
getUserByEmailCustom(): User;
};
}
$
.
function getUserByEmailCustom(): Promise<User>
getUserByEmailCustom
()
// OR if in the context of a react component (cache friendly with tanstack query)
function
function MyReactComponent(): div
MyReactComponent
() {
const user =
import $
const $: {
getUserByEmailCustom(): Promise<User>;
useQuery: {
getUserByEmailCustom(): User;
};
}
$
.
useQuery: {
getUserByEmailCustom(): User;
}
useQuery
.
function getUserByEmailCustom(): User
getUserByEmailCustom
()
const user: User
return <
type div = /*unresolved*/ any
div
>
any
Welcome
{
const user: User
user
.name}</div>
name: string
}

API services Doc

Frontend Usage Doc



Shared Models, Unified Security

Generate a new model and DAO (data access object) with npx green_dot generate and configure it:

company.model.ts
export const companyModel = _.mongoModel(
// Automatic timestamp fields
['creationDate', 'updateDate'],
{
name: _.string().required(),
admin: _.ref('user').required(), // ref to user model
companyIdenfier: _.string().required().unique(), // unique fields
}
)
export type CompanyModel = InferType<typeof companyModel>
// type may differ when writing (create / update) vs reading
export type CompanyModelWrite = InferTypeWrite<typeof companyModel>

Dao files are a way to configure the security of your model and expose automatically some method via API (getById, update…). Everything is unified in a single file so security is made easy and comprehensive:


company.dao.ts
export const dao = {
type: 'mongo', // other DBs drivers incoming
// EXPOSE: auto generate routes and SDK methods with configured access
expose: [{
for: 'appUser',
expose: ['getOne', 'create'], // so an appUser cannot update or delete
}, {
for: 'admin',
expose: ['read', 'write'], // admin has full access
}],
// FILTER
filter: [{
for: 'appUser',
filter: (ctx, filter) => {
// here, we force admin fields to be equal to user._id
// in other terms, user must be admin of the company to read/write model
filter.admin === ctx._id
}
}],
// MASK
mask: [{
for: 'appUser',
mask: ctx => ({
// user cannot see businessData field
businessData: true,
}),
}, {
on: 'read',
mask: ctx => ({
// no one can read password
password: true,
// dynamically hide fields according to user perms
businessData: ctx.isBusinessHolder,
}),
}],
// automatically populate (left join) data for this model,
// security is applied to any level of populated field
populate: [{ path: 'admin', select: ['firstName']}],
} satisfies MongoDao<User>
export default dao


And much more…

A powerful plugin system

Actually 3 plugins can be installed when you run npx green_dot@latest generate for the first time:

GDmanagedLogin: Managed JWT login, email and password updates with custom emails (see doc)

GDapiKeyAuthentication: Managed 2FA, Pin Code or biometric authentication (see doc)

GDdoubleAuthentication: Api Key Authentication (see doc)

Loved by your IDE

Whenever you are lost, just hover the name of anything green_dot to see a full documentation without leaving your IDE

Cursor and VSCode plugins for specific syntax highlights and helpers

Use gd_ snippets anywhere to help with writing code faster

Performance friendly

  • All your requests are automatically cached with @tanstack/react-query to use in frontend components without the need to await your requests
  • refresh cache or disable it on demand via simple configuration (in API service or SDK directly)
  • prefetch heavy requests via $.prefetch.myHeavyRequest() so that when you need them they’ll load instantly
  • defer requests to make them async $.defer.myHeavyRequest()

Learn more about caching and performances

Plus

  • File Generation from template via npx green_dot generate
  • MongoDb integration (more database to come)
  • Auto generates a swagger documentation
  • Open Source