@statlertronik/collection-json-utils

Helper Library for collection-json Hypermedia Format

Usage no npm install needed!

<script type="module">
  import statlertronikCollectionJsonUtils from 'https://cdn.skypack.dev/@statlertronik/collection-json-utils';
</script>

README

@statlertronik/collection-json-utils

Helper utility to generate data for 'Collection+JSON - Hypermedia Type'

How to use it

to install:

npm install @statlertronik/collection-json-utils

in code (typescript):

/*--------------------------------------------------------------------*/
/* Creating 'Collection+JSON' response object with collection data    */
/* and with references to 'queries' & 'template' objects.             */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ICollectionJSON, 
    buildCJResponse,
    addCJLink,
    IItem,
    addCJItem,
    addItemData,
    addItemLink
    } from '@statlertronik/collection-json-utils';

// create 'Collection+JSON' response object and initialize its 'version' and "href" properties
const cj: ICollectionJSON = buildCJResponse("1.0", "http://example.com/api/groups");

// add items to 'links' property array of 'Collection+JSON' response
addCJLink(cj, "http://example.com/api/groups/?queries" /*hr*/, "queries" /*rel*/);
addCJLink(cj, "http://example.com/api/groups/?template" /*hr*/, "template" /*rel*/);

// add items to 'items' property array of 'Collection+JSON' response
{
    const itm: IItem = addCJItem(cj, "http://example.com/api/groups/1"): 

    addItemData(itm, "name" /*name*/, "Writers" /*value*/, "Name" /*prompt*/);
    addItemData(itm, "active" /*name*/, "false" /*value*/, "Active" /*prompt*/);

    addItemLink(itm, "http://example.com/api/images/13" /*hr*/, "avatar" /*rel*/, "Avatar" /*prompt*/, "image" /*render*/);        
}

{
    const itm: IItem = addCJItem(cj, "http://example.com/api/groups/2"): 

    addItemData(itm, "name" /*name*/, "Others" /*value*/, "Name" /*prompt*/);
    addItemData(itm, "active" /*name*/, "true" /*value*/, "Active" /*prompt*/);

    addItemLink(itm, "http://example.com/api/images/24" /*hr*/, "avatar" /*rel*/, "Avatar" /*prompt*/, "image" /*render*/);    
}

// now convert it to JSON string and send it to client with HTTP 'content-type' set to 'CJ_MEDIA_TYPE'
...
/*--------------------------------------------------------------------*/
/* Creating 'Collection+JSON' response object with collection data,   */
/* 'queries' and 'template'.                                          */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ICollectionJSON, 
    buildCJResponse,
    addCJLink,
    IItem,
    addCJItem,
    addItemData,
    IQuery,
    addCJQuery,
    addQueryData,
    addCJTemplateData
    } from '@statlertronik/collection-json-utils';

// create 'Collection+JSON' response object and initialize its 'version' and "href" properties
const cj: ICollectionJSON = buildCJResponse("1.0", "http://example.com/api/groups");

// add items to 'links' property array of 'Collection+JSON' response
addCJLink(cj, "http://example.com/api/groups/page/?offset=10&length=5" /*hr*/, "next" /*rel*/);
addCJLink(cj, "http://example.com/api/groups/page/?offset=0&length=5" /*hr*/, "prev" /*rel*/);
addCJLink(cj, "http://example.com/api/groups/page/?offset=0&length=5" /*hr*/, "first" /*rel*/);
addCJLink(cj, "http://example.com/api/groups/page/?offset=95&length=5" /*hr*/, "last" /*rel*/);

// add items to 'items' property array of 'Collection+JSON' response
{
    const itm: IItem = addCJItem(cj, "http://example.com/api/groups/1"): 

    addItemData(itm, "name" /*name*/, "Writers" /*value*/, "Name" /*prompt*/);
    addItemData(itm, "active" /*name*/, "false" /*value*/, "Active" /*prompt*/);

    addItemLink(itm, "http://example.com/api/images/13" /*hr*/, "avatar" /*rel*/, "Avatar" /*prompt*/, "image" /*render*/);        
}

{
    const itm: IItem = addCJItem(cj, "http://example.com/api/groups/2"): 

    addItemData(itm, "name" /*name*/, "Others" /*value*/, "Name" /*prompt*/);
    addItemData(itm, "active" /*name*/, "true" /*value*/, "Active" /*prompt*/);

    addItemLink(itm, "http://example.com/api/images/24" /*hr*/, "avatar" /*rel*/, "Avatar" /*prompt*/, "image" /*render*/);    
}

// add items to 'queries' property array of 'Collection+JSON' response
{
    const qry: IQuery = addCJQuery(cj, "http://example.com/api/groups/search" /*href*/, "search" /*rel*/, "Search" /*prompt*/);

    addQueryData(qry, "search" /*name*/, "" /*value*/);
}

// add template data to 'template' propery 'data' array
addCJTemplateData(cj, "name" /*name*/, "Name" /*prompt*/);
addCJTemplateData(cj, "active" /*name*/, "Active" /*prompt*/);

// now convert it to JSON string and send it to client with HTTP 'content-type' set to 'CJ_MEDIA_TYPE'
...
/*--------------------------------------------------------------------*/
/* Creating 'Collection+JSON' response object with error              */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ICollectionJSON, 
    buildCJResponse,
    setCJError,
    } from '@statlertronik/collection-json-utils';

// create 'Collection+JSON' response object and initialize its 'version' and "href" properties
const cj: ICollectionJSON = buildCJResponse("1.0" /*ver*/, "http://example.com/api/groups" /*hr*/);

// add error object
setCJError(cj, "Server Error" /*title*/, "E7720" /*code*/, "Some unexpected event occured" /*message*/);

// now convert it to JSON string and send it to client with HTTP 'content-type' set to 'CJ_MEDIA_TYPE'
...
/*--------------------------------------------------------------------*/
/* Converting collection-JSON response object to array of             */
/* IDataRowObjWithRef objects corresponding to items.                 */
/* Client does it when it receives response from server.              */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ICollectionJSON, 
    IDataRowObjWithRef,
    cjConvertItems2ArrayOfObjects
    } from '@statlertronik/collection-json-utils';

// receive and convert JSON string to Collection+JSON response object
const cj: ICollectionJSON = ...;

const a: IDataRowObjWithRef[] = cjConvertItems2ArrayOfObjects(cj)

...
/*--------------------------------------------------------------------*/
/* Creating 'Collection+JSON' write object                            */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ITemplateResponse, 
    buildTemplateResponse,
    addTemplateRespData
    } from '@statlertronik/collection-json-utils';

// create 'Collection+JSON' write object
const templateResp: ITemplateResponse = buildTemplateResponse();

// add write object data
addTemplateRespData(templateResp, "name" /*name*/, "Pilots" /*value*/);
addTemplateRespData(templateResp, "active" /*name*/, "true" /*value*/);

// now convert it to JSON string and send it to server with HTTP 'content-type' set to 'CJ_MEDIA_TYPE'
...
/*--------------------------------------------------------------------*/
/* Creating 'Collection+JSON' write object from JavaScript plain      */
/* object.                                                            */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ITemplateResponse, 
    ICJPlainObject,
    cjConvertObject2TemplateResponse
    } from '@statlertronik/collection-json-utils';

// JavaScript plain object containing data for ITemplateResponse object
const o: ICJPlainObject = {
    name: "Citizens",
    active: false,
    size: 100 
}

// create 'Collection+JSON' write object
const templateResp: ITemplateResponse = cjConvertObject2TemplateResponse(o, ["size"] /*ignore*/);

// now convert it to JSON string and send it to server with HTTP 'content-type' set to 'CJ_MEDIA_TYPE'
...
/*--------------------------------------------------------------------*/
/* Converting 'Collection+JSON' ITemplate object to IColumnsInfo      */
/* object. It happens when server receives write object or client     */
/* receives collection object with template.                          */
/*--------------------------------------------------------------------*/
import { 
    CJ_MEDIA_TYPE,
    ITemplate,
    cjExtractColumnsValuesFromTemplate
    } from '@statlertronik/collection-json-utils';

// receives ITemplate object
templ: ITemplate = ...

try {
    const columns: IColumnsInfo = cjExtractColumnsValuesFromTemplate(templ, ["active"] /*extra_column_names*/);

    ...
}
catch(e) {
    ...
}

API

Basic

// string representing this hypermedia type used as value of HTTP 'content-type' header
const CJ_MEDIA_TYPE;
interface IData {
    name: STRING;
    value?: VALUE;
    prompt?: STRING;
}
interface ILink {
    rel: STRING;
    href: STRING;
    name?: STRING;
    render?: RENDER_TYPE;
    prompt?: STRING;
}
interface IItem {
    href?: URI;
    data?: IData[];
    links?: ILink[];
}
interface IQuery {
    href: URI;
    rel: STRING;
    prompt?: STRING;
    name?: STRING;
    data?: IData[];
}
interface ITemplate {
    data?: IData[];
}
interface ICJError {
    title?: STRING;
    code?: STRING;
    message?: STRING;
}
interface ICollection {
    version?: STRING;
    href?: URI;
    links?: ILink[];
    items?: IItem[];
    queries?: IQuery[];
    template?: ITemplate;
    error?: ICJError;
}
interface ICollectionJSON {
    collection: ICollection;
}
interface ITemplateResponse {
    template: ITemplate;
}

buildCJResponse(ver: STRING, hr: URI): ICollectionJSON

Function creates Collection-JSON root object containing version and href.

Parameters Name | Meaning -------|------- ver | version hr | href to the resource

addCJLink(cj: ICollectionJSON, hr: URI, rel: STRING, name?: STRING, prompt?: STRING, render?: RENDER_TYPE): void

Function adds single 'ILink' object to Collection-JSON root object

Parameters Name | Meaning -------|------- cj | Collection-JSON root object returned by buildCJResponse(...) hr | href of the resource rel | type of 'href' name | name of the link prompt | prompt string render | interpretation of reference, either 'image' or 'link' (default = 'link')

addCJItem(cj: ICollectionJSON, href?: URI): IItem

Function adds 'IItem' object to Collection-JSON root object

Parameters

Name Meaning
cj Collection-JSON root object returned by buildCJResponse(...)
href reference to the resource

addItemData(itm: IItem, name: STRING, value?: VALUE, prompt?: STRING): void

Function adds 'IData' object to 'IItem' object

Parameters

Name Meaning
itm 'IItem' object returned by addCJItem(...)
name name of column
value value of column
prompt prompt string

addItemLink(itm: IItem, hr: URI, rel: STRING, name?: STRING, prompt?: STRING, render?: RENDER_TYPE): void

Function adds 'ILink' object to 'IItem' object

Parameters

Name Meaning
itm 'IItem' object returned by addCJItem(...)
hr href
rel type of href
name name of the link
prompt prompt string
render interpretation of reference, either 'image' or 'link' (default = 'link')

addCJQuery(cj: ICollectionJSON, href: URI, rel: STRING, prompt?: STRING): IQuery

Function adds 'IQuery' object to Collection-JSON root object

Parameters

Name Meaning
cj Collection-JSON root object returned by buildCJResponse(...)
href reference to the resource
rel type of href
prompt prompt string

addQueryData(qry: IQuery, name: STRING, value: VALUE, prompt?: STRING): void

Function adds 'IData' object to 'IQuery' object

Parameters

Name Meaning
qry 'IQuery' object returned by addCJQuery(...)
name name of column
value value of column
prompt promppt string

addCJTemplateData(cj: ICollectionJSON, name: STRING, prompt?: STRING): void

Function adds data to 'ITemplate' object of Collection-JSON root object. It creates 'template' & 'template.data' if any of them is missing.

Parameters

Name Meaning
cj Collection-JSON root object returned by buildCJResponse(...)
name name of the template
prompt prompt string

setCJError(cj: ICollectionJSON, title?: STRING, code?: STRING, message?: STRING): void

Function sets 'ICJError' object for Collection-JSON root object.

Parameters

Name Meaning
cj Collection-JSON root object
title description
code error code
message error text

buildTemplateResponse(): ITemplateResponse

Function creates Collection-JSON ITemplateResponse object

addTemplateRespData(templateResp: TemplateResponse, name: STRING, value?: VALUE, prompt?: STRING): void

Function adds data to 'ITemplate' object of TemplateResponse object. It creates 'template.data' if missing.

Parameters

Name Meaning
template - ITemplate object returned by addTemplateRespData()
name name of the template
value value
prompt prompt string

Advanced

interface IDataRowObj {
    [index: string]: any;
}
interface IDataRowObjWithRef {
    href?: string;
    data: IDataRowObj;
}

cjConvertItems2ArrayOfObjects(cj: cjlib.ICollectionJSON): IDataRowObjWithRef[]

Function creates array of IDataRowObjWithRef objects containing collection items.

Parameters

Name Meaning
cj collection-JSON response object if type ICollectionJSON
interface IColumnsInfo {
    column_names: string[];
    column_values: cjlib.VALUE[];
    extra_column_names?: string[];
    extra_column_values?: cjlib.VALUE[];
}

cjExtractColumnsValuesFromTemplate(templ: cjlib.ITemplate, extra_column_names?: string[]): IColumnsInfo | never

Function creates an object containing arrays of column names/values from 'ITemplate' and returns it. It can also separately extract selected columns and place them in extra column names/value instead of in arrays of column names/values. It throws exception if templ.data is undefined or empty.

Parameters

Name Meaning
templ template object
extra_column_names array of extra column names
interface ICJPlainObject {
    [prop: string]: cjlib.VALUE;
}

cjConvertObject2TemplateResponse(o: ICJPlainObject, ignore?: string[]): cjlib.ITemplateResponse

Function creates 'ITemplateResponse' object populated from plain object.

Parameters

Name Meaning
o plain object
ignore array of names of columns to ignore