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

raml-typesystem-collections

v0.0.24

Published

``` The fundamental concept in any RESTful API is the resource. Resources can be grouped into collections. Each collection is homogeneous so that it contains only one type of resource, and unordered. Resources can also exist outside any collection.

Downloads

7

Readme

RAML TypeSystem Collections

The fundamental concept in any RESTful API is the resource. 
Resources can be grouped into collections. Each collection is homogeneous so 
that it contains only one type of resource, and unordered.
Resources can also exist outside any collection. 
In this case, we refer to these resources as singleton resources. 
Collections are themselves resources as well.

(This is taken from Very nice guide to RESTFull API design)

One most important property of collections is an ability of the client to iterate over them. Typical APIs split content of the collection into pages, where each page can be obtained by performing an HTTP request to particular url and contains collection members representations.

We use term collection protocol for the mechanism which should be used to traverse through the collection.

Project goals

Goal of this project is to provide a typescript node module which hides collection protocol implementation details from the developer and allows to traverse collections with a uniform interface.

We base our work on top of RPC Views which allows us to abstract from a particular RPC transport which is used to expose an API.

Collection kinds:

We are separating following kinds of the collections:

  • Random access page based - collections which allows you to jump to the page by it's number
  • Random access offset based - collections which allows you to jump to the element by it's number in the some ordering.
  • Link based collections - collections where you can only navigate to the neighbours of the current page.

Some collections, provide information about number of the the total members in the collection and some are not.

Collection parameters

Sometimes collections have parameters, we split parameters in the following semantic categories

  • Filter control
  • Ordering control
  • Representation control
  • Unknown

Specifying collections:

We assume that any callable function without side effects (they are formed from GET methods of API) and which returns an array or is annotated with a paging annotation is a collection.

 paging:
  properties:
   offset?: 
     type: string  
     description: name of the parameter containing offset from the start of the collection
   page?: 
     type: string
     description: name of the parameter containing number of the page
   limit?: 
      type: string
      description: name of the parameter containing number of elements which you would like to get in the one page
   result?: 
     type: string
     description: name of the response body property containing elements of the collection
   total?: 
     type: string  
     description: name of the response body property containing total number of  elements in the collection(with respect to current collection filters)       
   zeroBased?: 
     type: boolean
     description: you can pass false here if element numbering in your collection starts from 1

or alternatively you may use this annotations:

   offset?: 
     type: nil  
     description: annotate parameter with this annotation to mark that it contains  offset from the start of the collection
   page?: 
     type: nil
     description: annotate parameter with this annotation to mark that it contains number of the page
   limit?: 
      type: nil
      description: annotate parameter with this annotation to mark that it contains number of elements in the page
   result?: 
     type: nil
     description: annotate property of the result with this annotation to mark that it contains elements of the collection
   total?: 
     type: nil  
     description: annotate property of the response with this annotation to mark that it contains total number of  elements in the collection(with respect to current collection filters)       

If collection does not contains paging related annotations, we assume that collection is paged by Link headers in the same way as it is implemented in the Github API

Specifying Filters

You may annotate method parameters with the filter annotation, which allows you to mark that parameter is used for filtering. This annotation has a following syntax:

filter: FilterMapping |  nil

where FilterMapping is defined as following raml type:

  FilterMapping:
    properties:
      property?: 
         type: string 
         description: name of the property which is used to filter collection elements
      valueMappings?:
            properties:
               //: 
                 type: string  
                 description: allows to remap values of parameter to values of the filter
      noFilterValue?: 
        type: string 
        description: value which is used when filter is not set
      filterOp?: 
         description: operator which is used to perform filtration
         default: eq
         enum: [ eq, lt, gt, like, ge, le ]

you also may mark that parameter is used to sort elements of collection by using ordering annotation which we define as

ordering: OrderingMappings | nil

where OrderingMappings is defined as following raml type

  OrderingMapping:
    properties:
      property: string
      descending?: boolean
  OrderingMappings:
    properties:
      //: 
        type: string | OrderingMapping
        description: maps parameter value to the name of the property which is used to sort the collection

if parameter is used to choose sort direction you may annotate it with `sortDirection' annotation

sortDirection:  nil

Example:

this example shows how github issues endpoint might be annotated to get understanding about how to page and filter it.

 /issues:
    get:
      (core.paging): { page: page}
      queryParameters:
        milestone:
          (core.filter):
             property: milestone.number
        state:
            enum: [open, closed, all]
            default: open
            displayName: Issue State
            (core.filter):
               noFilterValue: all
        assignee:
           (core.filter):
              property: assignees.login
        creator:
           (core.filter):
              property: user.login
        mentioned:
          (core.reference): User.login
          (core.filter):
        direction:
          (core.sortDirection): 
          enum: [asc,desc]
          default: desc
        labels:
          type: string
          (core.filter):
             property: labels.name
        since:
           type: datetime
           (core.filter):
             property: updated_at
             op: ge
        sort:
          enum: [comments, created, updated]
          default: created
          displayName: Order by
          (core.ordering):
            created: created_at
            updated: updated_at
            comments: comments
        page: integer
      responses:
        200:
          body:
              type: Issue[]

Complete RAML library with annotation types describing semantics of collections may be found here.

Usage:


import modules=require("callables-rpc-views");
import collection=require("raml-typesystem-collections");
let module = main.module(api);
collections.toCollection(module.functions(0)).forEach(x=>console.log(x.title());