npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@prostojs/mate

v0.3.2

Published

MATE is TS Metadata Organizer

Downloads

1,871

Readme

prostojs/mate

This small library is TS Metadata Organizer based on reflect-metadata. "MA-TE" is for "ME-TA" in reverse order.

It allows you to define, manipulate, and read metadata at different levels, including classes, properties, methods, and parameters.

The primary purpose of Mate is to streamline the use of metadata, making it simpler and more efficient to handle.

Installation

You can install Mate from the npm registry.

npm install @prostojs/mate

Usage

After installation, you can start using Mate to define and handle metadata in your TypeScript project. Below is an example that showcases different levels of metadata usage.

import { TMateParamMeta } from '@prostojs/mate';
import { Mate } from '@prostojs/mate';

// Define your metadata interfaces
interface TClassMeta {
    name: string;
    model: string;
    fromParam: string;
    manufacturer: string;
    data: string[];
    inherit?: bolean;
}

interface TPropMeta<TParamMeta> {
    description: string;
    params: (TMateParamMeta & TParamMeta)[];
    inherit?: bolean
}

interface TParamMeta {
    required: boolean;
}

const mate = new Mate<TClassMeta, TPropMeta<TParamMeta>>('robot-meta', {
    readReturnType: true,
    readType: true,
    collectPropKeys: true,
    inherit(classMeta, targetMeta, level, prop) {
        return !!targetMeta?.inherit || !!classMeta?.inherit;
    },
});

// Annotate your class
@mate.decorate('name', 'NXT') 
@mate.decorate('model', 'EV3') 
@mate.decorate('manufacturer', 'LEGO')
@mate.decorate('data', 'NXT-0001', true)  
class Robot {
    @mate.decorate('description', 'Robotic arm for grabbing objects')
    arm: string;

    @mate.decorate('description', 'Sensors to detect objects') 
    sensors(
        @mate.decorateClass('fromParam', 'hoised value')  
        @mate.decorate('required', true) 
        input: string
    ): string {
        return 'Activated sensors with input: ' + input;
    }
}

// Read the metadata
let classMeta = mate.read(Robot);
console.log(classMeta);
// Expected Output:
// {
//     name: 'NXT',
//     model: 'EV3',
//     fromParam: 'hoised value',
//     manufacturer: 'LEGO',
//     data: ['NXT-0001'],  // Array type metadata
//     properties: ['arm', 'sensors'],
//     type: Function, // Type of Robot
//     returnType: undefined // Only for methods
// }

// read the property metadata
let armMeta = mate.read(Robot, 'arm');
console.log(armMeta);
// Expected Output:
// {
//     description: 'Robotic arm for grabbing objects',
//     params: [],
//     type: Function, // Type of 'arm'
//     returnType: undefined // Only for methods
// }

// read the method metadata
let sensorsMeta = mate.read(Robot, 'sensors');
console.log(sensorsMeta);
// Expected Output:
// {
//     description: 'Sensors to detect objects',
//     params: [{ type: String, required: true }],
//     type: Function, // Type of 'sensors'
//     returnType: String // Return type of 'sensors'
// }

Metadata Inheritance

It's possible to enable metadata inheritance and set some rules on whether it should be inherited from parent classes or not

Metadata Inheritance ON

Simply use true on inherit key to enable metadata inheritance

const mate = new Mate<MyMeta>('my-metadata-key', {
    inherit: true, // this will enable metadata inheritance for all the classes
})

Conditional Metadata Inheritance

This example illustrates how to set a callback with logic to decide whether to inherit or not

const mate = new Mate<MyMeta>('my-metadata-key', {
    inherit(classMeta, prop, methodMeta) {
        if (prop) {
            // if it is a method metadata
            // we require a key `inherit` to be true for inheritance
            return !!methodMeta?.inherit || !!(classMeta?.inherit && !methodMeta)
        }
        // otherwise (in case of class metadata) we require a key `inherit`
        // to be true for inheritance on class metadata
        return !!classMeta?.inherit
    }
})

API Reference

  1. Mate<TClassMeta, TPropMeta>: The main Mate class. It provides methods to decorate and read metadata.

  2. decorate(key, value?, isArray?, level?): A method for adding metadata to classes, properties, methods, and parameters.

  3. decorateClass(key, value?, isArray?): A method for hoisting metadata from methods or parameters to the class level.

  4. read(target, prop?, paramIndex?): A method for reading metadata.

Use of reflect-metadata

It is recomended to include reflect-metadata dependency to rely on the original implementation. Although it's still possible to use @prostojs/mate with no dependency on reflect-metadata because it already includes its own limited implementation of reflect-metadata which ships only the features used by @prostojs/mate such as:

  • getOwnMetadata(key, target, prop?)

  • defineMetadata(key, data, target, prop?)

  • metadata(key, data)