1
0
mirror of https://github.com/S2-/minifyfromhtml.git synced 2025-08-02 20:00:05 +02:00

update node modules

This commit is contained in:
s2
2021-05-07 15:56:33 +02:00
parent d81e8e9fb8
commit 3ec373077c
550 changed files with 84712 additions and 15991 deletions

57
node_modules/tough-cookie/README.md generated vendored
View File

@@ -2,7 +2,7 @@
[![npm package](https://nodei.co/npm/tough-cookie.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/tough-cookie/)
[![Build Status](https://travis-ci.org/salesforce/tough-cookie.png?branch=master)](https://travis-ci.org/salesforce/tough-cookie)
[![Build Status](https://travis-ci.org/salesforce/tough-cookie.svg?branch=master)](https://travis-ci.org/salesforce/tough-cookie)
# Synopsis
@@ -149,6 +149,7 @@ Cookie object properties:
* _path_ - string - the `Path=` of the cookie
* _secure_ - boolean - the `Secure` cookie flag
* _httpOnly_ - boolean - the `HttpOnly` cookie flag
* _sameSite_ - string - the `SameSite` cookie attribute (from [RFC6265bis]); must be one of `none`, `lax`, or `strict`
* _extensions_ - `Array` - any unrecognized cookie attributes as strings (even if equal-signs inside)
* _creation_ - `Date` - when this cookie was constructed
* _creationIndex_ - number - set at construction, used to provide greater sort precision (please see `cookieCompare(a,b)` for a full explanation)
@@ -251,6 +252,8 @@ The `options` object can be omitted and can have the following properties:
* _rejectPublicSuffixes_ - boolean - default `true` - reject cookies with domains like "com" and "co.uk"
* _looseMode_ - boolean - default `false` - accept malformed cookies like `bar` and `=bar`, which have an implied empty name.
* _prefixSecurity_ - string - default `silent` - set to `'unsafe-disabled'`, `'silent'`, or `'strict'`. See [Cookie Prefixes] below.
* _allowSpecialUseDomain_ - boolean - default `false` - accepts special-use domain suffixes, such as `local`. Useful for testing purposes.
This is not in the standard, but is used sometimes on the web and is accepted by (most) browsers.
Since eventually this module would like to support database/remote/etc. CookieJars, continuation passing style is used for CookieJar methods.
@@ -265,6 +268,7 @@ The `options` object can be omitted and can have the following properties:
* _secure_ - boolean - autodetect from url - indicates if this is a "Secure" API. If the currentUrl starts with `https:` or `wss:` then this is defaulted to `true`, otherwise `false`.
* _now_ - Date - default `new Date()` - what to use for the creation/access time of cookies
* _ignoreError_ - boolean - default `false` - silently ignore things like parse errors and invalid domains. `Store` errors aren't ignored by this option.
* _sameSiteContext_ - string - default unset - set to `'none'`, `'lax'`, or `'strict'` See [SameSite Cookies] below.
As per the RFC, the `.hostOnly` property is set if there was no "Domain=" parameter in the cookie string (or `.domain` was null on the Cookie object). The `.domain` property is set to the fully-qualified hostname of `currentUrl` in this case. Matching this cookie requires an exact hostname match (not a `domainMatch` as per usual).
@@ -285,6 +289,7 @@ The `options` object can be omitted and can have the following properties:
* _now_ - Date - default `new Date()` - what to use for the creation/access time of cookies
* _expire_ - boolean - default `true` - perform expiry-time checking of cookies and asynchronously remove expired cookies from the store. Using `false` will return expired cookies and **not** remove them from the store (which is useful for replaying Set-Cookie headers, potentially).
* _allPaths_ - boolean - default `false` - if `true`, do not scope cookies by path. The default uses RFC-compliant path scoping. **Note**: may not be supported by the underlying store (the default `MemoryCookieStore` supports it).
* _sameSiteContext_ - string - default unset - Set this to `'none'`, `'lax'` or `'strict'` to enforce SameSite cookies upon retrival. See [SameSite Cookies] below.
The `.lastAccessed` property of the returned cookies will have been updated.
@@ -491,6 +496,56 @@ These are some Store implementations authored and maintained by the community. T
}
```
# RFC6265bis
Support for RFC6265bis revision 02 is being developed. Since this is a bit of an omnibus revision to the RFC6252, support is broken up into the functional areas.
## Leave Secure Cookies Alone
Not yet supported.
This change makes it so that if a cookie is sent from the server to the client with a `Secure` attribute, the channel must also be secure or the cookie is ignored.
## SameSite Cookies
Supported.
This change makes it possible for servers, and supporting clients, to mitigate certain types of CSRF attacks by disallowing `SameSite` cookies from being sent cross-origin.
On the Cookie object itself, you can get/set the `.sameSite` attribute, which will be serialized into the `SameSite=` cookie attribute. When unset or `undefined`, no `SameSite=` attribute will be serialized. The valid values of this attribute are `'none'`, `'lax'`, or `'strict'`. Other values will be serialized as-is.
When parsing cookies with a `SameSite` cookie attribute, values other than `'lax'` or `'strict'` are parsed as `'none'`. For example, `SomeCookie=SomeValue; SameSite=garbage` will parse so that `cookie.sameSite === 'none'`.
In order to support SameSite cookies, you must provide a `sameSiteContext` option to _both_ `setCookie` and `getCookies`. Valid values for this option are just like for the Cookie object, but have particular meanings:
1. `'strict'` mode - If the request is on the same "site for cookies" (see the RFC draft for what this means), pass this option to add a layer of defense against CSRF.
2. `'lax'` mode - If the request is from another site, _but_ is directly because of navigation by the user, e.g., `<link type=prefetch>` or `<a href="...">`, pass `sameSiteContext: 'lax'`.
3. `'none'` - Otherwise, pass `sameSiteContext: 'none'` (this indicates a cross-origin request).
4. unset/`undefined` - SameSite **will not** be enforced! This can be a valid use-case for when CSRF isn't in the threat model of the system being built.
It is highly recommended that you read RFC 6265bis for fine details on SameSite cookies. In particular [Section 8.8](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02#section-8.8) discusses security considerations and defense in depth.
## Cookie Prefixes
Supported.
Cookie prefixes are a way to indicate that a given cookie was set with a set of attributes simply by inspecting the first few characters of the cookie's name.
Cookie prefixes are defined in [Section 4.1.3 of 6265bis](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.3). Two prefixes are defined:
1. `"__Secure-" Prefix`: If a cookie's name begins with a case-sensitive match for the string "__Secure-", then the cookie will have been set with a "Secure" attribute.
2. `"__Host-" Prefix`: If a cookie's name begins with a case-sensitive match for the string "__Host-", then the cookie will have been set with a "Secure" attribute, a "Path" attribute with a value of "/", and no "Domain" attribute.
If `prefixSecurity` is enabled for `CookieJar`, then cookies that match the prefixes defined above but do not obey the attribute restrictions will not be added.
You can define this functionality by passing in `prefixSecurity` option to `CookieJar`. It can be one of 3 values:
1. `silent`: Enable cookie prefix checking but silently fail to add the cookie if conditions not met. Default.
2. `strict`: Enable cookie prefix checking and error out if conditions not met.
3. `unsafe-disabled`: Disable cookie prefix checking.
Note that if `ignoreError` is passed in as `true` then the error will be silent regardless of `prefixSecurity` option (assuming it's enabled).
# Copyright and License
BSD-3-Clause:

2005
node_modules/tough-cookie/lib/cookie.js generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -28,154 +28,163 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
'use strict';
var Store = require('./store').Store;
var permuteDomain = require('./permuteDomain').permuteDomain;
var pathMatch = require('./pathMatch').pathMatch;
var util = require('util');
"use strict";
const { fromCallback } = require("universalify");
const Store = require("./store").Store;
const permuteDomain = require("./permuteDomain").permuteDomain;
const pathMatch = require("./pathMatch").pathMatch;
const util = require("util");
function MemoryCookieStore() {
Store.call(this);
this.idx = {};
}
util.inherits(MemoryCookieStore, Store);
exports.MemoryCookieStore = MemoryCookieStore;
MemoryCookieStore.prototype.idx = null;
// Since it's just a struct in RAM, this Store is synchronous
MemoryCookieStore.prototype.synchronous = true;
// force a default depth:
MemoryCookieStore.prototype.inspect = function() {
return "{ idx: "+util.inspect(this.idx, false, 2)+' }';
};
// Use the new custom inspection symbol to add the custom inspect function if
// available.
if (util.inspect.custom) {
MemoryCookieStore.prototype[util.inspect.custom] = MemoryCookieStore.prototype.inspect;
}
MemoryCookieStore.prototype.findCookie = function(domain, path, key, cb) {
if (!this.idx[domain]) {
return cb(null,undefined);
}
if (!this.idx[domain][path]) {
return cb(null,undefined);
}
return cb(null,this.idx[domain][path][key]||null);
};
MemoryCookieStore.prototype.findCookies = function(domain, path, cb) {
var results = [];
if (!domain) {
return cb(null,[]);
}
var pathMatcher;
if (!path) {
// null means "all paths"
pathMatcher = function matchAll(domainIndex) {
for (var curPath in domainIndex) {
var pathIndex = domainIndex[curPath];
for (var key in pathIndex) {
results.push(pathIndex[key]);
}
}
};
} else {
pathMatcher = function matchRFC(domainIndex) {
//NOTE: we should use path-match algorithm from S5.1.4 here
//(see : https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/canonical_cookie.cc#L299)
Object.keys(domainIndex).forEach(function (cookiePath) {
if (pathMatch(path, cookiePath)) {
var pathIndex = domainIndex[cookiePath];
for (var key in pathIndex) {
results.push(pathIndex[key]);
}
}
});
};
}
var domains = permuteDomain(domain) || [domain];
var idx = this.idx;
domains.forEach(function(curDomain) {
var domainIndex = idx[curDomain];
if (!domainIndex) {
return;
class MemoryCookieStore extends Store {
constructor() {
super();
this.synchronous = true;
this.idx = {};
if (util.inspect.custom) {
this[util.inspect.custom] = this.inspect;
}
pathMatcher(domainIndex);
});
cb(null,results);
};
MemoryCookieStore.prototype.putCookie = function(cookie, cb) {
if (!this.idx[cookie.domain]) {
this.idx[cookie.domain] = {};
}
if (!this.idx[cookie.domain][cookie.path]) {
this.idx[cookie.domain][cookie.path] = {};
inspect() {
return `{ idx: ${util.inspect(this.idx, false, 2)} }`;
}
this.idx[cookie.domain][cookie.path][cookie.key] = cookie;
cb(null);
};
MemoryCookieStore.prototype.updateCookie = function(oldCookie, newCookie, cb) {
// updateCookie() may avoid updating cookies that are identical. For example,
// lastAccessed may not be important to some stores and an equality
// comparison could exclude that field.
this.putCookie(newCookie,cb);
};
MemoryCookieStore.prototype.removeCookie = function(domain, path, key, cb) {
if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) {
delete this.idx[domain][path][key];
findCookie(domain, path, key, cb) {
if (!this.idx[domain]) {
return cb(null, undefined);
}
if (!this.idx[domain][path]) {
return cb(null, undefined);
}
return cb(null, this.idx[domain][path][key] || null);
}
cb(null);
};
findCookies(domain, path, allowSpecialUseDomain, cb) {
const results = [];
if (typeof allowSpecialUseDomain === "function") {
cb = allowSpecialUseDomain;
allowSpecialUseDomain = false;
}
if (!domain) {
return cb(null, []);
}
MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) {
if (this.idx[domain]) {
if (path) {
delete this.idx[domain][path];
let pathMatcher;
if (!path) {
// null means "all paths"
pathMatcher = function matchAll(domainIndex) {
for (const curPath in domainIndex) {
const pathIndex = domainIndex[curPath];
for (const key in pathIndex) {
results.push(pathIndex[key]);
}
}
};
} else {
delete this.idx[domain];
pathMatcher = function matchRFC(domainIndex) {
//NOTE: we should use path-match algorithm from S5.1.4 here
//(see : https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/canonical_cookie.cc#L299)
Object.keys(domainIndex).forEach(cookiePath => {
if (pathMatch(path, cookiePath)) {
const pathIndex = domainIndex[cookiePath];
for (const key in pathIndex) {
results.push(pathIndex[key]);
}
}
});
};
}
const domains = permuteDomain(domain, allowSpecialUseDomain) || [domain];
const idx = this.idx;
domains.forEach(curDomain => {
const domainIndex = idx[curDomain];
if (!domainIndex) {
return;
}
pathMatcher(domainIndex);
});
cb(null, results);
}
return cb(null);
};
MemoryCookieStore.prototype.removeAllCookies = function(cb) {
this.idx = {};
return cb(null);
}
putCookie(cookie, cb) {
if (!this.idx[cookie.domain]) {
this.idx[cookie.domain] = {};
}
if (!this.idx[cookie.domain][cookie.path]) {
this.idx[cookie.domain][cookie.path] = {};
}
this.idx[cookie.domain][cookie.path][cookie.key] = cookie;
cb(null);
}
updateCookie(oldCookie, newCookie, cb) {
// updateCookie() may avoid updating cookies that are identical. For example,
// lastAccessed may not be important to some stores and an equality
// comparison could exclude that field.
this.putCookie(newCookie, cb);
}
removeCookie(domain, path, key, cb) {
if (
this.idx[domain] &&
this.idx[domain][path] &&
this.idx[domain][path][key]
) {
delete this.idx[domain][path][key];
}
cb(null);
}
removeCookies(domain, path, cb) {
if (this.idx[domain]) {
if (path) {
delete this.idx[domain][path];
} else {
delete this.idx[domain];
}
}
return cb(null);
}
removeAllCookies(cb) {
this.idx = {};
return cb(null);
}
getAllCookies(cb) {
const cookies = [];
const idx = this.idx;
MemoryCookieStore.prototype.getAllCookies = function(cb) {
var cookies = [];
var idx = this.idx;
var domains = Object.keys(idx);
domains.forEach(function(domain) {
var paths = Object.keys(idx[domain]);
paths.forEach(function(path) {
var keys = Object.keys(idx[domain][path]);
keys.forEach(function(key) {
if (key !== null) {
cookies.push(idx[domain][path][key]);
}
const domains = Object.keys(idx);
domains.forEach(domain => {
const paths = Object.keys(idx[domain]);
paths.forEach(path => {
const keys = Object.keys(idx[domain][path]);
keys.forEach(key => {
if (key !== null) {
cookies.push(idx[domain][path][key]);
}
});
});
});
});
// Sort by creationIndex so deserializing retains the creation order.
// When implementing your own store, this SHOULD retain the order too
cookies.sort(function(a,b) {
return (a.creationIndex||0) - (b.creationIndex||0);
});
// Sort by creationIndex so deserializing retains the creation order.
// When implementing your own store, this SHOULD retain the order too
cookies.sort((a, b) => {
return (a.creationIndex || 0) - (b.creationIndex || 0);
});
cb(null, cookies);
};
cb(null, cookies);
}
}
[
"findCookie",
"findCookies",
"putCookie",
"updateCookie",
"removeCookie",
"removeCookies",
"removeAllCookies",
"getAllCookies"
].forEach(name => {
MemoryCookieStore[name] = fromCallback(MemoryCookieStore.prototype[name]);
});
exports.MemoryCookieStore = MemoryCookieStore;

View File

@@ -33,13 +33,13 @@
* "A request-path path-matches a given cookie-path if at least one of the
* following conditions holds:"
*/
function pathMatch (reqPath, cookiePath) {
function pathMatch(reqPath, cookiePath) {
// "o The cookie-path and the request-path are identical."
if (cookiePath === reqPath) {
return true;
}
var idx = reqPath.indexOf(cookiePath);
const idx = reqPath.indexOf(cookiePath);
if (idx === 0) {
// "o The cookie-path is a prefix of the request-path, and the last
// character of the cookie-path is %x2F ("/")."

View File

@@ -29,12 +29,26 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
var pubsuffix = require('./pubsuffix-psl');
const pubsuffix = require("./pubsuffix-psl");
// Gives the permutation of all possible domainMatch()es of a given domain. The
// array is in shortest-to-longest order. Handy for indexing.
function permuteDomain (domain) {
var pubSuf = pubsuffix.getPublicSuffix(domain);
const SPECIAL_USE_DOMAINS = ["local"]; // RFC 6761
function permuteDomain(domain, allowSpecialUseDomain) {
let pubSuf = null;
if (allowSpecialUseDomain) {
const domainParts = domain.split(".");
if (SPECIAL_USE_DOMAINS.includes(domainParts[domainParts.length - 1])) {
pubSuf = `${domainParts[domainParts.length - 2]}.${
domainParts[domainParts.length - 1]
}`;
} else {
pubSuf = pubsuffix.getPublicSuffix(domain);
}
} else {
pubSuf = pubsuffix.getPublicSuffix(domain);
}
if (!pubSuf) {
return null;
}
@@ -42,12 +56,12 @@ function permuteDomain (domain) {
return [domain];
}
var prefix = domain.slice(0, -(pubSuf.length + 1)); // ".example.com"
var parts = prefix.split('.').reverse();
var cur = pubSuf;
var permutations = [cur];
const prefix = domain.slice(0, -(pubSuf.length + 1)); // ".example.com"
const parts = prefix.split(".").reverse();
let cur = pubSuf;
const permutations = [cur];
while (parts.length) {
cur = parts.shift() + '.' + cur;
cur = `${parts.shift()}.${cur}`;
permutations.push(cur);
}
return permutations;

View File

@@ -28,8 +28,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
'use strict';
var psl = require('psl');
"use strict";
const psl = require("psl");
function getPublicSuffix(domain) {
return psl.get(domain);

View File

@@ -28,48 +28,49 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
'use strict';
"use strict";
/*jshint unused:false */
function Store() {
class Store {
constructor() {
this.synchronous = false;
}
findCookie(domain, path, key, cb) {
throw new Error("findCookie is not implemented");
}
findCookies(domain, path, allowSpecialUseDomain, cb) {
throw new Error("findCookies is not implemented");
}
putCookie(cookie, cb) {
throw new Error("putCookie is not implemented");
}
updateCookie(oldCookie, newCookie, cb) {
// recommended default implementation:
// return this.putCookie(newCookie, cb);
throw new Error("updateCookie is not implemented");
}
removeCookie(domain, path, key, cb) {
throw new Error("removeCookie is not implemented");
}
removeCookies(domain, path, cb) {
throw new Error("removeCookies is not implemented");
}
removeAllCookies(cb) {
throw new Error("removeAllCookies is not implemented");
}
getAllCookies(cb) {
throw new Error(
"getAllCookies is not implemented (therefore jar cannot be serialized)"
);
}
}
exports.Store = Store;
// Stores may be synchronous, but are still required to use a
// Continuation-Passing Style API. The CookieJar itself will expose a "*Sync"
// API that converts from synchronous-callbacks to imperative style.
Store.prototype.synchronous = false;
Store.prototype.findCookie = function(domain, path, key, cb) {
throw new Error('findCookie is not implemented');
};
Store.prototype.findCookies = function(domain, path, cb) {
throw new Error('findCookies is not implemented');
};
Store.prototype.putCookie = function(cookie, cb) {
throw new Error('putCookie is not implemented');
};
Store.prototype.updateCookie = function(oldCookie, newCookie, cb) {
// recommended default implementation:
// return this.putCookie(newCookie, cb);
throw new Error('updateCookie is not implemented');
};
Store.prototype.removeCookie = function(domain, path, key, cb) {
throw new Error('removeCookie is not implemented');
};
Store.prototype.removeCookies = function(domain, path, cb) {
throw new Error('removeCookies is not implemented');
};
Store.prototype.removeAllCookies = function(cb) {
throw new Error('removeAllCookies is not implemented');
}
Store.prototype.getAllCookies = function(cb) {
throw new Error('getAllCookies is not implemented (therefore jar cannot be serialized)');
};

View File

@@ -1,2 +1,2 @@
// generated by genversion
module.exports = '3.0.1'
module.exports = '4.0.0'

View File

@@ -1,26 +1,26 @@
{
"_from": "tough-cookie@^3.0.1",
"_id": "tough-cookie@3.0.1",
"_from": "tough-cookie@^4.0.0",
"_id": "tough-cookie@4.0.0",
"_inBundle": false,
"_integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
"_integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
"_location": "/tough-cookie",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "tough-cookie@^3.0.1",
"raw": "tough-cookie@^4.0.0",
"name": "tough-cookie",
"escapedName": "tough-cookie",
"rawSpec": "^3.0.1",
"rawSpec": "^4.0.0",
"saveSpec": null,
"fetchSpec": "^3.0.1"
"fetchSpec": "^4.0.0"
},
"_requiredBy": [
"/jsdom"
],
"_resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
"_shasum": "9df4f57e739c26930a018184887f4adb7dca73b2",
"_spec": "tough-cookie@^3.0.1",
"_resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
"_shasum": "d822234eeca882f991f0f908824ad2622ddbece4",
"_spec": "tough-cookie@^4.0.0",
"_where": "D:\\Projects\\minifyfromhtml\\node_modules\\jsdom",
"author": {
"name": "Jeremy Stashewsky",
@@ -32,36 +32,57 @@
"bundleDependencies": false,
"contributors": [
{
"name": "Alexander Savin"
"name": "Ivan Nikulin"
},
{
"name": "Shivan Kaul Sahib"
},
{
"name": "Clint Ruoho"
},
{
"name": "Ian Livingstone"
},
{
"name": "Ivan Nikulin"
"name": "Andrew Waterman"
},
{
"name": "Michael de Libero"
},
{
"name": "Jonathan Stewmon"
},
{
"name": "Miguel Roncancio"
},
{
"name": "Sebastian Mayr"
},
{
"name": "Alexander Savin"
},
{
"name": "Lalit Kapoor"
},
{
"name": "Sam Thompson"
},
{
"name": "Sebastian Mayr"
}
],
"dependencies": {
"ip-regex": "^2.1.0",
"psl": "^1.1.28",
"punycode": "^2.1.1"
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.1.2"
},
"deprecated": false,
"description": "RFC6265 Cookies and Cookie Jar for node.js",
"devDependencies": {
"async": "^1.4.2",
"async": "^2.6.2",
"eslint": "^5.16.0",
"eslint-config-prettier": "^4.2.0",
"eslint-plugin-prettier": "^3.0.1",
"genversion": "^2.1.0",
"nyc": "^11.6.0",
"string.prototype.repeat": "^0.2.0",
"nyc": "^14.0.0",
"prettier": "^1.17.0",
"vows": "^0.8.2"
},
"engines": {
@@ -90,8 +111,11 @@
},
"scripts": {
"cover": "nyc --reporter=lcov --reporter=html vows test/*_test.js",
"eslint": "eslint --env node --ext .js .",
"format": "npm run eslint -- --fix",
"prettier": "prettier '**/*.{json,ts,yaml,md}'",
"test": "vows test/*_test.js",
"version": "genversion lib/version.js && git add lib/version.js"
},
"version": "3.0.1"
"version": "4.0.0"
}