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

@packageforge/annotated-json

v0.0.2

Published

Create JSON output with comments describing the data. Yes, I know that means it's no longer JSON. I don't care. It's readable.

Downloads

10

Readme

@packageforge/annotated-json

Create JSON output with comments describing the data. Yes, I know that means it's no longer JSON. I don't care. It's readable.

Add the package to your project on the command line:

npm install @packageforge/annotated-json --save

Say you have a object that you wish to convert to JSON, but with annotated comments on the properties and values:

// An object with obtuse property names and values.
const myObject:IMyObject = {
  a : 2,
  c : 0,
  T : true,
  z : 0,
  r : [1,4],
  t : 1610761551415,
  d : {
    s: "value",
    n: 2,
    b: true
  },
  pl : {
    r: 23,
    b: 2,
    s: 2
  },
  q:[
    {
      s:121,
      q:0
    },
    {
      s:7413,
      q:12
    },
    {
      s:333,
      q:1
    }
  ]
};

First, import the annotate, annotatedJson, and parseJson functions into your code file:

import { annotate, annotatedJson, parseJson } from '@packageforge/annotated-json';

Next, create a function that understands the object to annotate it:

function annotateIMyObject(value?:IMyObject){
  // Return undefined if value is undefined, else annotate it.
  return value && annotate("Type IMyObject",// The is the annotation for the outer object. Always include this argument, even if as an empty string.
  // Then add the properties, in order you want them to appear in the JSON output, with their annotation.
  // Property,  Annotation
      "a",        "Age: "+value.a,
      "c",        "City: "+cities[value.c].name,
      "T",        value.T ? "MY TURN" : "NOT MY TURN",
      "r",        "Rolls: "+value.r.join(','),
      "t",        "Time: "+(new Date(value.t)).toLocaleString(),
      "d",        "Some data",
  // To quickly annotate the sub-properties in d use an array to specify the property names:
      ["d","s"],  "It's a string! "+value.d.s,
      ["d","n"],  "It's a number! "+value.d.n,
      ["d","b"],  "It's a boolean! "+value.d.b,
  // To annotate more complex objects, pass the result from another annotation function:
      "pl",       "Primary Location",      annotateILocation(value.pl),
  // To annotate an array, pass an array of annotations :
      "q",        value.q.map((sq:IStoreQuantity)=> annotateIStoreQuantity(sq)),
  // OPTIONAL PROPERTIES:
  // To annotate an optional simple property, use annotate as if it is there :
      "k",        "Kind: "+value.k,  // Note that since k does not exist, this annotation will not appear, so it does not matter that the string is incorrect.
  // To annotate missing complex objects, make sure the annotation function accepts undefined. The result is immaterial since it will not be displayed.
      "al",       "Alternate Location", annotateILocation(value.al), //Note the three arguments here, the second anotating the property, the third its value.
  // To annotate missing arrays, use the ? notation to return undefined when the property does not exist.
      "aq",       "Alternate Quantities", value.aq?.map((sq:IStoreQuantity)=> annotateIStoreQuantity(sq))
  );
}

function annotateILocation(value?:ILocation){
  // Return undefined if value is undefined, else annotate it.
  return value && annotate("",  // Always a value, even if empty!
    "r","Row: "+value.r,
    "b","Bay: "+value.b,
    "s","Shelf: "+value.s
  );
}
function annotateIStoreQuantity(entry?:IStoreQuantity){
  // Return undefined if entry is undefined, else annotate it.
  return entry && annotate( getStoreDescription(entry.s),  // Always a value, even if empty!
    "q","Quantity in stock: "+entry.q,
    "s","Store #: "+entry.s
  );
}

To create annotated JSON, first call the annotate function you created with the object:

const annotation=annotateMyObject(myObject);

Then call the annotatedJson function, passing the object, the annotation, and the indention size:

const output=annotatedJson(myObject,annotation,2);

Now output is a string that looks like so:

{ // Type IMyObject
  "a": 2,             // Age: 2
  "c": 0,             // City: London
  "T": true,          // MY TURN
  "r": [              // Rolls: 1,4
    1,
    4
  ],
  "t": 1610761551415, // Time: 1/15/2021, 7:45:51 PM
  "d": {              // Some data
    "s": "value", // It's a string! value
    "n": 2,       // It's a number! 2
    "b": true     // It's a boolean! true
  },
  "pl": {             // Primary Location
    "r": 23, // Row: 23
    "b": 2,  // Bay: 2
    "s": 2   // Shelf: 2
  },
  "q": [
    {  // 249 Ellis St., Electra TX 75602 737-555-9860
      "q": 12,  // Quantity in stock: 12
      "s": 7413 // Store #: 7413
    },
    {  // 81 Wood St., Rome TX 75895 786-555-6785
      "q": 1,  // Quantity in stock: 1
      "s": 333 // Store #: 333
    },
    {  // 344 Greenwood St., Paris TX 75761 788-555-3451
      "q": 0,  // Quantity in stock: 0
      "s": 121 // Store #: 121
    }
  ],
  "z": 0
}

The annotated JSON can be parsed back to an object using the parseJson method:

const copyOfMyObject=parseJson(output);

The parseJson function uses code poached from https://github.com/json5/json5 and we are greatfull for their work. Hopefully they will allow regular expressions and dates.