🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

velona

Package Overview
Dependencies
Maintainers
2
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

velona

TypeScript DI helper for functional programming

0.8.0
latest
Source
npm
Version published
Weekly downloads
8.6K
81.17%
Maintainers
2
Weekly downloads
 
Created
Source

velona
npm version npm download

Velona is TypeScript DI helper for functional programming.




Table of Contents

Installation

  • Using npm:

    $ npm install velona
    
  • Using Yarn:

    $ yarn add velona
    

Usage

index.ts

import { depend } from "velona";

const add = (a: number, b: number) => a + b;

export const basicFn = depend({ add }, ({ add }, a: number, b: number, c: number) => add(a, b) * c);

sample.ts

import { basicFn } from "./";

console.log(basicFn(2, 3, 4)); // 20

index.spec.ts

import { basicFn } from "./";

const injectedFn = basicFn.inject({ add: (a, b) => a * b });

expect(injectedFn(2, 3, 4)).toBe(2 * 3 * 4); // pass
expect(basicFn(2, 3, 4)).toBe((2 + 3) * 4); // pass

DI to browser API callback

handler.ts

import { depend } from "velona";

export const handler = depend(
  { print: (text: string) => alert(text) },
  ({ print }, e: Pick<MouseEvent, "type" | "x" | "y">) =>
    print(`type: ${e.type}, x: ${e.x}, y: ${e.y}`)
);

index.ts

import { handler } from "./handler";

document.body.addEventListener("click", handler, false);
document.body.click(); // alert('type: click, x: 0, y: 0')

index.spec.ts

import { handler } from "./handler";

const event = { type: "click", x: 1, y: 2 };

expect(() => handler(event)).toThrow(); // ReferenceError: alert is not defined (on Node.js)

const injectedHandler = handler.inject({ print: text => text });

expect(injectedHandler(event)).toBe(`type: ${event.type}, x: ${event.x}, y: ${event.y}`); // pass

Comparison with no DI

add.ts

export const add = (a: number, b: number) => a + b;

noDI.ts

import { add } from "./add";

export const noDIFn = (a: number, b: number, c: number) => add(a, b) * c;

index.ts

import { depend } from "velona";
import { add } from "./add";

export const basicFn = depend({ add }, ({ add }, a: number, b: number, c: number) => add(a, b) * c);

sample.ts

import { basicFn } from "./";
import { noDIFn } from "./noDI";

console.log(basicFn(2, 3, 4)); // 20
console.log(noDIFn(2, 3, 4)); // 20

index.spec.ts

import { basicFn } from "./";
import { noDIFn } from "./noDI";

const injectedFn = basicFn.inject({ add: (a, b) => a * b });

expect(injectedFn(2, 3, 4)).toBe(2 * 3 * 4); // pass
expect(basicFn(2, 3, 4)).toBe((2 + 3) * 4); // pass
expect(noDIFn(2, 3, 4)).toBe((2 + 3) * 4); // pass

Usage with fs

index.ts

import fs from "fs";
import { depend } from "velona";

type FS = {
  readFile(path: string, option: "utf8"): Promise<string>;
  writeFile(path: string, text: string, option: "utf8"): Promise<void>;
};

export const basicFn = depend(
  fs.promises as FS, // downcast for injection
  async (dependencies, path: string, text: string) => {
    await dependencies.writeFile(path, text, "utf8");
    return dependencies.readFile(path, "utf8");
  }
);

sample.ts

import { basicFn } from "./";

const text = await basicFn("sample.txt", "Hello world!"); // create sample.txt
console.log(text); // 'Hello world!'

index.spec.ts

import { basicFn } from "./";

const data: Record<string, string> = {};
const injectedFn = basicFn.inject({
  readFile: path => Promise.resolve(data[path]),
  writeFile: (path, text) => {
    data[path] = text;
    return Promise.resolve();
  },
});

const text = "Hello world!";
await expect(injectedFn("test.txt", text)).resolves.toBe(text);

Usage with prisma

tasks.ts

import { depend } from "velona";
import { PrismaClient } from "@prisma/client";

type Task = {
  id: number;
  label: string;
  done: boolean;
};

const prisma = new PrismaClient();

export const getTasks = depend(
  { prisma: prisma as { task: { findMany(): Promise<Task[]> } } }, // inject prisma
  ({ prisma }) => prisma.task.findMany() // prisma is injected object
);

tasks.spec.ts

import { getTasks } from "$/service/tasks";

const injectedGetTasks = getTasks.inject({
  prisma: {
    task: {
      findMany: () =>
        Promise.resolve([
          { id: 0, label: "task1", done: false },
          { id: 1, label: "task2", done: false },
          { id: 2, label: "task3", done: true },
          { id: 3, label: "task4", done: true },
          { id: 4, label: "task5", done: false },
        ]),
    },
  },
});

await expect(injectedGetTasks()).resolves.toHaveLength(5);

Integration test

add.ts

export const add = (a: number, b: number) => a + b;

grandchild.ts

import { depend } from "velona";
import { add } from "./add";

export const grandchild = depend({ add }, ({ add }, a: number, b: number) => add(a, b));

child.ts

import { depend } from "velona";
import { grandchild } from "./grandchild";

export const child = depend(
  { grandchild },
  ({ grandchild }, a: number, b: number, c: number) => grandchild(a, b) * c
);

parentFn.ts

import { depend } from "velona";
import { child } from "./child";

export const parentFn = depend(
  { child, print: (data: number) => alert(data) },
  ({ child, print }, a: number, b: number, c: number) => print(child(a, b, c))
);

index.ts

import { parentFn } from "./parentFn";

parentFn(2, 3, 4); // alert(20)

parentFn.spec.ts

import { parentFn } from "./parentFn";

const injectedFn = parentFn.inject(parentDeps => ({
  child: parentDeps.child.inject(childDeps => ({
    grandchild: clildDeps.grandchild.inject({
      add: (a, b) => a * b,
    }),
  })),
  print: data => data,
}));

expect(injectedFn(2, 3, 4)).toBe(2 * 3 * 4); // pass

License

Velona is licensed under a MIT License.

Keywords

typescript

FAQs

Package last updated on 05 Aug 2023

Did you know?

Socket

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.

Install

Related posts