Skip to content
This repository has been archived by the owner on May 3, 2023. It is now read-only.

Commit

Permalink
release/0.6.0 (#26)
Browse files Browse the repository at this point in the history
* Add support for custom key header mapping
  • Loading branch information
littlespex committed Nov 8, 2021
1 parent 062d982 commit 8750882
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cmcd.js",
"version": "0.5.1",
"version": "0.6.0",
"description": "CMCD (Common Media Client Data) library with Typescript definitions",
"main": "dist/cmcd.min.js",
"types": "dist/types/index.d.ts",
Expand Down Expand Up @@ -37,7 +37,7 @@
"terser": "5.9.0",
"ts-jest": "27.0.7",
"tslib": "2.3.1",
"typedoc": "0.22.7",
"typedoc": "^0.22.8",
"typescript": "4.4.4"
},
"jest": {
Expand Down
3 changes: 2 additions & 1 deletion src/Cmcd.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CmcdCustomKey } from './CmcdCustomKey';
import { CmcdObjectType } from './CmcdObjectType';
import { CmcdStreamingFormat } from './CmcdStreamingFormat';
import { CmcdStreamType } from './CmcdStreamType';
Expand All @@ -12,7 +13,7 @@ export interface Cmcd {
* Custom key names may be used, but they MUST carry a hyphenated prefix to ensure that there will not be a namespace collision
* with future revisions to this specification. Clients SHOULD use a reverse-DNS syntax when defining their own prefix.
*/
[index: `${string}-${string}`]: CmcdValue;
[index: CmcdCustomKey]: CmcdValue;

/////////////////
// CMCD Object //
Expand Down
1 change: 1 addition & 0 deletions src/CmcdCustomKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type CmcdCustomKey = `${string}-${string}`;
22 changes: 15 additions & 7 deletions src/CmcdUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Cmcd } from './Cmcd';
import { CmcdCustomKey } from './CmcdCustomKey';
import { CmcdHeader } from './CmcdHeader';
import { CmcdKey } from './CmcdKey';
import { CmcdValue } from './CmcdValue';
Expand Down Expand Up @@ -31,8 +32,11 @@ export function serialize(obj: Cmcd) {
return processData<string>(obj, (value, key) => {
const type = typeof value;

if (type === 'string' && key !== 'ot' && key !== 'sf' && key !== 'st') {
return `${key}="${value.replace(/"/g, '\\"')}"`;
if (key === 'ot' || key === 'sf' || key === 'st') {
return `${key}=${value}`;
}
if (type === 'string') {
return `${key}=${JSON.stringify(value)}`;
}
else if (type === 'boolean') {
return key;
Expand Down Expand Up @@ -89,7 +93,7 @@ function processData<T>(obj: Cmcd, map: Mapper<T>): T[] {
/**
* Convert a CMCD data object to request headers
*/
export function toHeaders(cmcd: Cmcd) {
export function toHeaders(cmcd: Cmcd, customHeaderMap: Record<CmcdCustomKey, CmcdHeader> = {}) {
const headers: Record<string, string> = {};

if (!cmcd) {
Expand All @@ -98,15 +102,19 @@ export function toHeaders(cmcd: Cmcd) {

const entries = Object.entries(cmcd) as [CmcdKey, CmcdValue][];
const headerGroups: Record<string, any>[] = [{}, {}, {}, {}];
const headerMap: Record<CmcdKey, number> = {
const headerMap: Record<CmcdKey, CmcdHeader> = {
br: 0, d: 0, ot: 0, tb: 0,
bl: 1, dl: 1, mtp: 1, nor: 1, nrr: 1, su: 1,
cid: 2, pr: 2, sf: 2, sid: 2, st: 2, v: 2,
bs: 3, rtp: 3,
};

entries.forEach(([key, value]) => {
const index = (headerMap[key] != null) ? headerMap[key] : 1;
let index = headerMap[key];
if (index == null) {
// @ts-ignore
index = customHeaderMap[key] != null ? customHeaderMap[key] : 1;
}
headerGroups[index][key] = value;
});

Expand Down Expand Up @@ -155,6 +163,6 @@ export function appendToUrl(url: string, cmcd: Cmcd) {
/**
* Append CMCD query args to a header object.
*/
export function appendToHeaders(headers: Record<string, string>, cmcd: Cmcd) {
return Object.assign(headers, toHeaders(cmcd));
export function appendToHeaders(headers: Record<string, string>, cmcd: Cmcd, customHeaderMap?: Record<CmcdCustomKey, CmcdHeader>) {
return Object.assign(headers, toHeaders(cmcd, customHeaderMap));
}
24 changes: 17 additions & 7 deletions tests/CmcdUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import crypto from 'crypto';
import { Cmcd } from '../src/Cmcd';
import { CmcdHeader } from '../src/CmcdHeader';
import { CmcdObjectType } from '../src/CmcdObjectType';
import { appendToHeaders, appendToUrl, serialize, toHeaders, toJson, toQuery, uuid } from '../src/CmcdUtils';

// @ts-ignore
Expand All @@ -17,6 +19,7 @@ const data: Cmcd = {
br: 200,
v: 1,
pr: 1,
ot: CmcdObjectType.MANIFEST,
// custom data
['com.example-hello']: 'world',
['com.example-testing']: 1234,
Expand All @@ -26,6 +29,13 @@ const data: Cmcd = {
['com.example-quote']: '"Quote"',
};

const headerMap = {
['com.example-hello']: CmcdHeader.Object,
['com.example-token']: CmcdHeader.Request,
['com.example-testing']: CmcdHeader.Session,
['com.example-exists']: CmcdHeader.Status,
};

describe('UUID generation', () => {
const regex = /^[A-F\d]{8}-[A-F\d]{4}-4[A-F\d]{3}-[89AB][A-F\d]{3}-[A-F\d]{12}$/i;
const id = uuid();
Expand All @@ -51,17 +61,17 @@ describe('Query serialization', () => {
});

test('returns encoded query string', () => {
expect(toQuery(data,)).toBe('CMCD=br%3D200%2Cbs%2Ccid%3D%22content-id%22%2Ccom.example-exists%2Ccom.example-hello%3D%22world%22%2Ccom.example-quote%3D%22%5C%22Quote%5C%22%22%2Ccom.example-testing%3D1234%2Ccom.example-token%3Ds%2Cd%3D325%2Cmtp%3D10000%2Cnor%3D%22..%252Ftesting%252F3.m4v%22%2Cnrr%3D%220-99%22%2Csid%3D%22session-id%22');
expect(toQuery(data,)).toBe('CMCD=br%3D200%2Cbs%2Ccid%3D%22content-id%22%2Ccom.example-exists%2Ccom.example-hello%3D%22world%22%2Ccom.example-quote%3D%22%5C%22Quote%5C%22%22%2Ccom.example-testing%3D1234%2Ccom.example-token%3Ds%2Cd%3D325%2Cmtp%3D10000%2Cnor%3D%22..%252Ftesting%252F3.m4v%22%2Cnrr%3D%220-99%22%2Cot%3Dm%2Csid%3D%22session-id%22');
});
});

describe('Header serialization', () => {
test('all shards', () => {
expect(toHeaders(data)).toEqual({
'CMCD-Object': 'br=200,d=325',
'CMCD-Request': 'com.example-exists,com.example-hello="world",com.example-quote="\\"Quote\\"",com.example-testing=1234,com.example-token=s,mtp=10000,nor="..%2Ftesting%2F3.m4v",nrr="0-99"',
'CMCD-Session': 'cid="content-id",sid="session-id"',
'CMCD-Status': 'bs',
expect(toHeaders(data, headerMap)).toEqual({
'CMCD-Object': 'br=200,com.example-hello="world",d=325,ot=m',
'CMCD-Request': 'com.example-quote="\\"Quote\\"",com.example-token=s,mtp=10000,nor="..%2Ftesting%2F3.m4v",nrr="0-99"',
'CMCD-Session': 'cid="content-id",com.example-testing=1234,sid="session-id"',
'CMCD-Status': 'bs,com.example-exists',
});
});

Expand All @@ -78,7 +88,7 @@ describe('Header serialization', () => {

describe('JSON serialization', () => {
test('json', () => {
expect(toJson(data)).toEqual('{"br":200,"bs":true,"cid":"content-id","com.example-exists":true,"com.example-hello":"world","com.example-quote":"\\"Quote\\"","com.example-testing":1234,"com.example-token":"s","d":325,"mtp":10000,"nor":"..%2Ftesting%2F3.m4v","nrr":"0-99","sid":"session-id"}');
expect(toJson(data)).toEqual('{"br":200,"bs":true,"cid":"content-id","com.example-exists":true,"com.example-hello":"world","com.example-quote":"\\"Quote\\"","com.example-testing":1234,"com.example-token":"s","d":325,"mtp":10000,"nor":"..%2Ftesting%2F3.m4v","nrr":"0-99","ot":"m","sid":"session-id"}');
});

test('empty', () => {
Expand Down

0 comments on commit 8750882

Please sign in to comment.