From dd416405d199ce5fa0dd751dca89434fc64cc47b Mon Sep 17 00:00:00 2001 From: NickLin Date: Tue, 10 Jun 2025 15:30:06 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=8E=AE=20test:=20add=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- coverage/base.css | 224 +++++ coverage/block-navigation.js | 87 ++ coverage/coverage-final.json | 8 + coverage/favicon.png | Bin 0 -> 445 bytes coverage/index.html | 146 +++ coverage/prettify.css | 1 + coverage/prettify.js | 2 + coverage/sort-arrow-sprite.png | Bin 0 -> 138 bytes coverage/sorter.js | 196 ++++ coverage/src/commands/index.html | 146 +++ coverage/src/commands/index.ts.html | 619 ++++++++++++ coverage/src/commands/init.ts.html | 256 +++++ coverage/src/commands/where.ts.html | 106 ++ coverage/src/helper/commit-types.ts.html | 325 ++++++ coverage/src/helper/index.html | 146 +++ coverage/src/helper/index.ts.html | 91 ++ coverage/src/helper/projects.ts.html | 181 ++++ coverage/src/index.html | 116 +++ coverage/src/index.ts.html | 181 ++++ package.json | 16 +- pnpm-lock.yaml | 1116 ++++++++++++++++++++- src/commands/init.ts | 2 +- src/helper/commit-types.ts | 2 +- tests/commands/cli-module-loading.test.ts | 58 ++ tests/commands/cli-validation.test.ts | 192 ++++ tests/commands/cli.test.ts | 362 +++++++ tests/commands/init.test.ts | 188 ++++ tests/commands/where.test.ts | 37 + tests/helper/commit-types.test.ts | 50 + tests/helper/projects.test.ts | 62 ++ tests/index.test.ts | 93 ++ tests/setup.ts | 11 + tests/utils/test-helpers.ts | 46 + vitest.config.ts | 27 + 35 files changed, 5084 insertions(+), 13 deletions(-) create mode 100644 coverage/base.css create mode 100644 coverage/block-navigation.js create mode 100644 coverage/coverage-final.json create mode 100644 coverage/favicon.png create mode 100644 coverage/index.html create mode 100644 coverage/prettify.css create mode 100644 coverage/prettify.js create mode 100644 coverage/sort-arrow-sprite.png create mode 100644 coverage/sorter.js create mode 100644 coverage/src/commands/index.html create mode 100644 coverage/src/commands/index.ts.html create mode 100644 coverage/src/commands/init.ts.html create mode 100644 coverage/src/commands/where.ts.html create mode 100644 coverage/src/helper/commit-types.ts.html create mode 100644 coverage/src/helper/index.html create mode 100644 coverage/src/helper/index.ts.html create mode 100644 coverage/src/helper/projects.ts.html create mode 100644 coverage/src/index.html create mode 100644 coverage/src/index.ts.html create mode 100644 tests/commands/cli-module-loading.test.ts create mode 100644 tests/commands/cli-validation.test.ts create mode 100644 tests/commands/cli.test.ts create mode 100644 tests/commands/init.test.ts create mode 100644 tests/commands/where.test.ts create mode 100644 tests/helper/commit-types.test.ts create mode 100644 tests/helper/projects.test.ts create mode 100644 tests/index.test.ts create mode 100644 tests/setup.ts create mode 100644 tests/utils/test-helpers.ts create mode 100644 vitest.config.ts diff --git a/README.md b/README.md index 4fb3fc8..8a9875c 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ input Jira issue ID name: 'storybook', emoji: '๐Ÿ“š', description: 'New storybook', - value: 'story' + value: 'storybook' }, { name: 'revert', @@ -193,5 +193,5 @@ input Jira issue ID ## Todo - [x] adapt for other projects prefix -- [ ] unit test +- [x] unit test - [ ] CLI diff --git a/coverage/base.css b/coverage/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js new file mode 100644 index 0000000..cc12130 --- /dev/null +++ b/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000..8b7cdd8 --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,8 @@ +{"/Users/nick/Desktop/Projects/cz/src/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":58}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":26}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":14}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":15}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":19}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":47}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":8}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":16}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":19}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":42}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":7}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":6}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":11}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":17}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":18}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":26}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":11}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":10}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":9}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":3}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":1}}},"s":{"0":1,"9":6,"10":6,"11":6,"12":6,"13":6,"14":6,"15":6,"16":6,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"24":6,"25":2,"26":6,"27":2,"28":2,"29":2,"30":2,"31":6},"branchMap":{"0":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"locations":[{"start":{"line":10,"column":0},"end":{"line":32,"column":1}}]},"1":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":17},"end":{"line":27,"column":13}},"locations":[{"start":{"line":25,"column":17},"end":{"line":27,"column":13}}]},"2":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":2},"end":{"line":31,"column":3}},"locations":[{"start":{"line":27,"column":2},"end":{"line":31,"column":3}}]},"3":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":25},"end":{"line":31,"column":3}},"locations":[{"start":{"line":27,"column":25},"end":{"line":31,"column":3}}]}},"b":{"0":[6],"1":[2],"2":[4],"3":[2]},"fnMap":{"0":{"name":"run","decl":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"loc":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"line":10}},"f":{"0":6}} +,"/Users/nick/Desktop/Projects/cz/src/commands/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":25}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":49}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":44}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":40}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":57}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":42}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":28}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":5}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":59}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":42}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":64}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":13}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":115}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":26}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":1}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":44}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":51}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":20}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":19}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":3}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":19}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":23}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":22}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":33}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":21}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":30}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":1}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":22}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":15}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":25}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":30}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":63}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":44}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":4}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":32}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":17}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":42}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":5}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":15}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":1}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":26}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":15}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":29}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":43}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":14}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":32}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":29}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":39}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":5}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":15}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":1}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":22}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":18}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":18}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":30}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":16}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":1}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":47}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":22}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":49}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":22}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":3}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":91}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":33}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":51}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":29}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":89}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":15}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":1}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":27}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":62}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":18}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":37}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":14}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":24}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":12}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":4}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":23}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":34}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":24}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":20}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":33}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":1}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":22}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":50}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":18}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":27}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":15}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":96}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":4}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":32}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":17}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":41}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":5}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":15}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":3}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":1}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":28}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":24}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":17}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":14}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":17}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":21}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":17}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":59}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":22}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":16}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":44}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":41}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":36}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":34}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":25}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":19}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":7}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":6}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":27}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":23}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":18}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":5}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":4}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":19}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":54}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":16}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":3}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":122}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":66}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":71}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":80}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":79}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":24}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":57}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":17}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":7}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":119}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":53}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":73}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":62}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":78}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":52}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":37}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":80}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":54}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":5}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":78}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":102}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":29}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":116}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":5}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":182}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":24}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":45}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":92}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":29}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":3}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"8":1,"9":1,"11":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"22":1,"23":39,"24":39,"25":39,"26":39,"27":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"37":1,"38":1,"39":1,"40":1,"41":0,"42":0,"43":0,"44":1,"45":0,"46":0,"47":0,"48":0,"49":0,"50":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":0,"59":0,"60":0,"61":0,"62":0,"63":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"72":1,"73":15,"74":15,"75":15,"76":1,"78":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"87":1,"88":1,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"102":1,"103":1,"104":1,"105":1,"106":1,"107":0,"108":0,"109":1,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"117":1,"118":33,"119":33,"120":33,"121":33,"122":33,"123":33,"124":33,"125":33,"126":33,"127":33,"128":33,"129":33,"130":1,"131":1,"132":1,"133":1,"134":1,"135":33,"136":1,"137":1,"138":1,"139":33,"141":33,"142":2,"143":2,"144":2,"146":31,"147":31,"148":31,"149":33,"150":33,"151":33,"152":11,"153":20,"155":33,"156":33,"157":33,"158":29,"159":29,"160":29,"161":29,"162":33,"163":3,"164":3,"165":3,"166":29,"167":29,"168":33,"169":2,"170":2,"171":29,"172":33,"173":2,"174":2,"175":1,"176":2,"177":33},"branchMap":{"0":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":0},"end":{"line":21,"column":1}},"locations":[{"start":{"line":18,"column":0},"end":{"line":21,"column":1}}]},"1":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":19},"end":{"line":84,"column":40}},"locations":[{"start":{"line":84,"column":19},"end":{"line":84,"column":40}}]},"2":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":59},"end":{"line":84,"column":86}},"locations":[{"start":{"line":84,"column":59},"end":{"line":84,"column":86}}]},"3":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":34},"end":{"line":28,"column":2}},"locations":[{"start":{"line":23,"column":34},"end":{"line":28,"column":2}}]},"4":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":34},"end":{"line":77,"column":2}},"locations":[{"start":{"line":73,"column":34},"end":{"line":77,"column":2}}]},"5":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":41},"end":{"line":79,"column":89}},"locations":[{"start":{"line":79,"column":41},"end":{"line":79,"column":89}}]},"6":{"type":"branch","line":118,"loc":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"locations":[{"start":{"line":118,"column":15},"end":{"line":178,"column":1}}]},"7":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":28},"end":{"line":125,"column":59}},"locations":[{"start":{"line":125,"column":28},"end":{"line":125,"column":59}}]},"8":{"type":"branch","line":142,"loc":{"start":{"line":142,"column":18},"end":{"line":145,"column":3}},"locations":[{"start":{"line":142,"column":18},"end":{"line":145,"column":3}}]},"9":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":150,"column":44}},"locations":[{"start":{"line":145,"column":2},"end":{"line":150,"column":44}}]},"10":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":23},"end":{"line":150,"column":68}},"locations":[{"start":{"line":150,"column":23},"end":{"line":150,"column":68}}]},"11":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":60},"end":{"line":150,"column":80}},"locations":[{"start":{"line":150,"column":60},"end":{"line":150,"column":80}}]},"12":{"type":"branch","line":152,"loc":{"start":{"line":152,"column":17},"end":{"line":153,"column":57}},"locations":[{"start":{"line":152,"column":17},"end":{"line":153,"column":57}}]},"13":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":55},"end":{"line":154,"column":17}},"locations":[{"start":{"line":153,"column":55},"end":{"line":154,"column":17}}]},"14":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":21},"end":{"line":157,"column":95}},"locations":[{"start":{"line":157,"column":21},"end":{"line":157,"column":95}}]},"15":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":91},"end":{"line":157,"column":119}},"locations":[{"start":{"line":157,"column":91},"end":{"line":157,"column":119}}]},"16":{"type":"branch","line":158,"loc":{"start":{"line":158,"column":52},"end":{"line":163,"column":36}},"locations":[{"start":{"line":158,"column":52},"end":{"line":163,"column":36}}]},"17":{"type":"branch","line":163,"loc":{"start":{"line":163,"column":36},"end":{"line":166,"column":5}},"locations":[{"start":{"line":163,"column":36},"end":{"line":166,"column":5}}]},"18":{"type":"branch","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":169,"column":28}},"locations":[{"start":{"line":166,"column":4},"end":{"line":169,"column":28}}]},"19":{"type":"branch","line":169,"loc":{"start":{"line":169,"column":28},"end":{"line":171,"column":5}},"locations":[{"start":{"line":169,"column":28},"end":{"line":171,"column":5}}]},"20":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":173,"column":11}},"locations":[{"start":{"line":171,"column":4},"end":{"line":173,"column":11}}]},"21":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":2},"end":{"line":177,"column":3}},"locations":[{"start":{"line":173,"column":2},"end":{"line":177,"column":3}}]},"22":{"type":"branch","line":175,"loc":{"start":{"line":175,"column":30},"end":{"line":176,"column":29}},"locations":[{"start":{"line":175,"column":30},"end":{"line":176,"column":29}}]},"23":{"type":"branch","line":130,"loc":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"locations":[{"start":{"line":130,"column":14},"end":{"line":135,"column":6}}]},"24":{"type":"branch","line":136,"loc":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"locations":[{"start":{"line":136,"column":14},"end":{"line":139,"column":5}}]},"25":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":30},"end":{"line":148,"column":64}},"locations":[{"start":{"line":148,"column":30},"end":{"line":148,"column":64}}]},"26":{"type":"branch","line":151,"loc":{"start":{"line":151,"column":36},"end":{"line":151,"column":77}},"locations":[{"start":{"line":151,"column":36},"end":{"line":151,"column":77}}]}},"b":{"0":[1],"1":[2],"2":[2],"3":[39],"4":[15],"5":[7],"6":[33],"7":[0],"8":[2],"9":[31],"10":[2],"11":[29],"12":[11],"13":[20],"14":[2],"15":[29],"16":[29],"17":[3],"18":[29],"19":[2],"20":[29],"21":[2],"22":[1],"23":[1],"24":[1],"25":[165],"26":[128]},"fnMap":{"0":{"name":"message","decl":{"start":{"line":41,"column":11},"end":{"line":44,"column":4}},"loc":{"start":{"line":41,"column":11},"end":{"line":44,"column":4}},"line":41},"1":{"name":"validate","decl":{"start":{"line":45,"column":12},"end":{"line":50,"column":3}},"loc":{"start":{"line":45,"column":12},"end":{"line":50,"column":3}},"line":45},"2":{"name":"validate","decl":{"start":{"line":58,"column":12},"end":{"line":63,"column":3}},"loc":{"start":{"line":58,"column":12},"end":{"line":63,"column":3}},"line":58},"3":{"name":"type","decl":{"start":{"line":82,"column":8},"end":{"line":82,"column":51}},"loc":{"start":{"line":82,"column":8},"end":{"line":82,"column":51}},"line":82},"4":{"name":"type","decl":{"start":{"line":89,"column":8},"end":{"line":95,"column":4}},"loc":{"start":{"line":89,"column":8},"end":{"line":95,"column":4}},"line":89},"5":{"name":"type","decl":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"loc":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"line":104},"6":{"name":"onRender","decl":{"start":{"line":107,"column":2},"end":{"line":109,"column":4}},"loc":{"start":{"line":107,"column":2},"end":{"line":109,"column":4}},"line":107},"7":{"name":"validate","decl":{"start":{"line":110,"column":12},"end":{"line":115,"column":3}},"loc":{"start":{"line":110,"column":12},"end":{"line":115,"column":3}},"line":110},"8":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"loc":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"line":118},"9":{"name":"onSubmit","decl":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"loc":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"line":130},"10":{"name":"onCancel","decl":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"loc":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"line":136}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":33,"9":1,"10":1}} +,"/Users/nick/Desktop/Projects/cz/src/commands/init.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/init.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":19}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":36}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":29}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":44}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":40}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":57}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":42}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":47}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":22}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":49}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":22}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":3}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":19}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":23}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":30}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":41}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":24}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":33}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":33}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":28}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":24}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":47}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":36}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":34}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":25}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":19}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":7}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":6}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":27}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":23}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":18}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":5}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":4}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":19}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":52}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":16}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":42}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":7}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":61}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":21}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":15}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":75}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":5}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":82}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":19}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":74}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"7":1,"8":1,"10":1,"11":5,"12":5,"13":5,"14":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"24":1,"25":11,"26":11,"27":11,"28":1,"29":1,"30":1,"31":1,"32":1,"33":11,"34":1,"35":1,"36":1,"37":11,"39":11,"40":2,"41":2,"42":2,"44":9,"46":9,"47":9,"48":9,"49":9,"50":9,"51":9,"52":9,"53":11,"54":1,"55":1,"56":11},"branchMap":{"0":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":34},"end":{"line":15,"column":2}},"locations":[{"start":{"line":11,"column":34},"end":{"line":15,"column":2}}]},"1":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"locations":[{"start":{"line":25,"column":15},"end":{"line":57,"column":1}}]},"2":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":18},"end":{"line":43,"column":3}},"locations":[{"start":{"line":40,"column":18},"end":{"line":43,"column":3}}]},"3":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":54,"column":11}},"locations":[{"start":{"line":43,"column":2},"end":{"line":54,"column":11}}]},"4":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":3}},"locations":[{"start":{"line":54,"column":2},"end":{"line":56,"column":3}}]},"5":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"locations":[{"start":{"line":28,"column":14},"end":{"line":33,"column":6}}]},"6":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"locations":[{"start":{"line":34,"column":14},"end":{"line":37,"column":5}}]}},"b":{"0":[5],"1":[11],"2":[2],"3":[9],"4":[1],"5":[1],"6":[1]},"fnMap":{"0":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"loc":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"line":25},"1":{"name":"onSubmit","decl":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"loc":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"line":28},"2":{"name":"onCancel","decl":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"loc":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"line":34}},"f":{"0":11,"1":1,"2":1}} +,"/Users/nick/Desktop/Projects/cz/src/commands/where.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/where.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":40}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":57}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":22}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":59}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":1}}},"s":{"0":1,"1":1,"3":1,"4":1,"5":2,"6":2},"branchMap":{"0":{"type":"branch","line":5,"loc":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"locations":[{"start":{"line":5,"column":15},"end":{"line":7,"column":1}}]}},"b":{"0":[2]},"fnMap":{"0":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"loc":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"line":5}},"f":{"0":2}} +,"/Users/nick/Desktop/Projects/cz/src/helper/commit-types.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/commit-types.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":3}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":18}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":16}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":59}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":18}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":4}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":15}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":16}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":38}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":15}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":4}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":3}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":16}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":46}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":17}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":4}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":3}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":17}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":16}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":33}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":17}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":4}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":3}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":16}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":16}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":29}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":16}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":19}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":16}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":33}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":19}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":4}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":3}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":17}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":15}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":59}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":17}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":4}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":21}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":16}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":76}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":21}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":4}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":20}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":16}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":43}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":20}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":4}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":18}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":16}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":75}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":18}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":4}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":3}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":17}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":16}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":40}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":17}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":4}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":3}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":22}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":16}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":33}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":22}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":4}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":19}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":16}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":35}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":19}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":3}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} +,"/Users/nick/Desktop/Projects/cz/src/helper/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}},"s":{"0":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} +,"/Users/nick/Desktop/Projects/cz/src/helper/projects.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/projects.ts","all":false,"statementMap":{"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":27}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":19}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":21}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":19}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":4}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":3}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":20}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":4}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":3}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":19}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":18}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":19}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":4}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":3}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":17}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":19}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":4}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":3}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":23}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":17}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":23}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":1}}},"s":{"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} +} diff --git a/coverage/favicon.png b/coverage/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 92.52% + Statements + 322/348 +
+ + +
+ 97.43% + Branches + 38/39 +
+ + +
+ 50% + Functions + 8/16 +
+ + +
+ 92.52% + Lines + 322/348 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
src +
+
100%23/23100%4/4100%1/1100%23/23
src/commands +
+
88.01%191/21797.14%34/3546.66%7/1588.01%191/217
src/helper +
+
100%108/108100%0/0100%0/0100%108/108
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/coverage/sorter.js b/coverage/sorter.js new file mode 100644 index 0000000..2bb296a --- /dev/null +++ b/coverage/sorter.js @@ -0,0 +1,196 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if ( + row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/src/commands/index.html b/coverage/src/commands/index.html new file mode 100644 index 0000000..b2754f2 --- /dev/null +++ b/coverage/src/commands/index.html @@ -0,0 +1,146 @@ + + + + + + Code coverage report for src/commands + + + + + + + + + +
+
+

All files src/commands

+
+ +
+ 88.01% + Statements + 191/217 +
+ + +
+ 97.14% + Branches + 34/35 +
+ + +
+ 46.66% + Functions + 7/15 +
+ + +
+ 88.01% + Lines + 191/217 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
index.ts +
+
83.85%135/16196.29%26/2727.27%3/1183.85%135/161
init.ts +
+
100%50/50100%7/7100%3/3100%50/50
where.ts +
+
100%6/6100%1/1100%1/1100%6/6
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/commands/index.ts.html b/coverage/src/commands/index.ts.html new file mode 100644 index 0000000..ed3dc0b --- /dev/null +++ b/coverage/src/commands/index.ts.html @@ -0,0 +1,619 @@ + + + + + + Code coverage report for src/commands/index.ts + + + + + + + + + +
+
+

All files / src/commands index.ts

+
+ +
+ 83.85% + Statements + 135/161 +
+ + +
+ 96.29% + Branches + 26/27 +
+ + +
+ 27.27% + Functions + 3/11 +
+ + +
+ 83.85% + Lines + 135/161 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +1791x +1x +1x +1x +1x +1x +1x +  +1x +1x +  +1x +  +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +39x +39x +39x +39x +1x +  +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +1x +  +  +  +1x +  +  +  +  +  +1x +  +1x +1x +1x +1x +1x +1x +  +  +  +  +  +1x +  +1x +1x +1x +1x +1x +1x +  +1x +15x +15x +15x +1x +  +1x +  +1x +1x +1x +1x +1x +1x +  +1x +1x +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +1x +1x +  +  +1x +  +  +  +  +  +1x +  +1x +33x +33x +33x +33x +33x +33x +33x +33x +33x +33x +33x +33x +1x +1x +1x +1x +1x +33x +1x +1x +1x +33x +  +33x +2x +2x +2x +  +31x +31x +31x +33x +33x +33x +11x +20x +  +33x +33x +33x +29x +29x +29x +29x +33x +3x +3x +3x +29x +29x +33x +2x +2x +29x +33x +2x +2x +1x +2x +33x + 
import prompts from 'prompts'
+import execa from 'execa'
+import { projects, commitTypes } from '../helper'
+import picocolors from 'picocolors'
+import fs from 'fs'
+import { dirname, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+ 
+const __dirname = dirname(fileURLToPath(import.meta.url))
+const rootPath = resolve(__dirname, '../')
+ 
+let defaultProjectValue = ''
+ 
+try {
+  const filePath = resolve(rootPath, 'keep/cz_config.json')
+  const config = fs.readFileSync(filePath)
+  defaultProjectValue = JSON.parse(config as any).defaultProject
+} catch (e) {
+  console.log(picocolors.yellow(picocolors.italic(' ๐Ÿ’ก You can try `cz -i` to choose a default project prefix. ')))
+  defaultProjectValue = ''
+}
+ 
+const typesList = commitTypes.map(type => ({
+  title: type.name,
+  description: `${type.emoji} ${type.description}`,
+  value: type.value,
+  emoji: type.emoji
+}))
+ 
+const step_type = {
+  type: 'autocomplete',
+  name: 'commit_type',
+  message: 'Pick a commit type.',
+  choices: typesList,
+  fallback: 'No matched type.'
+}
+ 
+const step_message = {
+  type: 'text',
+  name: 'commit_message',
+  message: (prev: string) => {
+    const target = typesList.find(type => type.value === prev)!
+    return `${target.emoji} ${target.title}`
+  },
+  validate: (value: string) => {
+    if (!value) {
+      return 'Commit message is required.'
+    }
+    return true
+  }
+}
+ 
+const step_description = {
+  type: 'text',
+  name: 'commit_description',
+  message: 'Commit description (optional)',
+  initial: '',
+  validate: (value: string) => {
+    if (value.length > 100) {
+      return 'Description is too long.'
+    }
+    return true
+  }
+}
+ 
+const step_is_jira = {
+  type: 'confirm',
+  name: 'is_jira',
+  message: 'Tag Jira issue ?',
+  initial: false
+}
+ 
+const projectsList = projects.map(project => ({
+  title: project.name,
+  description: `[${project.prefix}-13845] title`,
+  value: project.value
+}))
+ 
+const defaultProject = projectsList.find(project => project.value === defaultProjectValue)!
+ 
+const step_is_default_project = {
+  type: (prev: boolean) => prev ? 'confirm' : null,
+  name: 'is_default_project',
+  message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`,
+  initial: true
+}
+ 
+const step_project_type = {
+  type: (prev: string, { is_jira }: { is_jira: boolean }) => {
+    return is_jira
+      ? defaultProject?.value && prev
+        ? null
+        : 'autocomplete'
+      : null
+  },
+  name: 'project_type',
+  message: 'Pick a project type.',
+  choices: projectsList,
+  initial: 'owlpay',
+  fallback: 'No matched project.'
+}
+ 
+const step_jira_id = {
+  type: (prev: boolean) => prev ? 'number' : null,
+  name: 'jira_id',
+  message: 'Jira issue id',
+  onRender () {
+    (this as any).msg = picocolors.bgCyan(picocolors.white(' Jira issue ID ')) // TODO: fix type
+  },
+  validate: (value: number) => {
+    if (!value) {
+      return 'Jira issue ID is required.'
+    }
+    return true
+  }
+}
+ 
+export default async () => {
+  let isCanceled = false
+  const order = [
+    step_type,
+    step_message,
+    step_description,
+    step_is_jira,
+    defaultProject?.value ? step_is_default_project : null,
+    step_project_type,
+    step_jira_id
+  ].filter(Boolean) as any // TODO: fix type
+  const response = await prompts(order, {
+    onSubmit: (prompt, answers) => {
+      if (answers === undefined) {
+        isCanceled = true
+        return true
+      }
+    },
+    onCancel: (prompt) => {
+      isCanceled = true
+      return false
+    }
+  })
+ 
+  if (isCanceled) {
+    console.log(picocolors.magenta(' commit abort. '))
+    return false
+  }
+ 
+  const { commit_type, commit_message, commit_description, is_jira, is_default_project, project_type, jira_id } = response
+  const type = typesList.find(type => type.value === commit_type)!
+  const commitTitle = `${type.emoji} ${commit_type}: ${commit_message}`
+  const typeResponse = is_default_project ? defaultProject?.value : project_type
+  const projectType = projects.find(project => project.value === typeResponse)!
+  const result = is_jira
+    ? `[${projectType.prefix}-${jira_id}] ${commitTitle}`
+    : commitTitle
+ 
+  try {
+    const commands = commit_description ? ['commit', '-m', result, '-m', commit_description] : ['commit', '-m', result]
+    const commitResult = await execa('git', commands)
+    const branchHashName = commitResult.stdout.match(/\[(.*?)\]/)!.pop()!
+    const [branchName, branchHash] = branchHashName.split(' ')
+    console.log('-----------------------------------------------------------')
+    console.log(picocolors.dim(commitResult.stdout))
+    if (commitResult.stderr !== '') {
+      console.log('-----------------------------------------------------------')
+      console.log(picocolors.dim(commitResult.stderr))
+    }
+    console.log('-----------------------------------------------------------')
+    console.log(`${picocolors.bgGreen(picocolors.bold(' Title       '))} ${picocolors.green(result)}`)
+    if (commit_description) {
+      console.log(`${picocolors.bgGreen(picocolors.bold(' Description '))} ${picocolors.green(commit_description)}`)
+    }
+    console.log(`${picocolors.bgGreen(picocolors.bold(' Commit hash '))} ${picocolors.bold(picocolors.cyan(` ${branchHash} `))} (${picocolors.italic(picocolors.green(branchName))})`)
+  } catch (error: any) {
+    console.log(picocolors.red(error.stderr))
+    if (error.exitCode === 1) console.log(picocolors.bgRed(' No changes added to commit. '))
+    else console.error(error)
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/commands/init.ts.html b/coverage/src/commands/init.ts.html new file mode 100644 index 0000000..77c988f --- /dev/null +++ b/coverage/src/commands/init.ts.html @@ -0,0 +1,256 @@ + + + + + + Code coverage report for src/commands/init.ts + + + + + + + + + +
+
+

All files / src/commands init.ts

+
+ +
+ 100% + Statements + 50/50 +
+ + +
+ 100% + Branches + 7/7 +
+ + +
+ 100% + Functions + 3/3 +
+ + +
+ 100% + Lines + 50/50 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +581x +1x +1x +1x +1x +1x +  +1x +1x +  +1x +5x +5x +5x +1x +  +1x +1x +1x +1x +1x +1x +1x +  +1x +11x +11x +11x +1x +1x +1x +1x +1x +11x +1x +1x +1x +11x +  +11x +2x +2x +2x +  +9x +  +9x +9x +9x +9x +9x +9x +9x +11x +1x +1x +11x + 
import fs from 'fs'
+import { projects } from '../helper'
+import prompts from 'prompts'
+import picocolors from 'picocolors'
+import { dirname, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+ 
+const __dirname = dirname(fileURLToPath(import.meta.url))
+const rootPath = resolve(__dirname, '../')
+ 
+const projectsList = projects.map(project => ({
+  title: project.name,
+  description: `[${project.prefix}-13845] title`,
+  value: project.value
+}))
+ 
+const step_type = {
+  type: 'autocomplete',
+  name: 'set_default_project',
+  message: 'Set default project prefix.',
+  choices: projectsList,
+  fallback: 'No matched project.'
+} as const // TODO: Fix this type
+ 
+export default async () => {
+  let isCanceled = false
+  const response = await prompts([step_type], {
+    onSubmit: (prompt, answers) => {
+      if (answers === undefined) {
+        isCanceled = true
+        return true
+      }
+    },
+    onCancel: (prompt) => {
+      isCanceled = true
+      return false
+    }
+  })
+ 
+  if (isCanceled) {
+    console.log(picocolors.magenta(' init abort. '))
+    return false
+  }
+ 
+  const { set_default_project } = response
+ 
+  try {
+    const filePath = resolve(rootPath, 'keep/cz_config.json')
+    fs.writeFileSync(
+      filePath,
+      `${JSON.stringify({ defaultProject: set_default_project }, null, 2)}`
+    )
+    console.log(picocolors.green(` default project set: ${set_default_project} `))
+  } catch (error) {
+    console.log(picocolors.bgRed(picocolors.white(`init Fail: ${error}`)))
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/commands/where.ts.html b/coverage/src/commands/where.ts.html new file mode 100644 index 0000000..ac043ed --- /dev/null +++ b/coverage/src/commands/where.ts.html @@ -0,0 +1,106 @@ + + + + + + Code coverage report for src/commands/where.ts + + + + + + + + + +
+
+

All files / src/commands where.ts

+
+ +
+ 100% + Statements + 6/6 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 6/6 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +81x +1x +  +1x +1x +2x +2x + 
import { dirname } from 'node:path'
+import { fileURLToPath } from 'node:url'
+ 
+const __dirname = dirname(fileURLToPath(import.meta.url))
+export default () => {
+  console.log(`Your config will be saved in ${__dirname}.`)
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/helper/commit-types.ts.html b/coverage/src/helper/commit-types.ts.html new file mode 100644 index 0000000..6c60c89 --- /dev/null +++ b/coverage/src/helper/commit-types.ts.html @@ -0,0 +1,325 @@ + + + + + + Code coverage report for src/helper/commit-types.ts + + + + + + + + + +
+
+

All files / src/helper commit-types.ts

+
+ +
+ 100% + Statements + 80/80 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 80/80 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +811x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x + 
export default [
+  {
+    name: 'chore',
+    emoji: '๐Ÿงน',
+    description: 'Build process or auxiliary tool changes',
+    value: 'chore'
+  },
+  {
+    name: 'ci',
+    emoji: '๐Ÿ‘ท',
+    description: 'CI related changes',
+    value: 'ci'
+  },
+  {
+    name: 'docs',
+    emoji: '๐Ÿ“',
+    description: 'Documentation only changes',
+    value: 'docs'
+  },
+  {
+    name: 'feat',
+    emoji: '๐Ÿ’ก',
+    description: 'A new feature',
+    value: 'feat'
+  },
+  {
+    name: 'fix',
+    emoji: '๐Ÿ›',
+    description: 'A bug fix',
+    value: 'fix'
+  },
+  {
+    name: 'hotfix',
+    emoji: '๐Ÿšจ',
+    description: 'Emergency fix',
+    value: 'hotfix'
+  },
+  {
+    name: 'perf',
+    emoji: 'โšก',
+    description: 'A code change that improves performance',
+    value: 'perf'
+  },
+  {
+    name: 'refactor',
+    emoji: '๐Ÿ”จ',
+    description: 'A code change that neither fixes a bug or adds a feature',
+    value: 'refactor'
+  },
+  {
+    name: 'release',
+    emoji: '๐ŸŽ‰',
+    description: 'Create a release commit',
+    value: 'release'
+  },
+  {
+    name: 'style',
+    emoji: '๐ŸŽจ',
+    description: 'Markup, white-space, formatting, missing semi-colons...',
+    value: 'style'
+  },
+  {
+    name: 'test',
+    emoji: '๐ŸŽฎ',
+    description: 'Adding missing tests',
+    value: 'test'
+  },
+  {
+    name: 'storybook',
+    emoji: '๐Ÿ“š',
+    description: 'New storybook',
+    value: 'storybook'
+  },
+  {
+    name: 'revert',
+    emoji: '๐Ÿ”™',
+    description: 'Revert a commit',
+    value: 'revert'
+  }
+]
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/helper/index.html b/coverage/src/helper/index.html new file mode 100644 index 0000000..ee8fcdc --- /dev/null +++ b/coverage/src/helper/index.html @@ -0,0 +1,146 @@ + + + + + + Code coverage report for src/helper + + + + + + + + + +
+
+

All files src/helper

+
+ +
+ 100% + Statements + 108/108 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 108/108 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
commit-types.ts +
+
100%80/80100%0/0100%0/0100%80/80
index.ts +
+
100%1/1100%0/0100%0/0100%1/1
projects.ts +
+
100%27/27100%0/0100%0/0100%27/27
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/helper/index.ts.html b/coverage/src/helper/index.ts.html new file mode 100644 index 0000000..79582db --- /dev/null +++ b/coverage/src/helper/index.ts.html @@ -0,0 +1,91 @@ + + + + + + Code coverage report for src/helper/index.ts + + + + + + + + + +
+
+

All files / src/helper index.ts

+
+ +
+ 100% + Statements + 1/1 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 1/1 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +31x +  + 
export { default as commitTypes } from './commit-types'
+export { default as projects } from './projects'
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/helper/projects.ts.html b/coverage/src/helper/projects.ts.html new file mode 100644 index 0000000..60ccdfc --- /dev/null +++ b/coverage/src/helper/projects.ts.html @@ -0,0 +1,181 @@ + + + + + + Code coverage report for src/helper/projects.ts + + + + + + + + + +
+
+

All files / src/helper projects.ts

+
+ +
+ 100% + Statements + 27/27 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 27/27 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x
interface Project {
+  name: string
+  prefix: string
+  value: string
+}
+ 
+export default <Project[]>[
+  {
+    name: 'OwlPay',
+    prefix: 'OWLPAY',
+    value: 'owlpay'
+  },
+  {
+    name: 'OwlNest',
+    prefix: 'OW',
+    value: 'owlnest'
+  },
+  {
+    name: 'Market',
+    prefix: 'MAR',
+    value: 'market'
+  },
+  {
+    name: 'PayNow',
+    prefix: 'PN',
+    value: 'paynow'
+  },
+  {
+    name: 'Wallet Pro',
+    prefix: 'WP',
+    value: 'wallet-pro'
+  }
+]
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/index.html b/coverage/src/index.html new file mode 100644 index 0000000..8a613a6 --- /dev/null +++ b/coverage/src/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for src + + + + + + + + + +
+
+

All files src

+
+ +
+ 100% + Statements + 23/23 +
+ + +
+ 100% + Branches + 4/4 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 23/23 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
index.ts +
+
100%23/23100%4/4100%1/1100%23/23
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/index.ts.html b/coverage/src/index.ts.html new file mode 100644 index 0000000..a688a46 --- /dev/null +++ b/coverage/src/index.ts.html @@ -0,0 +1,181 @@ + + + + + + Code coverage report for src/index.ts + + + + + + + + + +
+
+

All files / src index.ts

+
+ +
+ 100% + Statements + 23/23 +
+ + +
+ 100% + Branches + 4/4 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 23/23 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +331x +  +  +  +  +  +  +  +  +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +  +6x +2x +6x +2x +2x +2x +2x +6x + 
import cli from './commands'
+import init from './commands/init'
+import where from './commands/where'
+import yargs from 'yargs/yargs'
+ 
+type Args = {
+  init?: boolean
+  where?: boolean
+}
+export async function run(args: string[]): Promise<void> {
+  const argv = yargs(args)
+    .options({
+      'init': {
+        alias: 'i',
+        describe: 'Set default project prefix.'
+      },
+      'where': {
+        alias: 'w',
+        describe: 'Show config file path.'
+      }
+    })
+    .help()
+    .argv as Args
+ 
+  if (argv.init) {
+    await init()
+  } else if (argv.where) {
+    where()
+  } else {
+    cli()
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index d991559..d47322c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "owlting_cz", - "version": "3.1.0", + "version": "3.2.0", "description": "create-commit for OwlTing", "type": "module", "dependencies": { @@ -14,7 +14,12 @@ "module": "dist/index.mjs", "types": "dist/index.d.ts", "scripts": { - "build": "unbuild" + "build": "unbuild", + "test": "vitest", + "test:run": "vitest run", + "test:watch": "vitest --watch", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "bin": { "cz": "bin/index.mjs" @@ -27,9 +32,14 @@ "commit" ], "author": "Nick", + "engines": { + "node": ">=14.0.0" + }, "devDependencies": { "@types/node": "^22.1.0", "@types/prompts": "^2.4.9", - "@types/yargs": "^17.0.33" + "@types/yargs": "^17.0.33", + "@vitest/coverage-v8": "^2.0.0", + "vitest": "^2.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7e2e8a..d8ef8c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,12 @@ importers: '@types/yargs': specifier: ^17.0.33 version: 17.0.33 + '@vitest/coverage-v8': + specifier: ^2.1.9 + version: 2.1.9(vitest@2.1.9(@types/node@22.1.0)) + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@22.1.0) packages: @@ -78,10 +84,18 @@ packages: resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} @@ -99,6 +113,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.5': + resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/standalone@7.25.3': resolution: {integrity: sha512-uR+EoBqIIIvKGCG7fOj7HKupu3zVObiMfdEwoPZfVCPpcWJaZ1PkshaP5/6cl6BKAm1Zcv25O1rf+uoQ7V8nqA==} engines: {node: '>=6.9.0'} @@ -115,12 +134,25 @@ packages: resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.6': + resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.23.0': resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} engines: {node: '>=18'} @@ -133,6 +165,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.23.0': resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} engines: {node: '>=18'} @@ -145,6 +183,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.23.0': resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} engines: {node: '>=18'} @@ -157,6 +201,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.23.0': resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} engines: {node: '>=18'} @@ -169,6 +219,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.23.0': resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} engines: {node: '>=18'} @@ -181,6 +237,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.23.0': resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} engines: {node: '>=18'} @@ -193,6 +255,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.23.0': resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} engines: {node: '>=18'} @@ -205,6 +273,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.23.0': resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} engines: {node: '>=18'} @@ -217,6 +291,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.23.0': resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} engines: {node: '>=18'} @@ -229,6 +309,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.23.0': resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} engines: {node: '>=18'} @@ -241,6 +327,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.23.0': resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} engines: {node: '>=18'} @@ -253,6 +345,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.23.0': resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} engines: {node: '>=18'} @@ -265,6 +363,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.23.0': resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} engines: {node: '>=18'} @@ -277,6 +381,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.23.0': resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} engines: {node: '>=18'} @@ -289,6 +399,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.23.0': resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} engines: {node: '>=18'} @@ -301,6 +417,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.23.0': resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} engines: {node: '>=18'} @@ -313,6 +435,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.23.0': resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} engines: {node: '>=18'} @@ -325,6 +453,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.23.0': resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} engines: {node: '>=18'} @@ -343,6 +477,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.23.0': resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} engines: {node: '>=18'} @@ -355,6 +495,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.23.0': resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} engines: {node: '>=18'} @@ -367,6 +513,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.23.0': resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} engines: {node: '>=18'} @@ -379,6 +531,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.23.0': resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} engines: {node: '>=18'} @@ -391,12 +549,26 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.23.0': resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -427,6 +599,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@rollup/plugin-alias@5.1.0': resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} engines: {node: '>=14.0.0'} @@ -481,6 +657,106 @@ packages: rollup: optional: true + '@rollup/rollup-android-arm-eabi@4.42.0': + resolution: {integrity: sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.42.0': + resolution: {integrity: sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.42.0': + resolution: {integrity: sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.42.0': + resolution: {integrity: sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.42.0': + resolution: {integrity: sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.42.0': + resolution: {integrity: sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.42.0': + resolution: {integrity: sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.42.0': + resolution: {integrity: sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.42.0': + resolution: {integrity: sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.42.0': + resolution: {integrity: sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.42.0': + resolution: {integrity: sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.42.0': + resolution: {integrity: sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.42.0': + resolution: {integrity: sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.42.0': + resolution: {integrity: sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.42.0': + resolution: {integrity: sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.42.0': + resolution: {integrity: sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.42.0': + resolution: {integrity: sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.42.0': + resolution: {integrity: sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.42.0': + resolution: {integrity: sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.42.0': + resolution: {integrity: sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==} + cpu: [x64] + os: [win32] + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -488,6 +764,9 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/node@22.1.0': resolution: {integrity: sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==} @@ -503,6 +782,44 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@vitest/coverage-v8@2.1.9': + resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} + peerDependencies: + '@vitest/browser': 2.1.9 + vitest: 2.1.9 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + acorn@8.12.1: resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} @@ -512,6 +829,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -520,6 +841,14 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -549,12 +878,20 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} caniuse-lite@1.0.30001651: resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -563,6 +900,10 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -607,6 +948,10 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + css-declaration-sorter@7.2.0: resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} engines: {node: ^14 || ^16 || >=18} @@ -664,6 +1009,19 @@ packages: supports-color: optional: true + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -688,21 +1046,35 @@ packages: domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + electron-to-chromium@1.5.5: resolution: {integrity: sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild@0.19.12: resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.23.0: resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} engines: {node: '>=18'} @@ -723,10 +1095,17 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -738,6 +1117,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -768,6 +1151,10 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} @@ -785,6 +1172,10 @@ packages: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -792,6 +1183,9 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -844,6 +1238,25 @@ packages: isexe@2.0.0: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jiti@1.21.6: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true @@ -875,12 +1288,28 @@ packages: lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + mdn-data@2.0.28: resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} @@ -906,6 +1335,14 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mkdist@1.5.4: resolution: {integrity: sha512-GEmKYJG5K1YGFIq3t0K3iihZ8FTgXphLf/4UjbmpXIAtBFn4lEjXk3pXNTSfy7EtcEXhp2Nn1vzw5pIus6RY3g==} hasBin: true @@ -931,6 +1368,14 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -957,6 +1402,9 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -964,6 +1412,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -971,12 +1423,19 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -1163,6 +1622,10 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.4: + resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==} + engines: {node: ^10 || ^12 || >=14} + pretty-bytes@6.1.1: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} @@ -1198,6 +1661,11 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true + rollup@4.42.0: + resolution: {integrity: sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -1221,9 +1689,16 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.5: resolution: {integrity: sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -1235,14 +1710,32 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -1257,6 +1750,10 @@ packages: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -1266,6 +1763,28 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinypool@1.1.0: + resolution: {integrity: sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -1298,24 +1817,94 @@ packages: resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} hasBin: true - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.19: + resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - browserslist: '>= 4.21.0' - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -1409,8 +1998,12 @@ snapshots: '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.24.8': {} '@babel/helpers@7.25.0': @@ -1429,6 +2022,10 @@ snapshots: dependencies: '@babel/types': 7.25.2 + '@babel/parser@7.27.5': + dependencies: + '@babel/types': 7.27.6 + '@babel/standalone@7.25.3': {} '@babel/template@7.25.0': @@ -1455,111 +2052,172 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.27.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + '@esbuild/aix-ppc64@0.19.12': optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.23.0': optional: true '@esbuild/android-arm64@0.19.12': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.23.0': optional: true '@esbuild/android-arm@0.19.12': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.23.0': optional: true '@esbuild/android-x64@0.19.12': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.23.0': optional: true '@esbuild/darwin-arm64@0.19.12': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.23.0': optional: true '@esbuild/darwin-x64@0.19.12': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.23.0': optional: true '@esbuild/freebsd-arm64@0.19.12': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.23.0': optional: true '@esbuild/freebsd-x64@0.19.12': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.23.0': optional: true '@esbuild/linux-arm64@0.19.12': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.23.0': optional: true '@esbuild/linux-arm@0.19.12': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.23.0': optional: true '@esbuild/linux-ia32@0.19.12': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.23.0': optional: true '@esbuild/linux-loong64@0.19.12': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.23.0': optional: true '@esbuild/linux-mips64el@0.19.12': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.23.0': optional: true '@esbuild/linux-ppc64@0.19.12': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.23.0': optional: true '@esbuild/linux-riscv64@0.19.12': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.23.0': optional: true '@esbuild/linux-s390x@0.19.12': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.23.0': optional: true '@esbuild/linux-x64@0.19.12': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.23.0': optional: true '@esbuild/netbsd-x64@0.19.12': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.23.0': optional: true @@ -1569,33 +2227,59 @@ snapshots: '@esbuild/openbsd-x64@0.19.12': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.23.0': optional: true '@esbuild/sunos-x64@0.19.12': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.23.0': optional: true '@esbuild/win32-arm64@0.19.12': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.23.0': optional: true '@esbuild/win32-ia32@0.19.12': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.23.0': optional: true '@esbuild/win32-x64@0.19.12': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.23.0': optional: true + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -1625,6 +2309,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@pkgjs/parseargs@0.11.0': + optional: true + '@rollup/plugin-alias@5.1.0(rollup@3.29.4)': dependencies: slash: 4.0.0 @@ -1674,10 +2361,72 @@ snapshots: optionalDependencies: rollup: 3.29.4 + '@rollup/rollup-android-arm-eabi@4.42.0': + optional: true + + '@rollup/rollup-android-arm64@4.42.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.42.0': + optional: true + + '@rollup/rollup-darwin-x64@4.42.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.42.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.42.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.42.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.42.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.42.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.42.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.42.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.42.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.42.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.42.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.42.0': + optional: true + '@trysound/sax@0.2.0': {} '@types/estree@1.0.5': {} + '@types/estree@1.0.7': {} + '@types/node@22.1.0': dependencies: undici-types: 6.13.0 @@ -1695,10 +2444,70 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@22.1.0))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.9.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.9(@types/node@22.1.0) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@22.1.0))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.19(@types/node@22.1.0) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + acorn@8.12.1: {} ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -1707,6 +2516,10 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.1: {} + + assertion-error@2.0.1: {} + autoprefixer@10.4.20(postcss@8.4.41): dependencies: browserslist: 4.23.3 @@ -1738,6 +2551,8 @@ snapshots: builtin-modules@3.3.0: {} + cac@6.7.14: {} + caniuse-api@3.0.0: dependencies: browserslist: 4.23.3 @@ -1747,6 +2562,14 @@ snapshots: caniuse-lite@1.0.30001651: {} + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -1755,6 +2578,8 @@ snapshots: chalk@5.3.0: {} + check-error@2.1.1: {} + citty@0.1.6: dependencies: consola: 3.2.3 @@ -1795,6 +2620,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + css-declaration-sorter@7.2.0(postcss@8.4.41): dependencies: postcss: 8.4.41 @@ -1873,6 +2704,12 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.4.1: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + deepmerge@4.3.1: {} defu@6.1.4: {} @@ -1899,12 +2736,18 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + eastasianwidth@0.2.0: {} + electron-to-chromium@1.5.5: {} emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + entities@4.5.0: {} + es-module-lexer@1.7.0: {} + esbuild@0.19.12: optionalDependencies: '@esbuild/aix-ppc64': 0.19.12 @@ -1931,6 +2774,32 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.23.0: optionalDependencies: '@esbuild/aix-ppc64': 0.23.0 @@ -1966,6 +2835,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -1978,6 +2851,8 @@ snapshots: signal-exit: 3.0.5 strip-final-newline: 2.0.0 + expect-type@1.2.1: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1994,6 +2869,11 @@ snapshots: dependencies: to-regex-range: 5.0.1 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + fraction.js@4.3.7: {} fs.realpath@1.0.0: {} @@ -2013,6 +2893,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@8.1.0: dependencies: fs.realpath: 1.0.0 @@ -2033,12 +2922,16 @@ snapshots: has-flag@3.0.0: {} + has-flag@4.0.0: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 hookable@5.5.3: {} + html-escaper@2.0.2: {} + human-signals@2.1.0: {} ignore@5.3.1: {} @@ -2078,6 +2971,33 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jiti@1.21.6: {} js-tokens@4.0.0: {} @@ -2094,6 +3014,10 @@ snapshots: lodash.uniq@4.5.0: {} + loupe@3.1.3: {} + + lru-cache@10.4.3: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -2102,6 +3026,20 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + source-map-js: 1.2.0 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + mdn-data@2.0.28: {} mdn-data@2.0.30: {} @@ -2121,6 +3059,12 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + mkdist@1.5.4(typescript@5.5.4): dependencies: autoprefixer: 10.4.20(postcss@8.4.41) @@ -2150,6 +3094,10 @@ snapshots: ms@2.1.2: {} + ms@2.1.3: {} + + nanoid@3.3.11: {} + nanoid@3.3.7: {} node-releases@2.0.18: {} @@ -2172,18 +3120,29 @@ snapshots: dependencies: mimic-fn: 2.1.0 + package-json-from-dist@1.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-type@4.0.0: {} pathe@1.1.2: {} + pathval@2.0.0: {} + picocolors@1.0.0: {} picocolors@1.0.1: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} pkg-types@1.1.3: @@ -2359,6 +3318,12 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 + postcss@8.5.4: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + pretty-bytes@6.1.1: {} prompts@2.4.2: @@ -2390,6 +3355,32 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + rollup@4.42.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.42.0 + '@rollup/rollup-android-arm64': 4.42.0 + '@rollup/rollup-darwin-arm64': 4.42.0 + '@rollup/rollup-darwin-x64': 4.42.0 + '@rollup/rollup-freebsd-arm64': 4.42.0 + '@rollup/rollup-freebsd-x64': 4.42.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.42.0 + '@rollup/rollup-linux-arm-musleabihf': 4.42.0 + '@rollup/rollup-linux-arm64-gnu': 4.42.0 + '@rollup/rollup-linux-arm64-musl': 4.42.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.42.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.42.0 + '@rollup/rollup-linux-riscv64-gnu': 4.42.0 + '@rollup/rollup-linux-riscv64-musl': 4.42.0 + '@rollup/rollup-linux-s390x-gnu': 4.42.0 + '@rollup/rollup-linux-x64-gnu': 4.42.0 + '@rollup/rollup-linux-x64-musl': 4.42.0 + '@rollup/rollup-win32-arm64-msvc': 4.42.0 + '@rollup/rollup-win32-ia32-msvc': 4.42.0 + '@rollup/rollup-win32-x64-msvc': 4.42.0 + fsevents: 2.3.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -2406,24 +3397,44 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + signal-exit@3.0.5: {} + signal-exit@4.1.0: {} + sisteransi@1.0.5: {} slash@4.0.0: {} source-map-js@1.2.0: {} + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.9.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-final-newline@2.0.0: {} stylehacks@7.0.2(postcss@8.4.41): @@ -2436,6 +3447,10 @@ snapshots: dependencies: has-flag: 3.0.0 + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} svgo@3.3.2: @@ -2448,6 +3463,22 @@ snapshots: csso: 5.0.5 picocolors: 1.0.0 + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinypool@1.1.0: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -2513,16 +3544,89 @@ snapshots: util-deprecate@1.0.2: {} + vite-node@2.1.9(@types/node@22.1.0): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.19(@types/node@22.1.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.19(@types/node@22.1.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.4 + rollup: 4.42.0 + optionalDependencies: + '@types/node': 22.1.0 + fsevents: 2.3.3 + + vitest@2.1.9(@types/node@22.1.0): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.19(@types/node@22.1.0)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.0 + tinyrainbow: 1.2.0 + vite: 5.4.19(@types/node@22.1.0) + vite-node: 2.1.9(@types/node@22.1.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.1.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + which@2.0.2: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} y18n@5.0.8: {} diff --git a/src/commands/init.ts b/src/commands/init.ts index 3664524..7f065c8 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -48,7 +48,7 @@ export default async () => { const filePath = resolve(rootPath, 'keep/cz_config.json') fs.writeFileSync( filePath, - `${JSON.stringify({ defaultProject: set_default_project } || {}, null, 2)}`, + `${JSON.stringify({ defaultProject: set_default_project }, null, 2)}` ) console.log(picocolors.green(` default project set: ${set_default_project} `)) } catch (error) { diff --git a/src/helper/commit-types.ts b/src/helper/commit-types.ts index 0baaef9..7fccf4d 100644 --- a/src/helper/commit-types.ts +++ b/src/helper/commit-types.ts @@ -69,7 +69,7 @@ export default [ name: 'storybook', emoji: '๐Ÿ“š', description: 'New storybook', - value: 'story' + value: 'storybook' }, { name: 'revert', diff --git a/tests/commands/cli-module-loading.test.ts b/tests/commands/cli-module-loading.test.ts new file mode 100644 index 0000000..0f9b1b6 --- /dev/null +++ b/tests/commands/cli-module-loading.test.ts @@ -0,0 +1,58 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import fs from 'fs' + +// Mock dependencies before importing the module +vi.mock('fs') +vi.mock('picocolors', () => ({ + default: { + yellow: (text: string) => text, + italic: (text: string) => text + } +})) + +const mockFs = vi.mocked(fs) + +describe('CLI module loading', () => { + const mockConsoleLog = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + console.log = mockConsoleLog + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should show warning when config file is missing during module load', async () => { + // Mock config file read error + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + // Import the module to trigger the warning + await import('../../src/commands/index') + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('You can try `cz -i` to choose a default project prefix') + ) + }) + + it('should not show warning when config file exists during module load', async () => { + // Mock config file exists + mockFs.readFileSync = vi.fn().mockReturnValue( + JSON.stringify({ defaultProject: 'owlpay' }) + ) + + // Clear any previous console calls + mockConsoleLog.mockClear() + + // Import the module + await import('../../src/commands/index') + + // Should not have warning message + expect(mockConsoleLog).not.toHaveBeenCalledWith( + expect.stringContaining('You can try `cz -i` to choose a default project prefix') + ) + }) +}) diff --git a/tests/commands/cli-validation.test.ts b/tests/commands/cli-validation.test.ts new file mode 100644 index 0000000..9074660 --- /dev/null +++ b/tests/commands/cli-validation.test.ts @@ -0,0 +1,192 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import fs from 'fs' +import prompts from 'prompts' +import execa from 'execa' + +// Mock dependencies +vi.mock('fs') +vi.mock('prompts') +vi.mock('execa') +vi.mock('picocolors', () => ({ + default: { + yellow: (text: string) => text, + italic: (text: string) => text, + magenta: (text: string) => text, + bgGreen: (text: string) => text, + bold: (text: string) => text, + green: (text: string) => text, + cyan: (text: string) => text, + dim: (text: string) => text, + red: (text: string) => text, + bgRed: (text: string) => text, + bgCyan: (text: string) => text, + white: (text: string) => text + } +})) + +const mockFs = vi.mocked(fs) +const mockPrompts = vi.mocked(prompts) +const mockExeca = vi.mocked(execa) + +describe('CLI validation and edge cases', () => { + const mockConsoleLog = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + console.log = mockConsoleLog + + // Default mock for file not found + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + describe('step type conditions', () => { + it('should handle step_is_default_project conditional type', async () => { + mockFs.readFileSync = vi.fn().mockReturnValue( + JSON.stringify({ defaultProject: 'owlpay' }) + ) + + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test', + commit_description: '', + is_jira: true, + is_default_project: false, // This should trigger the conditional logic + project_type: 'owlnest', + jira_id: 123 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main abc123] [OW-123] ๐Ÿ’ก feat: test', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[OW-123] ๐Ÿ’ก feat: test' + ]) + }) + + it('should handle step_project_type conditional logic when no default project', async () => { + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test', + commit_description: '', + is_jira: true, + project_type: 'market', + jira_id: 456 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main def456] [MAR-456] ๐Ÿ’ก feat: test', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[MAR-456] ๐Ÿ’ก feat: test' + ]) + }) + + it('should handle onSubmit with undefined answers', async () => { + mockPrompts.mockImplementation((questions, options) => { + if (options?.onSubmit) { + // Simulate onSubmit being called with undefined answers + const shouldStop = options.onSubmit({} as any, undefined, {} as any) + expect(shouldStop).toBe(true) + } + return Promise.resolve({}) + }) + + const { default: cli } = await import('../../src/commands/index') + const result = await cli() + + expect(result).toBe(false) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('commit abort') + ) + }) + }) + + describe('edge cases', () => { + it('should handle no default project with Jira flow', async () => { + // No config file, so no default project + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test', + commit_description: '', + is_jira: true, + project_type: 'paynow', + jira_id: 999 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main xyz999] [PN-999] ๐Ÿ’ก feat: test', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[PN-999] ๐Ÿ’ก feat: test' + ]) + }) + + it('should handle all project types in Jira flow', async () => { + const projects = [ + { value: 'owlpay', prefix: 'OWLPAY' }, + { value: 'owlnest', prefix: 'OW' }, + { value: 'market', prefix: 'MAR' }, + { value: 'paynow', prefix: 'PN' }, + { value: 'wallet-pro', prefix: 'WP' } + ] + + for (const project of projects) { + vi.clearAllMocks() + + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test', + commit_description: '', + is_jira: true, + project_type: project.value, + jira_id: 123 + }) + + mockExeca.mockResolvedValue({ + stdout: `[main abc123] [${project.prefix}-123] ๐Ÿ’ก feat: test`, + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', `[${project.prefix}-123] ๐Ÿ’ก feat: test` + ]) + } + }) + }) +}) diff --git a/tests/commands/cli.test.ts b/tests/commands/cli.test.ts new file mode 100644 index 0000000..8d021fa --- /dev/null +++ b/tests/commands/cli.test.ts @@ -0,0 +1,362 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import fs from 'fs' +import prompts from 'prompts' +import execa from 'execa' + +// Mock dependencies +vi.mock('fs') +vi.mock('prompts') +vi.mock('execa') +vi.mock('picocolors', () => ({ + default: { + yellow: (text: string) => text, + italic: (text: string) => text, + magenta: (text: string) => text, + bgGreen: (text: string) => text, + bold: (text: string) => text, + green: (text: string) => text, + cyan: (text: string) => text, + dim: (text: string) => text, + red: (text: string) => text, + bgRed: (text: string) => text, + bgCyan: (text: string) => text, + white: (text: string) => text + } +})) + +const mockFs = vi.mocked(fs) +const mockPrompts = vi.mocked(prompts) +const mockExeca = vi.mocked(execa) + +// Custom error type for git errors +interface GitError extends Error { + stderr?: string + exitCode?: number +} + +describe('CLI main command', () => { + const mockConsoleLog = vi.fn() + const mockConsoleError = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + console.log = mockConsoleLog + console.error = mockConsoleError + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + describe('config file handling', () => { + it('should load default project when config exists', async () => { + // Mock config file exists + mockFs.readFileSync = vi.fn().mockReturnValue( + JSON.stringify({ defaultProject: 'owlpay' }) + ) + + // Mock successful prompts flow + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test feature', + commit_description: '', + is_jira: false + }) + + // Mock successful git commit + mockExeca.mockResolvedValue({ + stdout: '[main abc123] ๐Ÿ’ก feat: test feature' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockFs.readFileSync).toHaveBeenCalled() + }) + + it('should handle missing config file gracefully', async () => { + // Mock config file read error + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + // Mock successful prompts flow + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test feature', + commit_description: '', + is_jira: false + }) + + // Mock successful git commit + mockExeca.mockResolvedValue({ + stdout: '[main abc123] ๐Ÿ’ก feat: test feature' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + // The warning message is shown during module loading, not during execution + // So we just verify the function completed successfully + expect(mockExeca).toHaveBeenCalledWith('git', ['commit', '-m', '๐Ÿ’ก feat: test feature']) + }) + }) + + describe('commit flow without Jira', () => { + beforeEach(() => { + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + }) + + it('should handle basic commit without description', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'add new feature', + commit_description: '', + is_jira: false + }) + + mockExeca.mockResolvedValue({ + stdout: '[main abc123] ๐Ÿ’ก feat: add new feature', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', ['commit', '-m', '๐Ÿ’ก feat: add new feature']) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('๐Ÿ’ก feat: add new feature') + ) + }) + + it('should handle commit with description', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'fix', + commit_message: 'fix bug', + commit_description: 'Fixed critical bug in authentication', + is_jira: false + }) + + mockExeca.mockResolvedValue({ + stdout: '[main def456] ๐Ÿ› fix: fix bug', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '๐Ÿ› fix: fix bug', '-m', 'Fixed critical bug in authentication' + ]) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('Fixed critical bug in authentication') + ) + }) + + it('should handle all commit types', async () => { + const commitTypes = ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'ci', 'hotfix', 'release', 'storybook', 'revert'] + + for (const type of commitTypes) { + vi.clearAllMocks() + + mockPrompts.mockResolvedValue({ + commit_type: type, + commit_message: `test ${type}`, + commit_description: '', + is_jira: false + }) + + mockExeca.mockResolvedValue({ + stdout: `[main abc123] ${type}: test ${type}`, + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', expect.stringContaining(`${type}: test ${type}`) + ]) + } + }) + }) + + describe('commit flow with Jira', () => { + beforeEach(() => { + mockFs.readFileSync = vi.fn().mockReturnValue( + JSON.stringify({ defaultProject: 'owlpay' }) + ) + }) + + it('should handle Jira commit with default project', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'new feature', + commit_description: '', + is_jira: true, + is_default_project: true, + jira_id: 12345 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main abc123] [OWLPAY-12345] ๐Ÿ’ก feat: new feature', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[OWLPAY-12345] ๐Ÿ’ก feat: new feature' + ]) + }) + + it('should handle Jira commit with custom project', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'fix', + commit_message: 'bug fix', + commit_description: '', + is_jira: true, + is_default_project: false, + project_type: 'owlnest', + jira_id: 98765 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main def456] [OW-98765] ๐Ÿ› fix: bug fix', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[OW-98765] ๐Ÿ› fix: bug fix' + ]) + }) + + it('should handle Jira commit with description', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'new feature', + commit_description: 'Added user authentication', + is_jira: true, + is_default_project: true, + jira_id: 11111 + }) + + mockExeca.mockResolvedValue({ + stdout: '[main ghi789] [OWLPAY-11111] ๐Ÿ’ก feat: new feature', + stderr: '' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockExeca).toHaveBeenCalledWith('git', [ + 'commit', '-m', '[OWLPAY-11111] ๐Ÿ’ก feat: new feature', '-m', 'Added user authentication' + ]) + }) + }) + + describe('error handling', () => { + beforeEach(() => { + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + }) + + it('should handle user cancellation', async () => { + mockPrompts.mockImplementation((questions, options) => { + if (options?.onCancel) { + options.onCancel({} as any, {} as any) + } + return Promise.resolve({}) + }) + + const { default: cli } = await import('../../src/commands/index') + const result = await cli() + + expect(result).toBe(false) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('commit abort') + ) + }) + + it('should handle git commit errors', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test feature', + commit_description: '', + is_jira: false + }) + + const gitError: GitError = new Error('Git error') + gitError.stderr = 'fatal: not a git repository' + gitError.exitCode = 128 + mockExeca.mockRejectedValue(gitError) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('fatal: not a git repository') + ) + expect(mockConsoleError).toHaveBeenCalledWith(gitError) + }) + + it('should handle "no changes" git error', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test feature', + commit_description: '', + is_jira: false + }) + + const gitError: GitError = new Error('No changes') + gitError.stderr = 'nothing to commit' + gitError.exitCode = 1 + mockExeca.mockRejectedValue(gitError) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('No changes added to commit') + ) + }) + + it('should handle git stderr output', async () => { + mockPrompts.mockResolvedValue({ + commit_type: 'feat', + commit_message: 'test feature', + commit_description: '', + is_jira: false + }) + + mockExeca.mockResolvedValue({ + stdout: '[main abc123] ๐Ÿ’ก feat: test feature', + stderr: 'warning: some git warning' + } as any) + + const { default: cli } = await import('../../src/commands/index') + await cli() + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('warning: some git warning') + ) + }) + }) + + describe('validation functions', () => { + it('should test commit message validation logic', async () => { + // We test validation indirectly by checking the prompts configuration + const { default: cli } = await import('../../src/commands/index') + + // This is more of a structural test to ensure the function exists + expect(typeof cli).toBe('function') + }) + }) +}) diff --git a/tests/commands/init.test.ts b/tests/commands/init.test.ts new file mode 100644 index 0000000..9bf47ba --- /dev/null +++ b/tests/commands/init.test.ts @@ -0,0 +1,188 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import fs from 'fs' +import prompts from 'prompts' + +// Mock dependencies +vi.mock('fs') +vi.mock('prompts') +vi.mock('picocolors', () => ({ + default: { + green: (text: string) => text, + bgRed: (text: string) => text, + white: (text: string) => text, + magenta: (text: string) => text + } +})) + +const mockFs = vi.mocked(fs) +const mockPrompts = vi.mocked(prompts) + +describe('init command', () => { + const mockConsoleLog = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + console.log = mockConsoleLog + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should save selected project to config file', async () => { + // Mock prompts response + mockPrompts.mockResolvedValue({ + set_default_project: 'owlpay' + }) + + // Mock fs.writeFileSync + mockFs.writeFileSync = vi.fn() + + const { default: init } = await import('../../src/commands/init') + + await init() + + expect(mockPrompts).toHaveBeenCalled() + expect(mockFs.writeFileSync).toHaveBeenCalledWith( + expect.stringContaining('keep/cz_config.json'), + JSON.stringify({ defaultProject: 'owlpay' }, null, 2) + ) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('default project set: owlpay') + ) + }) + + it('should handle user cancellation', async () => { + // Mock prompts cancellation + mockPrompts.mockImplementation((questions, options) => { + if (options?.onCancel) { + options.onCancel({} as any, {} as any) + } + return Promise.resolve({}) + }) + + const { default: init } = await import('../../src/commands/init') + + const result = await init() + + expect(result).toBe(false) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('init abort') + ) + }) + + it('should handle user cancellation via onSubmit with undefined', async () => { + // Mock prompts with onSubmit returning undefined + mockPrompts.mockImplementation((questions, options) => { + if (options?.onSubmit) { + // onSubmit should return true to stop, and answers being undefined triggers cancellation + options.onSubmit({} as any, undefined, {} as any) + } + return Promise.resolve({}) + }) + + const { default: init } = await import('../../src/commands/init') + + const result = await init() + + expect(result).toBe(false) + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('init abort') + ) + }) + + it('should handle file write errors', async () => { + // Mock prompts response + mockPrompts.mockResolvedValue({ + set_default_project: 'owlpay' + }) + + // Mock fs.writeFileSync to throw error + mockFs.writeFileSync = vi.fn().mockImplementation(() => { + throw new Error('Permission denied') + }) + + const { default: init } = await import('../../src/commands/init') + + await init() + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('init Fail') + ) + }) + + it('should present correct project choices', async () => { + mockPrompts.mockResolvedValue({ + set_default_project: 'owlnest' + }) + mockFs.writeFileSync = vi.fn() + + const { default: init } = await import('../../src/commands/init') + + await init() + + expect(mockPrompts).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ + type: 'autocomplete', + name: 'set_default_project', + message: 'Set default project prefix.', + choices: expect.arrayContaining([ + expect.objectContaining({ + title: 'OwlPay', + value: 'owlpay' + }), + expect.objectContaining({ + title: 'OwlNest', + value: 'owlnest' + }) + ]) + }) + ]), + expect.any(Object) + ) + }) + + it('should test all available projects in choices', async () => { + mockPrompts.mockResolvedValue({ + set_default_project: 'market' + }) + mockFs.writeFileSync = vi.fn() + + const { default: init } = await import('../../src/commands/init') + + await init() + + const callArgs = mockPrompts.mock.calls[0] + const stepType = callArgs[0][0] + expect(stepType.choices).toEqual( + expect.arrayContaining([ + expect.objectContaining({ title: 'OwlPay', value: 'owlpay' }), + expect.objectContaining({ title: 'OwlNest', value: 'owlnest' }), + expect.objectContaining({ title: 'Market', value: 'market' }), + expect.objectContaining({ title: 'PayNow', value: 'paynow' }), + expect.objectContaining({ title: 'Wallet Pro', value: 'wallet-pro' }) + ]) + ) + }) + + it('should handle successful completion with different projects', async () => { + const projects = ['owlpay', 'owlnest', 'market', 'paynow', 'wallet-pro'] + + for (const project of projects) { + vi.clearAllMocks() + + mockPrompts.mockResolvedValue({ + set_default_project: project + }) + mockFs.writeFileSync = vi.fn() + + const { default: init } = await import('../../src/commands/init') + await init() + + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining(`default project set: ${project}`) + ) + } + }) +}) diff --git a/tests/commands/where.test.ts b/tests/commands/where.test.ts new file mode 100644 index 0000000..9c5c586 --- /dev/null +++ b/tests/commands/where.test.ts @@ -0,0 +1,37 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' + +// Mock console.log to capture output +const mockConsoleLog = vi.fn() +console.log = mockConsoleLog + +describe('where command', () => { + beforeEach(() => { + mockConsoleLog.mockClear() + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should show config directory path', async () => { + // We need to dynamically import to ensure mocks are in place + const { default: where } = await import('../../src/commands/where') + + where() + + expect(mockConsoleLog).toHaveBeenCalled() + const output = mockConsoleLog.mock.calls[0][0] + expect(output).toContain('Your config will be saved in') + expect(output).toContain('src/commands') + }) + + it('should display a path ending with a period', async () => { + const { default: where } = await import('../../src/commands/where') + + where() + + expect(mockConsoleLog).toHaveBeenCalled() + const output = mockConsoleLog.mock.calls[0][0] + expect(output).toMatch(/.*\.$/) + }) +}) diff --git a/tests/helper/commit-types.test.ts b/tests/helper/commit-types.test.ts new file mode 100644 index 0000000..1a7c8a2 --- /dev/null +++ b/tests/helper/commit-types.test.ts @@ -0,0 +1,50 @@ +import { describe, it, expect } from 'vitest' +import commitTypes from '../../src/helper/commit-types' + +describe('commit-types', () => { + it('should export an array of commit types', () => { + expect(Array.isArray(commitTypes)).toBe(true) + expect(commitTypes.length).toBeGreaterThan(0) + }) + + it('should have all required properties for each commit type', () => { + commitTypes.forEach(type => { + expect(type).toHaveProperty('name') + expect(type).toHaveProperty('emoji') + expect(type).toHaveProperty('description') + expect(type).toHaveProperty('value') + + expect(typeof type.name).toBe('string') + expect(typeof type.emoji).toBe('string') + expect(typeof type.description).toBe('string') + expect(typeof type.value).toBe('string') + }) + }) + + it('should contain expected commit types', () => { + const expectedTypes = ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'ci', 'hotfix', 'release', 'storybook', 'revert'] + const actualTypes = commitTypes.map(type => type.value) + + expectedTypes.forEach(expectedType => { + expect(actualTypes).toContain(expectedType) + }) + }) + + it('should have unique values', () => { + const values = commitTypes.map(type => type.value) + const uniqueValues = [...new Set(values)] + expect(values.length).toBe(uniqueValues.length) + }) + + it('should have non-empty descriptions', () => { + commitTypes.forEach(type => { + expect(type.description.trim()).not.toBe('') + }) + }) + + it('should have emoji characters', () => { + commitTypes.forEach(type => { + expect(type.emoji).toMatch(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/u) + }) + }) +}) diff --git a/tests/helper/projects.test.ts b/tests/helper/projects.test.ts new file mode 100644 index 0000000..f755652 --- /dev/null +++ b/tests/helper/projects.test.ts @@ -0,0 +1,62 @@ +import { describe, it, expect } from 'vitest' +import projects from '../../src/helper/projects' + +describe('projects', () => { + it('should export an array of projects', () => { + expect(Array.isArray(projects)).toBe(true) + expect(projects.length).toBeGreaterThan(0) + }) + + it('should have all required properties for each project', () => { + projects.forEach(project => { + expect(project).toHaveProperty('name') + expect(project).toHaveProperty('prefix') + expect(project).toHaveProperty('value') + + expect(typeof project.name).toBe('string') + expect(typeof project.prefix).toBe('string') + expect(typeof project.value).toBe('string') + }) + }) + + it('should contain expected projects', () => { + const expectedProjects = ['owlpay', 'owlnest', 'market', 'paynow', 'wallet-pro'] + const actualProjects = projects.map(project => project.value) + + expectedProjects.forEach(expectedProject => { + expect(actualProjects).toContain(expectedProject) + }) + }) + + it('should have unique values', () => { + const values = projects.map(project => project.value) + const uniqueValues = [...new Set(values)] + expect(values.length).toBe(uniqueValues.length) + }) + + it('should have unique prefixes', () => { + const prefixes = projects.map(project => project.prefix) + const uniquePrefixes = [...new Set(prefixes)] + expect(prefixes.length).toBe(uniquePrefixes.length) + }) + + it('should have non-empty names and prefixes', () => { + projects.forEach(project => { + expect(project.name.trim()).not.toBe('') + expect(project.prefix.trim()).not.toBe('') + expect(project.value.trim()).not.toBe('') + }) + }) + + it('should have uppercase prefixes', () => { + projects.forEach(project => { + expect(project.prefix).toBe(project.prefix.toUpperCase()) + }) + }) + + it('should have lowercase values', () => { + projects.forEach(project => { + expect(project.value).toBe(project.value.toLowerCase()) + }) + }) +}) diff --git a/tests/index.test.ts b/tests/index.test.ts new file mode 100644 index 0000000..cb82fe0 --- /dev/null +++ b/tests/index.test.ts @@ -0,0 +1,93 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' + +// Mock the command modules +vi.mock('../src/commands', () => ({ + default: vi.fn() +})) + +vi.mock('../src/commands/init', () => ({ + default: vi.fn() +})) + +vi.mock('../src/commands/where', () => ({ + default: vi.fn() +})) + +describe('main index', () => { + let mockCli: any + let mockInit: any + let mockWhere: any + + beforeEach(async () => { + vi.clearAllMocks() + + // Import mocked modules + mockCli = (await import('../src/commands')).default + mockInit = (await import('../src/commands/init')).default + mockWhere = (await import('../src/commands/where')).default + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should call init command when --init flag is provided', async () => { + const { run } = await import('../src/index') + + await run(['cz', '--init']) + + expect(mockInit).toHaveBeenCalled() + expect(mockCli).not.toHaveBeenCalled() + expect(mockWhere).not.toHaveBeenCalled() + }) + + it('should call init command when -i flag is provided', async () => { + const { run } = await import('../src/index') + + await run(['cz', '-i']) + + expect(mockInit).toHaveBeenCalled() + expect(mockCli).not.toHaveBeenCalled() + expect(mockWhere).not.toHaveBeenCalled() + }) + + it('should call where command when --where flag is provided', async () => { + const { run } = await import('../src/index') + + await run(['cz', '--where']) + + expect(mockWhere).toHaveBeenCalled() + expect(mockInit).not.toHaveBeenCalled() + expect(mockCli).not.toHaveBeenCalled() + }) + + it('should call where command when -w flag is provided', async () => { + const { run } = await import('../src/index') + + await run(['cz', '-w']) + + expect(mockWhere).toHaveBeenCalled() + expect(mockInit).not.toHaveBeenCalled() + expect(mockCli).not.toHaveBeenCalled() + }) + + it('should call default cli command when no flags are provided', async () => { + const { run } = await import('../src/index') + + await run(['cz']) + + expect(mockCli).toHaveBeenCalled() + expect(mockInit).not.toHaveBeenCalled() + expect(mockWhere).not.toHaveBeenCalled() + }) + + it('should handle multiple arguments correctly', async () => { + const { run } = await import('../src/index') + + await run(['cz', 'some', 'other', 'args']) + + expect(mockCli).toHaveBeenCalled() + expect(mockInit).not.toHaveBeenCalled() + expect(mockWhere).not.toHaveBeenCalled() + }) +}) diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 0000000..bd3b059 --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,11 @@ +// Test setup file +import { vi } from 'vitest' + +// Setup global mocks +global.console = { + ...console, + log: vi.fn(), + error: vi.fn(), + warn: vi.fn(), + info: vi.fn() +} diff --git a/tests/utils/test-helpers.ts b/tests/utils/test-helpers.ts new file mode 100644 index 0000000..ae144ce --- /dev/null +++ b/tests/utils/test-helpers.ts @@ -0,0 +1,46 @@ +import { vi } from 'vitest' + +/** + * Creates a mock console object for testing console output + */ +export function createMockConsole() { + return { + log: vi.fn(), + error: vi.fn(), + warn: vi.fn(), + info: vi.fn() + } +} + +/** + * Helper to mock prompts responses + */ +export function mockPromptsResponse(response: any) { + const prompts = vi.hoisted(() => vi.fn()) + prompts.mockResolvedValue(response) + return prompts +} + +/** + * Helper to mock file system operations + */ +export function createMockFs() { + return { + writeFileSync: vi.fn(), + readFileSync: vi.fn(), + existsSync: vi.fn() + } +} + +/** + * Helper to test git command execution + */ +export function mockGitExecution(result: { stdout: string; stderr?: string; exitCode?: number }) { + const execa = vi.hoisted(() => vi.fn()) + execa.mockResolvedValue({ + stdout: result.stdout, + stderr: result.stderr || '', + exitCode: result.exitCode || 0 + }) + return execa +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2c4e5ac --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + setupFiles: ['./tests/setup.ts'], + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + exclude: [ + 'node_modules/', + 'dist/', + 'tests/', + '**/*.d.ts', + 'vitest.config.ts', + 'build.config.ts', + 'bin/' + ] + } + }, + resolve: { + alias: { + '@': './src' + } + } +}) \ No newline at end of file From fa5024a4107f9f406eb4a47b6c79e7ba69c4a4c2 Mon Sep 17 00:00:00 2001 From: NickLin Date: Tue, 10 Jun 2025 16:17:40 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=8E=AE=20test:=20test=20on=20pre-comm?= =?UTF-8?q?it=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/index.cjs | 2 +- dist/index.mjs | 2 +- lefthook.yml | 22 +++++++++++ package.json | 5 ++- pnpm-lock.yaml | 104 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 lefthook.yml diff --git a/dist/index.cjs b/dist/index.cjs index 88f5762..f34c668 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -88,7 +88,7 @@ const commitTypes = [ name: "storybook", emoji: "\u{1F4DA}", description: "New storybook", - value: "story" + value: "storybook" }, { name: "revert", diff --git a/dist/index.mjs b/dist/index.mjs index 179bf82..ce77413 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -77,7 +77,7 @@ const commitTypes = [ name: "storybook", emoji: "\u{1F4DA}", description: "New storybook", - value: "story" + value: "storybook" }, { name: "revert", diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..60ee40a --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,22 @@ +pre-commit: + parallel: true + commands: + tests: + run: pnpm test:run + fail_text: "โŒ Tests failed! Please fix the issues before committing." + stage_fixed: false + + type-check: + run: pnpm build + fail_text: "โŒ TypeScript compilation failed! Please fix type errors before committing." + stage_fixed: false + +pre-push: + parallel: true + commands: + coverage: + run: pnpm test:coverage + fail_text: "โŒ Coverage check failed! Ensure tests meet coverage requirements." + +# Configuration +assert_lefthook_installed: true diff --git a/package.json b/package.json index d47322c..50437ba 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "test:run": "vitest run", "test:watch": "vitest --watch", "test:coverage": "vitest run --coverage", - "test:ui": "vitest --ui" + "test:ui": "vitest --ui", + "hooks:install": "lefthook install", + "hooks:uninstall": "lefthook uninstall" }, "bin": { "cz": "bin/index.mjs" @@ -40,6 +42,7 @@ "@types/prompts": "^2.4.9", "@types/yargs": "^17.0.33", "@vitest/coverage-v8": "^2.0.0", + "lefthook": "^1.11.13", "vitest": "^2.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8ef8c9..0f79d16 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,10 +34,13 @@ importers: specifier: ^17.0.33 version: 17.0.33 '@vitest/coverage-v8': - specifier: ^2.1.9 + specifier: ^2.0.0 version: 2.1.9(vitest@2.1.9(@types/node@22.1.0)) + lefthook: + specifier: ^1.11.13 + version: 1.11.13 vitest: - specifier: ^2.1.9 + specifier: ^2.0.0 version: 2.1.9(@types/node@22.1.0) packages: @@ -1278,6 +1281,60 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + lefthook-darwin-arm64@1.11.13: + resolution: {integrity: sha512-gHwHofXupCtzNLN+8esdWfFTnAEkmBxE/WKA0EwxPPJXdZYa1GUsiG5ipq/CdG/0j8ekYyM9Hzyrrk5BqJ42xw==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@1.11.13: + resolution: {integrity: sha512-zYxkWNUirmTidhskY9J9AwxvdMi3YKH+TqZ3AQ1EOqkOwPBWJQW5PbnzsXDrd3YnrtZScYm/tE/moXJpEPPIpQ==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@1.11.13: + resolution: {integrity: sha512-gJzWnllcMcivusmPorEkXPpEciKotlBHn7QxWwYaSjss/U3YdZu+NTjDO30b3qeiVlyq4RAZ4BPKJODXxHHwUA==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@1.11.13: + resolution: {integrity: sha512-689XdchgtDvZQWFFx1szUvm/mqrq/v6laki0odq5FAfcSgUeLu3w+z6UicBS5l55eFJuQTDNKARFqrKJ04e+Vw==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@1.11.13: + resolution: {integrity: sha512-ujCLbaZg5S/Ao8KZAcNSb+Y3gl898ZEM0YKyiZmZo22dFFpm/5gcV46pF3xaqIw5IpH+3YYDTKDU+qTetmARyQ==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@1.11.13: + resolution: {integrity: sha512-O5WdodeBtFOXQlvPcckqp4W/yqVM9DbVQBkvOxwSJlmsxO4sGYK1TqdxH9ihLB85B2kPPssZj9ze36/oizzhVQ==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@1.11.13: + resolution: {integrity: sha512-SyBpciUfvY/lUDbZu7L6MtL/SVG2+yMTckBgb4PdJQhJlisY0IsyOYdlTw2icPPrY7JnwdsFv8UW0EJOB76W4g==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@1.11.13: + resolution: {integrity: sha512-6+/0j6O2dzo9cjTWUKfL2J6hRR7Krna/ssqnW8cWh8QHZKO9WJn34epto9qgjeHwSysou8byI7Mwv5zOGthLCQ==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@1.11.13: + resolution: {integrity: sha512-w5TwZ8bsZ17uOMtYGc5oEb4tCHjNTSeSXRy6H9Yic8E7IsPZtZLkaZGnIIwgXFuhhrcCdc6FuTvKt2tyV7EW2g==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@1.11.13: + resolution: {integrity: sha512-7lvwnIs8CNOXKU4y3i1Pbqna+QegIORkSD2VCuHBNpIJ8H84NpjoG3tKU91IM/aI1a2eUvCk+dw+1rfMRz7Ytg==} + cpu: [x64] + os: [win32] + + lefthook@1.11.13: + resolution: {integrity: sha512-SDTk3D4nW1XRpR9u9fdYQ/qj1xeZVIwZmIFdJUnyq+w9ZLdCCvIrOmtD8SFiJowSevISjQDC+f9nqyFXUxc0SQ==} + hasBin: true + lilconfig@3.1.2: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} engines: {node: '>=14'} @@ -3008,6 +3065,49 @@ snapshots: kleur@3.0.3: {} + lefthook-darwin-arm64@1.11.13: + optional: true + + lefthook-darwin-x64@1.11.13: + optional: true + + lefthook-freebsd-arm64@1.11.13: + optional: true + + lefthook-freebsd-x64@1.11.13: + optional: true + + lefthook-linux-arm64@1.11.13: + optional: true + + lefthook-linux-x64@1.11.13: + optional: true + + lefthook-openbsd-arm64@1.11.13: + optional: true + + lefthook-openbsd-x64@1.11.13: + optional: true + + lefthook-windows-arm64@1.11.13: + optional: true + + lefthook-windows-x64@1.11.13: + optional: true + + lefthook@1.11.13: + optionalDependencies: + lefthook-darwin-arm64: 1.11.13 + lefthook-darwin-x64: 1.11.13 + lefthook-freebsd-arm64: 1.11.13 + lefthook-freebsd-x64: 1.11.13 + lefthook-linux-arm64: 1.11.13 + lefthook-linux-x64: 1.11.13 + lefthook-openbsd-arm64: 1.11.13 + lefthook-openbsd-x64: 1.11.13 + lefthook-windows-arm64: 1.11.13 + lefthook-windows-x64: 1.11.13 + lilconfig@3.1.2: {} lodash.memoize@4.1.2: {} From bfab9c1f51c4316d99a6d0baa64917fafb8dc3b1 Mon Sep 17 00:00:00 2001 From: NickLin Date: Tue, 10 Jun 2025 16:33:42 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=8E=AE=20test:=20add=20coverage=20act?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/coverage.yml | 75 +++ .gitignore | 9 +- README.md | 24 + coverage/base.css | 224 -------- coverage/block-navigation.js | 87 ---- coverage/coverage-final.json | 8 - coverage/favicon.png | Bin 445 -> 0 bytes coverage/index.html | 146 ------ coverage/prettify.css | 1 - coverage/prettify.js | 2 - coverage/sort-arrow-sprite.png | Bin 138 -> 0 bytes coverage/sorter.js | 196 ------- coverage/src/commands/index.html | 146 ------ coverage/src/commands/index.ts.html | 619 ----------------------- coverage/src/commands/init.ts.html | 256 ---------- coverage/src/commands/where.ts.html | 106 ---- coverage/src/helper/commit-types.ts.html | 325 ------------ coverage/src/helper/index.html | 146 ------ coverage/src/helper/index.ts.html | 91 ---- coverage/src/helper/projects.ts.html | 181 ------- coverage/src/index.html | 116 ----- coverage/src/index.ts.html | 181 ------- lefthook.yml | 7 - package.json | 1 + scripts/generate-coverage-badge.js | 68 +++ vitest.config.ts | 19 +- 26 files changed, 186 insertions(+), 2848 deletions(-) create mode 100644 .github/workflows/coverage.yml delete mode 100644 coverage/base.css delete mode 100644 coverage/block-navigation.js delete mode 100644 coverage/coverage-final.json delete mode 100644 coverage/favicon.png delete mode 100644 coverage/index.html delete mode 100644 coverage/prettify.css delete mode 100644 coverage/prettify.js delete mode 100644 coverage/sort-arrow-sprite.png delete mode 100644 coverage/sorter.js delete mode 100644 coverage/src/commands/index.html delete mode 100644 coverage/src/commands/index.ts.html delete mode 100644 coverage/src/commands/init.ts.html delete mode 100644 coverage/src/commands/where.ts.html delete mode 100644 coverage/src/helper/commit-types.ts.html delete mode 100644 coverage/src/helper/index.html delete mode 100644 coverage/src/helper/index.ts.html delete mode 100644 coverage/src/helper/projects.ts.html delete mode 100644 coverage/src/index.html delete mode 100644 coverage/src/index.ts.html create mode 100644 scripts/generate-coverage-badge.js diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..99fe295 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,75 @@ +name: Coverage + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + coverage: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'pnpm' + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run tests with coverage + run: pnpm test:coverage + + - name: Generate coverage badge + run: node scripts/generate-coverage-badge.js + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + file: ./coverage/lcov.info + flags: unittests + name: codecov-umbrella + + - name: Coverage Badge + uses: tj-actions/coverage-badge-js@v1 + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + with: + coverage-file: './coverage/coverage-summary.json' + + - name: Verify Changed files + uses: tj-actions/verify-changed-files@v12 + id: verify-changed-files + with: + files: coverage-badge.json + + - name: Create Coverage Badge + if: steps.verify-changed-files.outputs.files_changed == 'true' + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "docs: update coverage badge" + title: "๐Ÿ“Š Update Coverage Badge" + body: | + ## Coverage Report Update + + This PR updates the coverage badge based on the latest test results. + + **Coverage Summary:** + - Statements: ${{ env.COVERAGE_STATEMENTS }}% + - Branches: ${{ env.COVERAGE_BRANCHES }}% + - Functions: ${{ env.COVERAGE_FUNCTIONS }}% + - Lines: ${{ env.COVERAGE_LINES }}% + + Auto-generated by GitHub Actions. + branch: update-coverage-badge diff --git a/.gitignore b/.gitignore index c453cb4..f60ee75 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,11 @@ node_modules .DS_Store .vscode keep/* -!keep/README.md \ No newline at end of file +!keep/README.md + +# Coverage reports +coverage/ +*.lcov + +# Generated files +coverage-badge.json \ No newline at end of file diff --git a/README.md b/README.md index 8a9875c..a4e9b0f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # create commit ![](https://img.shields.io/badge/node-%5E14-brightgreen.svg) +![Coverage](https://img.shields.io/badge/coverage-83%25-brightgreen) +![Tests](https://img.shields.io/badge/tests-49%20passed-brightgreen) create commit in human way. @@ -20,6 +22,28 @@ bun install -g OwlTing/cz > Add `export PATH="$(yarn global bin):$PATH"` to your `~./zshrc` if you installed it by yarn global +## Development + +### Running Tests +```shell +# Run tests in watch mode +pnpm test + +# Run tests once +pnpm test:run + +# Run tests with coverage +pnpm test:coverage + +# Generate coverage badge +pnpm coverage:badge +``` + +### Pre-commit Hooks +This project uses [lefthook](https://github.com/evilmartians/lefthook) for pre-commit hooks that automatically run: +- Unit tests (`pnpm test:run`) +- TypeScript compilation check (`pnpm build`) + ## Update version ```shell # npm diff --git a/coverage/base.css b/coverage/base.css deleted file mode 100644 index f418035..0000000 --- a/coverage/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js deleted file mode 100644 index cc12130..0000000 --- a/coverage/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selecter that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json deleted file mode 100644 index 8b7cdd8..0000000 --- a/coverage/coverage-final.json +++ /dev/null @@ -1,8 +0,0 @@ -{"/Users/nick/Desktop/Projects/cz/src/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":58}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":26}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":14}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":15}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":19}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":47}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":8}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":16}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":19}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":42}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":7}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":6}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":11}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":17}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":18}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":26}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":11}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":10}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":9}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":3}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":1}}},"s":{"0":1,"9":6,"10":6,"11":6,"12":6,"13":6,"14":6,"15":6,"16":6,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"24":6,"25":2,"26":6,"27":2,"28":2,"29":2,"30":2,"31":6},"branchMap":{"0":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"locations":[{"start":{"line":10,"column":0},"end":{"line":32,"column":1}}]},"1":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":17},"end":{"line":27,"column":13}},"locations":[{"start":{"line":25,"column":17},"end":{"line":27,"column":13}}]},"2":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":2},"end":{"line":31,"column":3}},"locations":[{"start":{"line":27,"column":2},"end":{"line":31,"column":3}}]},"3":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":25},"end":{"line":31,"column":3}},"locations":[{"start":{"line":27,"column":25},"end":{"line":31,"column":3}}]}},"b":{"0":[6],"1":[2],"2":[4],"3":[2]},"fnMap":{"0":{"name":"run","decl":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"loc":{"start":{"line":10,"column":0},"end":{"line":32,"column":1}},"line":10}},"f":{"0":6}} -,"/Users/nick/Desktop/Projects/cz/src/commands/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":25}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":49}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":44}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":40}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":57}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":42}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":28}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":5}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":59}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":42}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":64}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":13}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":115}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":26}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":1}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":44}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":51}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":20}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":19}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":3}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":19}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":23}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":22}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":33}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":21}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":30}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":1}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":22}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":15}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":25}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":30}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":63}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":44}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":4}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":32}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":17}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":42}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":5}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":15}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":1}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":26}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":15}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":29}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":43}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":14}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":32}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":29}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":39}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":5}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":15}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":1}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":22}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":18}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":18}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":30}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":16}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":1}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":47}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":22}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":49}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":22}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":3}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":91}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":33}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":51}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":29}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":89}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":15}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":1}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":27}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":62}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":18}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":37}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":14}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":24}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":12}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":4}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":23}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":34}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":24}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":20}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":33}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":1}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":22}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":50}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":18}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":27}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":15}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":96}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":4}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":32}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":17}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":41}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":5}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":15}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":3}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":1}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":28}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":24}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":17}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":14}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":17}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":21}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":17}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":59}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":22}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":16}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":44}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":41}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":36}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":34}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":25}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":19}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":7}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":6}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":27}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":23}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":18}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":5}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":4}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":19}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":54}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":16}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":3}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":122}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":66}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":71}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":80}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":79}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":24}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":57}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":17}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":7}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":119}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":53}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":73}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":62}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":78}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":52}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":37}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":80}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":54}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":5}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":78}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":102}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":29}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":116}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":5}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":182}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":24}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":45}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":92}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":29}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":3}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"8":1,"9":1,"11":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"22":1,"23":39,"24":39,"25":39,"26":39,"27":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"37":1,"38":1,"39":1,"40":1,"41":0,"42":0,"43":0,"44":1,"45":0,"46":0,"47":0,"48":0,"49":0,"50":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":0,"59":0,"60":0,"61":0,"62":0,"63":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"72":1,"73":15,"74":15,"75":15,"76":1,"78":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"87":1,"88":1,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"102":1,"103":1,"104":1,"105":1,"106":1,"107":0,"108":0,"109":1,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"117":1,"118":33,"119":33,"120":33,"121":33,"122":33,"123":33,"124":33,"125":33,"126":33,"127":33,"128":33,"129":33,"130":1,"131":1,"132":1,"133":1,"134":1,"135":33,"136":1,"137":1,"138":1,"139":33,"141":33,"142":2,"143":2,"144":2,"146":31,"147":31,"148":31,"149":33,"150":33,"151":33,"152":11,"153":20,"155":33,"156":33,"157":33,"158":29,"159":29,"160":29,"161":29,"162":33,"163":3,"164":3,"165":3,"166":29,"167":29,"168":33,"169":2,"170":2,"171":29,"172":33,"173":2,"174":2,"175":1,"176":2,"177":33},"branchMap":{"0":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":0},"end":{"line":21,"column":1}},"locations":[{"start":{"line":18,"column":0},"end":{"line":21,"column":1}}]},"1":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":19},"end":{"line":84,"column":40}},"locations":[{"start":{"line":84,"column":19},"end":{"line":84,"column":40}}]},"2":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":59},"end":{"line":84,"column":86}},"locations":[{"start":{"line":84,"column":59},"end":{"line":84,"column":86}}]},"3":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":34},"end":{"line":28,"column":2}},"locations":[{"start":{"line":23,"column":34},"end":{"line":28,"column":2}}]},"4":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":34},"end":{"line":77,"column":2}},"locations":[{"start":{"line":73,"column":34},"end":{"line":77,"column":2}}]},"5":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":41},"end":{"line":79,"column":89}},"locations":[{"start":{"line":79,"column":41},"end":{"line":79,"column":89}}]},"6":{"type":"branch","line":118,"loc":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"locations":[{"start":{"line":118,"column":15},"end":{"line":178,"column":1}}]},"7":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":28},"end":{"line":125,"column":59}},"locations":[{"start":{"line":125,"column":28},"end":{"line":125,"column":59}}]},"8":{"type":"branch","line":142,"loc":{"start":{"line":142,"column":18},"end":{"line":145,"column":3}},"locations":[{"start":{"line":142,"column":18},"end":{"line":145,"column":3}}]},"9":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":150,"column":44}},"locations":[{"start":{"line":145,"column":2},"end":{"line":150,"column":44}}]},"10":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":23},"end":{"line":150,"column":68}},"locations":[{"start":{"line":150,"column":23},"end":{"line":150,"column":68}}]},"11":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":60},"end":{"line":150,"column":80}},"locations":[{"start":{"line":150,"column":60},"end":{"line":150,"column":80}}]},"12":{"type":"branch","line":152,"loc":{"start":{"line":152,"column":17},"end":{"line":153,"column":57}},"locations":[{"start":{"line":152,"column":17},"end":{"line":153,"column":57}}]},"13":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":55},"end":{"line":154,"column":17}},"locations":[{"start":{"line":153,"column":55},"end":{"line":154,"column":17}}]},"14":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":21},"end":{"line":157,"column":95}},"locations":[{"start":{"line":157,"column":21},"end":{"line":157,"column":95}}]},"15":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":91},"end":{"line":157,"column":119}},"locations":[{"start":{"line":157,"column":91},"end":{"line":157,"column":119}}]},"16":{"type":"branch","line":158,"loc":{"start":{"line":158,"column":52},"end":{"line":163,"column":36}},"locations":[{"start":{"line":158,"column":52},"end":{"line":163,"column":36}}]},"17":{"type":"branch","line":163,"loc":{"start":{"line":163,"column":36},"end":{"line":166,"column":5}},"locations":[{"start":{"line":163,"column":36},"end":{"line":166,"column":5}}]},"18":{"type":"branch","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":169,"column":28}},"locations":[{"start":{"line":166,"column":4},"end":{"line":169,"column":28}}]},"19":{"type":"branch","line":169,"loc":{"start":{"line":169,"column":28},"end":{"line":171,"column":5}},"locations":[{"start":{"line":169,"column":28},"end":{"line":171,"column":5}}]},"20":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":173,"column":11}},"locations":[{"start":{"line":171,"column":4},"end":{"line":173,"column":11}}]},"21":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":2},"end":{"line":177,"column":3}},"locations":[{"start":{"line":173,"column":2},"end":{"line":177,"column":3}}]},"22":{"type":"branch","line":175,"loc":{"start":{"line":175,"column":30},"end":{"line":176,"column":29}},"locations":[{"start":{"line":175,"column":30},"end":{"line":176,"column":29}}]},"23":{"type":"branch","line":130,"loc":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"locations":[{"start":{"line":130,"column":14},"end":{"line":135,"column":6}}]},"24":{"type":"branch","line":136,"loc":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"locations":[{"start":{"line":136,"column":14},"end":{"line":139,"column":5}}]},"25":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":30},"end":{"line":148,"column":64}},"locations":[{"start":{"line":148,"column":30},"end":{"line":148,"column":64}}]},"26":{"type":"branch","line":151,"loc":{"start":{"line":151,"column":36},"end":{"line":151,"column":77}},"locations":[{"start":{"line":151,"column":36},"end":{"line":151,"column":77}}]}},"b":{"0":[1],"1":[2],"2":[2],"3":[39],"4":[15],"5":[7],"6":[33],"7":[0],"8":[2],"9":[31],"10":[2],"11":[29],"12":[11],"13":[20],"14":[2],"15":[29],"16":[29],"17":[3],"18":[29],"19":[2],"20":[29],"21":[2],"22":[1],"23":[1],"24":[1],"25":[165],"26":[128]},"fnMap":{"0":{"name":"message","decl":{"start":{"line":41,"column":11},"end":{"line":44,"column":4}},"loc":{"start":{"line":41,"column":11},"end":{"line":44,"column":4}},"line":41},"1":{"name":"validate","decl":{"start":{"line":45,"column":12},"end":{"line":50,"column":3}},"loc":{"start":{"line":45,"column":12},"end":{"line":50,"column":3}},"line":45},"2":{"name":"validate","decl":{"start":{"line":58,"column":12},"end":{"line":63,"column":3}},"loc":{"start":{"line":58,"column":12},"end":{"line":63,"column":3}},"line":58},"3":{"name":"type","decl":{"start":{"line":82,"column":8},"end":{"line":82,"column":51}},"loc":{"start":{"line":82,"column":8},"end":{"line":82,"column":51}},"line":82},"4":{"name":"type","decl":{"start":{"line":89,"column":8},"end":{"line":95,"column":4}},"loc":{"start":{"line":89,"column":8},"end":{"line":95,"column":4}},"line":89},"5":{"name":"type","decl":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"loc":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"line":104},"6":{"name":"onRender","decl":{"start":{"line":107,"column":2},"end":{"line":109,"column":4}},"loc":{"start":{"line":107,"column":2},"end":{"line":109,"column":4}},"line":107},"7":{"name":"validate","decl":{"start":{"line":110,"column":12},"end":{"line":115,"column":3}},"loc":{"start":{"line":110,"column":12},"end":{"line":115,"column":3}},"line":110},"8":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"loc":{"start":{"line":118,"column":15},"end":{"line":178,"column":1}},"line":118},"9":{"name":"onSubmit","decl":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"loc":{"start":{"line":130,"column":14},"end":{"line":135,"column":6}},"line":130},"10":{"name":"onCancel","decl":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"loc":{"start":{"line":136,"column":14},"end":{"line":139,"column":5}},"line":136}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":33,"9":1,"10":1}} -,"/Users/nick/Desktop/Projects/cz/src/commands/init.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/init.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":19}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":36}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":29}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":44}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":40}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":57}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":42}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":47}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":22}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":49}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":22}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":3}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":19}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":23}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":30}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":41}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":24}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":33}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":33}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":28}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":24}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":47}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":36}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":34}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":25}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":19}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":7}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":6}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":27}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":23}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":18}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":5}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":4}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":19}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":52}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":16}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":42}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":7}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":61}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":21}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":15}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":75}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":5}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":82}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":19}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":74}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"7":1,"8":1,"10":1,"11":5,"12":5,"13":5,"14":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"24":1,"25":11,"26":11,"27":11,"28":1,"29":1,"30":1,"31":1,"32":1,"33":11,"34":1,"35":1,"36":1,"37":11,"39":11,"40":2,"41":2,"42":2,"44":9,"46":9,"47":9,"48":9,"49":9,"50":9,"51":9,"52":9,"53":11,"54":1,"55":1,"56":11},"branchMap":{"0":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":34},"end":{"line":15,"column":2}},"locations":[{"start":{"line":11,"column":34},"end":{"line":15,"column":2}}]},"1":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"locations":[{"start":{"line":25,"column":15},"end":{"line":57,"column":1}}]},"2":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":18},"end":{"line":43,"column":3}},"locations":[{"start":{"line":40,"column":18},"end":{"line":43,"column":3}}]},"3":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":54,"column":11}},"locations":[{"start":{"line":43,"column":2},"end":{"line":54,"column":11}}]},"4":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":3}},"locations":[{"start":{"line":54,"column":2},"end":{"line":56,"column":3}}]},"5":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"locations":[{"start":{"line":28,"column":14},"end":{"line":33,"column":6}}]},"6":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"locations":[{"start":{"line":34,"column":14},"end":{"line":37,"column":5}}]}},"b":{"0":[5],"1":[11],"2":[2],"3":[9],"4":[1],"5":[1],"6":[1]},"fnMap":{"0":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"loc":{"start":{"line":25,"column":15},"end":{"line":57,"column":1}},"line":25},"1":{"name":"onSubmit","decl":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"loc":{"start":{"line":28,"column":14},"end":{"line":33,"column":6}},"line":28},"2":{"name":"onCancel","decl":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"loc":{"start":{"line":34,"column":14},"end":{"line":37,"column":5}},"line":34}},"f":{"0":11,"1":1,"2":1}} -,"/Users/nick/Desktop/Projects/cz/src/commands/where.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/commands/where.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":40}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":57}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":22}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":59}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":1}}},"s":{"0":1,"1":1,"3":1,"4":1,"5":2,"6":2},"branchMap":{"0":{"type":"branch","line":5,"loc":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"locations":[{"start":{"line":5,"column":15},"end":{"line":7,"column":1}}]}},"b":{"0":[2]},"fnMap":{"0":{"name":"__vite_ssr_exports__.default","decl":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"loc":{"start":{"line":5,"column":15},"end":{"line":7,"column":1}},"line":5}},"f":{"0":2}} -,"/Users/nick/Desktop/Projects/cz/src/helper/commit-types.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/commit-types.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":3}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":18}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":16}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":59}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":18}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":4}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":15}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":16}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":38}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":15}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":4}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":3}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":16}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":46}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":17}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":4}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":3}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":17}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":16}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":33}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":17}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":4}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":3}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":16}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":16}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":29}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":16}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":19}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":16}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":33}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":19}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":4}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":3}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":17}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":15}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":59}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":17}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":4}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":21}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":16}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":76}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":21}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":4}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":20}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":16}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":43}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":20}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":4}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":18}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":16}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":75}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":18}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":4}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":3}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":17}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":16}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":40}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":17}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":4}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":3}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":22}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":16}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":33}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":22}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":4}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":19}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":16}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":35}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":19}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":3}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} -,"/Users/nick/Desktop/Projects/cz/src/helper/index.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}},"s":{"0":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} -,"/Users/nick/Desktop/Projects/cz/src/helper/projects.ts": {"path":"/Users/nick/Desktop/Projects/cz/src/helper/projects.ts","all":false,"statementMap":{"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":27}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":19}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":21}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":19}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":4}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":3}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":20}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":4}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":3}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":19}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":18}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":19}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":4}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":3}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":17}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":19}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":4}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":3}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":23}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":17}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":23}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":1}}},"s":{"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} -} diff --git a/coverage/favicon.png b/coverage/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 92.52% - Statements - 322/348 -
- - -
- 97.43% - Branches - 38/39 -
- - -
- 50% - Functions - 8/16 -
- - -
- 92.52% - Lines - 322/348 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
src -
-
100%23/23100%4/4100%1/1100%23/23
src/commands -
-
88.01%191/21797.14%34/3546.66%7/1588.01%191/217
src/helper -
-
100%108/108100%0/0100%0/0100%108/108
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js deleted file mode 100644 index b322523..0000000 --- a/coverage/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/sorter.js b/coverage/sorter.js deleted file mode 100644 index 2bb296a..0000000 --- a/coverage/sorter.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - if ( - row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()) - ) { - row.style.display = ''; - } else { - row.style.display = 'none'; - } - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/src/commands/index.html b/coverage/src/commands/index.html deleted file mode 100644 index b2754f2..0000000 --- a/coverage/src/commands/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for src/commands - - - - - - - - - -
-
-

All files src/commands

-
- -
- 88.01% - Statements - 191/217 -
- - -
- 97.14% - Branches - 34/35 -
- - -
- 46.66% - Functions - 7/15 -
- - -
- 88.01% - Lines - 191/217 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
83.85%135/16196.29%26/2727.27%3/1183.85%135/161
init.ts -
-
100%50/50100%7/7100%3/3100%50/50
where.ts -
-
100%6/6100%1/1100%1/1100%6/6
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/commands/index.ts.html b/coverage/src/commands/index.ts.html deleted file mode 100644 index ed3dc0b..0000000 --- a/coverage/src/commands/index.ts.html +++ /dev/null @@ -1,619 +0,0 @@ - - - - - - Code coverage report for src/commands/index.ts - - - - - - - - - -
-
-

All files / src/commands index.ts

-
- -
- 83.85% - Statements - 135/161 -
- - -
- 96.29% - Branches - 26/27 -
- - -
- 27.27% - Functions - 3/11 -
- - -
- 83.85% - Lines - 135/161 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -1791x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -39x -39x -39x -39x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -1x -  -  -  -  -  -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -15x -15x -15x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -  -  -  -  -  -1x -  -1x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -1x -1x -1x -1x -1x -33x -1x -1x -1x -33x -  -33x -2x -2x -2x -  -31x -31x -31x -33x -33x -33x -11x -20x -  -33x -33x -33x -29x -29x -29x -29x -33x -3x -3x -3x -29x -29x -33x -2x -2x -29x -33x -2x -2x -1x -2x -33x - 
import prompts from 'prompts'
-import execa from 'execa'
-import { projects, commitTypes } from '../helper'
-import picocolors from 'picocolors'
-import fs from 'fs'
-import { dirname, resolve } from 'node:path'
-import { fileURLToPath } from 'node:url'
- 
-const __dirname = dirname(fileURLToPath(import.meta.url))
-const rootPath = resolve(__dirname, '../')
- 
-let defaultProjectValue = ''
- 
-try {
-  const filePath = resolve(rootPath, 'keep/cz_config.json')
-  const config = fs.readFileSync(filePath)
-  defaultProjectValue = JSON.parse(config as any).defaultProject
-} catch (e) {
-  console.log(picocolors.yellow(picocolors.italic(' ๐Ÿ’ก You can try `cz -i` to choose a default project prefix. ')))
-  defaultProjectValue = ''
-}
- 
-const typesList = commitTypes.map(type => ({
-  title: type.name,
-  description: `${type.emoji} ${type.description}`,
-  value: type.value,
-  emoji: type.emoji
-}))
- 
-const step_type = {
-  type: 'autocomplete',
-  name: 'commit_type',
-  message: 'Pick a commit type.',
-  choices: typesList,
-  fallback: 'No matched type.'
-}
- 
-const step_message = {
-  type: 'text',
-  name: 'commit_message',
-  message: (prev: string) => {
-    const target = typesList.find(type => type.value === prev)!
-    return `${target.emoji} ${target.title}`
-  },
-  validate: (value: string) => {
-    if (!value) {
-      return 'Commit message is required.'
-    }
-    return true
-  }
-}
- 
-const step_description = {
-  type: 'text',
-  name: 'commit_description',
-  message: 'Commit description (optional)',
-  initial: '',
-  validate: (value: string) => {
-    if (value.length > 100) {
-      return 'Description is too long.'
-    }
-    return true
-  }
-}
- 
-const step_is_jira = {
-  type: 'confirm',
-  name: 'is_jira',
-  message: 'Tag Jira issue ?',
-  initial: false
-}
- 
-const projectsList = projects.map(project => ({
-  title: project.name,
-  description: `[${project.prefix}-13845] title`,
-  value: project.value
-}))
- 
-const defaultProject = projectsList.find(project => project.value === defaultProjectValue)!
- 
-const step_is_default_project = {
-  type: (prev: boolean) => prev ? 'confirm' : null,
-  name: 'is_default_project',
-  message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`,
-  initial: true
-}
- 
-const step_project_type = {
-  type: (prev: string, { is_jira }: { is_jira: boolean }) => {
-    return is_jira
-      ? defaultProject?.value && prev
-        ? null
-        : 'autocomplete'
-      : null
-  },
-  name: 'project_type',
-  message: 'Pick a project type.',
-  choices: projectsList,
-  initial: 'owlpay',
-  fallback: 'No matched project.'
-}
- 
-const step_jira_id = {
-  type: (prev: boolean) => prev ? 'number' : null,
-  name: 'jira_id',
-  message: 'Jira issue id',
-  onRender () {
-    (this as any).msg = picocolors.bgCyan(picocolors.white(' Jira issue ID ')) // TODO: fix type
-  },
-  validate: (value: number) => {
-    if (!value) {
-      return 'Jira issue ID is required.'
-    }
-    return true
-  }
-}
- 
-export default async () => {
-  let isCanceled = false
-  const order = [
-    step_type,
-    step_message,
-    step_description,
-    step_is_jira,
-    defaultProject?.value ? step_is_default_project : null,
-    step_project_type,
-    step_jira_id
-  ].filter(Boolean) as any // TODO: fix type
-  const response = await prompts(order, {
-    onSubmit: (prompt, answers) => {
-      if (answers === undefined) {
-        isCanceled = true
-        return true
-      }
-    },
-    onCancel: (prompt) => {
-      isCanceled = true
-      return false
-    }
-  })
- 
-  if (isCanceled) {
-    console.log(picocolors.magenta(' commit abort. '))
-    return false
-  }
- 
-  const { commit_type, commit_message, commit_description, is_jira, is_default_project, project_type, jira_id } = response
-  const type = typesList.find(type => type.value === commit_type)!
-  const commitTitle = `${type.emoji} ${commit_type}: ${commit_message}`
-  const typeResponse = is_default_project ? defaultProject?.value : project_type
-  const projectType = projects.find(project => project.value === typeResponse)!
-  const result = is_jira
-    ? `[${projectType.prefix}-${jira_id}] ${commitTitle}`
-    : commitTitle
- 
-  try {
-    const commands = commit_description ? ['commit', '-m', result, '-m', commit_description] : ['commit', '-m', result]
-    const commitResult = await execa('git', commands)
-    const branchHashName = commitResult.stdout.match(/\[(.*?)\]/)!.pop()!
-    const [branchName, branchHash] = branchHashName.split(' ')
-    console.log('-----------------------------------------------------------')
-    console.log(picocolors.dim(commitResult.stdout))
-    if (commitResult.stderr !== '') {
-      console.log('-----------------------------------------------------------')
-      console.log(picocolors.dim(commitResult.stderr))
-    }
-    console.log('-----------------------------------------------------------')
-    console.log(`${picocolors.bgGreen(picocolors.bold(' Title       '))} ${picocolors.green(result)}`)
-    if (commit_description) {
-      console.log(`${picocolors.bgGreen(picocolors.bold(' Description '))} ${picocolors.green(commit_description)}`)
-    }
-    console.log(`${picocolors.bgGreen(picocolors.bold(' Commit hash '))} ${picocolors.bold(picocolors.cyan(` ${branchHash} `))} (${picocolors.italic(picocolors.green(branchName))})`)
-  } catch (error: any) {
-    console.log(picocolors.red(error.stderr))
-    if (error.exitCode === 1) console.log(picocolors.bgRed(' No changes added to commit. '))
-    else console.error(error)
-  }
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/commands/init.ts.html b/coverage/src/commands/init.ts.html deleted file mode 100644 index 77c988f..0000000 --- a/coverage/src/commands/init.ts.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - Code coverage report for src/commands/init.ts - - - - - - - - - -
-
-

All files / src/commands init.ts

-
- -
- 100% - Statements - 50/50 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 50/50 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -581x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -5x -5x -5x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -11x -11x -11x -1x -1x -1x -1x -1x -11x -1x -1x -1x -11x -  -11x -2x -2x -2x -  -9x -  -9x -9x -9x -9x -9x -9x -9x -11x -1x -1x -11x - 
import fs from 'fs'
-import { projects } from '../helper'
-import prompts from 'prompts'
-import picocolors from 'picocolors'
-import { dirname, resolve } from 'node:path'
-import { fileURLToPath } from 'node:url'
- 
-const __dirname = dirname(fileURLToPath(import.meta.url))
-const rootPath = resolve(__dirname, '../')
- 
-const projectsList = projects.map(project => ({
-  title: project.name,
-  description: `[${project.prefix}-13845] title`,
-  value: project.value
-}))
- 
-const step_type = {
-  type: 'autocomplete',
-  name: 'set_default_project',
-  message: 'Set default project prefix.',
-  choices: projectsList,
-  fallback: 'No matched project.'
-} as const // TODO: Fix this type
- 
-export default async () => {
-  let isCanceled = false
-  const response = await prompts([step_type], {
-    onSubmit: (prompt, answers) => {
-      if (answers === undefined) {
-        isCanceled = true
-        return true
-      }
-    },
-    onCancel: (prompt) => {
-      isCanceled = true
-      return false
-    }
-  })
- 
-  if (isCanceled) {
-    console.log(picocolors.magenta(' init abort. '))
-    return false
-  }
- 
-  const { set_default_project } = response
- 
-  try {
-    const filePath = resolve(rootPath, 'keep/cz_config.json')
-    fs.writeFileSync(
-      filePath,
-      `${JSON.stringify({ defaultProject: set_default_project }, null, 2)}`
-    )
-    console.log(picocolors.green(` default project set: ${set_default_project} `))
-  } catch (error) {
-    console.log(picocolors.bgRed(picocolors.white(`init Fail: ${error}`)))
-  }
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/commands/where.ts.html b/coverage/src/commands/where.ts.html deleted file mode 100644 index ac043ed..0000000 --- a/coverage/src/commands/where.ts.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - Code coverage report for src/commands/where.ts - - - - - - - - - -
-
-

All files / src/commands where.ts

-
- -
- 100% - Statements - 6/6 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 6/6 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -81x -1x -  -1x -1x -2x -2x - 
import { dirname } from 'node:path'
-import { fileURLToPath } from 'node:url'
- 
-const __dirname = dirname(fileURLToPath(import.meta.url))
-export default () => {
-  console.log(`Your config will be saved in ${__dirname}.`)
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/helper/commit-types.ts.html b/coverage/src/helper/commit-types.ts.html deleted file mode 100644 index 6c60c89..0000000 --- a/coverage/src/helper/commit-types.ts.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - - - Code coverage report for src/helper/commit-types.ts - - - - - - - - - -
-
-

All files / src/helper commit-types.ts

-
- -
- 100% - Statements - 80/80 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 80/80 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -811x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
export default [
-  {
-    name: 'chore',
-    emoji: '๐Ÿงน',
-    description: 'Build process or auxiliary tool changes',
-    value: 'chore'
-  },
-  {
-    name: 'ci',
-    emoji: '๐Ÿ‘ท',
-    description: 'CI related changes',
-    value: 'ci'
-  },
-  {
-    name: 'docs',
-    emoji: '๐Ÿ“',
-    description: 'Documentation only changes',
-    value: 'docs'
-  },
-  {
-    name: 'feat',
-    emoji: '๐Ÿ’ก',
-    description: 'A new feature',
-    value: 'feat'
-  },
-  {
-    name: 'fix',
-    emoji: '๐Ÿ›',
-    description: 'A bug fix',
-    value: 'fix'
-  },
-  {
-    name: 'hotfix',
-    emoji: '๐Ÿšจ',
-    description: 'Emergency fix',
-    value: 'hotfix'
-  },
-  {
-    name: 'perf',
-    emoji: 'โšก',
-    description: 'A code change that improves performance',
-    value: 'perf'
-  },
-  {
-    name: 'refactor',
-    emoji: '๐Ÿ”จ',
-    description: 'A code change that neither fixes a bug or adds a feature',
-    value: 'refactor'
-  },
-  {
-    name: 'release',
-    emoji: '๐ŸŽ‰',
-    description: 'Create a release commit',
-    value: 'release'
-  },
-  {
-    name: 'style',
-    emoji: '๐ŸŽจ',
-    description: 'Markup, white-space, formatting, missing semi-colons...',
-    value: 'style'
-  },
-  {
-    name: 'test',
-    emoji: '๐ŸŽฎ',
-    description: 'Adding missing tests',
-    value: 'test'
-  },
-  {
-    name: 'storybook',
-    emoji: '๐Ÿ“š',
-    description: 'New storybook',
-    value: 'storybook'
-  },
-  {
-    name: 'revert',
-    emoji: '๐Ÿ”™',
-    description: 'Revert a commit',
-    value: 'revert'
-  }
-]
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/helper/index.html b/coverage/src/helper/index.html deleted file mode 100644 index ee8fcdc..0000000 --- a/coverage/src/helper/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for src/helper - - - - - - - - - -
-
-

All files src/helper

-
- -
- 100% - Statements - 108/108 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 108/108 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
commit-types.ts -
-
100%80/80100%0/0100%0/0100%80/80
index.ts -
-
100%1/1100%0/0100%0/0100%1/1
projects.ts -
-
100%27/27100%0/0100%0/0100%27/27
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/helper/index.ts.html b/coverage/src/helper/index.ts.html deleted file mode 100644 index 79582db..0000000 --- a/coverage/src/helper/index.ts.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - Code coverage report for src/helper/index.ts - - - - - - - - - -
-
-

All files / src/helper index.ts

-
- -
- 100% - Statements - 1/1 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 1/1 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -31x -  - 
export { default as commitTypes } from './commit-types'
-export { default as projects } from './projects'
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/helper/projects.ts.html b/coverage/src/helper/projects.ts.html deleted file mode 100644 index 60ccdfc..0000000 --- a/coverage/src/helper/projects.ts.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - Code coverage report for src/helper/projects.ts - - - - - - - - - -
-
-

All files / src/helper projects.ts

-
- -
- 100% - Statements - 27/27 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 27/27 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x
interface Project {
-  name: string
-  prefix: string
-  value: string
-}
- 
-export default <Project[]>[
-  {
-    name: 'OwlPay',
-    prefix: 'OWLPAY',
-    value: 'owlpay'
-  },
-  {
-    name: 'OwlNest',
-    prefix: 'OW',
-    value: 'owlnest'
-  },
-  {
-    name: 'Market',
-    prefix: 'MAR',
-    value: 'market'
-  },
-  {
-    name: 'PayNow',
-    prefix: 'PN',
-    value: 'paynow'
-  },
-  {
-    name: 'Wallet Pro',
-    prefix: 'WP',
-    value: 'wallet-pro'
-  }
-]
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/index.html b/coverage/src/index.html deleted file mode 100644 index 8a613a6..0000000 --- a/coverage/src/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for src - - - - - - - - - -
-
-

All files src

-
- -
- 100% - Statements - 23/23 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 23/23 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
100%23/23100%4/4100%1/1100%23/23
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/index.ts.html b/coverage/src/index.ts.html deleted file mode 100644 index a688a46..0000000 --- a/coverage/src/index.ts.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - Code coverage report for src/index.ts - - - - - - - - - -
-
-

All files / src index.ts

-
- -
- 100% - Statements - 23/23 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 23/23 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -331x -  -  -  -  -  -  -  -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -  -6x -2x -6x -2x -2x -2x -2x -6x - 
import cli from './commands'
-import init from './commands/init'
-import where from './commands/where'
-import yargs from 'yargs/yargs'
- 
-type Args = {
-  init?: boolean
-  where?: boolean
-}
-export async function run(args: string[]): Promise<void> {
-  const argv = yargs(args)
-    .options({
-      'init': {
-        alias: 'i',
-        describe: 'Set default project prefix.'
-      },
-      'where': {
-        alias: 'w',
-        describe: 'Show config file path.'
-      }
-    })
-    .help()
-    .argv as Args
- 
-  if (argv.init) {
-    await init()
-  } else if (argv.where) {
-    where()
-  } else {
-    cli()
-  }
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/lefthook.yml b/lefthook.yml index 60ee40a..f271f2c 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -11,12 +11,5 @@ pre-commit: fail_text: "โŒ TypeScript compilation failed! Please fix type errors before committing." stage_fixed: false -pre-push: - parallel: true - commands: - coverage: - run: pnpm test:coverage - fail_text: "โŒ Coverage check failed! Ensure tests meet coverage requirements." - # Configuration assert_lefthook_installed: true diff --git a/package.json b/package.json index 50437ba..369f049 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "test:watch": "vitest --watch", "test:coverage": "vitest run --coverage", "test:ui": "vitest --ui", + "coverage:badge": "pnpm test:coverage && node scripts/generate-coverage-badge.js", "hooks:install": "lefthook install", "hooks:uninstall": "lefthook uninstall" }, diff --git a/scripts/generate-coverage-badge.js b/scripts/generate-coverage-badge.js new file mode 100644 index 0000000..c2c5e9a --- /dev/null +++ b/scripts/generate-coverage-badge.js @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +import { readFileSync, writeFileSync } from 'fs'; +import { join } from 'path'; + +try { + // ่ฎ€ๅ– coverage summary + const coverageFile = join(process.cwd(), 'coverage', 'coverage-summary.json'); + const coverageData = JSON.parse(readFileSync(coverageFile, 'utf8')); + + // ๅ–ๅพ—็ธฝ้ซ”่ฆ†่“‹็އ + const totalCoverage = coverageData.total; + const statements = totalCoverage.statements.pct; + const branches = totalCoverage.branches.pct; + const functions = totalCoverage.functions.pct; + const lines = totalCoverage.lines.pct; + + // ่จˆ็ฎ—ๅนณๅ‡่ฆ†่“‹็އ + const avgCoverage = Math.round((statements + branches + functions + lines) / 4); + + // ๆฑบๅฎš badge ้ก่‰ฒ + let color = 'red'; + if (avgCoverage >= 80) color = 'brightgreen'; + else if (avgCoverage >= 60) color = 'yellow'; + else if (avgCoverage >= 40) color = 'orange'; + + // ็”Ÿๆˆ badge URL + const badgeUrl = `https://img.shields.io/badge/coverage-${avgCoverage}%25-${color}`; + + // ็”Ÿๆˆ coverage ๅ ฑๅ‘Š + const coverageReport = { + timestamp: new Date().toISOString(), + coverage: { + statements: `${statements}%`, + branches: `${branches}%`, + functions: `${functions}%`, + lines: `${lines}%`, + average: `${avgCoverage}%` + }, + badge: { + url: badgeUrl, + markdown: `![Coverage](${badgeUrl})`, + html: `Coverage Badge` + }, + details: { + statements: totalCoverage.statements, + branches: totalCoverage.branches, + functions: totalCoverage.functions, + lines: totalCoverage.lines + } + }; + + // ่ผธๅ‡บๅˆฐๆช”ๆกˆ + writeFileSync('coverage-badge.json', JSON.stringify(coverageReport, null, 2)); + + // ่ผธๅ‡บๅˆฐ console + console.log('๐Ÿ“Š Coverage Report Generated:'); + console.log(`๐Ÿ“ˆ Statements: ${statements}%`); + console.log(`๐ŸŒฟ Branches: ${branches}%`); + console.log(`โšก Functions: ${functions}%`); + console.log(`๐Ÿ“ Lines: ${lines}%`); + console.log(`๐ŸŽฏ Average: ${avgCoverage}%`); + console.log(`\n๐Ÿท๏ธ Badge Markdown: ${coverageReport.badge.markdown}`); + console.log(`๐Ÿ“„ Coverage badge saved to: coverage-badge.json`); +} catch (error) { + console.error('โŒ Error generating coverage badge:', error.message); + process.exit(1); +} diff --git a/vitest.config.ts b/vitest.config.ts index 2c4e5ac..73cc21f 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -7,16 +7,17 @@ export default defineConfig({ setupFiles: ['./tests/setup.ts'], coverage: { provider: 'v8', - reporter: ['text', 'json', 'html'], + reporter: ['text', 'json', 'json-summary', 'html', 'lcov'], exclude: [ - 'node_modules/', - 'dist/', - 'tests/', - '**/*.d.ts', - 'vitest.config.ts', - 'build.config.ts', - 'bin/' - ] + 'node_modules/**', + 'tests/**', + 'dist/**', + 'coverage/**', + '*.config.{js,ts}', + 'bin/**', + 'scripts/**' + ], + all: true } }, resolve: { From d8402054ca818e6e8fc4ebe8529e28acf45061ae Mon Sep 17 00:00:00 2001 From: NickLin Date: Tue, 10 Jun 2025 17:02:59 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=94=A8=20refactor:=20rewrite=20index.?= =?UTF-8?q?ts=20using=20TDD=20approach?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/index.cjs | 310 ++++++++++------ dist/index.mjs | 310 ++++++++++------ src/commands/index.ts | 386 +++++++++++++------- src/helper/commit-types.ts | 6 +- src/helper/projects.ts | 10 +- src/types/index.ts | 74 ++++ tests/commands/cli-module-loading.test.ts | 43 +-- tests/commands/index-refactored.test.ts | 407 ++++++++++++++++++++++ vitest.config.ts | 5 +- 9 files changed, 1160 insertions(+), 391 deletions(-) create mode 100644 src/types/index.ts create mode 100644 tests/commands/index-refactored.test.ts diff --git a/dist/index.cjs b/dist/index.cjs index f34c668..93e483e 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -128,100 +128,147 @@ const projects = [ const __dirname$3 = node_path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))); const rootPath$1 = node_path.resolve(__dirname$3, "../"); -let defaultProjectValue = ""; -try { - const filePath = node_path.resolve(rootPath$1, "keep/cz_config.json"); - const config = fs__default.readFileSync(filePath); - defaultProjectValue = JSON.parse(config).defaultProject; -} catch (e) { - console.log(picocolors__default.yellow(picocolors__default.italic(" \u{1F4A1} You can try `cz -i` to choose a default project prefix. "))); - defaultProjectValue = ""; -} -const typesList = commitTypes.map((type) => ({ - title: type.name, - description: `${type.emoji} ${type.description}`, - value: type.value, - emoji: type.emoji -})); -const step_type$1 = { - type: "autocomplete", - name: "commit_type", - message: "Pick a commit type.", - choices: typesList, - fallback: "No matched type." -}; -const step_message = { - type: "text", - name: "commit_message", - message: (prev) => { - const target = typesList.find((type) => type.value === prev); - return `${target.emoji} ${target.title}`; - }, - validate: (value) => { - if (!value) { - return "Commit message is required."; - } - return true; +const loadProjectConfig = (filePath) => { + try { + const config = fs__default.readFileSync(filePath, "utf8"); + return JSON.parse(config); + } catch (e) { + return null; } }; -const step_description = { - type: "text", - name: "commit_description", - message: "Commit description (optional)", - initial: "", - validate: (value) => { - if (value.length > 100) { - return "Description is too long."; - } - return true; - } +const getDefaultProjectValue = (config) => { + return config?.defaultProject || ""; }; -const step_is_jira = { - type: "confirm", - name: "is_jira", - message: "Tag Jira issue ?", - initial: false +const buildCommitTypesList = () => { + return commitTypes.map((type) => ({ + title: type.name, + description: `${type.emoji} ${type.description}`, + value: type.value, + emoji: type.emoji + })); }; -const projectsList$1 = projects.map((project) => ({ - title: project.name, - description: `[${project.prefix}-13845] title`, - value: project.value -})); -const defaultProject = projectsList$1.find((project) => project.value === defaultProjectValue); -const step_is_default_project = { - type: (prev) => prev ? "confirm" : null, - name: "is_default_project", - message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, - initial: true +const buildProjectsList = () => { + return projects.map((project) => ({ + title: project.name, + description: `[${project.prefix}-13845] title`, + value: project.value + })); }; -const step_project_type = { - type: (prev, { is_jira }) => { - return is_jira ? defaultProject?.value && prev ? null : "autocomplete" : null; - }, - name: "project_type", - message: "Pick a project type.", - choices: projectsList$1, - initial: "owlpay", - fallback: "No matched project." +const findCommitType = (commitTypeValue) => { + return commitTypes.find((type) => type.value === commitTypeValue); }; -const step_jira_id = { - type: (prev) => prev ? "number" : null, - name: "jira_id", - message: "Jira issue id", - onRender() { - this.msg = picocolors__default.bgCyan(picocolors__default.white(" Jira issue ID ")); - }, - validate: (value) => { - if (!value) { - return "Jira issue ID is required."; - } - return true; +const findProject = (projectValue) => { + return projects.find((project) => project.value === projectValue); +}; +const buildCommitTitle = (commitType, message) => { + const type = findCommitType(commitType); + if (!type) { + throw new Error(`Invalid commit type: ${commitType}`); } + return `${type.emoji} ${commitType}: ${message}`; }; -const cli = async () => { - let isCanceled = false; - const order = [ - step_type$1, +const buildFinalCommitMessage = (commitTitle, response, defaultProjectValue) => { + const { is_jira, is_default_project, project_type, jira_id } = response; + if (!is_jira) { + return commitTitle; + } + const typeResponse = is_default_project ? defaultProjectValue : project_type; + const projectType = findProject(typeResponse); + if (!projectType) { + throw new Error(`Invalid project type: ${typeResponse}`); + } + if (!jira_id) { + throw new Error("Jira ID is required when using Jira integration"); + } + return `[${projectType.prefix}-${jira_id}] ${commitTitle}`; +}; +const buildGitCommands = (commitMessage, description) => { + if (description) { + return ["commit", "-m", commitMessage, "-m", description]; + } + return ["commit", "-m", commitMessage]; +}; +const parseCommitResult = (stdout) => { + const branchHashName = stdout.match(/\[(.*?)\]/)?.pop(); + if (!branchHashName) { + throw new Error("Could not parse commit result"); + } + const [branchName, branchHash] = branchHashName.split(" "); + return { branch: branchName, hash: branchHash }; +}; +const buildPromptSteps = (defaultProjectValue, projectsList, typesList) => { + const defaultProject = projectsList.find((project) => project.value === defaultProjectValue); + const step_type = { + type: "autocomplete", + name: "commit_type", + message: "Pick a commit type.", + choices: typesList, + fallback: "No matched type." + }; + const step_message = { + type: "text", + name: "commit_message", + message: (prev) => { + const target = typesList.find((type) => type.value === prev); + return `${target.emoji} ${target.title}`; + }, + validate: (value) => { + if (!value) { + return "Commit message is required."; + } + return true; + } + }; + const step_description = { + type: "text", + name: "commit_description", + message: "Commit description (optional)", + initial: "", + validate: (value) => { + if (value.length > 100) { + return "Description is too long."; + } + return true; + } + }; + const step_is_jira = { + type: "confirm", + name: "is_jira", + message: "Tag Jira issue ?", + initial: false + }; + const step_is_default_project = { + type: (prev) => prev ? "confirm" : null, + name: "is_default_project", + message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, + initial: true + }; + const step_project_type = { + type: (prev, { is_jira }) => { + return is_jira ? defaultProject?.value && prev ? null : "autocomplete" : null; + }, + name: "project_type", + message: "Pick a project type.", + choices: projectsList, + initial: "owlpay", + fallback: "No matched project." + }; + const step_jira_id = { + type: (prev) => prev ? "number" : null, + name: "jira_id", + message: "Jira issue id", + onRender() { + this.msg = picocolors__default.bgCyan(picocolors__default.white(" Jira issue ID ")); + }, + validate: (value) => { + if (!value) { + return "Jira issue ID is required."; + } + return true; + } + }; + return [ + step_type, step_message, step_description, step_is_jira, @@ -229,7 +276,52 @@ const cli = async () => { step_project_type, step_jira_id ].filter(Boolean); - const response = await prompts__default(order, { +}; +const showConfigMissingWarning = () => { + console.log(picocolors__default.yellow(picocolors__default.italic(" \u{1F4A1} You can try `cz -i` to choose a default project prefix. "))); +}; +const showCancelMessage = () => { + console.log(picocolors__default.magenta(" commit abort. ")); +}; +const showCommitResult = (result) => { + console.log("-----------------------------------------------------------"); + console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Title "))} ${picocolors__default.green(result.title)}`); + if (result.description) { + console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Description "))} ${picocolors__default.green(result.description)}`); + } + if (result.hash && result.branch) { + console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Commit hash "))} ${picocolors__default.bold(picocolors__default.cyan(` ${result.hash} `))} (${picocolors__default.italic(picocolors__default.green(result.branch))})`); + } +}; +const showGitOutput = (stdout, stderr) => { + console.log("-----------------------------------------------------------"); + console.log(picocolors__default.dim(stdout)); + if (stderr && stderr !== "") { + console.log("-----------------------------------------------------------"); + console.log(picocolors__default.dim(stderr)); + } + console.log("-----------------------------------------------------------"); +}; +const showGitError = (error) => { + console.log(picocolors__default.red(error.stderr)); + if (error.exitCode === 1) { + console.log(picocolors__default.bgRed(" No changes added to commit. ")); + } else { + console.error(error); + } +}; +const cli = async () => { + const configPath = node_path.resolve(rootPath$1, "keep/cz_config.json"); + const config = loadProjectConfig(configPath); + const defaultProjectValue = getDefaultProjectValue(config); + if (!config) { + showConfigMissingWarning(); + } + const typesList = buildCommitTypesList(); + const projectsList = buildProjectsList(); + const steps = buildPromptSteps(defaultProjectValue, projectsList, typesList); + let isCanceled = false; + const response = await prompts__default(steps, { onSubmit: (prompt, answers) => { if (answers === void 0) { isCanceled = true; @@ -242,38 +334,26 @@ const cli = async () => { } }); if (isCanceled) { - console.log(picocolors__default.magenta(" commit abort. ")); + showCancelMessage(); return false; } - const { commit_type, commit_message, commit_description, is_jira, is_default_project, project_type, jira_id } = response; - const type = typesList.find((type2) => type2.value === commit_type); - const commitTitle = `${type.emoji} ${commit_type}: ${commit_message}`; - const typeResponse = is_default_project ? defaultProject?.value : project_type; - const projectType = projects.find((project) => project.value === typeResponse); - const result = is_jira ? `[${projectType.prefix}-${jira_id}] ${commitTitle}` : commitTitle; try { - const commands = commit_description ? ["commit", "-m", result, "-m", commit_description] : ["commit", "-m", result]; - const commitResult = await execa__default("git", commands); - const branchHashName = commitResult.stdout.match(/\[(.*?)\]/).pop(); - const [branchName, branchHash] = branchHashName.split(" "); - console.log("-----------------------------------------------------------"); - console.log(picocolors__default.dim(commitResult.stdout)); - if (commitResult.stderr !== "") { - console.log("-----------------------------------------------------------"); - console.log(picocolors__default.dim(commitResult.stderr)); - } - console.log("-----------------------------------------------------------"); - console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Title "))} ${picocolors__default.green(result)}`); - if (commit_description) { - console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Description "))} ${picocolors__default.green(commit_description)}`); - } - console.log(`${picocolors__default.bgGreen(picocolors__default.bold(" Commit hash "))} ${picocolors__default.bold(picocolors__default.cyan(` ${branchHash} `))} (${picocolors__default.italic(picocolors__default.green(branchName))})`); + const commitTitle = buildCommitTitle(response.commit_type, response.commit_message); + const finalCommitMessage = buildFinalCommitMessage(commitTitle, response, defaultProjectValue); + const gitCommands = buildGitCommands(finalCommitMessage, response.commit_description); + const commitResult = await execa__default("git", gitCommands); + const { branch, hash } = parseCommitResult(commitResult.stdout); + showGitOutput(commitResult.stdout, commitResult.stderr); + showCommitResult({ + title: finalCommitMessage, + description: response.commit_description, + hash, + branch + }); + return true; } catch (error) { - console.log(picocolors__default.red(error.stderr)); - if (error.exitCode === 1) - console.log(picocolors__default.bgRed(" No changes added to commit. ")); - else - console.error(error); + showGitError(error); + return false; } }; diff --git a/dist/index.mjs b/dist/index.mjs index ce77413..6c2010d 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -117,100 +117,147 @@ const projects = [ const __dirname$2 = dirname(fileURLToPath(import.meta.url)); const rootPath$1 = resolve(__dirname$2, "../"); -let defaultProjectValue = ""; -try { - const filePath = resolve(rootPath$1, "keep/cz_config.json"); - const config = fs.readFileSync(filePath); - defaultProjectValue = JSON.parse(config).defaultProject; -} catch (e) { - console.log(picocolors.yellow(picocolors.italic(" \u{1F4A1} You can try `cz -i` to choose a default project prefix. "))); - defaultProjectValue = ""; -} -const typesList = commitTypes.map((type) => ({ - title: type.name, - description: `${type.emoji} ${type.description}`, - value: type.value, - emoji: type.emoji -})); -const step_type$1 = { - type: "autocomplete", - name: "commit_type", - message: "Pick a commit type.", - choices: typesList, - fallback: "No matched type." -}; -const step_message = { - type: "text", - name: "commit_message", - message: (prev) => { - const target = typesList.find((type) => type.value === prev); - return `${target.emoji} ${target.title}`; - }, - validate: (value) => { - if (!value) { - return "Commit message is required."; - } - return true; +const loadProjectConfig = (filePath) => { + try { + const config = fs.readFileSync(filePath, "utf8"); + return JSON.parse(config); + } catch (e) { + return null; } }; -const step_description = { - type: "text", - name: "commit_description", - message: "Commit description (optional)", - initial: "", - validate: (value) => { - if (value.length > 100) { - return "Description is too long."; - } - return true; - } +const getDefaultProjectValue = (config) => { + return config?.defaultProject || ""; }; -const step_is_jira = { - type: "confirm", - name: "is_jira", - message: "Tag Jira issue ?", - initial: false +const buildCommitTypesList = () => { + return commitTypes.map((type) => ({ + title: type.name, + description: `${type.emoji} ${type.description}`, + value: type.value, + emoji: type.emoji + })); }; -const projectsList$1 = projects.map((project) => ({ - title: project.name, - description: `[${project.prefix}-13845] title`, - value: project.value -})); -const defaultProject = projectsList$1.find((project) => project.value === defaultProjectValue); -const step_is_default_project = { - type: (prev) => prev ? "confirm" : null, - name: "is_default_project", - message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, - initial: true +const buildProjectsList = () => { + return projects.map((project) => ({ + title: project.name, + description: `[${project.prefix}-13845] title`, + value: project.value + })); }; -const step_project_type = { - type: (prev, { is_jira }) => { - return is_jira ? defaultProject?.value && prev ? null : "autocomplete" : null; - }, - name: "project_type", - message: "Pick a project type.", - choices: projectsList$1, - initial: "owlpay", - fallback: "No matched project." +const findCommitType = (commitTypeValue) => { + return commitTypes.find((type) => type.value === commitTypeValue); }; -const step_jira_id = { - type: (prev) => prev ? "number" : null, - name: "jira_id", - message: "Jira issue id", - onRender() { - this.msg = picocolors.bgCyan(picocolors.white(" Jira issue ID ")); - }, - validate: (value) => { - if (!value) { - return "Jira issue ID is required."; - } - return true; +const findProject = (projectValue) => { + return projects.find((project) => project.value === projectValue); +}; +const buildCommitTitle = (commitType, message) => { + const type = findCommitType(commitType); + if (!type) { + throw new Error(`Invalid commit type: ${commitType}`); } + return `${type.emoji} ${commitType}: ${message}`; }; -const cli = async () => { - let isCanceled = false; - const order = [ - step_type$1, +const buildFinalCommitMessage = (commitTitle, response, defaultProjectValue) => { + const { is_jira, is_default_project, project_type, jira_id } = response; + if (!is_jira) { + return commitTitle; + } + const typeResponse = is_default_project ? defaultProjectValue : project_type; + const projectType = findProject(typeResponse); + if (!projectType) { + throw new Error(`Invalid project type: ${typeResponse}`); + } + if (!jira_id) { + throw new Error("Jira ID is required when using Jira integration"); + } + return `[${projectType.prefix}-${jira_id}] ${commitTitle}`; +}; +const buildGitCommands = (commitMessage, description) => { + if (description) { + return ["commit", "-m", commitMessage, "-m", description]; + } + return ["commit", "-m", commitMessage]; +}; +const parseCommitResult = (stdout) => { + const branchHashName = stdout.match(/\[(.*?)\]/)?.pop(); + if (!branchHashName) { + throw new Error("Could not parse commit result"); + } + const [branchName, branchHash] = branchHashName.split(" "); + return { branch: branchName, hash: branchHash }; +}; +const buildPromptSteps = (defaultProjectValue, projectsList, typesList) => { + const defaultProject = projectsList.find((project) => project.value === defaultProjectValue); + const step_type = { + type: "autocomplete", + name: "commit_type", + message: "Pick a commit type.", + choices: typesList, + fallback: "No matched type." + }; + const step_message = { + type: "text", + name: "commit_message", + message: (prev) => { + const target = typesList.find((type) => type.value === prev); + return `${target.emoji} ${target.title}`; + }, + validate: (value) => { + if (!value) { + return "Commit message is required."; + } + return true; + } + }; + const step_description = { + type: "text", + name: "commit_description", + message: "Commit description (optional)", + initial: "", + validate: (value) => { + if (value.length > 100) { + return "Description is too long."; + } + return true; + } + }; + const step_is_jira = { + type: "confirm", + name: "is_jira", + message: "Tag Jira issue ?", + initial: false + }; + const step_is_default_project = { + type: (prev) => prev ? "confirm" : null, + name: "is_default_project", + message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, + initial: true + }; + const step_project_type = { + type: (prev, { is_jira }) => { + return is_jira ? defaultProject?.value && prev ? null : "autocomplete" : null; + }, + name: "project_type", + message: "Pick a project type.", + choices: projectsList, + initial: "owlpay", + fallback: "No matched project." + }; + const step_jira_id = { + type: (prev) => prev ? "number" : null, + name: "jira_id", + message: "Jira issue id", + onRender() { + this.msg = picocolors.bgCyan(picocolors.white(" Jira issue ID ")); + }, + validate: (value) => { + if (!value) { + return "Jira issue ID is required."; + } + return true; + } + }; + return [ + step_type, step_message, step_description, step_is_jira, @@ -218,7 +265,52 @@ const cli = async () => { step_project_type, step_jira_id ].filter(Boolean); - const response = await prompts(order, { +}; +const showConfigMissingWarning = () => { + console.log(picocolors.yellow(picocolors.italic(" \u{1F4A1} You can try `cz -i` to choose a default project prefix. "))); +}; +const showCancelMessage = () => { + console.log(picocolors.magenta(" commit abort. ")); +}; +const showCommitResult = (result) => { + console.log("-----------------------------------------------------------"); + console.log(`${picocolors.bgGreen(picocolors.bold(" Title "))} ${picocolors.green(result.title)}`); + if (result.description) { + console.log(`${picocolors.bgGreen(picocolors.bold(" Description "))} ${picocolors.green(result.description)}`); + } + if (result.hash && result.branch) { + console.log(`${picocolors.bgGreen(picocolors.bold(" Commit hash "))} ${picocolors.bold(picocolors.cyan(` ${result.hash} `))} (${picocolors.italic(picocolors.green(result.branch))})`); + } +}; +const showGitOutput = (stdout, stderr) => { + console.log("-----------------------------------------------------------"); + console.log(picocolors.dim(stdout)); + if (stderr && stderr !== "") { + console.log("-----------------------------------------------------------"); + console.log(picocolors.dim(stderr)); + } + console.log("-----------------------------------------------------------"); +}; +const showGitError = (error) => { + console.log(picocolors.red(error.stderr)); + if (error.exitCode === 1) { + console.log(picocolors.bgRed(" No changes added to commit. ")); + } else { + console.error(error); + } +}; +const cli = async () => { + const configPath = resolve(rootPath$1, "keep/cz_config.json"); + const config = loadProjectConfig(configPath); + const defaultProjectValue = getDefaultProjectValue(config); + if (!config) { + showConfigMissingWarning(); + } + const typesList = buildCommitTypesList(); + const projectsList = buildProjectsList(); + const steps = buildPromptSteps(defaultProjectValue, projectsList, typesList); + let isCanceled = false; + const response = await prompts(steps, { onSubmit: (prompt, answers) => { if (answers === void 0) { isCanceled = true; @@ -231,38 +323,26 @@ const cli = async () => { } }); if (isCanceled) { - console.log(picocolors.magenta(" commit abort. ")); + showCancelMessage(); return false; } - const { commit_type, commit_message, commit_description, is_jira, is_default_project, project_type, jira_id } = response; - const type = typesList.find((type2) => type2.value === commit_type); - const commitTitle = `${type.emoji} ${commit_type}: ${commit_message}`; - const typeResponse = is_default_project ? defaultProject?.value : project_type; - const projectType = projects.find((project) => project.value === typeResponse); - const result = is_jira ? `[${projectType.prefix}-${jira_id}] ${commitTitle}` : commitTitle; try { - const commands = commit_description ? ["commit", "-m", result, "-m", commit_description] : ["commit", "-m", result]; - const commitResult = await execa("git", commands); - const branchHashName = commitResult.stdout.match(/\[(.*?)\]/).pop(); - const [branchName, branchHash] = branchHashName.split(" "); - console.log("-----------------------------------------------------------"); - console.log(picocolors.dim(commitResult.stdout)); - if (commitResult.stderr !== "") { - console.log("-----------------------------------------------------------"); - console.log(picocolors.dim(commitResult.stderr)); - } - console.log("-----------------------------------------------------------"); - console.log(`${picocolors.bgGreen(picocolors.bold(" Title "))} ${picocolors.green(result)}`); - if (commit_description) { - console.log(`${picocolors.bgGreen(picocolors.bold(" Description "))} ${picocolors.green(commit_description)}`); - } - console.log(`${picocolors.bgGreen(picocolors.bold(" Commit hash "))} ${picocolors.bold(picocolors.cyan(` ${branchHash} `))} (${picocolors.italic(picocolors.green(branchName))})`); + const commitTitle = buildCommitTitle(response.commit_type, response.commit_message); + const finalCommitMessage = buildFinalCommitMessage(commitTitle, response, defaultProjectValue); + const gitCommands = buildGitCommands(finalCommitMessage, response.commit_description); + const commitResult = await execa("git", gitCommands); + const { branch, hash } = parseCommitResult(commitResult.stdout); + showGitOutput(commitResult.stdout, commitResult.stderr); + showCommitResult({ + title: finalCommitMessage, + description: response.commit_description, + hash, + branch + }); + return true; } catch (error) { - console.log(picocolors.red(error.stderr)); - if (error.exitCode === 1) - console.log(picocolors.bgRed(" No changes added to commit. ")); - else - console.error(error); + showGitError(error); + return false; } }; diff --git a/src/commands/index.ts b/src/commands/index.ts index fe8d12a..d09c37c 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,6 +1,13 @@ import prompts from 'prompts' import execa from 'execa' import { projects, commitTypes } from '../helper' +import type { + ProjectConfig, + CommitResponse, + CommitResult, + ProjectType, + ParsedCommitResult +} from '../types' import picocolors from 'picocolors' import fs from 'fs' import { dirname, resolve } from 'node:path' @@ -9,115 +16,180 @@ import { fileURLToPath } from 'node:url' const __dirname = dirname(fileURLToPath(import.meta.url)) const rootPath = resolve(__dirname, '../') -let defaultProjectValue = '' +// Pure functions for business logic +export const loadProjectConfig = (filePath: string): ProjectConfig | null => { + try { + const config = fs.readFileSync(filePath, 'utf8') + return JSON.parse(config) + } catch (e) { + return null + } +} -try { - const filePath = resolve(rootPath, 'keep/cz_config.json') - const config = fs.readFileSync(filePath) - defaultProjectValue = JSON.parse(config as any).defaultProject -} catch (e) { - console.log(picocolors.yellow(picocolors.italic(' ๐Ÿ’ก You can try `cz -i` to choose a default project prefix. '))) - defaultProjectValue = '' -} - -const typesList = commitTypes.map(type => ({ - title: type.name, - description: `${type.emoji} ${type.description}`, - value: type.value, - emoji: type.emoji -})) - -const step_type = { - type: 'autocomplete', - name: 'commit_type', - message: 'Pick a commit type.', - choices: typesList, - fallback: 'No matched type.' -} - -const step_message = { - type: 'text', - name: 'commit_message', - message: (prev: string) => { - const target = typesList.find(type => type.value === prev)! - return `${target.emoji} ${target.title}` - }, - validate: (value: string) => { - if (!value) { - return 'Commit message is required.' - } - return true +export const getDefaultProjectValue = (config: ProjectConfig | null): string => { + return config?.defaultProject || '' +} + +export const buildCommitTypesList = () => { + return commitTypes.map(type => ({ + title: type.name, + description: `${type.emoji} ${type.description}`, + value: type.value, + emoji: type.emoji + })) +} + +export const buildProjectsList = () => { + return projects.map(project => ({ + title: project.name, + description: `[${project.prefix}-13845] title`, + value: project.value + })) +} + +export const findCommitType = (commitTypeValue: string) => { + return commitTypes.find(type => type.value === commitTypeValue) +} + +export const findProject = (projectValue: string): ProjectType | undefined => { + return projects.find(project => project.value === projectValue) +} + +export const buildCommitTitle = (commitType: string, message: string): string => { + const type = findCommitType(commitType) + if (!type) { + throw new Error(`Invalid commit type: ${commitType}`) } + return `${type.emoji} ${commitType}: ${message}` } -const step_description = { - type: 'text', - name: 'commit_description', - message: 'Commit description (optional)', - initial: '', - validate: (value: string) => { - if (value.length > 100) { - return 'Description is too long.' - } - return true +export const buildFinalCommitMessage = ( + commitTitle: string, + response: CommitResponse, + defaultProjectValue: string +): string => { + const { is_jira, is_default_project, project_type, jira_id } = response + + if (!is_jira) { + return commitTitle + } + + const typeResponse = is_default_project ? defaultProjectValue : project_type + const projectType = findProject(typeResponse!) + + if (!projectType) { + throw new Error(`Invalid project type: ${typeResponse}`) + } + + if (!jira_id) { + throw new Error('Jira ID is required when using Jira integration') } + + return `[${projectType.prefix}-${jira_id}] ${commitTitle}` } -const step_is_jira = { - type: 'confirm', - name: 'is_jira', - message: 'Tag Jira issue ?', - initial: false -} - -const projectsList = projects.map(project => ({ - title: project.name, - description: `[${project.prefix}-13845] title`, - value: project.value -})) - -const defaultProject = projectsList.find(project => project.value === defaultProjectValue)! - -const step_is_default_project = { - type: (prev: boolean) => prev ? 'confirm' : null, - name: 'is_default_project', - message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, - initial: true -} - -const step_project_type = { - type: (prev: string, { is_jira }: { is_jira: boolean }) => { - return is_jira - ? defaultProject?.value && prev - ? null - : 'autocomplete' - : null - }, - name: 'project_type', - message: 'Pick a project type.', - choices: projectsList, - initial: 'owlpay', - fallback: 'No matched project.' -} - -const step_jira_id = { - type: (prev: boolean) => prev ? 'number' : null, - name: 'jira_id', - message: 'Jira issue id', - onRender () { - (this as any).msg = picocolors.bgCyan(picocolors.white(' Jira issue ID ')) // TODO: fix type - }, - validate: (value: number) => { - if (!value) { - return 'Jira issue ID is required.' - } - return true +export const buildGitCommands = (commitMessage: string, description?: string): string[] => { + if (description) { + return ['commit', '-m', commitMessage, '-m', description] } + return ['commit', '-m', commitMessage] } -export default async () => { - let isCanceled = false - const order = [ +export const parseCommitResult = (stdout: string): ParsedCommitResult => { + const branchHashName = stdout.match(/\[(.*?)\]/)?.pop() + if (!branchHashName) { + throw new Error('Could not parse commit result') + } + + const [branchName, branchHash] = branchHashName.split(' ') + return { branch: branchName, hash: branchHash } +} + +// Step builders for better organization +export const buildPromptSteps = (defaultProjectValue: string, projectsList: any[], typesList: any[]) => { + const defaultProject = projectsList.find(project => project.value === defaultProjectValue) + + const step_type = { + type: 'autocomplete', + name: 'commit_type', + message: 'Pick a commit type.', + choices: typesList, + fallback: 'No matched type.' + } + + const step_message = { + type: 'text', + name: 'commit_message', + message: (prev: string) => { + const target = typesList.find(type => type.value === prev)! + return `${target.emoji} ${target.title}` + }, + validate: (value: string) => { + if (!value) { + return 'Commit message is required.' + } + return true + } + } + + const step_description = { + type: 'text', + name: 'commit_description', + message: 'Commit description (optional)', + initial: '', + validate: (value: string) => { + if (value.length > 100) { + return 'Description is too long.' + } + return true + } + } + + const step_is_jira = { + type: 'confirm', + name: 'is_jira', + message: 'Tag Jira issue ?', + initial: false + } + + const step_is_default_project = { + type: (prev: boolean) => prev ? 'confirm' : null, + name: 'is_default_project', + message: `use '${defaultProject?.title}' pattern? e.g. ${defaultProject?.description}`, + initial: true + } + + const step_project_type = { + type: (prev: string, { is_jira }: { is_jira: boolean }) => { + return is_jira + ? defaultProject?.value && prev + ? null + : 'autocomplete' + : null + }, + name: 'project_type', + message: 'Pick a project type.', + choices: projectsList, + initial: 'owlpay', + fallback: 'No matched project.' + } + + const step_jira_id = { + type: (prev: boolean) => prev ? 'number' : null, + name: 'jira_id', + message: 'Jira issue id', + onRender () { + (this as any).msg = picocolors.bgCyan(picocolors.white(' Jira issue ID ')) + }, + validate: (value: number) => { + if (!value) { + return 'Jira issue ID is required.' + } + return true + } + } + + return [ step_type, step_message, step_description, @@ -125,8 +197,67 @@ export default async () => { defaultProject?.value ? step_is_default_project : null, step_project_type, step_jira_id - ].filter(Boolean) as any // TODO: fix type - const response = await prompts(order, { + ].filter(Boolean) +} + +// Side effect functions +export const showConfigMissingWarning = () => { + console.log(picocolors.yellow(picocolors.italic(' ๐Ÿ’ก You can try `cz -i` to choose a default project prefix. '))) +} + +export const showCancelMessage = () => { + console.log(picocolors.magenta(' commit abort. ')) +} + +export const showCommitResult = (result: CommitResult) => { + console.log('-----------------------------------------------------------') + console.log(`${picocolors.bgGreen(picocolors.bold(' Title '))} ${picocolors.green(result.title)}`) + if (result.description) { + console.log(`${picocolors.bgGreen(picocolors.bold(' Description '))} ${picocolors.green(result.description)}`) + } + if (result.hash && result.branch) { + console.log(`${picocolors.bgGreen(picocolors.bold(' Commit hash '))} ${picocolors.bold(picocolors.cyan(` ${result.hash} `))} (${picocolors.italic(picocolors.green(result.branch))})`) + } +} + +export const showGitOutput = (stdout: string, stderr?: string) => { + console.log('-----------------------------------------------------------') + console.log(picocolors.dim(stdout)) + if (stderr && stderr !== '') { + console.log('-----------------------------------------------------------') + console.log(picocolors.dim(stderr)) + } + console.log('-----------------------------------------------------------') +} + +export const showGitError = (error: any) => { + console.log(picocolors.red(error.stderr)) + if (error.exitCode === 1) { + console.log(picocolors.bgRed(' No changes added to commit. ')) + } else { + console.error(error) + } +} + +// Main CLI function - orchestrates the flow +export default async () => { + // Load configuration + const configPath = resolve(rootPath, 'keep/cz_config.json') + const config = loadProjectConfig(configPath) + const defaultProjectValue = getDefaultProjectValue(config) + + if (!config) { + showConfigMissingWarning() + } + + // Build choices + const typesList = buildCommitTypesList() + const projectsList = buildProjectsList() + const steps = buildPromptSteps(defaultProjectValue, projectsList, typesList) + + // Handle user input + let isCanceled = false + const response = await prompts(steps as any, { onSubmit: (prompt, answers) => { if (answers === undefined) { isCanceled = true @@ -137,42 +268,35 @@ export default async () => { isCanceled = true return false } - }) + }) as CommitResponse if (isCanceled) { - console.log(picocolors.magenta(' commit abort. ')) + showCancelMessage() return false } - const { commit_type, commit_message, commit_description, is_jira, is_default_project, project_type, jira_id } = response - const type = typesList.find(type => type.value === commit_type)! - const commitTitle = `${type.emoji} ${commit_type}: ${commit_message}` - const typeResponse = is_default_project ? defaultProject?.value : project_type - const projectType = projects.find(project => project.value === typeResponse)! - const result = is_jira - ? `[${projectType.prefix}-${jira_id}] ${commitTitle}` - : commitTitle - try { - const commands = commit_description ? ['commit', '-m', result, '-m', commit_description] : ['commit', '-m', result] - const commitResult = await execa('git', commands) - const branchHashName = commitResult.stdout.match(/\[(.*?)\]/)!.pop()! - const [branchName, branchHash] = branchHashName.split(' ') - console.log('-----------------------------------------------------------') - console.log(picocolors.dim(commitResult.stdout)) - if (commitResult.stderr !== '') { - console.log('-----------------------------------------------------------') - console.log(picocolors.dim(commitResult.stderr)) - } - console.log('-----------------------------------------------------------') - console.log(`${picocolors.bgGreen(picocolors.bold(' Title '))} ${picocolors.green(result)}`) - if (commit_description) { - console.log(`${picocolors.bgGreen(picocolors.bold(' Description '))} ${picocolors.green(commit_description)}`) - } - console.log(`${picocolors.bgGreen(picocolors.bold(' Commit hash '))} ${picocolors.bold(picocolors.cyan(` ${branchHash} `))} (${picocolors.italic(picocolors.green(branchName))})`) + // Build commit message + const commitTitle = buildCommitTitle(response.commit_type, response.commit_message) + const finalCommitMessage = buildFinalCommitMessage(commitTitle, response, defaultProjectValue) + const gitCommands = buildGitCommands(finalCommitMessage, response.commit_description) + + // Execute git commit + const commitResult = await execa('git', gitCommands) + const { branch, hash } = parseCommitResult(commitResult.stdout) + + // Show results + showGitOutput(commitResult.stdout, commitResult.stderr) + showCommitResult({ + title: finalCommitMessage, + description: response.commit_description, + hash, + branch + }) + + return true } catch (error: any) { - console.log(picocolors.red(error.stderr)) - if (error.exitCode === 1) console.log(picocolors.bgRed(' No changes added to commit. ')) - else console.error(error) + showGitError(error) + return false } } diff --git a/src/helper/commit-types.ts b/src/helper/commit-types.ts index 7fccf4d..f304b1f 100644 --- a/src/helper/commit-types.ts +++ b/src/helper/commit-types.ts @@ -1,4 +1,8 @@ -export default [ +import type { CommitType } from '../types' + +export type { CommitType } + +export default [ { name: 'chore', emoji: '๐Ÿงน', diff --git a/src/helper/projects.ts b/src/helper/projects.ts index 38bc7ed..30ff63b 100644 --- a/src/helper/projects.ts +++ b/src/helper/projects.ts @@ -1,10 +1,8 @@ -interface Project { - name: string - prefix: string - value: string -} +import type { ProjectType } from '../types' -export default [ +export type { ProjectType } + +export default [ { name: 'OwlPay', prefix: 'OWLPAY', diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..f7d8ff8 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,74 @@ +// Configuration related types +export interface ProjectConfig { + defaultProject?: string +} + +// CLI response types +export interface CommitResponse { + commit_type: string + commit_message: string + commit_description?: string + is_jira: boolean + is_default_project?: boolean + project_type?: string + jira_id?: number +} + +// Result display types +export interface CommitResult { + title: string + description?: string + hash?: string + branch?: string +} + +// Project structure types +export interface ProjectType { + name: string + prefix: string + value: string +} + +// Commit type structure +export interface CommitType { + name: string + emoji: string + description: string + value: string +} + +// Git command result types +export interface GitCommitResult { + stdout: string + stderr?: string +} + +export interface ParsedCommitResult { + branch: string + hash: string +} + +// Error types +export interface GitError extends Error { + stderr?: string + exitCode?: number +} + +// Prompt step types +export interface PromptChoice { + title: string + description: string + value: string + emoji?: string +} + +export interface PromptStep { + type: string + name: string + message: string | ((prev: any) => string) + choices?: PromptChoice[] + initial?: any + validate?: (value: any) => boolean | string + fallback?: string + onRender?: () => void +} \ No newline at end of file diff --git a/tests/commands/cli-module-loading.test.ts b/tests/commands/cli-module-loading.test.ts index 0f9b1b6..e6c4749 100644 --- a/tests/commands/cli-module-loading.test.ts +++ b/tests/commands/cli-module-loading.test.ts @@ -1,18 +1,30 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { describe, it, expect, vi, beforeEach } from 'vitest' import fs from 'fs' // Mock dependencies before importing the module vi.mock('fs') +vi.mock('prompts') +vi.mock('execa') vi.mock('picocolors', () => ({ default: { yellow: (text: string) => text, - italic: (text: string) => text + italic: (text: string) => text, + magenta: (text: string) => text, + bgGreen: (text: string) => text, + bold: (text: string) => text, + green: (text: string) => text, + cyan: (text: string) => text, + dim: (text: string) => text, + red: (text: string) => text, + bgRed: (text: string) => text, + bgCyan: (text: string) => text, + white: (text: string) => text } })) const mockFs = vi.mocked(fs) -describe('CLI module loading', () => { +describe('CLI module loading behavior after refactoring', () => { const mockConsoleLog = vi.fn() beforeEach(() => { @@ -20,39 +32,28 @@ describe('CLI module loading', () => { console.log = mockConsoleLog }) - afterEach(() => { - vi.restoreAllMocks() - }) - - it('should show warning when config file is missing during module load', async () => { + it('should not show warning during module load (warning moved to function execution)', async () => { // Mock config file read error mockFs.readFileSync = vi.fn().mockImplementation(() => { throw new Error('File not found') }) - // Import the module to trigger the warning + // Import the module - this should NOT trigger any console.log await import('../../src/commands/index') - expect(mockConsoleLog).toHaveBeenCalledWith( - expect.stringContaining('You can try `cz -i` to choose a default project prefix') - ) + expect(mockConsoleLog).not.toHaveBeenCalled() }) - it('should not show warning when config file exists during module load', async () => { - // Mock config file exists + it('should load module successfully when config file exists', async () => { + // Mock successful config file read mockFs.readFileSync = vi.fn().mockReturnValue( JSON.stringify({ defaultProject: 'owlpay' }) ) - // Clear any previous console calls - mockConsoleLog.mockClear() - // Import the module await import('../../src/commands/index') - // Should not have warning message - expect(mockConsoleLog).not.toHaveBeenCalledWith( - expect.stringContaining('You can try `cz -i` to choose a default project prefix') - ) + // No console.log should be called during module loading + expect(mockConsoleLog).not.toHaveBeenCalled() }) }) diff --git a/tests/commands/index-refactored.test.ts b/tests/commands/index-refactored.test.ts new file mode 100644 index 0000000..809e598 --- /dev/null +++ b/tests/commands/index-refactored.test.ts @@ -0,0 +1,407 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import fs from 'fs' +import type { CommitResponse, ProjectConfig, CommitResult } from '../../src/types' +import { + loadProjectConfig, + getDefaultProjectValue, + buildCommitTypesList, + buildProjectsList, + findCommitType, + findProject, + buildCommitTitle, + buildFinalCommitMessage, + buildGitCommands, + parseCommitResult, + buildPromptSteps, + showConfigMissingWarning, + showCancelMessage, + showCommitResult, + showGitOutput, + showGitError +} from '../../src/commands/index' + +// Mock dependencies +vi.mock('fs') +vi.mock('picocolors', () => ({ + default: { + yellow: (text: string) => text, + italic: (text: string) => text, + magenta: (text: string) => text, + bgGreen: (text: string) => text, + bold: (text: string) => text, + green: (text: string) => text, + cyan: (text: string) => text, + dim: (text: string) => text, + red: (text: string) => text, + bgRed: (text: string) => text, + bgCyan: (text: string) => text, + white: (text: string) => text + } +})) + +const mockFs = vi.mocked(fs) + +describe('Refactored CLI Functions (TDD Style)', () => { + const mockConsoleLog = vi.fn() + const mockConsoleError = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + console.log = mockConsoleLog + console.error = mockConsoleError + }) + + describe('Configuration Loading Functions', () => { + describe('loadProjectConfig', () => { + it('should load valid config file', () => { + const mockConfig = { defaultProject: 'owlpay' } + mockFs.readFileSync = vi.fn().mockReturnValue(JSON.stringify(mockConfig)) + + const result = loadProjectConfig('/path/to/config.json') + + expect(result).toEqual(mockConfig) + expect(mockFs.readFileSync).toHaveBeenCalledWith('/path/to/config.json', 'utf8') + }) + + it('should return null for invalid config file', () => { + mockFs.readFileSync = vi.fn().mockImplementation(() => { + throw new Error('File not found') + }) + + const result = loadProjectConfig('/path/to/config.json') + + expect(result).toBeNull() + }) + + it('should return null for invalid JSON', () => { + mockFs.readFileSync = vi.fn().mockReturnValue('invalid json') + + const result = loadProjectConfig('/path/to/config.json') + + expect(result).toBeNull() + }) + }) + + describe('getDefaultProjectValue', () => { + it('should return default project when config exists', () => { + const config: ProjectConfig = { defaultProject: 'owlpay' } + const result = getDefaultProjectValue(config) + expect(result).toBe('owlpay') + }) + + it('should return empty string when config is null', () => { + const result = getDefaultProjectValue(null) + expect(result).toBe('') + }) + + it('should return empty string when defaultProject is undefined', () => { + const config: ProjectConfig = {} + const result = getDefaultProjectValue(config) + expect(result).toBe('') + }) + }) + }) + + describe('List Building Functions', () => { + describe('buildCommitTypesList', () => { + it('should build commit types list correctly', () => { + const result = buildCommitTypesList() + + expect(result).toHaveLength(13) + expect(result[0]).toMatchObject({ + title: 'chore', + description: '๐Ÿงน Build process or auxiliary tool changes', + value: 'chore', + emoji: '๐Ÿงน' + }) + }) + }) + + describe('buildProjectsList', () => { + it('should build projects list correctly', () => { + const result = buildProjectsList() + + expect(result).toHaveLength(5) + expect(result[0]).toMatchObject({ + title: 'OwlPay', + description: '[OWLPAY-13845] title', + value: 'owlpay' + }) + }) + }) + }) + + describe('Finder Functions', () => { + describe('findCommitType', () => { + it('should find existing commit type', () => { + const result = findCommitType('feat') + expect(result).toMatchObject({ + name: 'feat', + emoji: '๐Ÿ’ก', + value: 'feat' + }) + }) + + it('should return undefined for non-existing commit type', () => { + const result = findCommitType('nonexistent') + expect(result).toBeUndefined() + }) + }) + + describe('findProject', () => { + it('should find existing project', () => { + const result = findProject('owlpay') + expect(result).toMatchObject({ + name: 'OwlPay', + prefix: 'OWLPAY', + value: 'owlpay' + }) + }) + + it('should return undefined for non-existing project', () => { + const result = findProject('nonexistent') + expect(result).toBeUndefined() + }) + }) + }) + + describe('Commit Message Building Functions', () => { + describe('buildCommitTitle', () => { + it('should build commit title correctly', () => { + const result = buildCommitTitle('feat', 'add new feature') + expect(result).toBe('๐Ÿ’ก feat: add new feature') + }) + + it('should throw error for invalid commit type', () => { + expect(() => buildCommitTitle('invalid', 'message')).toThrow('Invalid commit type: invalid') + }) + }) + + describe('buildFinalCommitMessage', () => { + it('should return plain commit title when not using Jira', () => { + const response: CommitResponse = { + commit_type: 'feat', + commit_message: 'test', + is_jira: false + } + + const result = buildFinalCommitMessage('๐Ÿ’ก feat: test', response, 'owlpay') + expect(result).toBe('๐Ÿ’ก feat: test') + }) + + it('should build Jira commit with default project', () => { + const response: CommitResponse = { + commit_type: 'feat', + commit_message: 'test', + is_jira: true, + is_default_project: true, + jira_id: 12345 + } + + const result = buildFinalCommitMessage('๐Ÿ’ก feat: test', response, 'owlpay') + expect(result).toBe('[OWLPAY-12345] ๐Ÿ’ก feat: test') + }) + + it('should build Jira commit with selected project', () => { + const response: CommitResponse = { + commit_type: 'feat', + commit_message: 'test', + is_jira: true, + is_default_project: false, + project_type: 'owlnest', + jira_id: 67890 + } + + const result = buildFinalCommitMessage('๐Ÿ’ก feat: test', response, 'owlpay') + expect(result).toBe('[OW-67890] ๐Ÿ’ก feat: test') + }) + + it('should throw error for invalid project type', () => { + const response: CommitResponse = { + commit_type: 'feat', + commit_message: 'test', + is_jira: true, + is_default_project: false, + project_type: 'invalid' + } + + expect(() => buildFinalCommitMessage('๐Ÿ’ก feat: test', response, 'owlpay')) + .toThrow('Invalid project type: invalid') + }) + + it('should throw error when Jira ID is missing', () => { + const response: CommitResponse = { + commit_type: 'feat', + commit_message: 'test', + is_jira: true, + is_default_project: true + } + + expect(() => buildFinalCommitMessage('๐Ÿ’ก feat: test', response, 'owlpay')) + .toThrow('Jira ID is required when using Jira integration') + }) + }) + + describe('buildGitCommands', () => { + it('should build basic git command without description', () => { + const result = buildGitCommands('feat: add feature') + expect(result).toEqual(['commit', '-m', 'feat: add feature']) + }) + + it('should build git command with description', () => { + const result = buildGitCommands('feat: add feature', 'detailed description') + expect(result).toEqual(['commit', '-m', 'feat: add feature', '-m', 'detailed description']) + }) + + it('should handle empty description as falsy value', () => { + const result = buildGitCommands('feat: add feature', '') + // Empty string is falsy, so it should NOT include the second -m flag + expect(result).toEqual(['commit', '-m', 'feat: add feature']) + }) + }) + }) + + describe('Result Parsing Functions', () => { + describe('parseCommitResult', () => { + it('should parse git commit output correctly', () => { + const stdout = '[main abc123] feat: add new feature' + const result = parseCommitResult(stdout) + + expect(result).toEqual({ + branch: 'main', + hash: 'abc123' + }) + }) + + it('should handle different branch names', () => { + const stdout = '[feature/test-branch def456] fix: bug fix' + const result = parseCommitResult(stdout) + + expect(result).toEqual({ + branch: 'feature/test-branch', + hash: 'def456' + }) + }) + + it('should throw error for invalid output format', () => { + const stdout = 'invalid git output' + expect(() => parseCommitResult(stdout)).toThrow('Could not parse commit result') + }) + }) + }) + + describe('Prompt Step Building Functions', () => { + describe('buildPromptSteps', () => { + it('should build all steps when default project exists', () => { + const projectsList = buildProjectsList() + const typesList = buildCommitTypesList() + + const steps = buildPromptSteps('owlpay', projectsList, typesList) + + expect(steps).toHaveLength(7) // All steps including default project step + expect(steps[0]).toMatchObject({ + type: 'autocomplete', + name: 'commit_type' + }) + }) + + it('should skip default project step when no default project', () => { + const projectsList = buildProjectsList() + const typesList = buildCommitTypesList() + + const steps = buildPromptSteps('', projectsList, typesList) + + expect(steps).toHaveLength(6) // Missing default project step + }) + }) + }) + + describe('Display Functions', () => { + describe('showConfigMissingWarning', () => { + it('should display warning message', () => { + showConfigMissingWarning() + expect(mockConsoleLog).toHaveBeenCalledWith( + expect.stringContaining('You can try `cz -i` to choose a default project prefix') + ) + }) + }) + + describe('showCancelMessage', () => { + it('should display cancel message', () => { + showCancelMessage() + expect(mockConsoleLog).toHaveBeenCalledWith(' commit abort. ') + }) + }) + + describe('showCommitResult', () => { + it('should display basic commit result', () => { + const result: CommitResult = { + title: 'feat: new feature' + } + + showCommitResult(result) + + expect(mockConsoleLog).toHaveBeenCalledWith('-----------------------------------------------------------') + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('feat: new feature')) + }) + + it('should display commit result with description and hash', () => { + const result: CommitResult = { + title: 'feat: new feature', + description: 'detailed description', + hash: 'abc123', + branch: 'main' + } + + showCommitResult(result) + + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('feat: new feature')) + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('detailed description')) + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('abc123')) + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('main')) + }) + }) + + describe('showGitOutput', () => { + it('should display git stdout only', () => { + showGitOutput('git output') + + expect(mockConsoleLog).toHaveBeenCalledWith('-----------------------------------------------------------') + expect(mockConsoleLog).toHaveBeenCalledWith('git output') + }) + + it('should display git stdout and stderr', () => { + showGitOutput('git output', 'git error') + + expect(mockConsoleLog).toHaveBeenCalledWith('git output') + expect(mockConsoleLog).toHaveBeenCalledWith('git error') + }) + }) + + describe('showGitError', () => { + it('should display git error with no changes message', () => { + const error = { + stderr: 'git error', + exitCode: 1 + } + + showGitError(error) + + expect(mockConsoleLog).toHaveBeenCalledWith('git error') + expect(mockConsoleLog).toHaveBeenCalledWith(' No changes added to commit. ') + }) + + it('should display git error without special message', () => { + const error = { + stderr: 'some other error', + exitCode: 2 + } + + showGitError(error) + + expect(mockConsoleLog).toHaveBeenCalledWith('some other error') + expect(mockConsoleError).toHaveBeenCalledWith(error) + }) + }) + }) +}) diff --git a/vitest.config.ts b/vitest.config.ts index 73cc21f..1861f49 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -15,7 +15,8 @@ export default defineConfig({ 'coverage/**', '*.config.{js,ts}', 'bin/**', - 'scripts/**' + 'scripts/**', + 'src/types/**' ], all: true } @@ -25,4 +26,4 @@ export default defineConfig({ '@': './src' } } -}) \ No newline at end of file +}) From de9b17fab85f99978e7ac159a2dbbd44d9dff8bb Mon Sep 17 00:00:00 2001 From: NickLin Date: Tue, 10 Jun 2025 17:08:12 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=90=9B=20fix:=20gh=20action=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/coverage.yml | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 99fe295..daef242 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -14,19 +14,20 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 9 + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - - name: Install dependencies - run: pnpm install --frozen-lockfile + run: | + pnpm install --frozen-lockfile || pnpm install --no-frozen-lockfile - name: Run tests with coverage run: pnpm test:coverage @@ -34,13 +35,6 @@ jobs: - name: Generate coverage badge run: node scripts/generate-coverage-badge.js - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - file: ./coverage/lcov.info - flags: unittests - name: codecov-umbrella - - name: Coverage Badge uses: tj-actions/coverage-badge-js@v1 if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'