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

@universal-packages/namespaced-decorators

v1.3.3

Published

Easily track and decide which and how decorators will transform your clases

Downloads

11,166

Readme

Namespaced Decorators

npm version Testing codecov

Easily track and decide which and how decorators will transform your classes. Decorators are still in stage: 3, so they are experimental either in Typescript and Babel.

Install

npm install @universal-packages/namespaced-decorators

Decorators

The base decorators are meant to be used to register decorations in a certain namespace, with a single decoration object to be passed to whoever is going to finally decorate the class depending on what is in that decoration object.

You shouldn't use these base decorators directly in your classes, instead you create a new decorator function that takes your custom arguments to be collected into a decoration object.

All decorators take a namespace as first argument to be grouped accordingly, and a decoration object with a required __type property useful to know what to do with the decorated element.

  • ClassDecorator Registers a class decoration
  • AccessorDecorator Registers an accessor decoration
  • MethodDecorator Registers a method decoration
  • ArgumentDecorator Registers a method's argument decoration
  • PropertyDecorator Registers a property decoration, it also takes a third argument, a DescriptorGenerator which is a function that returns a descriptor to describe the property, useful to make properties read only.

Example usage

import { ClassDecorator, PropertyDecorator, AccessorDecorator, MethodDecorator, ArgumentDecorator } from '@universal-packages/namespaced-decorators'

function Controller(path) {
  return ClassDecorator('web', { __type: 'controller', path })
}

function RequestBody(parser) {
  return PropertyDecorator('web', { __type: 'request-body', parser }, () => {
    return { configurable: false }
  })
}

function Globals() {
  return AccessorDecorator('web', { __type: 'globals' })
}

function Endpoint(verb) {
  return MethodDecorator('web', { __type: 'endpoint', verb })
}

function Param(key) {
  return ArgumentDecorator('web', { __type: 'param', key })
}

@Controller('/')
export default class ApplicationController {
  @RequestBody('json')
  body

  @Globals()
  get globals(): string {
    return this.setGlobals
  }

  @Endpoint('get')
  async root(@Param('id') id) {
    this.setGlobals = (user: { name: 'David' })
  }
}

Global methods

getNamespace(namespace: string, location: string, [conventionPrefix: string])
getNamespace(namespace: string, sharedModules: ModuleRegistry[], [conventionPrefix: string])

Get the namespaced decorators registry as a useful structured decorations object. It can load a directory and import modules to trigger decorations, get class directory location and share imported modules that may have errors.

Optionally instead of providing a location to load you can pass an array of already loaded modules, this way the registry can be filled with the class directory location.

In order to get the location of a decorated class all imported modules should have that class as a default export.

import { loadModules } from '@universal-packages/module-loader'
import { getNamespace } from '@universal-packages/namespaced-decorators'

const namespaceRegistry = getNamespace('web', './src', 'controller')

// You can pass already loaded modules
const modules = loadModules('./lib')
const namespaceRegistry = getNamespace('web', modules)

NamespaceRegistry

The namespace registry is structured as follow:

  • name String The name of the namespace
  • classes ClassRegistry[] An array of all classes decorated in order of activation. The class registry is structured as follow:
    • name String The name of the class
    • decorations Decoration[] All the decorations are being applied to the class in order of activation.
    • location String If a loading location object is provided when getting a namespace this property will be populated with the class src file path.
    • target ClassType The actual reference to the decorated class.
    • accessors AccessorRegistry[] An array of all the decorated accessors in this class. The Accessor Registry is structured as follow:
      • propertyKey String The accessor name
      • decorations Decoration[] All the decorations being applied to the accessor in order of activation.
    • methods MethodRegistry[] An array of all the decorated methods in this class. The Method Registry is structured as follow:
      • propertyKey String The accessor name
      • decorations Decoration[] All the decorations being applied to the method in order of activation.
      • arguments ArgumentRegistry[] An array of all the decorated arguments in this method. The Argument Registry is structured as follow:
        • index number The index of the method argument from left to right.
        • decorations Decoration[] All the decorations being applied to the argument in order of activation.
    • properties PropertyRegistry[] An array of all the decorated properties in this class. The Property Registry is structured as follow:
      • propertyKey String The accessor name
      • decorations Decoration[] All the decorations being applied to the property in order of activation.
  • importedModules ModuleRegistry[] All modules imported when loading namespace, useful to know if any module may have an error.

How does it look?

const namespace = {
  name: 'web',
  classes: [
    {
      name: 'ApplicationController',
      decorations: [{ __type: 'controller', path: '/' }],
      location: '/Users/david/project/src/Application.controller.ts',
      target: ApplicationController,
      accessors: [
        {
          decorations: [{ __type: 'globals' }],
          propertyKey: 'globals'
        }
      ],
      methods: [
        {
          propertyKey: 'root',
          decorations: [{ __type: 'endpoint', verb: 'get' }],
          arguments: [
            {
              index: 0,
              decorations: [{ __type: 'param', key: 'id' }]
            }
          ]
        }
      ],
      properties: [
        {
          propertyKey: 'body',
          decorations: [{ __type: 'request-body', parser: 'json' }]
        }
      ]
    }
  ],
  importedModules: [
    {
      export: [ApplicationController],
      location: '/Users/david/project/src/Application.controller.ts',
      error: null
    },
    {
      export: null,
      location: '/Users/david/project/src/Users.controller.ts',
      error: Error('Unexpected error')
    }
  ]
}

Typescript

This library is developed in TypeScript and shipped fully typed.

Contributing

The development of this library happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving this library.

License

MIT licensed.