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

windy-moon

v4.3.0

Published

DSL for CCNQ4 validation functions

Downloads

1

Readme

A DSL for CCNQ4 validation functions

Main DSL

Usage: main -> @unauthorized 'Not admin' unless @is_admin()

deepEqual = require './deepEqual'
stateChange = require './stateChange'

main = (f) ->
  (doc,oldDoc,userCtx,secObj) ->

Error reporting

    forbidden = (reason) -> throw forbidden: reason
    unauthorized = (reason) -> throw unauthorized: reason

Field presence

    has = (field) -> field of doc
    had = (field) -> field of oldDoc

    required = (field) ->
      return if has field
      forbidden "Field `#{field}` is required."

    unchanged = (field) ->
      return if deepEqual oldDoc[field], doc[field]
      forbidden "Field `#{field}` was modified."

Field validation

validators is an Object which maps fields to validation functions.

    validate_fields = (validators) ->
      for own field, validator of validators
        value = doc[field]
        unless validator value, doc
          forbidden "Field `#{field}` has invalid value `#{JSON.stringify value}`."

Changes validations

    restrict_adding_fields = (allowed = []) ->
      for own k of doc when k not in allowed
        unless had k
          forbidden "Field `#{k}` was added."

    restrict_removing_fields = (allowed = []) ->
      for own k of oldDoc when k not in allowed
        unless has k
          forbidden "Field `#{k}` was removed."

    restrict_modifying_fields = (allowed = []) ->
      for own k of doc when k isnt '_revisions' and k not in allowed
        unchanged k

Document type

    is_design = doc._id?[0] is '_'

validators is a list of validation functions (using the same model as the CouchDB validation functions).

    validate = (validators) =>
      validators.forEach (validator) =>
        validator.call this, doc, oldDoc, userCtx, secObj
      return

CCNQ4 conventions for document types and keys

    $ = doc._id?.match /^(\w+):(.+)$/
    type = $?[1]
    key = $?[2]

    validate_type = ->

      unless type? and key?
        forbidden '`_id` must be <type>:<key>'

      unless doc.type is type
        forbidden 'Missing or invalid `type` field.'

      unless doc[type] is key
        forbidden "Field `#{type}` must contain `#{key}`."

      switch type
        when 'number'
          if '@' in key
            'local-number'
          else
            'global-number'
        else
          type

User

    {db,name,roles} = userCtx

    is_logged_in = name?
    enforce_logged_in = ->
      unless is_logged_in
        unauthorized 'Not logged in.'

The updated_by field in the document is a charming-circle convention.

    enforce_updated_by = ->
      required 'updated_by'
      unless doc.updated_by is name
        forbidden "Field `updated_by` must contain `#{name}`."

Roles

    may = (role) -> role in roles
    is_admin = -> may '_admin'

Database security

    {admins,members} = secObj

    is_owner = members?.names? and name in members.names

    enforce_ownership = ->
      unless is_owner
        unauthorized 'Not owner.'

State changes

    event = stateChange oldDoc, doc

    forbid_deletion = ->
      if doc._deleted
        forbidden "You may not delete `#{type}` documents."

    forbid_creation = ->
      if not oldDoc? or oldDoc._deleted
        forbidden "You may not create `#{type}` documents."

Document-level access

This uses the convention that a user is authorized to access/modify a document iff that document ID is in the user's roles.

    might = ->
      return false if not doc._id?
      return true if may doc._id
      if m = doc._id.match /^(?:number|endpoint):\d+@(\S+)$/
        domain = m[1]
        return true if may "number_domain:#{domain}"
      return false

    enforce_might = ->
      unless might()
        forbidden 'Not permitted to modify this record.'

Context

    ctx = {

Parameters

      doc
      oldDoc
      userCtx
      secObj

      id: doc._id
      rev: doc._rev

Error reporting

      forbidden
      unauthorized

Field presence

      has
      had
      required
      unchanged

Field validation

      validate_fields
      restrict_adding_fields
      restrict_removing_fields
      restrict_modifying_fields

Document type

      is_design
      validate

      type
      key
      validate_type

User

      db

      name
      is_logged_in
      enforce_logged_in
      enforce_updated_by

Roles

      roles
      may
      is: may
      is_admin

Database security

      admins
      admins_names: admins?.names
      admins_roles: admins?.roles

      members
      members_names: members?.names
      members_roles: members?.roles

      is_owner
      enforce_ownership

State changes

      event
      forbid_deletion
      forbid_creation

Document-level access

      might
      enforce_might

    }

    f.call ctx, ctx

module.exports = {main}