arraybuffer-xml-parser
Advanced tools
Comparing version 0.5.0 to 0.5.1
628
lib/index.js
@@ -1,614 +0,18 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var dynamicTyping = require('dynamic-typing'); | ||
const utf8Decoder$1 = new TextDecoder(); | ||
const decoder$1 = { | ||
decode: (array) => { | ||
return utf8Decoder$1.decode(array); | ||
}, | ||
}; | ||
const defaultOptions = { | ||
trimValues: true, | ||
attributeNamePrefix: '$', | ||
attributesNodeName: false, | ||
ignoreAttributes: false, | ||
ignoreNameSpace: false, | ||
allowBooleanAttributes: false, | ||
dynamicTypingAttributeValue: true, | ||
textNodeName: '#text', | ||
dynamicTypingNodeValue: true, | ||
arrayMode: false, | ||
cdataTagName: false, | ||
tagValueProcessor: (value) => { | ||
return decoder$1.decode(value).replace(/\r/g, ''); | ||
}, | ||
attributeValueProcessor: (value) => value, | ||
stopNodes: [], | ||
}; | ||
class XMLNode { | ||
constructor(tagName, parent, value) { | ||
this.tagName = tagName; | ||
this.parent = parent; | ||
this.children = Object.create({}); //child tags | ||
this.attributes = Object.create({}); //attributes map | ||
this.value = value; //text only | ||
this.startIndex = -1; | ||
} | ||
addChild(child) { | ||
if (Array.isArray(this.children[child.tagName])) { | ||
//already presents | ||
this.children[child.tagName].push(child); | ||
} else { | ||
this.children[child.tagName] = [child]; | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
} | ||
} | ||
function arrayIndexOf(array, referenceArray, index = 0) { | ||
let found = 0; | ||
let foundIndex = -1; | ||
for (let i = index; i < array.length && found < referenceArray.length; i++) { | ||
if (array[i] === referenceArray[found]) { | ||
if (!found) { | ||
foundIndex = i; | ||
} | ||
found++; | ||
} else { | ||
if (found > 0) { | ||
let j = 0; | ||
for ( | ||
; | ||
j <= found && array[foundIndex + j] === array[foundIndex + found]; | ||
j++ | ||
); | ||
if (j < found + 1) { | ||
foundIndex = -1; | ||
found = 0; | ||
} else { | ||
foundIndex++; | ||
} | ||
} else { | ||
found = 0; | ||
foundIndex = -1; | ||
} | ||
} | ||
} | ||
if (found !== referenceArray.length) { | ||
foundIndex = -1; | ||
} | ||
return foundIndex; | ||
} | ||
function arrayTrim(array) { | ||
let i = 0; | ||
let j = array.length - 1; | ||
for (; i < array.length && array[i] <= 0x20; i++); | ||
for (; j >= i && array[j] <= 0x20; j--); | ||
if (i === 0 && j === array.length - 1) return array; | ||
return array.subarray(i, j + 1); | ||
} | ||
function closingIndexForOpeningTag(data, i) { | ||
let attrBoundary; | ||
let endIndex = 0; | ||
for (let index = i; index < data.length; index++) { | ||
let byte = data[index]; | ||
if (attrBoundary) { | ||
if (byte === attrBoundary) attrBoundary = 0; //reset | ||
} else if (byte === 0x22 || byte === 0x27) { | ||
attrBoundary = byte; | ||
} else if (byte === 0x3e) { | ||
return { | ||
data: decoder.decode(data.subarray(i, i + endIndex)), | ||
index, | ||
}; | ||
} else if (byte === 0x09) { | ||
byte = 0x20; | ||
} | ||
endIndex++; | ||
} | ||
} | ||
function findClosingIndex(xmlData, str, i, errMsg) { | ||
const closingIndex = arrayIndexOf(xmlData, str, i); | ||
if (closingIndex === -1) { | ||
throw new Error(errMsg); | ||
} else { | ||
return closingIndex + str.length - 1; | ||
} | ||
} | ||
function getAllMatches(string, regex) { | ||
return Array.from(string.matchAll(regex)); | ||
} | ||
function isEmptyObject(obj) { | ||
// fastest implementation: https://jsbench.me/qfkqv692c8/1 | ||
// eslint-disable-next-line no-unreachable-loop | ||
for (const key in obj) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Copy all the properties of a into b. | ||
* @param {object} target | ||
* @param {object} source | ||
*/ | ||
function merge(target, source, arrayMode) { | ||
if (!source) return; | ||
for (const key in source) { | ||
if (arrayMode === 'strict') { | ||
target[key] = [source[key]]; | ||
} else { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
/** | ||
* Check if a tag name should be treated as array | ||
* | ||
* @param tagName the node tagName | ||
* @param arrayMode the array mode option | ||
* @param parentTagName the parent tag name | ||
* @returns {boolean} true if node should be parsed as array | ||
*/ | ||
function isTagNameInArrayMode(tagName, arrayMode, parentTagName) { | ||
if (arrayMode === false) { | ||
return false; | ||
} else if (arrayMode instanceof RegExp) { | ||
return arrayMode.test(tagName); | ||
} else if (typeof arrayMode === 'function') { | ||
return !!arrayMode(tagName, parentTagName); | ||
} | ||
return arrayMode === 'strict'; | ||
} | ||
const newLocal = '([^\\s=]+)\\s*(=\\s*([\'"])(.*?)\\3)?'; | ||
const attrsRegx = new RegExp(newLocal, 'g'); | ||
//Attributes are strings so no point in using arrayBuffers here | ||
function parseAttributesString(string, options) { | ||
if (options.ignoreAttributes) { | ||
return; | ||
} | ||
string = string.replace(/\r?\n/g, ' '); | ||
const matches = getAllMatches(string, attrsRegx); | ||
const attributes = {}; | ||
for (let match of matches) { | ||
const attrName = resolveNameSpace(match[1], options); | ||
if (attrName.length) { | ||
if (match[4] !== undefined) { | ||
if (options.trimValues) { | ||
match[4] = match[4].trim(); | ||
} | ||
match[4] = options.attributeValueProcessor(match[4], attrName); | ||
attributes[attrName] = stringParseValue( | ||
match[4], | ||
options.dynamicTypingAttributeValue, | ||
); | ||
} else if (options.allowBooleanAttributes) { | ||
attributes[attrName] = true; | ||
} | ||
} | ||
} | ||
if (isEmptyObject(attributes)) return; | ||
return attributes; | ||
} | ||
function stringParseValue(value, shouldParse) { | ||
if (shouldParse && typeof value === 'string') { | ||
return dynamicTyping.parseString(value); | ||
} else { | ||
return value === undefined ? '' : value; | ||
} | ||
} | ||
function resolveNameSpace(tagName, options) { | ||
if (options.ignoreNameSpace) { | ||
const tags = tagName.split(':'); | ||
const prefix = tagName.charAt(0) === '/' ? '/' : ''; | ||
if (tags[0] === 'xmlns') { | ||
return ''; | ||
} | ||
if (tags.length === 2) { | ||
tagName = prefix + tags[1]; | ||
} | ||
} | ||
return tagName; | ||
} | ||
const utf8Decoder = new TextDecoder(); | ||
const decoder = { | ||
decode: (array) => { | ||
return utf8Decoder.decode(array); | ||
}, | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
function getTraversable(xmlData, options) { | ||
const traversable = new XMLNode('!xml'); | ||
let currentNode = traversable; | ||
let dataSize = 0; | ||
let dataIndex = 0; | ||
for (let i = 0; i < xmlData.length; i++) { | ||
if (xmlData[i] === 0x3c) { | ||
// < | ||
const xmlData1 = xmlData[i + 1]; | ||
const xmlData2 = xmlData[i + 2]; | ||
if (xmlData1 === 0x2f) { | ||
// </ Closing Tag | ||
const closeIndex = findClosingIndex( | ||
xmlData, | ||
[0x3e], //> | ||
i, | ||
'Closing Tag is not closed.', | ||
); | ||
let tagName = decoder.decode( | ||
arrayTrim(xmlData.subarray(i + 2, closeIndex)), | ||
); | ||
tagName = removeNameSpaceIfNeeded(tagName, options); | ||
if (currentNode) { | ||
const value = options.trimValues | ||
? arrayTrim(xmlData.subarray(dataIndex, dataIndex + dataSize)) | ||
: xmlData.subarray(dataIndex, dataIndex + dataSize); | ||
if (currentNode.value === undefined) { | ||
currentNode.value = value; | ||
} else { | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
} | ||
if ( | ||
options.stopNodes.length && | ||
options.stopNodes.includes(currentNode.tagName) | ||
) { | ||
currentNode.children = []; | ||
if (currentNode.attributes === undefined) { | ||
currentNode.attributes = {}; | ||
} | ||
currentNode.value = xmlData.subarray(currentNode.startIndex + 1, i); | ||
} | ||
currentNode = currentNode.parent; | ||
i = closeIndex; | ||
dataSize = 0; | ||
dataIndex = i + 1; | ||
} else if (xmlData1 === 0x3f) { | ||
// <? PI, processing instruction | ||
i = findClosingIndex(xmlData, [0x3f, 0x3e], i, 'Pi Tag is not closed.'); | ||
} else if ( | ||
//!-- comment | ||
xmlData1 === 0x21 && | ||
xmlData2 === 0x2d && | ||
xmlData[i + 3] === 0x2d | ||
) { | ||
i = findClosingIndex( | ||
xmlData, | ||
[0x2d, 0x2d, 0x3e], //--> | ||
i, | ||
'Comment is not closed.', | ||
); | ||
if (currentNode && dataSize !== 0) { | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
? arrayTrim(xmlData.subarray(dataIndex, dataSize + dataIndex)) | ||
: xmlData.subarray(dataIndex, dataSize + dataIndex), | ||
); | ||
} | ||
} | ||
dataSize = 0; | ||
dataIndex = i + 1; | ||
//!D | ||
} else if (xmlData1 === 0x21 && xmlData2 === 0x44) { | ||
// <!D | ||
const closeIndex = findClosingIndex( | ||
xmlData, | ||
[0x3e], //> | ||
i, | ||
'DOCTYPE is not closed.', | ||
); | ||
const tagExp = xmlData.subarray(i, closeIndex); | ||
if (arrayIndexOf(tagExp, [0x5b]) >= 0) { | ||
i = arrayIndexOf(xmlData, [0x5d, 0x3e], i) + 1; | ||
} else { | ||
i = closeIndex; | ||
} //![ | ||
} else if (xmlData1 === 0x21 && xmlData2 === 0x5b) { | ||
// <![CDATA[some stuff]]> | ||
const closeIndex = | ||
findClosingIndex( | ||
xmlData, | ||
[0x5d, 0x5d, 0x3e], //]]> | ||
i, | ||
'CDATA is not closed.', | ||
) - 2; | ||
const tagExp = xmlData.subarray(i + 9, closeIndex); | ||
//considerations | ||
//1. CDATA will always have parent node | ||
//2. A tag with CDATA is not a leaf node so it's value would be string type. | ||
if (dataSize !== 0) { | ||
const value = options.trimValues | ||
? arrayTrim(xmlData.subarray(dataIndex, dataIndex + dataSize)) | ||
: xmlData.subarray(dataIndex, dataIndex + dataSize); | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
if (options.cdataTagName) { | ||
//add cdata node | ||
const childNode = new XMLNode( | ||
options.cdataTagName, | ||
currentNode, | ||
tagExp, | ||
); | ||
currentNode.addChild(childNode); | ||
//add rest value to parent node | ||
if (tagExp) { | ||
childNode.value = tagExp; | ||
} | ||
} else { | ||
currentNode.value = concat(currentNode.value, tagExp); | ||
} | ||
i = closeIndex + 2; | ||
dataSize = 0; | ||
dataIndex = i + 1; | ||
} else { | ||
//Opening a normal tag | ||
const parsedOpeningTag = closingIndexForOpeningTag(xmlData, i + 1); | ||
let tagData = parsedOpeningTag.data.replace(/\r?\n|\t/g, ' '); | ||
const closeIndex = parsedOpeningTag.index; | ||
const separatorIndex = tagData.indexOf(' '); | ||
let shouldBuildAttributesMap = true; | ||
let tagName = | ||
separatorIndex >= 0 | ||
? tagData.substr(0, separatorIndex).replace(/\s+$/, '') | ||
: tagData; | ||
let tagAttributes = | ||
separatorIndex >= 0 ? tagData.substr(separatorIndex + 1) : ''; | ||
if (options.ignoreNameSpace) { | ||
const colonIndex = tagName.indexOf(':'); | ||
if (colonIndex !== -1) { | ||
tagName = tagName.substr(colonIndex + 1); | ||
shouldBuildAttributesMap = | ||
tagName !== parsedOpeningTag.data.substr(colonIndex + 1); | ||
} | ||
} | ||
//save text to parent node | ||
if (currentNode && dataSize !== 0) { | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
? arrayTrim(xmlData.subarray(dataIndex, dataIndex + dataSize)) | ||
: xmlData.subarray(dataIndex, dataIndex + dataSize), | ||
); | ||
} | ||
} | ||
if (tagData.length > 0 && tagData[tagData.length - 1] === '/') { | ||
//selfClosing tag | ||
if (tagAttributes) { | ||
// <abc def="123"/> | ||
tagAttributes = tagAttributes.substr(0, tagAttributes.length - 1); | ||
} else { | ||
// <abc/> | ||
tagName = tagName.substr(0, tagName.length - 1); | ||
} | ||
const childNode = new XMLNode(tagName, currentNode, ''); | ||
if (tagAttributes) { | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
currentNode.addChild(childNode); | ||
} else { | ||
//opening tag | ||
const childNode = new XMLNode(tagName, currentNode); | ||
if ( | ||
options.stopNodes.length && | ||
options.stopNodes.includes(childNode.tagName) | ||
) { | ||
childNode.startIndex = closeIndex; | ||
} | ||
if (tagAttributes && shouldBuildAttributesMap) { | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
currentNode.addChild(childNode); | ||
currentNode = childNode; | ||
} | ||
i = closeIndex; | ||
dataSize = 0; | ||
dataIndex = i + 1; | ||
} | ||
} else { | ||
dataSize++; | ||
} | ||
} | ||
return traversable; | ||
} | ||
function concat(a, b) { | ||
if (a === undefined) { | ||
a = typeof b === 'string' ? '' : new Uint8Array(0); | ||
} | ||
if (b === undefined) { | ||
b = typeof a === 'string' ? '' : new Uint8Array(0); | ||
} | ||
if (typeof a === 'string' && typeof b === 'string') { | ||
return a + b; | ||
} else if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { | ||
const arrayConcat = new Uint8Array(a.length + b.length); | ||
arrayConcat.set(a); | ||
arrayConcat.set(b, a.length); | ||
return arrayConcat; | ||
} else { | ||
throw new Error( | ||
`Unsuported value type for concatenation: ${typeof a} ${typeof b}`, | ||
); | ||
} | ||
} | ||
function removeNameSpaceIfNeeded(tagName, options) { | ||
if (!options.ignoreNameSpace) return tagName; | ||
const colonIndex = tagName.indexOf(':'); | ||
if (colonIndex !== -1) { | ||
tagName = tagName.substr(colonIndex + 1); | ||
} | ||
} | ||
/** | ||
* | ||
* @param {*} node | ||
* @param {*} options | ||
* @param {*} parentTagName | ||
* @returns | ||
*/ | ||
function traversableToJSON(node, options, parentTagName) { | ||
const { | ||
dynamicTypingNodeValue, | ||
tagValueProcessor, | ||
arrayMode, | ||
tagNameProcessor, | ||
attributeNameProcessor, | ||
} = options; | ||
const result = {}; | ||
if (tagValueProcessor) { | ||
node.value = node.value && tagValueProcessor(node.value, node); | ||
} | ||
if (typeof node.value === 'string' && dynamicTypingNodeValue) { | ||
node.value = dynamicTyping.parseString(node.value); | ||
} | ||
// when no child node or attr is present | ||
if ( | ||
(!node.children || isEmptyObject(node.children)) && | ||
(!node.attributes || isEmptyObject(node.attributes)) | ||
) { | ||
return node.value === undefined ? '' : node.value; | ||
} | ||
// otherwise create a textnode if node has some text | ||
if (node.value !== undefined && node.value.length !== 0) { | ||
const asArray = isTagNameInArrayMode( | ||
node.tagName, | ||
arrayMode, | ||
parentTagName, | ||
); | ||
result[options.textNodeName] = asArray ? [node.value] : node.value; | ||
} | ||
if (node.attributes && !isEmptyObject(node.attributes)) { | ||
let attributes = options.parseAttributesString ? {} : node.attributes; | ||
if (options.attributeNamePrefix) { | ||
// need to rename the attributes | ||
const renamedAttributes = {}; | ||
for (let attributeName in node.attributes) { | ||
const newAttributeName = attributeNameProcessor | ||
? attributeNameProcessor(attributeName) | ||
: attributeName; | ||
renamedAttributes[options.attributeNamePrefix + newAttributeName] = | ||
node.attributes[attributeName]; | ||
} | ||
attributes = renamedAttributes; | ||
} | ||
if (options.attributesNodeName) { | ||
let encapsulatedAttributes = {}; | ||
encapsulatedAttributes[options.attributesNodeName] = attributes; | ||
attributes = encapsulatedAttributes; | ||
} | ||
merge(result, attributes, arrayMode); | ||
} | ||
for (const tagName in node.children) { | ||
const newTagName = tagNameProcessor ? tagNameProcessor(tagName) : tagName; | ||
if (node.children[tagName] && node.children[tagName].length > 1) { | ||
result[tagName] = []; | ||
for (let tag in node.children[tagName]) { | ||
if (Object.prototype.hasOwnProperty.call(node.children[tagName], tag)) { | ||
result[newTagName].push( | ||
traversableToJSON(node.children[tagName][tag], options, tagName), | ||
); | ||
} | ||
} | ||
} else { | ||
const subResult = traversableToJSON( | ||
node.children[tagName][0], | ||
options, | ||
tagName, | ||
); | ||
const asArray = | ||
(arrayMode === true && typeof subResult === 'object') || | ||
isTagNameInArrayMode(tagName, arrayMode, parentTagName); | ||
result[newTagName] = asArray ? [subResult] : subResult; | ||
} | ||
} | ||
return result; | ||
} | ||
/** | ||
* Parse an ArrayBuffer or Uint8Array representing an XML | ||
* @param {string|ArrayBuffer|Uint8Array} xmlData | ||
* @param {object} [options={}] | ||
* @param {string} [options.attributeNamePrefix='$'] | ||
* @param {boolean} [options.attributesNodeName=false] | ||
* @param {string} [options.textNodeName='#text'] | ||
* @param {boolean} [options.trimValues=true] should we remove ascii < 32 | ||
* @param {boolean} [options.ignoreAttributes=false] skip attributes | ||
* @param {boolean} [options.ignoreNameSpace=false] | ||
* @param {boolean} [options.dynamicTypingAttributeValue=true] Parse attribute values that looks like number or boolean | ||
* @param {boolean} [options.allowBooleanAttributes=false] | ||
* @param {boolean} [options.dynamicTypingNodeValue=true] Parse tag values that looks like number or boolean | ||
* @param {boolean} [options.arrayMode=false] | ||
* @param {boolean} [options.cdataTagName=false] | ||
* @param {function} [options.tagValueProcessor=(v, node) => decoder.decode(v)] Tag values can be modified during parsing. By default we decode the tag value (a Uint8Array) using TextDecoder | ||
* @param {function} [options.attributeValueProcessor=(v) => v] Attribute values can be modified during parsing | ||
* @param {function} [options.tagNameProcessor=(v) => v] Callback allowing to rename tag names | ||
* @param {function} [options.attributeNameProcessor=(v) => v] Callback allowing to rename attribute name | ||
* @param {boolean} [options.stopNodes=[]] prevent further parsing | ||
* | ||
* @returns {object} | ||
*/ | ||
function parse(xmlData, options = {}) { | ||
if (typeof xmlData === 'string') { | ||
const encoder = new TextEncoder(); | ||
xmlData = encoder.encode(xmlData); | ||
} | ||
if (!ArrayBuffer.isView(xmlData)) { | ||
xmlData = new Uint8Array(xmlData); | ||
} | ||
options = { ...defaultOptions, ...options }; | ||
const traversable = getTraversable(xmlData, options); | ||
return traversableToJSON(traversable, options); | ||
} | ||
exports.parse = parse; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./parse"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "arraybuffer-xml-parser", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "Parse XML files contained in an array buffer", | ||
"main": "lib/index.js", | ||
"module": "src/index.js", | ||
"main": "./lib/index.js", | ||
"module": "./lib-esm/index.js", | ||
"types": "./lib/index.d.ts", | ||
"files": [ | ||
"src", | ||
"lib", | ||
"src" | ||
"lib-esm" | ||
], | ||
"scripts": { | ||
"build": "cheminfo-build --entry src/index.js --root XMLParser", | ||
"build": "npm run tsc-esm && cheminfo-build --entry lib-esm/index.js --root XMLParser", | ||
"check-types": "tsc --noEmit", | ||
"clean": "rimraf lib lib-esm", | ||
"eslint": "eslint src", | ||
"eslint-fix": "npm run eslint -- --fix", | ||
"prepack": "rollup -c", | ||
"prepack": "npm run tsc", | ||
"prettier": "prettier --check src", | ||
"prettier-write": "prettier --write src", | ||
"test": "npm run test-coverage && npm run eslint && npm run prettier", | ||
"test": "npm run test-coverage && npm run eslint && npm run prettier && npm run check-types", | ||
"test-coverage": "jest --coverage", | ||
"test-only": "jest" | ||
"test-only": "jest", | ||
"tsc": "npm run clean && npm run tsc-cjs && npm run tsc-esm", | ||
"tsc-cjs": "tsc --project tsconfig.cjs.json", | ||
"tsc-esm": "tsc --project tsconfig.esm.json" | ||
}, | ||
@@ -33,17 +40,16 @@ "repository": { | ||
"homepage": "https://github.com/cheminfo/arraybuffer-xml-parser#readme", | ||
"jest": { | ||
"testEnvironment": "node" | ||
}, | ||
"devDependencies": { | ||
"@babel/plugin-transform-modules-commonjs": "^7.15.4", | ||
"@types/jest": "^27.0.2", | ||
"@types/he": "^1.1.2", | ||
"@types/jest": "^27.5.0", | ||
"cheminfo-build": "^1.1.11", | ||
"eslint": "^8.0.1", | ||
"eslint-config-cheminfo": "^7.1.1", | ||
"eslint": "^8.15.0", | ||
"eslint-config-cheminfo-typescript": "^10.4.0", | ||
"he": "^1.2.0", | ||
"iobuffer": "^5.0.4", | ||
"jest": "^27.3.1", | ||
"iobuffer": "^5.1.0", | ||
"jest": "^28.1.0", | ||
"pako": "^2.0.4", | ||
"prettier": "^2.4.1", | ||
"rollup": "^2.58.0", | ||
"prettier": "^2.6.2", | ||
"rimraf": "^3.0.2", | ||
"ts-jest": "^28.0.2", | ||
"typescript": "^4.6.4", | ||
"uint8-base64": "^0.1.1" | ||
@@ -50,0 +56,0 @@ }, |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
151739
147
2297
14
1