node-html-parser
Advanced tools
Comparing version 1.1.11 to 1.1.12
@@ -58,2 +58,5 @@ export declare enum NodeType { | ||
export declare class HTMLElement extends Node { | ||
tagName: string; | ||
private rawAttrs; | ||
parentNode: Node; | ||
private _attrs; | ||
@@ -63,7 +66,4 @@ private _rawAttrs; | ||
classNames: string[]; | ||
tagName: string; | ||
rawAttrs: string; | ||
/** | ||
* Node Type declaration. | ||
* @type {Number} | ||
*/ | ||
@@ -73,10 +73,20 @@ nodeType: NodeType; | ||
* Creates an instance of HTMLElement. | ||
* @param {string} name tagName | ||
* @param {KeyAttributes} keyAttrs id and class attribute | ||
* @param {string} [rawAttrs] attributes in string | ||
* @param keyAttrs id and class attribute | ||
* @param [rawAttrs] attributes in string | ||
* | ||
* @memberof HTMLElement | ||
*/ | ||
constructor(name: string, keyAttrs: KeyAttributes, rawAttrs?: string); | ||
constructor(tagName: string, keyAttrs: KeyAttributes, rawAttrs?: string, parentNode?: Node); | ||
/** | ||
* Remove Child element from childNodes array | ||
* @param {HTMLElement} node node to remove | ||
*/ | ||
removeChild(node: Node): void; | ||
/** | ||
* Exchanges given child with new child | ||
* @param {HTMLElement} oldNode node to exchange | ||
* @param {HTMLElement} newNode new node | ||
*/ | ||
exchangeChild(oldNode: Node, newNode: Node): void; | ||
/** | ||
* Get escpaed (as-it) text value of current node and its children. | ||
@@ -122,3 +132,3 @@ * @return {string} text content | ||
*/ | ||
querySelectorAll(selector: string | Matcher): Node[]; | ||
querySelectorAll(selector: string | Matcher): HTMLElement[]; | ||
/** | ||
@@ -130,3 +140,3 @@ * Query CSS Selector to find matching node. | ||
*/ | ||
querySelector(selector: string | Matcher): Node; | ||
querySelector(selector: string | Matcher): HTMLElement; | ||
/** | ||
@@ -137,3 +147,3 @@ * Append a child node to childNodes | ||
*/ | ||
appendChild(node: Node): Node; | ||
appendChild<T extends Node = Node>(node: T): T; | ||
/** | ||
@@ -207,3 +217,8 @@ * Get first child node | ||
export declare function parse(data: string, options?: { | ||
lowerCaseTagName: boolean; | ||
}): HTMLElement; | ||
lowerCaseTagName?: boolean; | ||
noFix?: boolean; | ||
}): (TextNode & { | ||
valid: boolean; | ||
}) | (HTMLElement & { | ||
valid: boolean; | ||
}); |
@@ -78,19 +78,19 @@ "use strict"; | ||
* Creates an instance of HTMLElement. | ||
* @param {string} name tagName | ||
* @param {KeyAttributes} keyAttrs id and class attribute | ||
* @param {string} [rawAttrs] attributes in string | ||
* @param keyAttrs id and class attribute | ||
* @param [rawAttrs] attributes in string | ||
* | ||
* @memberof HTMLElement | ||
*/ | ||
constructor(name, keyAttrs, rawAttrs) { | ||
constructor(tagName, keyAttrs, rawAttrs = '', parentNode = null) { | ||
super(); | ||
this.tagName = tagName; | ||
this.rawAttrs = rawAttrs; | ||
this.parentNode = parentNode; | ||
this.classNames = []; | ||
/** | ||
* Node Type declaration. | ||
* @type {Number} | ||
*/ | ||
this.nodeType = NodeType.ELEMENT_NODE; | ||
this.tagName = name; | ||
this.rawAttrs = rawAttrs || ''; | ||
// this.parentNode = null; | ||
this.parentNode = parentNode || null; | ||
this.childNodes = []; | ||
@@ -105,2 +105,26 @@ if (keyAttrs.id) { | ||
/** | ||
* Remove Child element from childNodes array | ||
* @param {HTMLElement} node node to remove | ||
*/ | ||
removeChild(node) { | ||
this.childNodes = this.childNodes.filter((child) => { | ||
return (child !== node); | ||
}); | ||
} | ||
/** | ||
* Exchanges given child with new child | ||
* @param {HTMLElement} oldNode node to exchange | ||
* @param {HTMLElement} newNode new node | ||
*/ | ||
exchangeChild(oldNode, newNode) { | ||
let idx = -1; | ||
for (let i = 0; i < this.childNodes.length; i++) { | ||
if (this.childNodes[i] === oldNode) { | ||
idx = i; | ||
break; | ||
} | ||
} | ||
this.childNodes[idx] = newNode; | ||
} | ||
/** | ||
* Get escpaed (as-it) text value of current node and its children. | ||
@@ -211,19 +235,16 @@ * @return {string} text content | ||
trimRight(pattern) { | ||
function dfs(node) { | ||
for (let i = 0; i < node.childNodes.length; i++) { | ||
const childNode = node.childNodes[i]; | ||
if (childNode.nodeType === NodeType.ELEMENT_NODE) { | ||
dfs(childNode); | ||
for (let i = 0; i < this.childNodes.length; i++) { | ||
const childNode = this.childNodes[i]; | ||
if (childNode.nodeType === NodeType.ELEMENT_NODE) { | ||
childNode.trimRight(pattern); | ||
} | ||
else { | ||
const index = childNode.rawText.search(pattern); | ||
if (index > -1) { | ||
childNode.rawText = childNode.rawText.substr(0, index); | ||
// trim all following nodes. | ||
this.childNodes.length = i + 1; | ||
} | ||
else { | ||
const index = childNode.rawText.search(pattern); | ||
if (index > -1) { | ||
childNode.rawText = childNode.rawText.substr(0, index); | ||
// trim all following nodes. | ||
node.childNodes.length = i + 1; | ||
} | ||
} | ||
} | ||
} | ||
dfs(this); | ||
return this; | ||
@@ -385,2 +406,5 @@ } | ||
this.childNodes.push(node); | ||
if (node instanceof HTMLElement) { | ||
node.parentNode = this; | ||
} | ||
return node; | ||
@@ -444,3 +468,3 @@ } | ||
*/ | ||
let functionCache = { | ||
const functionCache = { | ||
"f145": function (el, tagName, classes, attr_key, value) { | ||
@@ -454,3 +478,3 @@ "use strict"; | ||
return false; | ||
for (var cls = classes, i = 0; i < cls.length; i++) | ||
for (let cls = classes, i = 0; i < cls.length; i++) | ||
if (el.classNames.indexOf(cls[i]) === -1) | ||
@@ -466,3 +490,3 @@ return false; | ||
value = value || ""; | ||
for (var cls = classes, i = 0; i < cls.length; i++) | ||
for (let cls = classes, i = 0; i < cls.length; i++) | ||
if (el.classNames.indexOf(cls[i]) === -1) | ||
@@ -506,4 +530,4 @@ return false; | ||
value = value || ""; | ||
var attrs = el.attributes; | ||
for (var key in attrs) { | ||
let attrs = el.attributes; | ||
for (let key in attrs) { | ||
const val = attrs[key]; | ||
@@ -515,3 +539,3 @@ if (key == attr_key && val == value) { | ||
return false; | ||
// for (var cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}} | ||
// for (let cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}} | ||
// return true; | ||
@@ -525,4 +549,4 @@ }, | ||
value = value || ""; | ||
var attrs = el.attributes; | ||
for (var key in attrs) { | ||
let attrs = el.attributes; | ||
for (let key in attrs) { | ||
const val = attrs[key]; | ||
@@ -542,4 +566,4 @@ if (key == attr_key && val == value) { | ||
value = value || ""; | ||
var attrs = el.attributes; | ||
for (var key in attrs) { | ||
let attrs = el.attributes; | ||
for (let key in attrs) { | ||
const val = attrs[key]; | ||
@@ -560,3 +584,3 @@ if (key == attr_key && val == value) { | ||
return false; | ||
for (var cls = classes, i = 0; i < cls.length; i++) | ||
for (let cls = classes, i = 0; i < cls.length; i++) | ||
if (el.classNames.indexOf(cls[i]) === -1) | ||
@@ -627,3 +651,3 @@ return false; | ||
value = matcher[7] || matcher[8]; | ||
source += `var attrs = el.attributes;for (var key in attrs){const val = attrs[key]; if (key == "${attr_key}" && val == "${value}"){return true;}} return false;`; //2 | ||
source += `let attrs = el.attributes;for (let key in attrs){const val = attrs[key]; if (key == "${attr_key}" && val == "${value}"){return true;}} return false;`; //2 | ||
function_name += '2'; | ||
@@ -637,3 +661,3 @@ } | ||
if (classes.length > 0) { | ||
source += 'for (var cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;'; //4 | ||
source += 'for (let cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;'; //4 | ||
function_name += '4'; | ||
@@ -699,9 +723,11 @@ } | ||
const kSelfClosingElements = { | ||
meta: true, | ||
area: true, | ||
base: true, | ||
br: true, | ||
col: true, | ||
hr: true, | ||
img: true, | ||
input: true, | ||
link: true, | ||
input: true, | ||
area: true, | ||
br: true, | ||
hr: true | ||
meta: true | ||
}; | ||
@@ -711,4 +737,11 @@ const kElementsClosedByOpening = { | ||
p: { p: true, div: true }, | ||
b: { div: true }, | ||
td: { td: true, th: true }, | ||
th: { td: true, th: true } | ||
th: { td: true, th: true }, | ||
h1: { h1: true }, | ||
h2: { h2: true }, | ||
h3: { h3: true }, | ||
h4: { h4: true }, | ||
h5: { h5: true }, | ||
h6: { h6: true } | ||
}; | ||
@@ -760,6 +793,6 @@ const kElementsClosedByClosing = { | ||
// not </ tags | ||
var attrs = {}; | ||
for (var attMatch; attMatch = kAttributePattern.exec(match[3]);) | ||
let attrs = {}; | ||
for (let attMatch; attMatch = kAttributePattern.exec(match[3]);) { | ||
attrs[attMatch[2]] = attMatch[4] || attMatch[5] || attMatch[6]; | ||
// console.log(attrs); | ||
} | ||
if (!match[4] && kElementsClosedByOpening[currentParent.tagName]) { | ||
@@ -775,4 +808,4 @@ if (kElementsClosedByOpening[currentParent.tagName][match[2]]) { | ||
// a little test to find next </script> or </style> ... | ||
var closeMarkup = '</' + match[2] + '>'; | ||
var index = data.indexOf(closeMarkup, kMarkupPattern.lastIndex); | ||
let closeMarkup = '</' + match[2] + '>'; | ||
let index = data.indexOf(closeMarkup, kMarkupPattern.lastIndex); | ||
if (options[match[2]]) { | ||
@@ -787,4 +820,5 @@ let text; | ||
} | ||
if (text.length > 0) | ||
if (text.length > 0) { | ||
currentParent.appendChild(new TextNode(text)); | ||
} | ||
} | ||
@@ -824,4 +858,44 @@ if (index == -1) { | ||
} | ||
return root; | ||
const valid = !!(stack.length === 1); | ||
if (!options.noFix) { | ||
const response = root; | ||
response.valid = valid; | ||
while (stack.length > 1) { | ||
// Handle each error elements. | ||
const last = stack.pop(); | ||
const oneBefore = arr_back(stack); | ||
if (last.parentNode && last.parentNode.parentNode) { | ||
if (last.parentNode === oneBefore && last.tagName === oneBefore.tagName) { | ||
// Pair error case <h3> <h3> handle : Fixes to <h3> </h3> | ||
oneBefore.removeChild(last); | ||
last.childNodes.forEach((child) => { | ||
oneBefore.parentNode.appendChild(child); | ||
}); | ||
stack.pop(); | ||
} | ||
else { | ||
// Single error <div> <h3> </div> handle: Just removes <h3> | ||
oneBefore.removeChild(last); | ||
last.childNodes.forEach((child) => { | ||
oneBefore.appendChild(child); | ||
}); | ||
} | ||
} | ||
else { | ||
// If it's final element just skip. | ||
} | ||
} | ||
response.childNodes.forEach((node) => { | ||
if (node instanceof HTMLElement) { | ||
node.parentNode = null; | ||
} | ||
}); | ||
return response; | ||
} | ||
else { | ||
const response = new TextNode(data); | ||
response.valid = valid; | ||
return response; | ||
} | ||
} | ||
exports.parse = parse; |
@@ -58,2 +58,5 @@ export declare enum NodeType { | ||
export declare class HTMLElement extends Node { | ||
tagName: string; | ||
private rawAttrs; | ||
parentNode: Node; | ||
private _attrs; | ||
@@ -63,7 +66,4 @@ private _rawAttrs; | ||
classNames: string[]; | ||
tagName: string; | ||
rawAttrs: string; | ||
/** | ||
* Node Type declaration. | ||
* @type {Number} | ||
*/ | ||
@@ -73,10 +73,20 @@ nodeType: NodeType; | ||
* Creates an instance of HTMLElement. | ||
* @param {string} name tagName | ||
* @param {KeyAttributes} keyAttrs id and class attribute | ||
* @param {string} [rawAttrs] attributes in string | ||
* @param keyAttrs id and class attribute | ||
* @param [rawAttrs] attributes in string | ||
* | ||
* @memberof HTMLElement | ||
*/ | ||
constructor(name: string, keyAttrs: KeyAttributes, rawAttrs?: string); | ||
constructor(tagName: string, keyAttrs: KeyAttributes, rawAttrs?: string, parentNode?: Node); | ||
/** | ||
* Remove Child element from childNodes array | ||
* @param {HTMLElement} node node to remove | ||
*/ | ||
removeChild(node: Node): void; | ||
/** | ||
* Exchanges given child with new child | ||
* @param {HTMLElement} oldNode node to exchange | ||
* @param {HTMLElement} newNode new node | ||
*/ | ||
exchangeChild(oldNode: Node, newNode: Node): void; | ||
/** | ||
* Get escpaed (as-it) text value of current node and its children. | ||
@@ -122,3 +132,3 @@ * @return {string} text content | ||
*/ | ||
querySelectorAll(selector: string | Matcher): Node[]; | ||
querySelectorAll(selector: string | Matcher): HTMLElement[]; | ||
/** | ||
@@ -130,3 +140,3 @@ * Query CSS Selector to find matching node. | ||
*/ | ||
querySelector(selector: string | Matcher): Node; | ||
querySelector(selector: string | Matcher): HTMLElement; | ||
/** | ||
@@ -137,3 +147,3 @@ * Append a child node to childNodes | ||
*/ | ||
appendChild(node: Node): Node; | ||
appendChild<T extends Node = Node>(node: T): T; | ||
/** | ||
@@ -207,3 +217,8 @@ * Get first child node | ||
export declare function parse(data: string, options?: { | ||
lowerCaseTagName: boolean; | ||
}): HTMLElement; | ||
lowerCaseTagName?: boolean; | ||
noFix?: boolean; | ||
}): (TextNode & { | ||
valid: boolean; | ||
}) | (HTMLElement & { | ||
valid: boolean; | ||
}); |
@@ -113,19 +113,21 @@ var __extends = (this && this.__extends) || (function () { | ||
* Creates an instance of HTMLElement. | ||
* @param {string} name tagName | ||
* @param {KeyAttributes} keyAttrs id and class attribute | ||
* @param {string} [rawAttrs] attributes in string | ||
* @param keyAttrs id and class attribute | ||
* @param [rawAttrs] attributes in string | ||
* | ||
* @memberof HTMLElement | ||
*/ | ||
function HTMLElement(name, keyAttrs, rawAttrs) { | ||
function HTMLElement(tagName, keyAttrs, rawAttrs, parentNode) { | ||
if (rawAttrs === void 0) { rawAttrs = ''; } | ||
if (parentNode === void 0) { parentNode = null; } | ||
var _this = _super.call(this) || this; | ||
_this.tagName = tagName; | ||
_this.rawAttrs = rawAttrs; | ||
_this.parentNode = parentNode; | ||
_this.classNames = []; | ||
/** | ||
* Node Type declaration. | ||
* @type {Number} | ||
*/ | ||
_this.nodeType = NodeType.ELEMENT_NODE; | ||
_this.tagName = name; | ||
_this.rawAttrs = rawAttrs || ''; | ||
// this.parentNode = null; | ||
_this.parentNode = parentNode || null; | ||
_this.childNodes = []; | ||
@@ -140,2 +142,26 @@ if (keyAttrs.id) { | ||
} | ||
/** | ||
* Remove Child element from childNodes array | ||
* @param {HTMLElement} node node to remove | ||
*/ | ||
HTMLElement.prototype.removeChild = function (node) { | ||
this.childNodes = this.childNodes.filter(function (child) { | ||
return (child !== node); | ||
}); | ||
}; | ||
/** | ||
* Exchanges given child with new child | ||
* @param {HTMLElement} oldNode node to exchange | ||
* @param {HTMLElement} newNode new node | ||
*/ | ||
HTMLElement.prototype.exchangeChild = function (oldNode, newNode) { | ||
var idx = -1; | ||
for (var i = 0; i < this.childNodes.length; i++) { | ||
if (this.childNodes[i] === oldNode) { | ||
idx = i; | ||
break; | ||
} | ||
} | ||
this.childNodes[idx] = newNode; | ||
}; | ||
Object.defineProperty(HTMLElement.prototype, "rawText", { | ||
@@ -267,19 +293,16 @@ /** | ||
HTMLElement.prototype.trimRight = function (pattern) { | ||
function dfs(node) { | ||
for (var i = 0; i < node.childNodes.length; i++) { | ||
var childNode = node.childNodes[i]; | ||
if (childNode.nodeType === NodeType.ELEMENT_NODE) { | ||
dfs(childNode); | ||
for (var i = 0; i < this.childNodes.length; i++) { | ||
var childNode = this.childNodes[i]; | ||
if (childNode.nodeType === NodeType.ELEMENT_NODE) { | ||
childNode.trimRight(pattern); | ||
} | ||
else { | ||
var index = childNode.rawText.search(pattern); | ||
if (index > -1) { | ||
childNode.rawText = childNode.rawText.substr(0, index); | ||
// trim all following nodes. | ||
this.childNodes.length = i + 1; | ||
} | ||
else { | ||
var index = childNode.rawText.search(pattern); | ||
if (index > -1) { | ||
childNode.rawText = childNode.rawText.substr(0, index); | ||
// trim all following nodes. | ||
node.childNodes.length = i + 1; | ||
} | ||
} | ||
} | ||
} | ||
dfs(this); | ||
return this; | ||
@@ -445,2 +468,5 @@ }; | ||
this.childNodes.push(node); | ||
if (node instanceof HTMLElement) { | ||
node.parentNode = this; | ||
} | ||
return node; | ||
@@ -588,3 +614,3 @@ }; | ||
return false; | ||
// for (var cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}} | ||
// for (let cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}} | ||
// return true; | ||
@@ -697,3 +723,3 @@ }, | ||
value = matcher_1[7] || matcher_1[8]; | ||
source += "var attrs = el.attributes;for (var key in attrs){const val = attrs[key]; if (key == \"" + attr_key + "\" && val == \"" + value + "\"){return true;}} return false;"; //2 | ||
source += "let attrs = el.attributes;for (let key in attrs){const val = attrs[key]; if (key == \"" + attr_key + "\" && val == \"" + value + "\"){return true;}} return false;"; //2 | ||
function_name += '2'; | ||
@@ -707,3 +733,3 @@ } | ||
if (classes.length > 0) { | ||
source += 'for (var cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;'; //4 | ||
source += 'for (let cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;'; //4 | ||
function_name += '4'; | ||
@@ -774,9 +800,11 @@ } | ||
var kSelfClosingElements = { | ||
meta: true, | ||
area: true, | ||
base: true, | ||
br: true, | ||
col: true, | ||
hr: true, | ||
img: true, | ||
input: true, | ||
link: true, | ||
input: true, | ||
area: true, | ||
br: true, | ||
hr: true | ||
meta: true | ||
}; | ||
@@ -786,4 +814,11 @@ var kElementsClosedByOpening = { | ||
p: { p: true, div: true }, | ||
b: { div: true }, | ||
td: { td: true, th: true }, | ||
th: { td: true, th: true } | ||
th: { td: true, th: true }, | ||
h1: { h1: true }, | ||
h2: { h2: true }, | ||
h3: { h3: true }, | ||
h4: { h4: true }, | ||
h5: { h5: true }, | ||
h6: { h6: true } | ||
}; | ||
@@ -836,5 +871,5 @@ var kElementsClosedByClosing = { | ||
var attrs = {}; | ||
for (var attMatch; attMatch = kAttributePattern.exec(match[3]);) | ||
for (var attMatch = void 0; attMatch = kAttributePattern.exec(match[3]);) { | ||
attrs[attMatch[2]] = attMatch[4] || attMatch[5] || attMatch[6]; | ||
// console.log(attrs); | ||
} | ||
if (!match[4] && kElementsClosedByOpening[currentParent.tagName]) { | ||
@@ -861,4 +896,5 @@ if (kElementsClosedByOpening[currentParent.tagName][match[2]]) { | ||
} | ||
if (text.length > 0) | ||
if (text.length > 0) { | ||
currentParent.appendChild(new TextNode(text)); | ||
} | ||
} | ||
@@ -898,5 +934,48 @@ if (index == -1) { | ||
} | ||
return root; | ||
var valid = !!(stack.length === 1); | ||
if (!options.noFix) { | ||
var response = root; | ||
response.valid = valid; | ||
var _loop_1 = function () { | ||
// Handle each error elements. | ||
var last = stack.pop(); | ||
var oneBefore = arr_back(stack); | ||
if (last.parentNode && last.parentNode.parentNode) { | ||
if (last.parentNode === oneBefore && last.tagName === oneBefore.tagName) { | ||
// Pair error case <h3> <h3> handle : Fixes to <h3> </h3> | ||
oneBefore.removeChild(last); | ||
last.childNodes.forEach(function (child) { | ||
oneBefore.parentNode.appendChild(child); | ||
}); | ||
stack.pop(); | ||
} | ||
else { | ||
// Single error <div> <h3> </div> handle: Just removes <h3> | ||
oneBefore.removeChild(last); | ||
last.childNodes.forEach(function (child) { | ||
oneBefore.appendChild(child); | ||
}); | ||
} | ||
} | ||
else { | ||
// If it's final element just skip. | ||
} | ||
}; | ||
while (stack.length > 1) { | ||
_loop_1(); | ||
} | ||
response.childNodes.forEach(function (node) { | ||
if (node instanceof HTMLElement) { | ||
node.parentNode = null; | ||
} | ||
}); | ||
return response; | ||
} | ||
else { | ||
var response = new TextNode(data); | ||
response.valid = valid; | ||
return response; | ||
} | ||
} | ||
exports.parse = parse; | ||
}); |
{ | ||
"name": "node-html-parser", | ||
"version": "1.1.11", | ||
"version": "1.1.12", | ||
"description": "A very fast HTML parser, generating a simplified DOM, with basic element query support.", | ||
@@ -9,5 +9,7 @@ "main": "dist/index.js", | ||
"test": "mocha", | ||
"build": "gulp", | ||
"pretest": "gulp", | ||
"prepare": "gulp" | ||
"clean": "del-cli ./dist/", | ||
"ts:cjs": "tsc -m commonjs", | ||
"ts:umd": "tsc -t es5 -m umd --outDir ./dist/umd/", | ||
"build": "npm run clean && npm run ts:cjs && npm run ts:umd", | ||
"dev": "tsc -w" | ||
}, | ||
@@ -30,6 +32,3 @@ "keywords": [ | ||
"blanket": "latest", | ||
"del": "latest", | ||
"gulp": "latest", | ||
"gulp-sequence": "latest", | ||
"gulp-shell": "latest", | ||
"del-cli": "latest", | ||
"mocha": "latest", | ||
@@ -36,0 +35,0 @@ "should": "latest", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
123891
10
9
2308