├── .eslintignore
├── .eslintrc.js
├── .github
├── CODEOWNERS
└── FUNDING.yml
├── .gitignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── index.js
├── package-lock.json
├── package.json
├── test.js
└── tests
└── fixtures
├── babel_class_component.js
├── es6_class_component.js
└── function_class_component.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Development files
2 | /node_modules
3 |
4 | # This file is autogenerated and shouldn't be linted
5 | /tests/fixtures/babel_class_component.js
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true,
6 | node: true,
7 | },
8 | parserOptions: {
9 | ecmaVersion: 2017,
10 | },
11 | extends: 'eslint:recommended',
12 | rules: {
13 | 'prefer-const': 'error',
14 | 'no-var': 'error',
15 | indent: ['error', 2],
16 | 'linebreak-style': ['error', 'unix'],
17 | quotes: ['error', 'single'],
18 | semi: ['error', 'never'],
19 | indent: 'off',
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @MithrilJS/Committers
2 | /.github/ @MithrilJS/Admins
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | open_collective: mithriljs
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Development files
2 | /node_modules
3 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": false,
3 | "printWidth": 80,
4 | "tabWidth": 2,
5 | "singleQuote": true,
6 | "trailingComma": "es5",
7 | "arrowParens": "avoid",
8 | "semi": false
9 | }
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - node
5 | - 8
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Stephan Hoyer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | mithril-node-render
2 | ===================
3 | [](https://mithril.zulipchat.com)
4 | [](https://travis-ci.org/MithrilJS/mithril-node-render)
5 | [](https://github.com/rethinkjs/manifest)
6 | 
7 |
8 | Use mithril views to render server side
9 |
10 | Demo
11 | ----
12 |
13 | [Usage Example](https://github.com/StephanHoyer/mithril-isomorphic-example/)
14 |
15 | Installation
16 | ------------
17 |
18 | ```
19 | npm install mithril-node-render
20 | ```
21 |
22 | Usage
23 | -----
24 |
25 | ```javascript
26 | // Make Mithril happy
27 | if (!global.window) {
28 | global.window = global.document = global.requestAnimationFrame = undefined
29 | }
30 |
31 | var m = require('mithril')
32 | var render = require('mithril-node-render')
33 |
34 | render(m('span', 'huhu')).then(function (html) {
35 | // html === 'huhu'
36 | })
37 |
38 | var html = render.sync(m('span', 'huhu'))
39 | // html === 'huhu'
40 | ```
41 |
42 | Async components
43 | ----------------
44 |
45 | As you see the rendering is asynchronous. It lets you await certain data from within `oninit` hooks.
46 |
47 | ```javascript
48 | var myAsyncComponent = {
49 | oninit: function (node, waitFor) {
50 | waitFor(new Promise(function (resolve) {
51 | node.state.foo = 'bar'
52 | resolve()
53 | }))
54 | },
55 | view: function (node) {
56 | return m('div', node.state.foo)
57 | }
58 | }
59 |
60 | render(myAsyncComponent).then(function (html) {
61 | // html === '
bar
'
62 | })
63 | ```
64 |
65 | Sync rendering
66 | --------------
67 |
68 | You can also render synchronously. You just don't get the `waitFor` callback.
69 |
70 | ```js
71 | var myAsyncComponent = {
72 | oninit: function (node, waitFor) {
73 | // waitFor === undefined
74 | new Promise(function (resolve) {
75 | node.state.foo = 'bar'
76 | resolve()
77 | })
78 | },
79 | view: function (node) {
80 | return m('div', node.state.foo)
81 | }
82 | }
83 |
84 | var html = render.sync(myAsyncComponent)
85 | // html === 'bar
'
86 | ```
87 |
88 | Options
89 | -------
90 |
91 | Optionally pass in options as an object: `render(component, options)`.
92 |
93 | The following options are supported:
94 |
95 | **escapeAttribute(value)**
96 | `Default: render.escapeAttribute`
97 | A filter function for attribute values. Receives value, returns what is printed.
98 |
99 | **escapeText(value)**
100 | `Default: render.escapeText`
101 | A filter function for string nodes. Receives value, returns what is printed.
102 |
103 | **strict**
104 | `Default: false`
105 | Set this to true to close all empty tags automatically. Default is standard HTML mode where tags like `
` and `` are allowed to implicitly close themselves. This should be set to `true` if you're rendering XML-compatible HTML documents.
106 |
107 | **xml**
108 | `Default: false`
109 | Set this to true to render as generic XML instead of (possibly XML-compatible) HTML. Default is HTML mode, where children of void elements are ignored. This implies `strict: true`.
110 |
111 |
112 | See also
113 | --------
114 |
115 | * [Blog post](https://gist.github.com/StephanHoyer/bddccd9e159828867d2a) about isomorphic mithril applications
116 | * [Usage Example](https://github.com/StephanHoyer/mithril-isomorphic-example/blob/master/README.md)
117 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const m = require('mithril/hyperscript')
4 | const Vnode = require('mithril/render/vnode')
5 |
6 | const VOID_TAGS = new RegExp(
7 | '^(?:' +
8 | 'area|' +
9 | 'base|' +
10 | 'br|' +
11 | 'col|' +
12 | 'command|' +
13 | 'embed|' +
14 | 'hr|' +
15 | 'img|' +
16 | 'input|' +
17 | 'keygen|' +
18 | 'link|' +
19 | 'meta|' +
20 | 'param|' +
21 | 'source|' +
22 | 'track|' +
23 | 'wbr|' +
24 | '!doctype' +
25 | ')$',
26 | 'i'
27 | )
28 |
29 | const hasOwn = {}.hasOwnProperty
30 |
31 | function toStyleKey(str) {
32 | if (str[0] === '-' && str[1] === '-') {
33 | return str
34 | }
35 | return str
36 | .replace(/\W+/g, '-')
37 | .replace(/([a-z\d])([A-Z])/g, '$1-$2')
38 | .toLowerCase()
39 | }
40 |
41 | function replaceHtml(m) {
42 | if (m === '&') return '&'
43 | if (m === '<') return '<'
44 | return '>'
45 | }
46 |
47 | function replaceAttribute(m) {
48 | if (m === '&') return '&'
49 | if (m === '<') return '<'
50 | if (m === '>') return '>'
51 | return '"'
52 | }
53 |
54 | const defaults = {
55 | escapeText(s) {
56 | return s.replace(/[&<>]/g, replaceHtml)
57 | },
58 |
59 | escapeAttribute(s) {
60 | return s.replace(/[&<>"]/g, replaceAttribute)
61 | },
62 | }
63 |
64 | function bindOpt(options, key) {
65 | return options[key] ? options[key].bind(options) : defaults[key]
66 | }
67 |
68 | // Using a generator so I can just yield promises that need awaited. Can't just
69 | // use `async`/`await` since this is used for both sync and async renders. At
70 | // least I have generators (read: coroutines), or I'd have to implement this
71 | // using a giant pushdown automaton. :-)
72 | function* tryRender(view, attrs, options, allowAwait) {
73 | // Fast-path a very simple case. Also lets me perform some renderer
74 | // optimizations later.
75 | if (view == null) return ''
76 | if (view.view || typeof view === 'function') {
77 | // root component
78 | view = m(view, attrs)
79 | options = options || {}
80 | } else {
81 | options = attrs || {}
82 | }
83 | const hooks = []
84 | let result = ''
85 | const escapeAttribute = bindOpt(options, 'escapeAttribute')
86 | const escapeText = bindOpt(options, 'escapeText')
87 | const xml = !!options.xml
88 | const strict = xml || !!options.strict
89 |
90 | function write(value) {
91 | result = '' + result + value
92 | }
93 |
94 | function* setHooks(source, vnode) {
95 | const promises = []
96 | let waitFor
97 | if (allowAwait)
98 | waitFor = p => {
99 | promises.push(p)
100 | }
101 | if (source.oninit) {
102 | source.oninit.call(vnode.state, vnode, waitFor)
103 | }
104 | if (source.onremove) {
105 | hooks.push(source.onremove.bind(vnode.state, vnode))
106 | }
107 | if (promises.length) yield promises
108 | }
109 |
110 | function createAttrString(view) {
111 | for (const key in view.attrs) {
112 | if (hasOwn.call(view.attrs, key)) {
113 | let value = view.attrs[key]
114 | if (value == null || typeof value === 'function') continue
115 | const name = key === 'className' ? 'class' : key
116 |
117 | if (name === 'style' && typeof value === 'object') {
118 | const styles = value
119 | const props = []
120 | for (const key of Object.keys(styles)) {
121 | const prop = styles[key]
122 | if (prop) props.push(`${toStyleKey(key)}:${prop}`)
123 | }
124 | if (!props.length) continue
125 | value = props.join(';')
126 | }
127 |
128 | if (typeof value === 'boolean') {
129 | if (xml) value = value ? 'true' : 'false'
130 | else if (!value) continue
131 | else value = ''
132 | } else {
133 | value = '' + value
134 | }
135 |
136 | write(` ${name}`)
137 | if (strict || value !== '') {
138 | write(`="${escapeAttribute(value)}"`)
139 | }
140 | }
141 | }
142 | }
143 |
144 | function* renderComponent(vnode) {
145 | if (typeof vnode.tag !== 'function') {
146 | vnode.state = Object.create(vnode.tag)
147 | } else if (vnode.tag.prototype && vnode.tag.prototype.view) {
148 | vnode.state = new vnode.tag(vnode)
149 | } else {
150 | vnode.state = vnode.tag(vnode)
151 | }
152 |
153 | yield* setHooks(vnode.state, vnode)
154 | if (vnode.attrs != null) yield* setHooks(vnode.attrs, vnode)
155 | vnode.instance = Vnode.normalize(vnode.state.view(vnode))
156 | if (vnode.instance != null) yield* renderNode(vnode.instance)
157 | }
158 |
159 | function* renderElement(vnode) {
160 | write(`<${vnode.tag}`)
161 | createAttrString(vnode)
162 | // Don't write children for void HTML elements
163 | if (!xml && VOID_TAGS.test(vnode.tag)) {
164 | write(strict ? '/>' : '>')
165 | } else {
166 | write('>')
167 | if (vnode.text != null) {
168 | const text = '' + vnode.text
169 | if (text !== '') write(escapeText(text))
170 | } else {
171 | yield* renderChildren(vnode.children)
172 | }
173 | write(`${vnode.tag}>`)
174 | }
175 | }
176 |
177 | function* renderChildren(vnodes) {
178 | for (const v of vnodes) {
179 | if (v != null) yield* renderNode(v)
180 | }
181 | }
182 |
183 | function* renderNode(vnode) {
184 | if (vnode == null) return
185 | if (typeof vnode.tag === 'string') {
186 | vnode.state = {}
187 | if (vnode.attrs != null) yield* setHooks(vnode.attrs, vnode)
188 | switch (vnode.tag) {
189 | case '#':
190 | write(escapeText('' + vnode.children))
191 | break
192 | case '<':
193 | write(vnode.children)
194 | break
195 | case '[':
196 | yield* renderChildren(vnode.children)
197 | break
198 | default:
199 | yield* renderElement(vnode)
200 | }
201 | } else {
202 | yield* renderComponent(vnode)
203 | }
204 | }
205 |
206 | yield* renderNode(Vnode.normalize(view))
207 | for (const hook of hooks) hook()
208 | return result.concat() // hint to flatten
209 | }
210 |
211 | module.exports = async (view, attrs, options) => {
212 | const iter = tryRender(view, attrs, options, true)
213 | // eslint-disable-next-line no-constant-condition
214 | while (true) {
215 | const { done, value } = iter.next()
216 | if (done) return value
217 | await Promise.all(value)
218 | }
219 | }
220 |
221 | module.exports.sync = (view, attrs, options) => {
222 | return tryRender(view, attrs, options, false).next().value
223 | }
224 |
225 | module.exports.escapeText = defaults.escapeText
226 | module.exports.escapeAttribute = defaults.escapeAttribute
227 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mithril-node-render",
3 | "version": "3.0.2",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@eslint-community/eslint-utils": {
8 | "version": "4.4.0",
9 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
10 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
11 | "dev": true,
12 | "requires": {
13 | "eslint-visitor-keys": "^3.3.0"
14 | }
15 | },
16 | "@eslint-community/regexpp": {
17 | "version": "4.5.0",
18 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz",
19 | "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==",
20 | "dev": true
21 | },
22 | "@eslint/eslintrc": {
23 | "version": "2.0.2",
24 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz",
25 | "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==",
26 | "dev": true,
27 | "requires": {
28 | "ajv": "^6.12.4",
29 | "debug": "^4.3.2",
30 | "espree": "^9.5.1",
31 | "globals": "^13.19.0",
32 | "ignore": "^5.2.0",
33 | "import-fresh": "^3.2.1",
34 | "js-yaml": "^4.1.0",
35 | "minimatch": "^3.1.2",
36 | "strip-json-comments": "^3.1.1"
37 | },
38 | "dependencies": {
39 | "ignore": {
40 | "version": "5.2.4",
41 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
42 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
43 | "dev": true
44 | },
45 | "minimatch": {
46 | "version": "3.1.2",
47 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
48 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
49 | "dev": true,
50 | "requires": {
51 | "brace-expansion": "^1.1.7"
52 | }
53 | }
54 | }
55 | },
56 | "@eslint/js": {
57 | "version": "8.38.0",
58 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
59 | "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
60 | "dev": true
61 | },
62 | "@humanwhocodes/config-array": {
63 | "version": "0.11.8",
64 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
65 | "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
66 | "dev": true,
67 | "requires": {
68 | "@humanwhocodes/object-schema": "^1.2.1",
69 | "debug": "^4.1.1",
70 | "minimatch": "^3.0.5"
71 | },
72 | "dependencies": {
73 | "minimatch": {
74 | "version": "3.1.2",
75 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
76 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
77 | "dev": true,
78 | "requires": {
79 | "brace-expansion": "^1.1.7"
80 | }
81 | }
82 | }
83 | },
84 | "@humanwhocodes/module-importer": {
85 | "version": "1.0.1",
86 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
87 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
88 | "dev": true
89 | },
90 | "@humanwhocodes/object-schema": {
91 | "version": "1.2.1",
92 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
93 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
94 | "dev": true
95 | },
96 | "@nodelib/fs.scandir": {
97 | "version": "2.1.5",
98 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
99 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
100 | "dev": true,
101 | "requires": {
102 | "@nodelib/fs.stat": "2.0.5",
103 | "run-parallel": "^1.1.9"
104 | }
105 | },
106 | "@nodelib/fs.stat": {
107 | "version": "2.0.5",
108 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
109 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
110 | "dev": true
111 | },
112 | "@nodelib/fs.walk": {
113 | "version": "1.2.8",
114 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
115 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
116 | "dev": true,
117 | "requires": {
118 | "@nodelib/fs.scandir": "2.1.5",
119 | "fastq": "^1.6.0"
120 | }
121 | },
122 | "acorn": {
123 | "version": "8.8.2",
124 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
125 | "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
126 | "dev": true
127 | },
128 | "acorn-jsx": {
129 | "version": "5.3.2",
130 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
131 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
132 | "dev": true
133 | },
134 | "ajv": {
135 | "version": "6.12.6",
136 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
137 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
138 | "dev": true,
139 | "requires": {
140 | "fast-deep-equal": "^3.1.1",
141 | "fast-json-stable-stringify": "^2.0.0",
142 | "json-schema-traverse": "^0.4.1",
143 | "uri-js": "^4.2.2"
144 | }
145 | },
146 | "ansi-regex": {
147 | "version": "5.0.1",
148 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
149 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
150 | "dev": true
151 | },
152 | "ansi-styles": {
153 | "version": "4.3.0",
154 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
155 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
156 | "dev": true,
157 | "requires": {
158 | "color-convert": "^2.0.1"
159 | }
160 | },
161 | "argparse": {
162 | "version": "2.0.1",
163 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
164 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
165 | "dev": true
166 | },
167 | "balanced-match": {
168 | "version": "1.0.0",
169 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
170 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
171 | "dev": true
172 | },
173 | "brace-expansion": {
174 | "version": "1.1.11",
175 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
176 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
177 | "dev": true,
178 | "requires": {
179 | "balanced-match": "^1.0.0",
180 | "concat-map": "0.0.1"
181 | }
182 | },
183 | "builtin-modules": {
184 | "version": "1.1.1",
185 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
186 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
187 | "dev": true
188 | },
189 | "callsites": {
190 | "version": "3.1.0",
191 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
192 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
193 | "dev": true
194 | },
195 | "chalk": {
196 | "version": "4.1.2",
197 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
198 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
199 | "dev": true,
200 | "requires": {
201 | "ansi-styles": "^4.1.0",
202 | "supports-color": "^7.1.0"
203 | }
204 | },
205 | "color-convert": {
206 | "version": "2.0.1",
207 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
208 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
209 | "dev": true,
210 | "requires": {
211 | "color-name": "~1.1.4"
212 | }
213 | },
214 | "color-name": {
215 | "version": "1.1.4",
216 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
217 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
218 | "dev": true
219 | },
220 | "concat-map": {
221 | "version": "0.0.1",
222 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
223 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
224 | "dev": true
225 | },
226 | "contains-path": {
227 | "version": "0.1.0",
228 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
229 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
230 | "dev": true
231 | },
232 | "cross-spawn": {
233 | "version": "7.0.3",
234 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
235 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
236 | "dev": true,
237 | "requires": {
238 | "path-key": "^3.1.0",
239 | "shebang-command": "^2.0.0",
240 | "which": "^2.0.1"
241 | }
242 | },
243 | "debug": {
244 | "version": "4.3.4",
245 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
246 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
247 | "dev": true,
248 | "requires": {
249 | "ms": "2.1.2"
250 | }
251 | },
252 | "deep-is": {
253 | "version": "0.1.4",
254 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
255 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
256 | "dev": true
257 | },
258 | "doctrine": {
259 | "version": "3.0.0",
260 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
261 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
262 | "dev": true,
263 | "requires": {
264 | "esutils": "^2.0.2"
265 | }
266 | },
267 | "error-ex": {
268 | "version": "1.3.2",
269 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
270 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
271 | "dev": true,
272 | "requires": {
273 | "is-arrayish": "^0.2.1"
274 | }
275 | },
276 | "escape-string-regexp": {
277 | "version": "4.0.0",
278 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
279 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
280 | "dev": true
281 | },
282 | "eslint": {
283 | "version": "8.38.0",
284 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
285 | "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
286 | "dev": true,
287 | "requires": {
288 | "@eslint-community/eslint-utils": "^4.2.0",
289 | "@eslint-community/regexpp": "^4.4.0",
290 | "@eslint/eslintrc": "^2.0.2",
291 | "@eslint/js": "8.38.0",
292 | "@humanwhocodes/config-array": "^0.11.8",
293 | "@humanwhocodes/module-importer": "^1.0.1",
294 | "@nodelib/fs.walk": "^1.2.8",
295 | "ajv": "^6.10.0",
296 | "chalk": "^4.0.0",
297 | "cross-spawn": "^7.0.2",
298 | "debug": "^4.3.2",
299 | "doctrine": "^3.0.0",
300 | "escape-string-regexp": "^4.0.0",
301 | "eslint-scope": "^7.1.1",
302 | "eslint-visitor-keys": "^3.4.0",
303 | "espree": "^9.5.1",
304 | "esquery": "^1.4.2",
305 | "esutils": "^2.0.2",
306 | "fast-deep-equal": "^3.1.3",
307 | "file-entry-cache": "^6.0.1",
308 | "find-up": "^5.0.0",
309 | "glob-parent": "^6.0.2",
310 | "globals": "^13.19.0",
311 | "grapheme-splitter": "^1.0.4",
312 | "ignore": "^5.2.0",
313 | "import-fresh": "^3.0.0",
314 | "imurmurhash": "^0.1.4",
315 | "is-glob": "^4.0.0",
316 | "is-path-inside": "^3.0.3",
317 | "js-sdsl": "^4.1.4",
318 | "js-yaml": "^4.1.0",
319 | "json-stable-stringify-without-jsonify": "^1.0.1",
320 | "levn": "^0.4.1",
321 | "lodash.merge": "^4.6.2",
322 | "minimatch": "^3.1.2",
323 | "natural-compare": "^1.4.0",
324 | "optionator": "^0.9.1",
325 | "strip-ansi": "^6.0.1",
326 | "strip-json-comments": "^3.1.0",
327 | "text-table": "^0.2.0"
328 | },
329 | "dependencies": {
330 | "find-up": {
331 | "version": "5.0.0",
332 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
333 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
334 | "dev": true,
335 | "requires": {
336 | "locate-path": "^6.0.0",
337 | "path-exists": "^4.0.0"
338 | }
339 | },
340 | "ignore": {
341 | "version": "5.2.4",
342 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
343 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
344 | "dev": true
345 | },
346 | "locate-path": {
347 | "version": "6.0.0",
348 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
349 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
350 | "dev": true,
351 | "requires": {
352 | "p-locate": "^5.0.0"
353 | }
354 | },
355 | "minimatch": {
356 | "version": "3.1.2",
357 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
358 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
359 | "dev": true,
360 | "requires": {
361 | "brace-expansion": "^1.1.7"
362 | }
363 | },
364 | "p-limit": {
365 | "version": "3.1.0",
366 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
367 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
368 | "dev": true,
369 | "requires": {
370 | "yocto-queue": "^0.1.0"
371 | }
372 | },
373 | "p-locate": {
374 | "version": "5.0.0",
375 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
376 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
377 | "dev": true,
378 | "requires": {
379 | "p-limit": "^3.0.2"
380 | }
381 | },
382 | "path-exists": {
383 | "version": "4.0.0",
384 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
385 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
386 | "dev": true
387 | }
388 | }
389 | },
390 | "eslint-config-standard": {
391 | "version": "10.2.1",
392 | "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
393 | "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=",
394 | "dev": true
395 | },
396 | "eslint-import-resolver-node": {
397 | "version": "0.3.2",
398 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
399 | "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
400 | "dev": true,
401 | "requires": {
402 | "debug": "^2.6.9",
403 | "resolve": "^1.5.0"
404 | },
405 | "dependencies": {
406 | "debug": {
407 | "version": "2.6.9",
408 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
409 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
410 | "dev": true,
411 | "requires": {
412 | "ms": "2.0.0"
413 | }
414 | },
415 | "ms": {
416 | "version": "2.0.0",
417 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
418 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
419 | "dev": true
420 | }
421 | }
422 | },
423 | "eslint-module-utils": {
424 | "version": "2.4.1",
425 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz",
426 | "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==",
427 | "dev": true,
428 | "requires": {
429 | "debug": "^2.6.8",
430 | "pkg-dir": "^2.0.0"
431 | },
432 | "dependencies": {
433 | "debug": {
434 | "version": "2.6.9",
435 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
436 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
437 | "dev": true,
438 | "requires": {
439 | "ms": "2.0.0"
440 | }
441 | },
442 | "ms": {
443 | "version": "2.0.0",
444 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
445 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
446 | "dev": true
447 | }
448 | }
449 | },
450 | "eslint-plugin-import": {
451 | "version": "2.8.0",
452 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz",
453 | "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==",
454 | "dev": true,
455 | "requires": {
456 | "builtin-modules": "^1.1.1",
457 | "contains-path": "^0.1.0",
458 | "debug": "^2.6.8",
459 | "doctrine": "1.5.0",
460 | "eslint-import-resolver-node": "^0.3.1",
461 | "eslint-module-utils": "^2.1.1",
462 | "has": "^1.0.1",
463 | "lodash.cond": "^4.3.0",
464 | "minimatch": "^3.0.3",
465 | "read-pkg-up": "^2.0.0"
466 | },
467 | "dependencies": {
468 | "debug": {
469 | "version": "2.6.9",
470 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
471 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
472 | "dev": true,
473 | "requires": {
474 | "ms": "2.0.0"
475 | }
476 | },
477 | "doctrine": {
478 | "version": "1.5.0",
479 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
480 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
481 | "dev": true,
482 | "requires": {
483 | "esutils": "^2.0.2",
484 | "isarray": "^1.0.0"
485 | }
486 | },
487 | "ms": {
488 | "version": "2.0.0",
489 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
490 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
491 | "dev": true
492 | }
493 | }
494 | },
495 | "eslint-plugin-node": {
496 | "version": "5.2.1",
497 | "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz",
498 | "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==",
499 | "dev": true,
500 | "requires": {
501 | "ignore": "^3.3.6",
502 | "minimatch": "^3.0.4",
503 | "resolve": "^1.3.3",
504 | "semver": "5.3.0"
505 | },
506 | "dependencies": {
507 | "semver": {
508 | "version": "5.3.0",
509 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
510 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
511 | "dev": true
512 | }
513 | }
514 | },
515 | "eslint-plugin-promise": {
516 | "version": "3.6.0",
517 | "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz",
518 | "integrity": "sha512-YQzM6TLTlApAr7Li8vWKR+K3WghjwKcYzY0d2roWap4SLK+kzuagJX/leTetIDWsFcTFnKNJXWupDCD6aZkP2Q==",
519 | "dev": true
520 | },
521 | "eslint-plugin-standard": {
522 | "version": "3.0.1",
523 | "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
524 | "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=",
525 | "dev": true
526 | },
527 | "eslint-scope": {
528 | "version": "7.2.0",
529 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
530 | "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
531 | "dev": true,
532 | "requires": {
533 | "esrecurse": "^4.3.0",
534 | "estraverse": "^5.2.0"
535 | }
536 | },
537 | "eslint-visitor-keys": {
538 | "version": "3.4.0",
539 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
540 | "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
541 | "dev": true
542 | },
543 | "espree": {
544 | "version": "9.5.1",
545 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz",
546 | "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==",
547 | "dev": true,
548 | "requires": {
549 | "acorn": "^8.8.0",
550 | "acorn-jsx": "^5.3.2",
551 | "eslint-visitor-keys": "^3.4.0"
552 | }
553 | },
554 | "esquery": {
555 | "version": "1.5.0",
556 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
557 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
558 | "dev": true,
559 | "requires": {
560 | "estraverse": "^5.1.0"
561 | }
562 | },
563 | "esrecurse": {
564 | "version": "4.3.0",
565 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
566 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
567 | "dev": true,
568 | "requires": {
569 | "estraverse": "^5.2.0"
570 | }
571 | },
572 | "estraverse": {
573 | "version": "5.3.0",
574 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
575 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
576 | "dev": true
577 | },
578 | "esutils": {
579 | "version": "2.0.3",
580 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
581 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
582 | "dev": true
583 | },
584 | "fast-deep-equal": {
585 | "version": "3.1.3",
586 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
587 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
588 | "dev": true
589 | },
590 | "fast-json-stable-stringify": {
591 | "version": "2.1.0",
592 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
593 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
594 | "dev": true
595 | },
596 | "fast-levenshtein": {
597 | "version": "2.0.6",
598 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
599 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
600 | "dev": true
601 | },
602 | "fastq": {
603 | "version": "1.15.0",
604 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
605 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
606 | "dev": true,
607 | "requires": {
608 | "reusify": "^1.0.4"
609 | }
610 | },
611 | "file-entry-cache": {
612 | "version": "6.0.1",
613 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
614 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
615 | "dev": true,
616 | "requires": {
617 | "flat-cache": "^3.0.4"
618 | }
619 | },
620 | "find-up": {
621 | "version": "2.1.0",
622 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
623 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
624 | "dev": true,
625 | "requires": {
626 | "locate-path": "^2.0.0"
627 | }
628 | },
629 | "flat-cache": {
630 | "version": "3.0.4",
631 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
632 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
633 | "dev": true,
634 | "requires": {
635 | "flatted": "^3.1.0",
636 | "rimraf": "^3.0.2"
637 | }
638 | },
639 | "flatted": {
640 | "version": "3.2.7",
641 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
642 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
643 | "dev": true
644 | },
645 | "fs.realpath": {
646 | "version": "1.0.0",
647 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
648 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
649 | "dev": true
650 | },
651 | "function-bind": {
652 | "version": "1.1.1",
653 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
654 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
655 | "dev": true
656 | },
657 | "glob": {
658 | "version": "7.1.4",
659 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
660 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
661 | "dev": true,
662 | "requires": {
663 | "fs.realpath": "^1.0.0",
664 | "inflight": "^1.0.4",
665 | "inherits": "2",
666 | "minimatch": "^3.0.4",
667 | "once": "^1.3.0",
668 | "path-is-absolute": "^1.0.0"
669 | }
670 | },
671 | "glob-parent": {
672 | "version": "6.0.2",
673 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
674 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
675 | "dev": true,
676 | "requires": {
677 | "is-glob": "^4.0.3"
678 | }
679 | },
680 | "globals": {
681 | "version": "13.20.0",
682 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
683 | "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
684 | "dev": true,
685 | "requires": {
686 | "type-fest": "^0.20.2"
687 | }
688 | },
689 | "graceful-fs": {
690 | "version": "4.2.2",
691 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
692 | "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
693 | "dev": true
694 | },
695 | "grapheme-splitter": {
696 | "version": "1.0.4",
697 | "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
698 | "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
699 | "dev": true
700 | },
701 | "has": {
702 | "version": "1.0.3",
703 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
704 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
705 | "dev": true,
706 | "requires": {
707 | "function-bind": "^1.1.1"
708 | }
709 | },
710 | "has-flag": {
711 | "version": "4.0.0",
712 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
713 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
714 | "dev": true
715 | },
716 | "hosted-git-info": {
717 | "version": "2.8.9",
718 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
719 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
720 | "dev": true
721 | },
722 | "ignore": {
723 | "version": "3.3.10",
724 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
725 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
726 | "dev": true
727 | },
728 | "import-fresh": {
729 | "version": "3.3.0",
730 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
731 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
732 | "dev": true,
733 | "requires": {
734 | "parent-module": "^1.0.0",
735 | "resolve-from": "^4.0.0"
736 | }
737 | },
738 | "imurmurhash": {
739 | "version": "0.1.4",
740 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
741 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
742 | "dev": true
743 | },
744 | "inflight": {
745 | "version": "1.0.6",
746 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
747 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
748 | "dev": true,
749 | "requires": {
750 | "once": "^1.3.0",
751 | "wrappy": "1"
752 | }
753 | },
754 | "inherits": {
755 | "version": "2.0.4",
756 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
757 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
758 | "dev": true
759 | },
760 | "is-arrayish": {
761 | "version": "0.2.1",
762 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
763 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
764 | "dev": true
765 | },
766 | "is-extglob": {
767 | "version": "2.1.1",
768 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
769 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
770 | "dev": true
771 | },
772 | "is-glob": {
773 | "version": "4.0.3",
774 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
775 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
776 | "dev": true,
777 | "requires": {
778 | "is-extglob": "^2.1.1"
779 | }
780 | },
781 | "is-path-inside": {
782 | "version": "3.0.3",
783 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
784 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
785 | "dev": true
786 | },
787 | "isarray": {
788 | "version": "1.0.0",
789 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
790 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
791 | "dev": true
792 | },
793 | "isexe": {
794 | "version": "2.0.0",
795 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
796 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
797 | "dev": true
798 | },
799 | "js-sdsl": {
800 | "version": "4.4.0",
801 | "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
802 | "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
803 | "dev": true
804 | },
805 | "js-yaml": {
806 | "version": "4.1.0",
807 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
808 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
809 | "dev": true,
810 | "requires": {
811 | "argparse": "^2.0.1"
812 | }
813 | },
814 | "json-schema-traverse": {
815 | "version": "0.4.1",
816 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
817 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
818 | "dev": true
819 | },
820 | "json-stable-stringify-without-jsonify": {
821 | "version": "1.0.1",
822 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
823 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
824 | "dev": true
825 | },
826 | "levn": {
827 | "version": "0.4.1",
828 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
829 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
830 | "dev": true,
831 | "requires": {
832 | "prelude-ls": "^1.2.1",
833 | "type-check": "~0.4.0"
834 | }
835 | },
836 | "load-json-file": {
837 | "version": "2.0.0",
838 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
839 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
840 | "dev": true,
841 | "requires": {
842 | "graceful-fs": "^4.1.2",
843 | "parse-json": "^2.2.0",
844 | "pify": "^2.0.0",
845 | "strip-bom": "^3.0.0"
846 | }
847 | },
848 | "locate-path": {
849 | "version": "2.0.0",
850 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
851 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
852 | "dev": true,
853 | "requires": {
854 | "p-locate": "^2.0.0",
855 | "path-exists": "^3.0.0"
856 | }
857 | },
858 | "lodash.cond": {
859 | "version": "4.5.2",
860 | "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
861 | "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
862 | "dev": true
863 | },
864 | "lodash.merge": {
865 | "version": "4.6.2",
866 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
867 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
868 | "dev": true
869 | },
870 | "minimatch": {
871 | "version": "3.1.2",
872 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
873 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
874 | "dev": true,
875 | "requires": {
876 | "brace-expansion": "^1.1.7"
877 | }
878 | },
879 | "mithril": {
880 | "version": "2.0.4",
881 | "resolved": "https://registry.npmjs.org/mithril/-/mithril-2.0.4.tgz",
882 | "integrity": "sha512-mgw+DMZlhMS4PpprF6dl7ZoeZq5GGcAuWnrg5e12MvaGauc4jzWsDZtVGRCktsiQczOEUr2K5teKbE5k44RlOg==",
883 | "dev": true
884 | },
885 | "ms": {
886 | "version": "2.1.2",
887 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
888 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
889 | "dev": true
890 | },
891 | "natural-compare": {
892 | "version": "1.4.0",
893 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
894 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
895 | "dev": true
896 | },
897 | "normalize-package-data": {
898 | "version": "2.5.0",
899 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
900 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
901 | "dev": true,
902 | "requires": {
903 | "hosted-git-info": "^2.1.4",
904 | "resolve": "^1.10.0",
905 | "semver": "2 || 3 || 4 || 5",
906 | "validate-npm-package-license": "^3.0.1"
907 | }
908 | },
909 | "once": {
910 | "version": "1.4.0",
911 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
912 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
913 | "dev": true,
914 | "requires": {
915 | "wrappy": "1"
916 | }
917 | },
918 | "optionator": {
919 | "version": "0.9.1",
920 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
921 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
922 | "dev": true,
923 | "requires": {
924 | "deep-is": "^0.1.3",
925 | "fast-levenshtein": "^2.0.6",
926 | "levn": "^0.4.1",
927 | "prelude-ls": "^1.2.1",
928 | "type-check": "^0.4.0",
929 | "word-wrap": "^1.2.3"
930 | }
931 | },
932 | "ospec": {
933 | "version": "4.0.1",
934 | "resolved": "https://registry.npmjs.org/ospec/-/ospec-4.0.1.tgz",
935 | "integrity": "sha512-iHx5jkuXh/hU4eEFFf6FH/4vj5RH7041jhuJw7WnqIPHDJgEXkSBdmuD644I/qQm8s5aZEPOpSoVagGCr8ebag==",
936 | "dev": true,
937 | "requires": {
938 | "glob": "^7.1.3"
939 | }
940 | },
941 | "p-limit": {
942 | "version": "1.3.0",
943 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
944 | "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
945 | "dev": true,
946 | "requires": {
947 | "p-try": "^1.0.0"
948 | }
949 | },
950 | "p-locate": {
951 | "version": "2.0.0",
952 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
953 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
954 | "dev": true,
955 | "requires": {
956 | "p-limit": "^1.1.0"
957 | }
958 | },
959 | "p-try": {
960 | "version": "1.0.0",
961 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
962 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
963 | "dev": true
964 | },
965 | "parent-module": {
966 | "version": "1.0.1",
967 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
968 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
969 | "dev": true,
970 | "requires": {
971 | "callsites": "^3.0.0"
972 | }
973 | },
974 | "parse-json": {
975 | "version": "2.2.0",
976 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
977 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
978 | "dev": true,
979 | "requires": {
980 | "error-ex": "^1.2.0"
981 | }
982 | },
983 | "path-exists": {
984 | "version": "3.0.0",
985 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
986 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
987 | "dev": true
988 | },
989 | "path-is-absolute": {
990 | "version": "1.0.1",
991 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
992 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
993 | "dev": true
994 | },
995 | "path-key": {
996 | "version": "3.1.1",
997 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
998 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
999 | "dev": true
1000 | },
1001 | "path-parse": {
1002 | "version": "1.0.7",
1003 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1004 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1005 | "dev": true
1006 | },
1007 | "path-type": {
1008 | "version": "2.0.0",
1009 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
1010 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
1011 | "dev": true,
1012 | "requires": {
1013 | "pify": "^2.0.0"
1014 | }
1015 | },
1016 | "pify": {
1017 | "version": "2.3.0",
1018 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1019 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
1020 | "dev": true
1021 | },
1022 | "pkg-dir": {
1023 | "version": "2.0.0",
1024 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
1025 | "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
1026 | "dev": true,
1027 | "requires": {
1028 | "find-up": "^2.1.0"
1029 | }
1030 | },
1031 | "prelude-ls": {
1032 | "version": "1.2.1",
1033 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
1034 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
1035 | "dev": true
1036 | },
1037 | "punycode": {
1038 | "version": "2.3.0",
1039 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
1040 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
1041 | "dev": true
1042 | },
1043 | "queue-microtask": {
1044 | "version": "1.2.3",
1045 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
1046 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
1047 | "dev": true
1048 | },
1049 | "read-pkg": {
1050 | "version": "2.0.0",
1051 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
1052 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
1053 | "dev": true,
1054 | "requires": {
1055 | "load-json-file": "^2.0.0",
1056 | "normalize-package-data": "^2.3.2",
1057 | "path-type": "^2.0.0"
1058 | }
1059 | },
1060 | "read-pkg-up": {
1061 | "version": "2.0.0",
1062 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
1063 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
1064 | "dev": true,
1065 | "requires": {
1066 | "find-up": "^2.0.0",
1067 | "read-pkg": "^2.0.0"
1068 | }
1069 | },
1070 | "resolve": {
1071 | "version": "1.12.0",
1072 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
1073 | "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
1074 | "dev": true,
1075 | "requires": {
1076 | "path-parse": "^1.0.6"
1077 | }
1078 | },
1079 | "resolve-from": {
1080 | "version": "4.0.0",
1081 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
1082 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
1083 | "dev": true
1084 | },
1085 | "reusify": {
1086 | "version": "1.0.4",
1087 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1088 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1089 | "dev": true
1090 | },
1091 | "rimraf": {
1092 | "version": "3.0.2",
1093 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1094 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1095 | "dev": true,
1096 | "requires": {
1097 | "glob": "^7.1.3"
1098 | }
1099 | },
1100 | "run-parallel": {
1101 | "version": "1.2.0",
1102 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1103 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1104 | "dev": true,
1105 | "requires": {
1106 | "queue-microtask": "^1.2.2"
1107 | }
1108 | },
1109 | "semver": {
1110 | "version": "5.7.1",
1111 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1112 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1113 | "dev": true
1114 | },
1115 | "shebang-command": {
1116 | "version": "2.0.0",
1117 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1118 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1119 | "dev": true,
1120 | "requires": {
1121 | "shebang-regex": "^3.0.0"
1122 | }
1123 | },
1124 | "shebang-regex": {
1125 | "version": "3.0.0",
1126 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1127 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1128 | "dev": true
1129 | },
1130 | "spdx-correct": {
1131 | "version": "3.1.0",
1132 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
1133 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
1134 | "dev": true,
1135 | "requires": {
1136 | "spdx-expression-parse": "^3.0.0",
1137 | "spdx-license-ids": "^3.0.0"
1138 | }
1139 | },
1140 | "spdx-exceptions": {
1141 | "version": "2.2.0",
1142 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
1143 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
1144 | "dev": true
1145 | },
1146 | "spdx-expression-parse": {
1147 | "version": "3.0.0",
1148 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
1149 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
1150 | "dev": true,
1151 | "requires": {
1152 | "spdx-exceptions": "^2.1.0",
1153 | "spdx-license-ids": "^3.0.0"
1154 | }
1155 | },
1156 | "spdx-license-ids": {
1157 | "version": "3.0.5",
1158 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
1159 | "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
1160 | "dev": true
1161 | },
1162 | "strip-ansi": {
1163 | "version": "6.0.1",
1164 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1165 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1166 | "dev": true,
1167 | "requires": {
1168 | "ansi-regex": "^5.0.1"
1169 | }
1170 | },
1171 | "strip-bom": {
1172 | "version": "3.0.0",
1173 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
1174 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
1175 | "dev": true
1176 | },
1177 | "strip-json-comments": {
1178 | "version": "3.1.1",
1179 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
1180 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
1181 | "dev": true
1182 | },
1183 | "supports-color": {
1184 | "version": "7.2.0",
1185 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1186 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1187 | "dev": true,
1188 | "requires": {
1189 | "has-flag": "^4.0.0"
1190 | }
1191 | },
1192 | "text-table": {
1193 | "version": "0.2.0",
1194 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
1195 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
1196 | "dev": true
1197 | },
1198 | "type-check": {
1199 | "version": "0.4.0",
1200 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
1201 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
1202 | "dev": true,
1203 | "requires": {
1204 | "prelude-ls": "^1.2.1"
1205 | }
1206 | },
1207 | "type-fest": {
1208 | "version": "0.20.2",
1209 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
1210 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
1211 | "dev": true
1212 | },
1213 | "uri-js": {
1214 | "version": "4.4.1",
1215 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
1216 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
1217 | "dev": true,
1218 | "requires": {
1219 | "punycode": "^2.1.0"
1220 | }
1221 | },
1222 | "validate-npm-package-license": {
1223 | "version": "3.0.4",
1224 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
1225 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
1226 | "dev": true,
1227 | "requires": {
1228 | "spdx-correct": "^3.0.0",
1229 | "spdx-expression-parse": "^3.0.0"
1230 | }
1231 | },
1232 | "which": {
1233 | "version": "2.0.2",
1234 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1235 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1236 | "dev": true,
1237 | "requires": {
1238 | "isexe": "^2.0.0"
1239 | }
1240 | },
1241 | "word-wrap": {
1242 | "version": "1.2.4",
1243 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
1244 | "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
1245 | "dev": true
1246 | },
1247 | "wrappy": {
1248 | "version": "1.0.2",
1249 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1250 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1251 | "dev": true
1252 | },
1253 | "yocto-queue": {
1254 | "version": "0.1.0",
1255 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
1256 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
1257 | "dev": true
1258 | }
1259 | }
1260 | }
1261 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mithril-node-render",
3 | "version": "3.0.2",
4 | "description": "Node rending of mithril views",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "node test.js && eslint index.js test.js"
8 | },
9 | "keywords": [
10 | "mithril",
11 | "node",
12 | "render",
13 | "template"
14 | ],
15 | "author": "Stephan Hoyer ",
16 | "license": "MIT",
17 | "peerDependencies": {
18 | "mithril": "^2.0.4"
19 | },
20 | "devDependencies": {
21 | "eslint": "8.38.0",
22 | "eslint-config-standard": "10.2.1",
23 | "eslint-plugin-import": "2.8.0",
24 | "eslint-plugin-node": "5.2.1",
25 | "eslint-plugin-promise": "3.6.0",
26 | "eslint-plugin-standard": "3.0.1",
27 | "mithril": "2.0.4",
28 | "ospec": "4.0.1"
29 | },
30 | "repository": "MithrilJS/mithril-node-render",
31 | "bugs": "https://github.com/MithrilJS/mithril-node-render/issues",
32 | "homepage": "https://github.com/MithrilJS/mithril-node-render#readme"
33 | }
34 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const o = require('ospec')
4 | const m = require('mithril/hyperscript')
5 | const render = require('./index')
6 |
7 | const ES6ClassComponent = require('./tests/fixtures/es6_class_component')
8 | const BabelClassComponent = require('./tests/fixtures/babel_class_component')
9 | const FunctionClassComponent = require('./tests/fixtures/function_class_component')
10 |
11 | o.spec('render', () => {
12 | o('should render tag', () => {
13 | o(render.sync(m('span', 'content'))).equals('content')
14 | })
15 | o('should render classname', () => {
16 | o(render.sync(m('.foo', 'content'))).equals(
17 | 'content
'
18 | )()
19 | })
20 |
21 | o('should render id', () => {
22 | o(render.sync(m('#bar', 'content'))).equals('content
')()
23 | })
24 |
25 | o('should render short nodes when no children', () => {
26 | o(render.sync(m('br'))).equals('
')()
27 | })
28 |
29 | o(
30 | 'should render short nodes when no children and tag name is uppercase',
31 | () => {
32 | o(render.sync(m('HR'))).equals('
')()
33 | }
34 | )
35 |
36 | o('should render short node doctype', () => {
37 | o(render.sync(m('!doctype'))).equals('')()
38 | })
39 |
40 | o('should render short node doctype HTML5', () => {
41 | o(render.sync(m('!doctype', { html: true }))).equals('')()
42 | })
43 |
44 | o('should render attributes', () => {
45 | o(
46 | render.sync(m('span', { 'data-foo': 'bar', selected: 'selected' }))
47 | ).equals('')()
48 | })
49 |
50 | o('should render string', () => {
51 | o(render.sync(m('ul', 'huhu'))).equals('')()
52 | })
53 |
54 | o('should render arrays', () => {
55 | o(render.sync([m('span', 'foo'), m('div', 'bar')])).equals(
56 | 'foobar
'
57 | )()
58 | })
59 |
60 | o('should render nested arrays', () => {
61 | o(render.sync(m('div', [[m('span', 'foo'), m('div', 'bar')]]))).equals(
62 | ''
63 | )()
64 | })
65 |
66 | o('should render children', () => {
67 | o(render.sync(m('span', m('div')))).equals('')()
68 | })
69 |
70 | o('should not render events', () => {
71 | o(render.sync(m('span', { onmousemove() {} }))).equals('')()
72 | })
73 |
74 | o('should render simple styles', () => {
75 | o(
76 | render.sync(
77 | m('div', { style: { height: '20px', color: '', width: '10px' } })
78 | )
79 | ).equals('')
80 | })
81 |
82 | o('should render camelcase styles', () => {
83 | o(
84 | render.sync(m('span', { style: { paddingLeft: '10px', color: 'red' } }))
85 | ).equals('')
86 | })
87 |
88 | o('should respect css vars', () => {
89 | o(
90 | render.sync(
91 | m('span', { style: { '--some-var': '10px', '--someVar': 'red' } })
92 | )
93 | ).equals('')
94 | })
95 |
96 | o('should render numbers as text nodes', () => {
97 | o(render.sync(m('div', [1, m('span'), '2']))).equals(
98 | '12
'
99 | )
100 | })
101 |
102 | o('renders attributes', () => {
103 | o(render.sync(m('div', 0))).equals('0
')
104 | o(render.sync(m('div', false))).equals('')
105 | o(render.sync(m('div', { a: true }))).equals('')
106 | o(render.sync(m('div', { a: false }))).equals('')
107 | o(render.sync(m('div', { a: undefined }))).equals('')
108 | o(render.sync(m('div', { a: 1 }))).equals('')
109 | o(render.sync(m('div', { key: 1 }))).equals('')
110 | o(render.sync(m('div', { style: null }))).equals('')
111 | o(render.sync(m('div', { style: '' }))).equals('')
112 | o(render.sync(m('div', { style: { color: '' } }))).equals('')
113 | o(render.sync(m('div', { style: { height: '20px', color: '' } }))).equals(
114 | ''
115 | )
116 |
117 | o(
118 | render.sync(
119 | m('div', { style: { height: '20px', color: '', width: '10px' } })
120 | )
121 | ).equals('')
122 | o(render.sync(m('div', { a: 'foo' }))).equals('')
123 | o(render.sync(m('div', m.trust('')))).equals(
124 | '
'
125 | )
126 | o(render.sync(m('div', ''))).equals(
127 | '<foo></foo>
'
128 | )
129 | o(render.sync(m('div', { style: '">'
131 | )
132 | o(
133 | render.sync(m('div', { style: '">')
139 | o(render.sync(m('pre', 'var = ' + JSON.stringify({ foo: 1 })))).equals(
140 | 'var = {"foo":1}
'
141 | )
142 | })
143 |
144 | o('renders svg xlink:href correctly', () => {
145 | o(render.sync(m('svg', m('use', { href: 'fooga.com' })))).equals(
146 | ''
147 | )
148 | o(render.sync(m('svg', m('use', { 'xlink:href': 'fooga.com' })))).equals(
149 | ''
150 | )
151 | })
152 |
153 | o('should render closed input-tag', () => {
154 | o(render.sync(m('input'), { strict: true })).equals('')
155 | o(render.sync(m('input'), { strict: true, xml: true })).equals(
156 | ''
157 | )
158 | })
159 | o('should render closed div-tag', () => {
160 | o(render.sync(m('div'), { strict: true })).equals('')
161 | o(render.sync(m('div'), { strict: true, xml: true })).equals('')
162 | })
163 | })
164 |
165 | o.spec('components', () => {
166 | let myComponent, onremove
167 |
168 | o.beforeEach(() => {
169 | onremove = o.spy()
170 | myComponent = {
171 | oninit(node) {
172 | node.state.foo = 'bar'
173 | },
174 | onremove,
175 | view(node) {
176 | return m('div', ['hello', node.state.foo, node.attrs.foo])
177 | },
178 | }
179 | })
180 |
181 | o('embedded', () => {
182 | o(onremove.callCount).equals(0)
183 | o(render.sync(m('div', m(myComponent)))).equals(
184 | ''
185 | )
186 | o(onremove.callCount).equals(1)
187 | o(render.sync(m('span', m(myComponent, { foo: 'foz' })))).equals(
188 | 'hellobarfoz
'
189 | )
190 | o(
191 | render.sync(
192 | m(
193 | 'div',
194 | m({
195 | oninit() {},
196 | view() {
197 | return m('span', 'huhu')
198 | },
199 | })
200 | )
201 | )
202 | ).equals('huhu
')
203 | o(
204 | render.sync(
205 | m(
206 | 'div',
207 | m({
208 | view() {
209 | return m('span', 'huhu')
210 | },
211 | })
212 | )
213 | )
214 | ).equals('huhu
')
215 | })
216 |
217 | o('as root', () => {
218 | o(render.sync(myComponent)).equals('hellobar
')
219 | o(render.sync(myComponent, { foo: '-attr-foo' })).equals(
220 | 'hellobar-attr-foo
'
221 | )
222 | })
223 |
224 | o('with children', () => {
225 | const parentComponent = {
226 | view(node) {
227 | return m('div', node.children)
228 | },
229 | }
230 |
231 | o(render.sync(m(parentComponent, 'howdy'))).equals('howdy
')
232 | o(render.sync(m(parentComponent, m('span', 'howdy')))).equals(
233 | 'howdy
'
234 | )
235 | o(
236 | render.sync(m(parentComponent, [m('span', 'foo'), m('span', 'bar')]))
237 | ).equals('foobar
')
238 | o(render.sync(m(parentComponent, m.trust('trust me')))).equals(
239 | 'trust me
'
240 | )
241 | o(render.sync(m(parentComponent, m(myComponent, { foo: 'foz' })))).equals(
242 | ''
243 | )
244 | })
245 |
246 | o('quouting html content right', () => {
247 | const component = {
248 | view() {
249 | return m('span', ['huh', '> >'])
250 | },
251 | }
252 | const out = render.sync(component)
253 | o(out).equals('huh> >')
254 | })
255 | })
256 |
257 | const classComponents = {
258 | es6: ES6ClassComponent,
259 | babel: BabelClassComponent,
260 | function: FunctionClassComponent,
261 | }
262 | for (const type in classComponents) {
263 | o.spec('component of ' + type + ' class', () => {
264 | const classComponent = classComponents[type]
265 |
266 | o('embedded', () => {
267 | o(render.sync(m('div', m(classComponent)))).equals(
268 | ''
269 | )
270 | o(render.sync(m('span', m(classComponent, { foo: 'foz' })))).equals(
271 | 'hellobarfoz
'
272 | )
273 | })
274 |
275 | o('as root', () => {
276 | o(render.sync(classComponent)).equals('hellobar
')
277 | o(render.sync(classComponent, { foo: '-attr-foo' })).equals(
278 | 'hellobar-attr-foo
'
279 | )
280 | })
281 | })
282 | }
283 |
284 | o('`this` in component', () => {
285 | const oninit = o.spy()
286 | const myComponent = {
287 | oninit(vnode) {
288 | oninit()
289 | o(this).equals(vnode.state)(
290 | 'vnode.state should be the context in `oninit`'
291 | )
292 | o(this.foo).equals(undefined)('this.foo should be undefined initially')
293 | this.foo = 5
294 | o(vnode.state.bar).equals(4)(
295 | 'component properties should be copied to the state'
296 | )
297 | },
298 | view(vnode) {
299 | o(this).equals(vnode.state)(
300 | 'vnode.state should be the context in the view'
301 | )
302 | return m('div', 'hello')
303 | },
304 | onremove(vnode) {
305 | o(this).equals(vnode.state)(
306 | 'vnode.state should be the context in `onremove`'
307 | )
308 | },
309 | bar: 4,
310 | }
311 |
312 | o(render.sync([m(myComponent), m(myComponent)])).equals(
313 | 'hello
hello
'
314 | )
315 |
316 | o(oninit.callCount).equals(2)(
317 | 'the component should have been initialized twice'
318 | )
319 | })
320 |
321 | o('lifecycle hooks as attributes on elements', () => {
322 | let initialized, removed
323 | render.sync(
324 | m('p', {
325 | oninit(vnode) {
326 | initialized = true
327 | o(this).equals(vnode.state)(
328 | 'vnode.state should be the context in `oninit`'
329 | )
330 | },
331 | onremove(vnode) {
332 | removed = true
333 | o(this).equals(vnode.state)(
334 | 'vnode.state should be the context in `onremove`'
335 | )
336 | },
337 | })
338 | )
339 | o(initialized).equals(true)('attr.oninit should run')
340 | o(removed).equals(true)('attr.onremove should run')
341 | })
342 |
343 | o('lifecycle hooks as attributes on components', () => {
344 | let attrInitialized = false
345 | let attrRemoved = false
346 | let tagInitialized = false
347 | let tagRemoved = false
348 | const myComponent = {
349 | oninit() {
350 | o(attrInitialized).equals(false)(
351 | '`attr.oninit()` should run after `tag.oninit()`'
352 | )
353 | tagInitialized = true
354 | },
355 | view() {
356 | return m('p', 'p')
357 | },
358 | onremove() {
359 | o(attrRemoved).equals(false)(
360 | '`attr.onremove()` should run after `tag.onremove()`'
361 | )
362 | tagRemoved = true
363 | },
364 | }
365 | o(
366 | render.sync(
367 | m(myComponent, {
368 | oninit(vnode) {
369 | o(this).equals(vnode.state)(
370 | 'vnode.state should be the context in `attr.oninit`'
371 | )
372 | attrInitialized = true
373 | o(tagInitialized).equals(true)(
374 | '`attr.oninit()` should run after `tag.oninit()`'
375 | )
376 | },
377 | onremove(vnode) {
378 | o(this).equals(vnode.state)(
379 | 'vnode.state should be the context in `attr.onremove`'
380 | )
381 | attrRemoved = true
382 | o(tagRemoved).equals(true)(
383 | '`attr.onremove()` should run after `tag.onremove()`'
384 | )
385 | },
386 | })
387 | )
388 | ).equals('p
')
389 | o(tagInitialized).equals(true)('tag.oninit should be called')
390 | o(tagRemoved).equals(true)('tag.onremove should be called')
391 | })
392 |
393 | o('lifecycle hooks of class component', () => {
394 | let initialized, removed
395 | const classComponent = class {
396 | constructor(vnode) {
397 | this.vnode = vnode
398 | }
399 | oninit(vnode) {
400 | initialized = true
401 | o(this).equals(vnode.state)(
402 | 'vnode.state should be the context in `oninit`'
403 | )
404 | o(this.vnode).equals(vnode)('vnode.state equals passed in constructor')
405 | }
406 | onremove(vnode) {
407 | removed = true
408 | o(this).equals(vnode.state)(
409 | 'vnode.state should be the context in `onremove`'
410 | )
411 | o(this.vnode).equals(vnode)('vnode.state equals passed in constructor')
412 | }
413 | view(vnode) {
414 | o(this).equals(vnode.state)('vnode.state should be the context in `view`')
415 | o(this.vnode).equals(vnode)('vnode.state equals passed in constructor')
416 | return m('p', 'hello')
417 | }
418 | }
419 | o(render.sync(m(classComponent))).equals('hello
')
420 | o(initialized).equals(true)('classComponent#oninit should run')
421 | o(removed).equals(true)('classComponent#onremove should run')
422 | })
423 |
424 | o(
425 | 'onremove hooks should be called once the whole tree has been inititalized',
426 | () => {
427 | let initialized = 0
428 | const onremove = o.spy()
429 | function oninit() {
430 | initialized++
431 | o(onremove.callCount).equals(0)
432 | }
433 | const attrs = { oninit, onremove }
434 | const myComponent = {
435 | oninit,
436 | view() {
437 | return m('p', attrs, 'p')
438 | },
439 | onremove,
440 | }
441 | render.sync([m(myComponent, attrs), m(myComponent, attrs)])
442 |
443 | /*
444 | We just rendered two components, and each has three sets of hooks defined:
445 | one on the component object, one passed as component attributes, and one passed
446 | as attributes in the view. => 2 × 3 === 6
447 | */
448 | o(initialized).equals(6)('oninit should run six times')
449 | o(onremove.callCount).equals(6)('onremove should run six times')
450 | }
451 | )
452 |
453 | o('hooks are called top-down, depth-first on elements', () => {
454 | /*
455 | Suppose a tree with the following structure: two levels of depth,
456 | two components on the first depth level, the first one having a
457 | single child on level 2.
458 |
459 | +-- p
460 | | +-- a
461 | |
462 | +-- ul
463 |
464 | */
465 | let pInit = false
466 | let aInit = false
467 | let ulInit = false
468 | let pRemoved = false
469 | let aRemoved = false
470 | let ulRemoved = false
471 | const html = render.sync([
472 | m(
473 | 'p',
474 | {
475 | oninit() {
476 | pInit = true
477 | o(aInit).equals(false)
478 | o(ulInit).equals(false)
479 | },
480 | onremove() {
481 | pRemoved = true
482 | o(aRemoved).equals(false)
483 | o(ulRemoved).equals(false)
484 | },
485 | },
486 | m(
487 | 'a',
488 | {
489 | oninit() {
490 | aInit = true
491 | o(pInit).equals(true)
492 | o(ulInit).equals(false)
493 | },
494 | onremove() {
495 | aRemoved = true
496 | o(pRemoved).equals(true)
497 | o(ulRemoved).equals(false)
498 | },
499 | },
500 | 'q'
501 | )
502 | ),
503 | m(
504 | 'ul',
505 | {
506 | oninit() {
507 | ulInit = true
508 | o(pInit).equals(true)
509 | o(aInit).equals(true)
510 | },
511 | onremove() {
512 | ulRemoved = true
513 | o(pRemoved).equals(true)
514 | o(aRemoved).equals(true)
515 | },
516 | },
517 | 'r'
518 | ),
519 | ])
520 | o(html).equals('q
')
521 | o(pInit && ulInit && aInit && pRemoved && ulRemoved && aRemoved).equals(true)
522 | })
523 |
524 | o.spec('async', () => {
525 | o('render object components', async () => {
526 | const oninitSpy = o.spy()
527 | const viewSpy = o.spy()
528 | const myAsyncComponent = {
529 | oninit(vnode, waitFor) {
530 | this.foo = 'bar'
531 | oninitSpy()
532 | waitFor(
533 | Promise.resolve().then(() => {
534 | this.foo = 'baz'
535 | })
536 | )
537 | },
538 | view() {
539 | viewSpy()
540 | return m('div', this.foo)
541 | },
542 | }
543 |
544 | const p = render(myAsyncComponent)
545 | o(oninitSpy.callCount).equals(1)
546 | o(viewSpy.callCount).equals(0)
547 | const html = await p
548 | o(html).equals('baz
')
549 | o(oninitSpy.callCount).equals(1)
550 | o(viewSpy.callCount).equals(1)
551 | })
552 |
553 | o('render nodes', async () => {
554 | const oninitSpy = o.spy()
555 | const html = await render(
556 | m(
557 | 'span',
558 | {
559 | oninit(node, waitFor) {
560 | waitFor(
561 | new Promise(resolve => {
562 | oninitSpy()
563 | setTimeout(resolve, 10)
564 | })
565 | )
566 | },
567 | },
568 | 'foo'
569 | )
570 | )
571 | o(html).equals('foo')
572 | o(oninitSpy.callCount).equals(1)
573 | })
574 |
575 | o('render object components sync', () => {
576 | const waitFors = []
577 | const myAsyncComponent = {
578 | oninit(vnode, waitFor) {
579 | waitFors.push(waitFor)
580 | this.foo = 'bar'
581 | return Promise.resolve().then(() => {
582 | this.foo = 'baz'
583 | })
584 | },
585 | view() {
586 | return m('div', this.foo)
587 | },
588 | }
589 |
590 | const html = render.sync(myAsyncComponent)
591 | o(waitFors).deepEquals([undefined])
592 | o(html).equals('bar
')
593 | })
594 |
595 | o('render nodes sync', () => {
596 | const waitFors = []
597 | const oninitSpy = o.spy()
598 | const html = render.sync(
599 | m(
600 | 'span',
601 | {
602 | oninit(node, waitFor) {
603 | waitFors.push(waitFor)
604 | return new Promise(resolve => {
605 | oninitSpy()
606 | setTimeout(resolve, 10)
607 | })
608 | },
609 | },
610 | 'foo'
611 | )
612 | )
613 | o(waitFors).deepEquals([undefined])
614 | o(html).equals('foo')
615 | o(oninitSpy.callCount).equals(1)
616 | })
617 | })
618 |
619 | o('render closure components', () => {
620 | const closureComponent = () => {
621 | return {
622 | view() {
623 | return m('p', 'p')
624 | },
625 | }
626 | }
627 | o(render.sync(closureComponent())).equals('p
')
628 | })
629 |
630 | o.run()
631 |
--------------------------------------------------------------------------------
/tests/fixtures/babel_class_component.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
4 |
5 | function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6 |
7 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
8 |
9 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
10 |
11 | var m = require('mithril/hyperscript');
12 |
13 | var BabelClassComponent =
14 | /*#__PURE__*/
15 | function () {
16 | function BabelClassComponent(vnode) {
17 | _classCallCheck(this, BabelClassComponent);
18 |
19 | this.vnode = vnode;
20 | }
21 |
22 | _createClass(BabelClassComponent, [{
23 | key: "oninit",
24 | value: function oninit() {
25 | this.vnode.state.foo = 'bar';
26 | }
27 | }, {
28 | key: "view",
29 | value: function view() {
30 | return m('div', ['hello', this.vnode.state.foo, this.vnode.attrs.foo]);
31 | }
32 | }]);
33 |
34 | return BabelClassComponent;
35 | }();
36 |
37 | module.exports = BabelClassComponent;
38 |
--------------------------------------------------------------------------------
/tests/fixtures/es6_class_component.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const m = require('mithril/hyperscript')
3 |
4 | class ES6ClassComponent {
5 | constructor (vnode) {
6 | this.vnode = vnode
7 | }
8 |
9 | oninit () {
10 | this.vnode.state.foo = 'bar'
11 | }
12 |
13 | view () {
14 | return m('div', ['hello', this.vnode.state.foo, this.vnode.attrs.foo])
15 | }
16 | }
17 |
18 | module.exports = ES6ClassComponent
19 |
--------------------------------------------------------------------------------
/tests/fixtures/function_class_component.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const m = require('mithril/hyperscript')
4 |
5 | function ClassComponent (vnode) {
6 | this.vnode = vnode
7 | }
8 |
9 | ClassComponent.prototype.oninit = function oninit () {
10 | this.vnode.state.foo = 'bar'
11 | }
12 |
13 | ClassComponent.prototype.view = function view () {
14 | return m('div', ['hello', this.vnode.state.foo, this.vnode.attrs.foo])
15 | }
16 |
17 | module.exports = ClassComponent
18 |
--------------------------------------------------------------------------------