Skip to content

Commit

Permalink
feat(types): add type definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
pgoldrbx committed Feb 22, 2020
1 parent c4977b5 commit 15cbc7e
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 5 deletions.
77 changes: 77 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
export interface JsonMLAttributes {
[key: string]: any // @TODO - can this be anything but a string? it technically SHOULD be,
// but I'm not sure if we want to be that strict. maybe it should be primitives at least?
// or maybe we just leave it alone?
}

export type JsonMLChildNode = string | JsonMLNode;

export type JsonMLChildren = Array<JsonMLChildNode>;

export interface JsonMLNode extends Array<string | JsonMLAttributes | JsonMLChildNode> {
0: string;
}

export namespace utils {
export function isFragment(jml: JsonMLNode): boolean;

export function getTagName(jml: JsonMLNode): string;

export function isElement(value: any): boolean;

export function isAttributes(value: any): boolean;

export function hasAttributes(jml: JsonMLNode): boolean;

export function getAttributes(jml: JsonMLNode, addIfMissing?: boolean): JsonMLAttributes;

export function addAttributes(jml: JsonMLNode, attr: JsonMLAttributes): undefined;

export function getAttribute(jml: JsonMLNode, key: string): any;

export function setAttribute(jml: JsonMLNode, key: string, value: any): undefined;

export function appendChild(jml: JsonMLNode, child: JsonMLChildNode): boolean;

export function getChildren(jml: JsonMLNode): JsonMLChildren;
}


// Initial, basic type definition in lieu of adding external packages
type DOMNode = {
[key: string]: any,
nodeType: number
};


export namespace dom {
export type ElementFilterFunction = (jml: JsonMLNode, elem: DOMNode) => JsonMLNode | null;

export function fromHTML(elem: DOMNode, filter?: ElementFilterFunction): JsonMLNode | null;

export function fromHTMLText(html: string, filter?: ElementFilterFunction): JsonMLNode | null;
}


export namespace html {
export class Markup {
value: string
toString(): string
}

export type HtmlElementFilter = (elem: DOMNode) => DOMNode

export type ErrorHandler = (err: Error, jml: JsonMLNode, filter?: HtmlElementFilter) => any

export function raw(value: string): Markup;

export function isRaw(value: any): boolean;

export let onerror: null | ErrorHandler

export function patch(elem: DOMNode, jml: JsonMLNode, filter?: HtmlElementFilter): DOMNode

export function toHTML(jml: string | JsonMLNode, filter?: HtmlElementFilter): DOMNode

export function toHTMLText(jml: string | JsonMLNode, filter?: HtmlElementFilter): string
}
9 changes: 7 additions & 2 deletions package-lock.json

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

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"version": "1.0.2",
"description": "JsonML-related tools.",
"main": "index.js",
"types": "index.d.ts",
"files": [
"*.md",
"dist",
"index.js"
"index.js",
"index.d.ts"
],
"scripts": {
"lint": "eslint ./lib/utils.js ./test",
Expand All @@ -15,7 +17,9 @@
"build": "babel lib --out-dir dist",
"prepublishOnly": "babel lib --out-dir dist",
"pretest": "npm run lint",
"test": "nyc mocha"
"test": "nyc mocha",
"test:types": "tsc --noEmit test/types.test.ts",
"posttest": "npm run test:types"
},
"keywords": [
"jsonml",
Expand Down Expand Up @@ -55,6 +59,7 @@
"eslint": "^6.0.0",
"eslint-config-egg": "^8.0.0",
"mocha": "^7.0.0",
"nyc": "^15.0.0"
"nyc": "^15.0.0",
"typescript": "^3.8.2"
}
}
36 changes: 36 additions & 0 deletions test/types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
JsonMLAttributes,
JsonMLChildren,
utils,
} from '..';

// Utils
const isFragYes: boolean = utils.isFragment(['', 'hi']);
const isFragNo: boolean = utils.isFragment(['div', 'hi']);

const paraTag: string = utils.getTagName(['p', 'some text']);
const fragTag: string = utils.getTagName(['', 'some fragment text']);

const isElemYes: boolean = utils.isElement(['img', { href: 'https://example.com/foo.jpg' }]);
const isElemNo: boolean = utils.isElement({});

const isAttrsYes: boolean = utils.isAttributes({ foo: 'bar' });
const isAttrsNo: boolean = utils.isAttributes(['foo']);

const hasAttrsYes: boolean = utils.hasAttributes(['p', { foo: 'bar' }]);
const hasAttrsNo: boolean = utils.hasAttributes(['p']);

const gotAttrs: JsonMLAttributes = utils.getAttributes(['p', { foo: 'bar' }]);
const gotAddedAttrs: JsonMLAttributes = utils.getAttributes(['p'], true);
const gotEmptyAttrs: JsonMLAttributes = utils.getAttributes(['p'], false);

const addAttributesRetval: undefined = utils.addAttributes(['p'], { foo: 'bar', a: 1 });

const gotAttr: string = utils.getAttribute(['p', { foo: 'bar' }], 'foo');
const gotNoAttr: undefined = utils.getAttribute(['p', { foo: 'bar' }], 'this-does-not-exist');

const setAttributeRetval: undefined = utils.setAttribute(['p'], 'foo', 'bar');

const childWasAppended: boolean = utils.appendChild(['p', { foo: 'bar'}], ['strong', 'Hello World']);

const gotChildren: JsonMLChildren = utils.getChildren(['div', ['p', 'one'], ['p', 'two']]);
7 changes: 7 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"strict": true,
"target": "es6"
}
}

0 comments on commit 15cbc7e

Please sign in to comment.