onbuzz 4.6.4 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +8 -0
- package/package.json +1 -1
- package/src/__tests__/autoUpdateConfig.test.js +44 -0
- package/src/__tests__/releaseWorkflow.test.js +72 -0
- package/src/interfaces/__tests__/accountRoutes.test.js +429 -0
- package/src/interfaces/__tests__/apiKeyManagerContract.test.js +39 -0
- package/src/interfaces/__tests__/authRoutes.test.js +8 -8
- package/src/interfaces/accountRoutes.js +250 -0
- package/src/interfaces/webServer.js +63 -10
- package/src/services/__tests__/apiKeyManager.test.js +4 -6
- package/src/services/__tests__/authCacheStore.test.js +118 -0
- package/src/services/apiKeyManager.js +12 -99
- package/src/services/authCacheStore.js +140 -0
- package/src/tools/__tests__/webTool.e2e.test.js +9 -1
- package/src/tools/webTool.js +20 -4
- package/src/utilities/__tests__/secretsCipher.test.js +97 -0
- package/src/utilities/__tests__/updateNotifier.test.js +139 -0
- package/src/utilities/secretsCipher.js +116 -0
- package/src/utilities/updateNotifier.js +140 -0
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-D_MLuenD.js +1 -0
- package/web-ui/build/static/abap-BNvFMksw.js +1 -0
- package/web-ui/build/static/abnf-WlnRJIp2.js +1 -0
- package/web-ui/build/static/abnf-mx1Wbtnp.js +1 -0
- package/web-ui/build/static/accesslog-CJumJuuV.js +1 -0
- package/web-ui/build/static/actionscript-B6CbK7n7.js +1 -0
- package/web-ui/build/static/actionscript-DZ5xfmPr.js +1 -0
- package/web-ui/build/static/ada-CCVAXM0c.js +1 -0
- package/web-ui/build/static/ada-DtGkgqC4.js +1 -0
- package/web-ui/build/static/agda-gMFRTChb.js +1 -0
- package/web-ui/build/static/al-88fYQh4r.js +1 -0
- package/web-ui/build/static/angelscript-Bibc8YWJ.js +1 -0
- package/web-ui/build/static/antlr4-DgibPJaJ.js +1 -0
- package/web-ui/build/static/apache-_pZ-s8l6.js +1 -0
- package/web-ui/build/static/apacheconf-YDldOH3Q.js +1 -0
- package/web-ui/build/static/apex-CIj23tyF.js +1 -0
- package/web-ui/build/static/apl-DtRSC0Xv.js +1 -0
- package/web-ui/build/static/applescript-CKhcPsla.js +1 -0
- package/web-ui/build/static/applescript-DuJeHJ1r.js +1 -0
- package/web-ui/build/static/aql-BgmI8Ors.js +1 -0
- package/web-ui/build/static/arcade-BX83978b.js +1 -0
- package/web-ui/build/static/arduino-BVdatcJb.js +1 -0
- package/web-ui/build/static/arduino-h6ifuWka.js +1 -0
- package/web-ui/build/static/arff-DHmbMeIA.js +1 -0
- package/web-ui/build/static/armasm-DiDgI5h5.js +1 -0
- package/web-ui/build/static/asciidoc-CBro7xXU.js +1 -0
- package/web-ui/build/static/asciidoc-DRC2X4bq.js +1 -0
- package/web-ui/build/static/asm6502-53VLu0lq.js +1 -0
- package/web-ui/build/static/asmatmel-DlRHdXes.js +1 -0
- package/web-ui/build/static/aspectj-DTSWMNl9.js +1 -0
- package/web-ui/build/static/aspnet-DEUO05ai.js +1 -0
- package/web-ui/build/static/autohotkey-3gt8xVo-.js +1 -0
- package/web-ui/build/static/autohotkey-BWcbMbe_.js +1 -0
- package/web-ui/build/static/autoit-CackGf4X.js +1 -0
- package/web-ui/build/static/autoit-Dyf0FSt2.js +1 -0
- package/web-ui/build/static/avisynth-DfCuxmn5.js +1 -0
- package/web-ui/build/static/avrasm-DdDiRWhx.js +1 -0
- package/web-ui/build/static/avro-idl-DppsvvwR.js +1 -0
- package/web-ui/build/static/awk-Cjk3U-Y4.js +1 -0
- package/web-ui/build/static/axapta-WwnY3TVf.js +1 -0
- package/web-ui/build/static/bash-C5Xkqken.js +1 -0
- package/web-ui/build/static/bash-ckPXa-RG.js +1 -0
- package/web-ui/build/static/basic-BCVHqHd2.js +1 -0
- package/web-ui/build/static/basic-D0dZbGrs.js +1 -0
- package/web-ui/build/static/batch-DUo60tbI.js +1 -0
- package/web-ui/build/static/bbcode-BVzBKrPV.js +1 -0
- package/web-ui/build/static/bicep-DkTjKL2N.js +1 -0
- package/web-ui/build/static/birb-C0rKI0h6.js +1 -0
- package/web-ui/build/static/bison-ChzwcDVc.js +1 -0
- package/web-ui/build/static/bnf-COhTgjpr.js +1 -0
- package/web-ui/build/static/bnf-DUYKVI2p.js +1 -0
- package/web-ui/build/static/brainfuck-BBJLbMxW.js +1 -0
- package/web-ui/build/static/brainfuck-DufOqE73.js +1 -0
- package/web-ui/build/static/brightscript-DXhkwfCc.js +1 -0
- package/web-ui/build/static/bro-BOFEsT-K.js +1 -0
- package/web-ui/build/static/bsl-ClV9GpNm.js +1 -0
- package/web-ui/build/static/c-Cl_3N1WB.js +1 -0
- package/web-ui/build/static/c-D0hFoAJ3.js +1 -0
- package/web-ui/build/static/c-like-D4BQ8VhL.js +1 -0
- package/web-ui/build/static/cal-CVIQ5DKG.js +1 -0
- package/web-ui/build/static/capnproto-l7oAqnCr.js +1 -0
- package/web-ui/build/static/ceylon-BEhCsFMw.js +1 -0
- package/web-ui/build/static/cfscript-DMh-xvVk.js +1 -0
- package/web-ui/build/static/chaiscript-DCvDoIGS.js +1 -0
- package/web-ui/build/static/cil-Ccn-j3TB.js +1 -0
- package/web-ui/build/static/clean-CjrEwcC-.js +1 -0
- package/web-ui/build/static/clojure-Dgo-8qFd.js +1 -0
- package/web-ui/build/static/clojure-M1AknfQi.js +1 -0
- package/web-ui/build/static/clojure-repl-BY1VLOSH.js +1 -0
- package/web-ui/build/static/cmake-CdHJ7Mp0.js +1 -0
- package/web-ui/build/static/cmake-DDGvi7kU.js +1 -0
- package/web-ui/build/static/cobol-BdrXYRxi.js +1 -0
- package/web-ui/build/static/coffeescript-BMDvMAy2.js +1 -0
- package/web-ui/build/static/coffeescript-CAYcMTRg.js +1 -0
- package/web-ui/build/static/concurnas-B8vcX0ec.js +1 -0
- package/web-ui/build/static/coq-CqvluN1S.js +1 -0
- package/web-ui/build/static/coq-vhnnRdWb.js +1 -0
- package/web-ui/build/static/cos-DY4p0y_u.js +1 -0
- package/web-ui/build/static/cpp-C3m_aEUX.js +1 -0
- package/web-ui/build/static/cpp-DRs9bbEm.js +1 -0
- package/web-ui/build/static/crmsh-CY6InunC.js +1 -0
- package/web-ui/build/static/crystal-Cwk1figA.js +1 -0
- package/web-ui/build/static/crystal-DeCJ5Pz7.js +1 -0
- package/web-ui/build/static/csharp-WmvubeKF.js +1 -0
- package/web-ui/build/static/csharp-zL1j7hXr.js +1 -0
- package/web-ui/build/static/cshtml-CbvGCaf_.js +1 -0
- package/web-ui/build/static/csp-BH2nxxKs.js +1 -0
- package/web-ui/build/static/csp-CHlC7KoB.js +1 -0
- package/web-ui/build/static/css-_X0ZO87y.js +1 -0
- package/web-ui/build/static/css-extras-wgFh56PY.js +1 -0
- package/web-ui/build/static/csv-momqe7r6.js +1 -0
- package/web-ui/build/static/cypher-hOeHFCfk.js +1 -0
- package/web-ui/build/static/d-B3d-tfyQ.js +1 -0
- package/web-ui/build/static/d-C6iyl9wX.js +1 -0
- package/web-ui/build/static/dart-BDKSE6LE.js +1 -0
- package/web-ui/build/static/dart-Bjchg8qI.js +1 -0
- package/web-ui/build/static/dataweave-ZgvdD-pH.js +1 -0
- package/web-ui/build/static/dax-yfGYNpUh.js +1 -0
- package/web-ui/build/static/delphi-CRLCdiTE.js +1 -0
- package/web-ui/build/static/dhall-yl1p1XUr.js +1 -0
- package/web-ui/build/static/diff-5SMtcFK7.js +1 -0
- package/web-ui/build/static/diff-y2RTBWsQ.js +1 -0
- package/web-ui/build/static/django-CtjG6w9L.js +1 -0
- package/web-ui/build/static/django-DNXOxI3v.js +1 -0
- package/web-ui/build/static/dns-D7Czwn_S.js +1 -0
- package/web-ui/build/static/dns-zone-file-D3yPxpjz.js +1 -0
- package/web-ui/build/static/docker-CWC5NqQQ.js +1 -0
- package/web-ui/build/static/dockerfile-CKFBVY9d.js +1 -0
- package/web-ui/build/static/dos-B7gYphQ-.js +1 -0
- package/web-ui/build/static/dot-BsisNMX4.js +1 -0
- package/web-ui/build/static/dsconfig-CEWwz7T6.js +1 -0
- package/web-ui/build/static/dts-UM5u5dMt.js +1 -0
- package/web-ui/build/static/dust-DlPmuh4d.js +1 -0
- package/web-ui/build/static/ebnf-BE6vq-fo.js +1 -0
- package/web-ui/build/static/ebnf-Czd8moGp.js +1 -0
- package/web-ui/build/static/editorconfig-Ctn83uRn.js +1 -0
- package/web-ui/build/static/eiffel-CZP01HVF.js +1 -0
- package/web-ui/build/static/ejs-BAXhrtLI.js +1 -0
- package/web-ui/build/static/elixir-C9PFjTwP.js +1 -0
- package/web-ui/build/static/elixir-DMjZPYCh.js +1 -0
- package/web-ui/build/static/elm-BH_KfOxJ.js +1 -0
- package/web-ui/build/static/elm-DRnNerE2.js +1 -0
- package/web-ui/build/static/erb-BhzUuTTy.js +1 -0
- package/web-ui/build/static/erb-DNbmX3N2.js +1 -0
- package/web-ui/build/static/erlang-BBPIw_V_.js +1 -0
- package/web-ui/build/static/erlang-BWdcSiKs.js +1 -0
- package/web-ui/build/static/erlang-repl-DQ9I6Dh_.js +1 -0
- package/web-ui/build/static/etlua-BeVNUecy.js +1 -0
- package/web-ui/build/static/excel-DYFvX5ms.js +1 -0
- package/web-ui/build/static/excel-formula-BtiqixBz.js +1 -0
- package/web-ui/build/static/factor-BCHyN6XZ.js +1 -0
- package/web-ui/build/static/false-UDWS0Dzk.js +1 -0
- package/web-ui/build/static/firestore-security-rules-B1-wJ42j.js +1 -0
- package/web-ui/build/static/fix-DrXU-V21.js +1 -0
- package/web-ui/build/static/flix-BjF0RPW9.js +1 -0
- package/web-ui/build/static/flow-DovuDACs.js +1 -0
- package/web-ui/build/static/fortran-DOqQP_9c.js +1 -0
- package/web-ui/build/static/fortran-DPASe5gH.js +1 -0
- package/web-ui/build/static/fsharp-Ckup0uPw.js +1 -0
- package/web-ui/build/static/fsharp-DyfRmGjn.js +1 -0
- package/web-ui/build/static/ftl-Coj24bDj.js +1 -0
- package/web-ui/build/static/gams-GwREZQh1.js +1 -0
- package/web-ui/build/static/gap-B7d6Bkmk.js +1 -0
- package/web-ui/build/static/gauss-DrLvPj5Z.js +1 -0
- package/web-ui/build/static/gcode-40iTJ2U1.js +1 -0
- package/web-ui/build/static/gcode-CISHXDj4.js +1 -0
- package/web-ui/build/static/gdscript-DmopCB0R.js +1 -0
- package/web-ui/build/static/gedcom-LiECv7gg.js +1 -0
- package/web-ui/build/static/gherkin-CYp_kcve.js +1 -0
- package/web-ui/build/static/gherkin-C_QgMjxf.js +1 -0
- package/web-ui/build/static/git-CfTT-600.js +1 -0
- package/web-ui/build/static/glsl-DRFMhvlG.js +1 -0
- package/web-ui/build/static/glsl-PNmpuSn0.js +1 -0
- package/web-ui/build/static/gml-3qmqfrt3.js +1 -0
- package/web-ui/build/static/gml-BTCmr4y5.js +1 -0
- package/web-ui/build/static/gn-BX0L2dQ-.js +1 -0
- package/web-ui/build/static/go-BXYOf5mS.js +1 -0
- package/web-ui/build/static/go-BnvPVHID.js +1 -0
- package/web-ui/build/static/go-module-BsPBvEmG.js +1 -0
- package/web-ui/build/static/golo-B6l7i4bX.js +1 -0
- package/web-ui/build/static/gradle-9DvvuDBJ.js +1 -0
- package/web-ui/build/static/graphql-OcCfd-Bc.js +1 -0
- package/web-ui/build/static/groovy-B33LZAt0.js +1 -0
- package/web-ui/build/static/groovy-Uyg0ruyE.js +1 -0
- package/web-ui/build/static/haml-D_FDAM6q.js +1 -0
- package/web-ui/build/static/haml-DjG31i1A.js +1 -0
- package/web-ui/build/static/handlebars-BKPDMksf.js +1 -0
- package/web-ui/build/static/handlebars-PP4M-qJ8.js +1 -0
- package/web-ui/build/static/haskell-HD9Gv3Wo.js +1 -0
- package/web-ui/build/static/haskell-nUf9ckz5.js +1 -0
- package/web-ui/build/static/haxe-BSsJNrQU.js +1 -0
- package/web-ui/build/static/haxe-D7yTwhdv.js +1 -0
- package/web-ui/build/static/hcl-_dqjptFs.js +1 -0
- package/web-ui/build/static/hlsl-DKixrsyy.js +1 -0
- package/web-ui/build/static/hoon-Di28eQfV.js +1 -0
- package/web-ui/build/static/hpkp-CXYG9zoQ.js +1 -0
- package/web-ui/build/static/hsp-lYl9KN6o.js +1 -0
- package/web-ui/build/static/hsts-CaYq9R8-.js +1 -0
- package/web-ui/build/static/htmlbars-eoY2PWS6.js +1 -0
- package/web-ui/build/static/http-2DXUmN2h.js +1 -0
- package/web-ui/build/static/http-Yjic3oWm.js +1 -0
- package/web-ui/build/static/hy-DVImg5uG.js +1 -0
- package/web-ui/build/static/ichigojam-Bdk-szlv.js +1 -0
- package/web-ui/build/static/icon-BEs9UbI_.js +1 -0
- package/web-ui/build/static/icu-message-format-DMfiLVs5.js +1 -0
- package/web-ui/build/static/idris-meksg0Ce.js +1 -0
- package/web-ui/build/static/iecst-DMPBiTmw.js +1 -0
- package/web-ui/build/static/ignore-BOQ9ZPvw.js +1 -0
- package/web-ui/build/static/index-BSEOP86D.js +1 -0
- package/web-ui/build/static/index-Be9WvMkI.js +1162 -0
- package/web-ui/build/static/index-Cr9q1fNq.css +1 -0
- package/web-ui/build/static/index-CuZ_erP9.js +13 -0
- package/web-ui/build/static/inform7-CNqu8FhU.js +1 -0
- package/web-ui/build/static/inform7-Cvfrdb0X.js +1 -0
- package/web-ui/build/static/ini-4DHUSW37.js +1 -0
- package/web-ui/build/static/ini-BgZ18Nk6.js +1 -0
- package/web-ui/build/static/io-c519ulw2.js +1 -0
- package/web-ui/build/static/irpf90-Kzq81vn5.js +1 -0
- package/web-ui/build/static/isbl-CeBN_o-W.js +1 -0
- package/web-ui/build/static/j-BmSuFx5E.js +1 -0
- package/web-ui/build/static/java-BezG0JQd.js +1 -0
- package/web-ui/build/static/java-BxBhTA1D.js +1 -0
- package/web-ui/build/static/javadoc-b96LRy9-.js +1 -0
- package/web-ui/build/static/javadoclike-BTNVp6pR.js +1 -0
- package/web-ui/build/static/javascript-B75gzQUI.js +1 -0
- package/web-ui/build/static/javastacktrace-D4xVOdoe.js +1 -0
- package/web-ui/build/static/jboss-cli-DH30pghK.js +1 -0
- package/web-ui/build/static/jexl-DF2RGmtX.js +1 -0
- package/web-ui/build/static/jolie-BlwO_Eyn.js +1 -0
- package/web-ui/build/static/jq-C7YhIw1G.js +1 -0
- package/web-ui/build/static/js-extras-JVZxoi4Q.js +1 -0
- package/web-ui/build/static/js-templates-D1CnsXgJ.js +1 -0
- package/web-ui/build/static/jsdoc-vf63NOxo.js +1 -0
- package/web-ui/build/static/json-CiKwLA5O.js +1 -0
- package/web-ui/build/static/json-pgLQeaes.js +1 -0
- package/web-ui/build/static/json5-_HMAYh1c.js +1 -0
- package/web-ui/build/static/jsonp-BeHQpb2r.js +1 -0
- package/web-ui/build/static/jsstacktrace-nw21JEtY.js +1 -0
- package/web-ui/build/static/jsx-Nxt_XhcW.js +1 -0
- package/web-ui/build/static/julia-BFczE4HB.js +1 -0
- package/web-ui/build/static/julia-DeDNID0K.js +1 -0
- package/web-ui/build/static/julia-repl-CoPTZMue.js +1 -0
- package/web-ui/build/static/keepalived-DP1sFl1b.js +1 -0
- package/web-ui/build/static/keyman-CCQVTHgo.js +1 -0
- package/web-ui/build/static/kotlin-CdZP58gi.js +1 -0
- package/web-ui/build/static/kotlin-CzNKVbXq.js +1 -0
- package/web-ui/build/static/kumir-lPok55sq.js +1 -0
- package/web-ui/build/static/kusto-oLek_zqj.js +1 -0
- package/web-ui/build/static/lasso-BFOYENIx.js +1 -0
- package/web-ui/build/static/latex-BH6YJXW6.js +1 -0
- package/web-ui/build/static/latex-IweVcDOS.js +1 -0
- package/web-ui/build/static/latte-Cmzytj93.js +1 -0
- package/web-ui/build/static/ldif-Bp4o5m10.js +1 -0
- package/web-ui/build/static/leaf-BFbMre84.js +1 -0
- package/web-ui/build/static/less-BVpV_iBx.js +1 -0
- package/web-ui/build/static/less-vdx-pGtM.js +1 -0
- package/web-ui/build/static/lilypond-Da6mCtwg.js +1 -0
- package/web-ui/build/static/liquid-RVC3EWUf.js +1 -0
- package/web-ui/build/static/lisp-Bgt-EmTk.js +1 -0
- package/web-ui/build/static/lisp-E8gUigGo.js +1 -0
- package/web-ui/build/static/livecodeserver-DDFQieJg.js +1 -0
- package/web-ui/build/static/livescript-C7FEDmfm.js +1 -0
- package/web-ui/build/static/livescript-Cc5SDmvx.js +1 -0
- package/web-ui/build/static/llvm-C22gmUEJ.js +1 -0
- package/web-ui/build/static/llvm-CjnVIiX4.js +1 -0
- package/web-ui/build/static/log-duIQICZV.js +1 -0
- package/web-ui/build/static/lolcode-Chrz9tTZ.js +1 -0
- package/web-ui/build/static/lsl-D1sdqECW.js +1 -0
- package/web-ui/build/static/lua-BFoJUb0S.js +1 -0
- package/web-ui/build/static/lua-D8RyRvqw.js +1 -0
- package/web-ui/build/static/magma-Cb3OhPkH.js +1 -0
- package/web-ui/build/static/makefile-BoVTcm8r.js +1 -0
- package/web-ui/build/static/makefile-LpYbnzZi.js +1 -0
- package/web-ui/build/static/markdown-CtQc_FZV.js +1 -0
- package/web-ui/build/static/markdown-DKz9qNdH.js +1 -0
- package/web-ui/build/static/markup-templating-D4EP19Lc.js +1 -0
- package/web-ui/build/static/mathematica-CIjlHVkd.js +1 -0
- package/web-ui/build/static/matlab-2b895p29.js +1 -0
- package/web-ui/build/static/matlab-BuluE4GS.js +1 -0
- package/web-ui/build/static/maxima-BGR8Puew.js +1 -0
- package/web-ui/build/static/maxscript-B429y77A.js +1 -0
- package/web-ui/build/static/mel-CYh_3LnF.js +1 -0
- package/web-ui/build/static/mel-CbYDscql.js +1 -0
- package/web-ui/build/static/mercury-DOee0RcU.js +1 -0
- package/web-ui/build/static/mermaid-Bgnlfred.js +1 -0
- package/web-ui/build/static/mipsasm-CB-uene8.js +1 -0
- package/web-ui/build/static/mizar-7qF42uX5.js +1 -0
- package/web-ui/build/static/mizar-Clogrskx.js +1 -0
- package/web-ui/build/static/mojolicious-BSIpTTKj.js +1 -0
- package/web-ui/build/static/mongodb--rWzrKDS.js +1 -0
- package/web-ui/build/static/monkey-C0lS2_fv.js +1 -0
- package/web-ui/build/static/monkey-DvqsFbfK.js +1 -0
- package/web-ui/build/static/moonscript-D6zFHk1D.js +1 -0
- package/web-ui/build/static/moonscript-JTxm8n_4.js +1 -0
- package/web-ui/build/static/n1ql-BwY55fjF.js +1 -0
- package/web-ui/build/static/n1ql-D8h3fDkJ.js +1 -0
- package/web-ui/build/static/n4js-5XIl8zQT.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-C4b_TExX.js +1 -0
- package/web-ui/build/static/naniscript-h2vnytgY.js +1 -0
- package/web-ui/build/static/nasm-SJmR3Ebn.js +1 -0
- package/web-ui/build/static/neon-B7dnnKEh.js +1 -0
- package/web-ui/build/static/nevod-zunhA02o.js +1 -0
- package/web-ui/build/static/nginx-BR_D0je7.js +1 -0
- package/web-ui/build/static/nginx-Cf7oQt-G.js +1 -0
- package/web-ui/build/static/nim-D-MjIxvw.js +1 -0
- package/web-ui/build/static/nim-D6YOyDC-.js +1 -0
- package/web-ui/build/static/nix-DCZEZqSO.js +1 -0
- package/web-ui/build/static/nix-Dx16U5rS.js +1 -0
- package/web-ui/build/static/node-repl-P-vGpiQ7.js +1 -0
- package/web-ui/build/static/nsis-CjyZMgjR.js +1 -0
- package/web-ui/build/static/nsis-X8NQeZjE.js +1 -0
- package/web-ui/build/static/objectivec-BejNoH7m.js +1 -0
- package/web-ui/build/static/objectivec-CGy2F8n6.js +1 -0
- package/web-ui/build/static/ocaml-C15hcRxR.js +1 -0
- package/web-ui/build/static/ocaml-U7N8L5Z7.js +1 -0
- package/web-ui/build/static/opencl-Bkm-SovU.js +1 -0
- package/web-ui/build/static/openqasm-BOc5975b.js +1 -0
- package/web-ui/build/static/openscad-CRpFnhV_.js +1 -0
- package/web-ui/build/static/oxygene-eHBZbxHy.js +1 -0
- package/web-ui/build/static/oz-B6RWw36L.js +1 -0
- package/web-ui/build/static/parigp-rifRy-ff.js +1 -0
- package/web-ui/build/static/parser-C0HBjZDk.js +1 -0
- package/web-ui/build/static/parser3-DSK81uS5.js +1 -0
- package/web-ui/build/static/pascal-BWha02r-.js +1 -0
- package/web-ui/build/static/pascaligo-B5sQ2hGz.js +1 -0
- package/web-ui/build/static/pcaxis-B1HLYPhm.js +1 -0
- package/web-ui/build/static/peoplecode-C4FPD4Yt.js +1 -0
- package/web-ui/build/static/perl-CyNx_mIa.js +1 -0
- package/web-ui/build/static/perl-rKxEWgtc.js +1 -0
- package/web-ui/build/static/pf-DbL4T2HZ.js +1 -0
- package/web-ui/build/static/pgsql-BKrwbRTY.js +1 -0
- package/web-ui/build/static/php-Cbd5TyJ-.js +1 -0
- package/web-ui/build/static/php-extras-DoVpsRj3.js +1 -0
- package/web-ui/build/static/php-template-DvdLavxo.js +1 -0
- package/web-ui/build/static/php-wYQJLv7J.js +1 -0
- package/web-ui/build/static/phpdoc-DTzZ5d0C.js +1 -0
- package/web-ui/build/static/plaintext-BRfzJjyj.js +1 -0
- package/web-ui/build/static/plsql-BLiE3aGC.js +1 -0
- package/web-ui/build/static/pony-CzLDxYVb.js +1 -0
- package/web-ui/build/static/powerquery-BdGgwM1a.js +1 -0
- package/web-ui/build/static/powershell-Cxl47yK_.js +1 -0
- package/web-ui/build/static/powershell-DrOFoqBE.js +1 -0
- package/web-ui/build/static/processing-9GbETrF_.js +1 -0
- package/web-ui/build/static/processing-M8gRGxck.js +1 -0
- package/web-ui/build/static/profile-CpNlvCnw.js +1 -0
- package/web-ui/build/static/prolog-CKZzbIr9.js +1 -0
- package/web-ui/build/static/prolog-mmIPeMRS.js +1 -0
- package/web-ui/build/static/promql-sDn1PHGN.js +1 -0
- package/web-ui/build/static/properties-CMFMCgWo.js +1 -0
- package/web-ui/build/static/properties-DQUf7KOp.js +1 -0
- package/web-ui/build/static/protobuf-CeY2Q-pH.js +1 -0
- package/web-ui/build/static/protobuf-WpfASK2n.js +1 -0
- package/web-ui/build/static/psl-D2GfEOkk.js +1 -0
- package/web-ui/build/static/pug-OMqhtHt8.js +1 -0
- package/web-ui/build/static/puppet-B68-xib8.js +1 -0
- package/web-ui/build/static/puppet-DEWzLqRg.js +1 -0
- package/web-ui/build/static/pure-C_CchY8g.js +1 -0
- package/web-ui/build/static/purebasic-D6vSqsja.js +1 -0
- package/web-ui/build/static/purebasic-Dy_z6LTs.js +1 -0
- package/web-ui/build/static/purescript-1f1OoM-A.js +1 -0
- package/web-ui/build/static/python-BssLWmNd.js +1 -0
- package/web-ui/build/static/python-CbOivp-X.js +1 -0
- package/web-ui/build/static/python-repl-Dsbi7aBP.js +1 -0
- package/web-ui/build/static/q-BC6w8B4U.js +1 -0
- package/web-ui/build/static/q-Brd1mf_C.js +1 -0
- package/web-ui/build/static/qml-BG4KN74g.js +1 -0
- package/web-ui/build/static/qml-BW-AE2Ma.js +1 -0
- package/web-ui/build/static/qore-m870d7ZA.js +1 -0
- package/web-ui/build/static/qsharp-BC9vEXOd.js +1 -0
- package/web-ui/build/static/r-BQySF8sO.js +1 -0
- package/web-ui/build/static/r-Cur0B9lo.js +1 -0
- package/web-ui/build/static/racket-CiJlajVU.js +1 -0
- package/web-ui/build/static/reason-C3VZcXa9.js +1 -0
- package/web-ui/build/static/reasonml-CpaxZwMO.js +1 -0
- package/web-ui/build/static/regex-bY-o17az.js +1 -0
- package/web-ui/build/static/rego-WPkEW7us.js +1 -0
- package/web-ui/build/static/renpy-DQr5LC4O.js +1 -0
- package/web-ui/build/static/rest-qmfCQ86m.js +1 -0
- package/web-ui/build/static/rib-DYzEblkc.js +1 -0
- package/web-ui/build/static/rip-D-NWUqHZ.js +1 -0
- package/web-ui/build/static/roboconf-CVmdy543.js +1 -0
- package/web-ui/build/static/roboconf-Ray0NGMb.js +1 -0
- package/web-ui/build/static/robotframework-DlxPBTF_.js +1 -0
- package/web-ui/build/static/routeros-S_f-nuVM.js +1 -0
- package/web-ui/build/static/rsl-CHtR71Pc.js +1 -0
- package/web-ui/build/static/ruby-ByuU-3cy.js +1 -0
- package/web-ui/build/static/ruby-DOin939S.js +1 -0
- package/web-ui/build/static/ruleslanguage-zhFrFxeU.js +1 -0
- package/web-ui/build/static/rust-B606UvZv.js +1 -0
- package/web-ui/build/static/rust-BJMuS7if.js +1 -0
- package/web-ui/build/static/sas-Bzk_0rOu.js +1 -0
- package/web-ui/build/static/sas-C-C55Hy4.js +1 -0
- package/web-ui/build/static/sass-DKkkoHtH.js +1 -0
- package/web-ui/build/static/scala-BKlnHttP.js +1 -0
- package/web-ui/build/static/scala-IsJjjIKA.js +1 -0
- package/web-ui/build/static/scheme-Bq_tfrRE.js +1 -0
- package/web-ui/build/static/scheme-DiXFvLKG.js +1 -0
- package/web-ui/build/static/scilab-DVyT87si.js +1 -0
- package/web-ui/build/static/scss-BtDpAVzH.js +1 -0
- package/web-ui/build/static/scss-D8cn4aNM.js +1 -0
- package/web-ui/build/static/shell-YROU1_yo.js +1 -0
- package/web-ui/build/static/shell-session-D06UXOLk.js +1 -0
- package/web-ui/build/static/smali-B1Wl_1dD.js +1 -0
- package/web-ui/build/static/smali-D2R-11j_.js +1 -0
- package/web-ui/build/static/smalltalk-M2S1lL6Z.js +1 -0
- package/web-ui/build/static/smalltalk-OWg84676.js +1 -0
- package/web-ui/build/static/smarty-l1m-zZmR.js +1 -0
- package/web-ui/build/static/sml-B6gSTHMm.js +1 -0
- package/web-ui/build/static/sml-BKURhRNM.js +1 -0
- package/web-ui/build/static/solidity-BcrqESJt.js +1 -0
- package/web-ui/build/static/solution-file-BYpCOi9k.js +1 -0
- package/web-ui/build/static/soy-DOQhQ7Di.js +1 -0
- package/web-ui/build/static/sparql-BwiIX_wO.js +1 -0
- package/web-ui/build/static/splunk-spl-DuIl6XxN.js +1 -0
- package/web-ui/build/static/sqf-8cYPidUR.js +1 -0
- package/web-ui/build/static/sqf-n8nRTmXc.js +1 -0
- package/web-ui/build/static/sql-D0WSLeXV.js +1 -0
- package/web-ui/build/static/sql-D8KWxFl_.js +1 -0
- package/web-ui/build/static/sql_more-D3ozDsf6.js +1 -0
- package/web-ui/build/static/squirrel-C4U4fAL5.js +1 -0
- package/web-ui/build/static/stan-BbFEvT-l.js +1 -0
- package/web-ui/build/static/stan-CJ4ny6dZ.js +1 -0
- package/web-ui/build/static/stata-BKEkbqzD.js +1 -0
- package/web-ui/build/static/step21-52PURHjy.js +1 -0
- package/web-ui/build/static/stylus-buszfxDg.js +1 -0
- package/web-ui/build/static/stylus-y0WOYXDO.js +1 -0
- package/web-ui/build/static/subunit-DU_iInw0.js +1 -0
- package/web-ui/build/static/swift-1VeEUHZi.js +1 -0
- package/web-ui/build/static/swift-Iw0x_Dum.js +1 -0
- package/web-ui/build/static/systemd-BT_5EOz8.js +1 -0
- package/web-ui/build/static/t4-cs-DlHeFrua.js +1 -0
- package/web-ui/build/static/t4-templating-Bz3RFfzp.js +1 -0
- package/web-ui/build/static/t4-vb-BMG0Q3qg.js +1 -0
- package/web-ui/build/static/taggerscript-CxwafGpT.js +1 -0
- package/web-ui/build/static/tap-6QugbkZA.js +1 -0
- package/web-ui/build/static/tap-SB1ST166.js +1 -0
- package/web-ui/build/static/tcl-CpV5bsKx.js +1 -0
- package/web-ui/build/static/tcl-Dikgd33H.js +1 -0
- package/web-ui/build/static/textile-aPmNtrkM.js +1 -0
- package/web-ui/build/static/thrift-B4Snltg5.js +1 -0
- package/web-ui/build/static/toml-B8SfswHQ.js +1 -0
- package/web-ui/build/static/tp-CdO-cn9g.js +1 -0
- package/web-ui/build/static/tremor-CqqCLe4A.js +1 -0
- package/web-ui/build/static/tsx-Ck0ZDqEy.js +1 -0
- package/web-ui/build/static/tt2-BrqZXSkJ.js +1 -0
- package/web-ui/build/static/turtle-DpnSIzmN.js +1 -0
- package/web-ui/build/static/twig-B5Et_eTY.js +1 -0
- package/web-ui/build/static/twig-C3vsy99c.js +1 -0
- package/web-ui/build/static/typescript-DH7tzpeO.js +1 -0
- package/web-ui/build/static/typescript-s1qBbHGm.js +1 -0
- package/web-ui/build/static/typoscript-DD8499cq.js +1 -0
- package/web-ui/build/static/unrealscript-C1zerCVR.js +1 -0
- package/web-ui/build/static/uorazor-CtRNfzg2.js +1 -0
- package/web-ui/build/static/uri-CAfIv8vn.js +1 -0
- package/web-ui/build/static/v-B6_f9ZGJ.js +1 -0
- package/web-ui/build/static/vala-BIpejmrf.js +1 -0
- package/web-ui/build/static/vala-BYLjm9ih.js +1 -0
- package/web-ui/build/static/vbnet-DEW7adbx.js +1 -0
- package/web-ui/build/static/vbnet-D_CuPCaz.js +1 -0
- package/web-ui/build/static/vbscript-Do9hsQ_u.js +1 -0
- package/web-ui/build/static/vbscript-html-4bMQ0-FJ.js +1 -0
- package/web-ui/build/static/velocity-CQjo2-fz.js +1 -0
- package/web-ui/build/static/verilog-C-Xvd__o.js +1 -0
- package/web-ui/build/static/verilog-Dn1ZGsRG.js +1 -0
- package/web-ui/build/static/vhdl-DZ-dTOLA.js +1 -0
- package/web-ui/build/static/vhdl-bDNJfpa7.js +1 -0
- package/web-ui/build/static/vim-BDAo5YHC.js +1 -0
- package/web-ui/build/static/vim-ClkOafc3.js +1 -0
- package/web-ui/build/static/visual-basic-DXIeLZZ8.js +1 -0
- package/web-ui/build/static/warpscript-f7veA-3J.js +1 -0
- package/web-ui/build/static/wasm-TToDlmNk.js +1 -0
- package/web-ui/build/static/web-idl-CrrjMFQT.js +1 -0
- package/web-ui/build/static/wiki-aicisDW2.js +1 -0
- package/web-ui/build/static/wolfram-C_A80rAh.js +1 -0
- package/web-ui/build/static/wren-DkVyeDoy.js +1 -0
- package/web-ui/build/static/x86asm-fx1o_ltw.js +1 -0
- package/web-ui/build/static/xeora-D-uaDMXn.js +1 -0
- package/web-ui/build/static/xl-Dnyvb9_S.js +1 -0
- package/web-ui/build/static/xml-BGV0zG9K.js +1 -0
- package/web-ui/build/static/xml-doc-DOGLcenw.js +1 -0
- package/web-ui/build/static/xojo-B3Qgvb5A.js +1 -0
- package/web-ui/build/static/xquery-C-B5-0Q9.js +1 -0
- package/web-ui/build/static/xquery-KbuiAVhj.js +1 -0
- package/web-ui/build/static/yaml-CBWBoq6m.js +1 -0
- package/web-ui/build/static/yaml-IghlDZf6.js +1 -0
- package/web-ui/build/static/yang-CArp62P5.js +1 -0
- package/web-ui/build/static/zephir-DMLTJ9_9.js +1 -0
- package/web-ui/build/static/zig-CWG2311v.js +1 -0
- package/web-ui/build/static/1c-4BRB87En.js +0 -1
- package/web-ui/build/static/abap-BXIqiAfL.js +0 -1
- package/web-ui/build/static/abnf-0gk1i0eD.js +0 -1
- package/web-ui/build/static/abnf-jcv7vN9a.js +0 -1
- package/web-ui/build/static/accesslog-bXE2aOZl.js +0 -1
- package/web-ui/build/static/actionscript-CF-bqawj.js +0 -1
- package/web-ui/build/static/actionscript-CodwLKar.js +0 -1
- package/web-ui/build/static/ada-BBEDI84F.js +0 -1
- package/web-ui/build/static/ada-Kb6JvaxP.js +0 -1
- package/web-ui/build/static/agda-UvnMXUUo.js +0 -1
- package/web-ui/build/static/al-D5QZ0ijQ.js +0 -1
- package/web-ui/build/static/angelscript-RpvZxbeT.js +0 -1
- package/web-ui/build/static/antlr4-BPyUvfii.js +0 -1
- package/web-ui/build/static/apache-CtM2pGik.js +0 -1
- package/web-ui/build/static/apacheconf-D-i9eISH.js +0 -1
- package/web-ui/build/static/apex-Dhn_SJi4.js +0 -1
- package/web-ui/build/static/apl-HWtdSaYy.js +0 -1
- package/web-ui/build/static/applescript-Br9NrmTP.js +0 -1
- package/web-ui/build/static/applescript-DLL0TuGw.js +0 -1
- package/web-ui/build/static/aql-MjCgNRUX.js +0 -1
- package/web-ui/build/static/arcade--DFvEPVv.js +0 -1
- package/web-ui/build/static/arduino-Cqw5W_fL.js +0 -1
- package/web-ui/build/static/arduino-DIDBbB7R.js +0 -1
- package/web-ui/build/static/arff-GGvbnOhc.js +0 -1
- package/web-ui/build/static/armasm-DKLRDLs1.js +0 -1
- package/web-ui/build/static/asciidoc-CN5qfm0K.js +0 -1
- package/web-ui/build/static/asciidoc-CeQEWYOj.js +0 -1
- package/web-ui/build/static/asm6502-B1l2Hc9j.js +0 -1
- package/web-ui/build/static/asmatmel-BAojNNWJ.js +0 -1
- package/web-ui/build/static/aspectj-DqZFhwdh.js +0 -1
- package/web-ui/build/static/aspnet-C0kQPqSr.js +0 -1
- package/web-ui/build/static/autohotkey-DY25td-Z.js +0 -1
- package/web-ui/build/static/autohotkey-DlqXINgk.js +0 -1
- package/web-ui/build/static/autoit-By7J2Y34.js +0 -1
- package/web-ui/build/static/autoit-nsu9sBga.js +0 -1
- package/web-ui/build/static/avisynth-DmhvVsr-.js +0 -1
- package/web-ui/build/static/avrasm-CHfBwwoQ.js +0 -1
- package/web-ui/build/static/avro-idl-BKgIWEIF.js +0 -1
- package/web-ui/build/static/awk-CpAb4d4E.js +0 -1
- package/web-ui/build/static/axapta-CM4aTfCZ.js +0 -1
- package/web-ui/build/static/bash-D1KTDlk-.js +0 -1
- package/web-ui/build/static/bash-DShkskxb.js +0 -1
- package/web-ui/build/static/basic-C4CfKvhg.js +0 -1
- package/web-ui/build/static/basic-CkQS4VwL.js +0 -1
- package/web-ui/build/static/batch-DZtrClI1.js +0 -1
- package/web-ui/build/static/bbcode-CY2FsfaO.js +0 -1
- package/web-ui/build/static/bicep-BeSEpm_3.js +0 -1
- package/web-ui/build/static/birb-huu22Mwu.js +0 -1
- package/web-ui/build/static/bison-CmbxfR57.js +0 -1
- package/web-ui/build/static/bnf-c2l_4HXN.js +0 -1
- package/web-ui/build/static/bnf-wucEDTqY.js +0 -1
- package/web-ui/build/static/brainfuck-CzWBg5U7.js +0 -1
- package/web-ui/build/static/brainfuck-I_YQ4sma.js +0 -1
- package/web-ui/build/static/brightscript-LOkD4eYW.js +0 -1
- package/web-ui/build/static/bro-CLJ7Afqo.js +0 -1
- package/web-ui/build/static/bsl-DbUgC2FQ.js +0 -1
- package/web-ui/build/static/c-C0S2D2ge.js +0 -1
- package/web-ui/build/static/c-KH25O_pL.js +0 -1
- package/web-ui/build/static/c-like-DtAFxyl_.js +0 -1
- package/web-ui/build/static/cal-uGiVJBNC.js +0 -1
- package/web-ui/build/static/capnproto-DSLchjOW.js +0 -1
- package/web-ui/build/static/ceylon-Bbxk66YL.js +0 -1
- package/web-ui/build/static/cfscript-CjDdgKbl.js +0 -1
- package/web-ui/build/static/chaiscript-CnRXaMae.js +0 -1
- package/web-ui/build/static/cil-CM9ygF3R.js +0 -1
- package/web-ui/build/static/clean-ppAH0SYy.js +0 -1
- package/web-ui/build/static/clojure-C5LVccGq.js +0 -1
- package/web-ui/build/static/clojure-DtLXiuuC.js +0 -1
- package/web-ui/build/static/clojure-repl-fSdrYuup.js +0 -1
- package/web-ui/build/static/cmake-AD1fuzSY.js +0 -1
- package/web-ui/build/static/cmake-D-o08Yta.js +0 -1
- package/web-ui/build/static/cobol-bDh1KHf9.js +0 -1
- package/web-ui/build/static/coffeescript-D8InK8kf.js +0 -1
- package/web-ui/build/static/coffeescript-MKWUOXb5.js +0 -1
- package/web-ui/build/static/concurnas-CR56nj6R.js +0 -1
- package/web-ui/build/static/coq-DDLBsBJu.js +0 -1
- package/web-ui/build/static/coq-WbhtANeW.js +0 -1
- package/web-ui/build/static/cos-Bfmre3op.js +0 -1
- package/web-ui/build/static/cpp-Cdy6A7gI.js +0 -1
- package/web-ui/build/static/cpp-De2KZejr.js +0 -1
- package/web-ui/build/static/crmsh-uf3vbKnN.js +0 -1
- package/web-ui/build/static/crystal-BHMyEVPP.js +0 -1
- package/web-ui/build/static/crystal-DXAQwftg.js +0 -1
- package/web-ui/build/static/csharp-Ci2MRG6L.js +0 -1
- package/web-ui/build/static/csharp-D8MV2a7f.js +0 -1
- package/web-ui/build/static/cshtml-kVj3v3uY.js +0 -1
- package/web-ui/build/static/csp-B83CCdVc.js +0 -1
- package/web-ui/build/static/csp-DUO7zlPh.js +0 -1
- package/web-ui/build/static/css-BWsx7mtO.js +0 -1
- package/web-ui/build/static/css-extras-oHch2Y5C.js +0 -1
- package/web-ui/build/static/csv-DIf0iNlc.js +0 -1
- package/web-ui/build/static/cypher-B1rOF_f3.js +0 -1
- package/web-ui/build/static/d-BUgLS87u.js +0 -1
- package/web-ui/build/static/d-ClM8XTCr.js +0 -1
- package/web-ui/build/static/dart-D5rVGtrb.js +0 -1
- package/web-ui/build/static/dart-Oal__k4m.js +0 -1
- package/web-ui/build/static/dataweave-B0uxnNDC.js +0 -1
- package/web-ui/build/static/dax-B9z6d1P6.js +0 -1
- package/web-ui/build/static/delphi-KMlx8q8A.js +0 -1
- package/web-ui/build/static/dhall-DLWFgSR8.js +0 -1
- package/web-ui/build/static/diff-DDMGnyhE.js +0 -1
- package/web-ui/build/static/diff-yg1oXq3U.js +0 -1
- package/web-ui/build/static/django-BDtkIu_c.js +0 -1
- package/web-ui/build/static/django-Bkn9HlyQ.js +0 -1
- package/web-ui/build/static/dns-Bx1VHfo6.js +0 -1
- package/web-ui/build/static/dns-zone-file-Bgn5zn_J.js +0 -1
- package/web-ui/build/static/docker-CTdrZJHc.js +0 -1
- package/web-ui/build/static/dockerfile-B7ziWbf_.js +0 -1
- package/web-ui/build/static/dos-cbBC5Icj.js +0 -1
- package/web-ui/build/static/dot-JXSVTLEH.js +0 -1
- package/web-ui/build/static/dsconfig-sEua2C2o.js +0 -1
- package/web-ui/build/static/dts-Zem_gT_O.js +0 -1
- package/web-ui/build/static/dust-B-dZ6-uQ.js +0 -1
- package/web-ui/build/static/ebnf-CXfeZoXF.js +0 -1
- package/web-ui/build/static/ebnf-raQs4FpT.js +0 -1
- package/web-ui/build/static/editorconfig-hp8ARbHf.js +0 -1
- package/web-ui/build/static/eiffel-tO3jaG00.js +0 -1
- package/web-ui/build/static/ejs-BGmD5Rvl.js +0 -1
- package/web-ui/build/static/elixir-CF0JDN9L.js +0 -1
- package/web-ui/build/static/elixir-CFSil_Ou.js +0 -1
- package/web-ui/build/static/elm-As6XaD-g.js +0 -1
- package/web-ui/build/static/elm-pw5GpqTZ.js +0 -1
- package/web-ui/build/static/erb-BrpCJIyN.js +0 -1
- package/web-ui/build/static/erb-D2_eJU9C.js +0 -1
- package/web-ui/build/static/erlang-5rSv6NMZ.js +0 -1
- package/web-ui/build/static/erlang-RCAxVMBd.js +0 -1
- package/web-ui/build/static/erlang-repl-BN0h_6XR.js +0 -1
- package/web-ui/build/static/etlua-BMtMnKtv.js +0 -1
- package/web-ui/build/static/excel-CRNS57iM.js +0 -1
- package/web-ui/build/static/excel-formula-BNw56R2m.js +0 -1
- package/web-ui/build/static/factor-7lsloWTf.js +0 -1
- package/web-ui/build/static/false-CQUvGnfd.js +0 -1
- package/web-ui/build/static/firestore-security-rules-WC1PabFS.js +0 -1
- package/web-ui/build/static/fix-Cs6kLeYV.js +0 -1
- package/web-ui/build/static/flix-1fdMgw2I.js +0 -1
- package/web-ui/build/static/flow-CRPduKSH.js +0 -1
- package/web-ui/build/static/fortran-C-3TUt5R.js +0 -1
- package/web-ui/build/static/fortran-CA4bbZCj.js +0 -1
- package/web-ui/build/static/fsharp-BScjCFae.js +0 -1
- package/web-ui/build/static/fsharp-BtHWuW4o.js +0 -1
- package/web-ui/build/static/ftl-Re-S2zvF.js +0 -1
- package/web-ui/build/static/gams-Cr12l-cM.js +0 -1
- package/web-ui/build/static/gap-H0O9-Zju.js +0 -1
- package/web-ui/build/static/gauss-CW8jwURx.js +0 -1
- package/web-ui/build/static/gcode-CIxfYtg9.js +0 -1
- package/web-ui/build/static/gcode-CVqRWYeB.js +0 -1
- package/web-ui/build/static/gdscript-BltZCaKl.js +0 -1
- package/web-ui/build/static/gedcom-nMT5ety_.js +0 -1
- package/web-ui/build/static/gherkin-B4M7CGOo.js +0 -1
- package/web-ui/build/static/gherkin-DumuqAQF.js +0 -1
- package/web-ui/build/static/git-BBiBlZ5H.js +0 -1
- package/web-ui/build/static/glsl-D8ckiRVo.js +0 -1
- package/web-ui/build/static/glsl-Z4VdDyPa.js +0 -1
- package/web-ui/build/static/gml-BHuSndHE.js +0 -1
- package/web-ui/build/static/gml-DZpfN_A4.js +0 -1
- package/web-ui/build/static/gn-BjpAHNh_.js +0 -1
- package/web-ui/build/static/go-BeZ9IgZB.js +0 -1
- package/web-ui/build/static/go-HEXrcgIc.js +0 -1
- package/web-ui/build/static/go-module-BGdPb7sP.js +0 -1
- package/web-ui/build/static/golo-Cr70KUbI.js +0 -1
- package/web-ui/build/static/gradle-C7MXrDnB.js +0 -1
- package/web-ui/build/static/graphql-CJK0wQjf.js +0 -1
- package/web-ui/build/static/groovy-Bwe7hkFG.js +0 -1
- package/web-ui/build/static/groovy-Dc6WDoKa.js +0 -1
- package/web-ui/build/static/haml-BSsAjltt.js +0 -1
- package/web-ui/build/static/haml-CZih7X_4.js +0 -1
- package/web-ui/build/static/handlebars-CN8hCpsy.js +0 -1
- package/web-ui/build/static/handlebars-XBLc7i13.js +0 -1
- package/web-ui/build/static/haskell-BH9WhK10.js +0 -1
- package/web-ui/build/static/haskell-Djf2J1vd.js +0 -1
- package/web-ui/build/static/haxe-BllD-W9e.js +0 -1
- package/web-ui/build/static/haxe-DY8Hyn7u.js +0 -1
- package/web-ui/build/static/hcl-CfktAP2o.js +0 -1
- package/web-ui/build/static/hlsl-B2JSOD9d.js +0 -1
- package/web-ui/build/static/hoon-BILyDobB.js +0 -1
- package/web-ui/build/static/hpkp-Bb8rXx4p.js +0 -1
- package/web-ui/build/static/hsp-BmjeJC21.js +0 -1
- package/web-ui/build/static/hsts-DJhW57Fu.js +0 -1
- package/web-ui/build/static/htmlbars-CJe_ZLjw.js +0 -1
- package/web-ui/build/static/http-D7SlABvQ.js +0 -1
- package/web-ui/build/static/http-DEUJqmEm.js +0 -1
- package/web-ui/build/static/hy-DVfsgEbr.js +0 -1
- package/web-ui/build/static/ichigojam-CPdz2bOt.js +0 -1
- package/web-ui/build/static/icon-DYK9RbU9.js +0 -1
- package/web-ui/build/static/icu-message-format-HiZB_alB.js +0 -1
- package/web-ui/build/static/idris-Clk3tJIE.js +0 -1
- package/web-ui/build/static/iecst-D7wkeksq.js +0 -1
- package/web-ui/build/static/ignore-GSm-L3jG.js +0 -1
- package/web-ui/build/static/index-BJe5td0v.js +0 -13
- package/web-ui/build/static/index-BYvljeMN.js +0 -1
- package/web-ui/build/static/index-CLelJq9j.js +0 -1156
- package/web-ui/build/static/index-f5UnFSsY.css +0 -1
- package/web-ui/build/static/inform7-D3gc0hSc.js +0 -1
- package/web-ui/build/static/inform7-DLdvZTxX.js +0 -1
- package/web-ui/build/static/ini-CVcWx1TA.js +0 -1
- package/web-ui/build/static/ini-CxYBdsvZ.js +0 -1
- package/web-ui/build/static/io-D760QF0i.js +0 -1
- package/web-ui/build/static/irpf90-DfkXdZut.js +0 -1
- package/web-ui/build/static/isbl-Bl3W-krY.js +0 -1
- package/web-ui/build/static/j-DyJj9FSc.js +0 -1
- package/web-ui/build/static/java-CLw1cH97.js +0 -1
- package/web-ui/build/static/java-vXaHBzP4.js +0 -1
- package/web-ui/build/static/javadoc-p5hIe48g.js +0 -1
- package/web-ui/build/static/javadoclike-OXi-sQ0q.js +0 -1
- package/web-ui/build/static/javascript-CTSqES8o.js +0 -1
- package/web-ui/build/static/javastacktrace-PC9-3moA.js +0 -1
- package/web-ui/build/static/jboss-cli-CxOZKDLi.js +0 -1
- package/web-ui/build/static/jexl-C4kSXhD1.js +0 -1
- package/web-ui/build/static/jolie-CntM8cWx.js +0 -1
- package/web-ui/build/static/jq-D_4bTCm0.js +0 -1
- package/web-ui/build/static/js-extras-Cx9VAZJd.js +0 -1
- package/web-ui/build/static/js-templates-BqyJUDxJ.js +0 -1
- package/web-ui/build/static/jsdoc-CNHLgAph.js +0 -1
- package/web-ui/build/static/json-BXIFrbVC.js +0 -1
- package/web-ui/build/static/json-DRUrJL_F.js +0 -1
- package/web-ui/build/static/json5-EsTrOpXr.js +0 -1
- package/web-ui/build/static/jsonp-RijEuTJY.js +0 -1
- package/web-ui/build/static/jsstacktrace-dM13uE1y.js +0 -1
- package/web-ui/build/static/jsx-Cf0j02DZ.js +0 -1
- package/web-ui/build/static/julia-BLrtj5Dj.js +0 -1
- package/web-ui/build/static/julia-D0PJgQhi.js +0 -1
- package/web-ui/build/static/julia-repl-BLnLCve4.js +0 -1
- package/web-ui/build/static/keepalived-SvzEYloD.js +0 -1
- package/web-ui/build/static/keyman-B5l2mmmE.js +0 -1
- package/web-ui/build/static/kotlin-B_6COR1e.js +0 -1
- package/web-ui/build/static/kotlin-vd1Xdz6D.js +0 -1
- package/web-ui/build/static/kumir-8mIZWgJQ.js +0 -1
- package/web-ui/build/static/kusto-CoV2oHqt.js +0 -1
- package/web-ui/build/static/lasso-BjjUNa_o.js +0 -1
- package/web-ui/build/static/latex-C9KOfuFk.js +0 -1
- package/web-ui/build/static/latex-DhLttY-I.js +0 -1
- package/web-ui/build/static/latte-CaYNaOoK.js +0 -1
- package/web-ui/build/static/ldif-DFxnpH3G.js +0 -1
- package/web-ui/build/static/leaf-DrMpC83a.js +0 -1
- package/web-ui/build/static/less-DUoYpEFn.js +0 -1
- package/web-ui/build/static/less-nh0XCcut.js +0 -1
- package/web-ui/build/static/lilypond-BlqjLr3W.js +0 -1
- package/web-ui/build/static/liquid-BVGHSG0T.js +0 -1
- package/web-ui/build/static/lisp-CEK8BtYQ.js +0 -1
- package/web-ui/build/static/lisp-D_jGHxhc.js +0 -1
- package/web-ui/build/static/livecodeserver-CFUDw_SK.js +0 -1
- package/web-ui/build/static/livescript-C5xzpiLM.js +0 -1
- package/web-ui/build/static/livescript-CKoPcK0c.js +0 -1
- package/web-ui/build/static/llvm-BBOVIeTl.js +0 -1
- package/web-ui/build/static/llvm-ioC5bCUB.js +0 -1
- package/web-ui/build/static/log-CPYTqm4T.js +0 -1
- package/web-ui/build/static/lolcode-BkT93adT.js +0 -1
- package/web-ui/build/static/lsl-M98YPNRW.js +0 -1
- package/web-ui/build/static/lua-D7Lum5n9.js +0 -1
- package/web-ui/build/static/lua-DHyr0QwE.js +0 -1
- package/web-ui/build/static/magma-BwMFjwQu.js +0 -1
- package/web-ui/build/static/makefile-BFYZ-SfG.js +0 -1
- package/web-ui/build/static/makefile-D6oyR2lD.js +0 -1
- package/web-ui/build/static/markdown-6jtg6KZm.js +0 -1
- package/web-ui/build/static/markdown-DTLtPgeP.js +0 -1
- package/web-ui/build/static/markup-templating-K8uoAIqY.js +0 -1
- package/web-ui/build/static/mathematica-cW5hOuB2.js +0 -1
- package/web-ui/build/static/matlab-CwSNWEq8.js +0 -1
- package/web-ui/build/static/matlab-MQ972BY-.js +0 -1
- package/web-ui/build/static/maxima-CMSFLri-.js +0 -1
- package/web-ui/build/static/maxscript-BzcoS2KA.js +0 -1
- package/web-ui/build/static/mel-Cd20pAs-.js +0 -1
- package/web-ui/build/static/mel-KWG5N49g.js +0 -1
- package/web-ui/build/static/mercury-eW1ljJh0.js +0 -1
- package/web-ui/build/static/mermaid-D3zeCM84.js +0 -1
- package/web-ui/build/static/mipsasm-B5g6Ndra.js +0 -1
- package/web-ui/build/static/mizar-C_nZ0Ts9.js +0 -1
- package/web-ui/build/static/mizar-CuTNEv2t.js +0 -1
- package/web-ui/build/static/mojolicious-C1Xq--lT.js +0 -1
- package/web-ui/build/static/mongodb-C_3giArw.js +0 -1
- package/web-ui/build/static/monkey-DQ1olPd-.js +0 -1
- package/web-ui/build/static/monkey-n4Tbrep7.js +0 -1
- package/web-ui/build/static/moonscript-CmnQJuIL.js +0 -1
- package/web-ui/build/static/moonscript-DXgmWjLy.js +0 -1
- package/web-ui/build/static/n1ql-531a3W-1.js +0 -1
- package/web-ui/build/static/n1ql-BYH9EvME.js +0 -1
- package/web-ui/build/static/n4js-Cy0LcM-V.js +0 -1
- package/web-ui/build/static/nand2tetris-hdl-CKOztBDD.js +0 -1
- package/web-ui/build/static/naniscript-oLFpxBGE.js +0 -1
- package/web-ui/build/static/nasm-DLPnwFkM.js +0 -1
- package/web-ui/build/static/neon-Cn03wGUR.js +0 -1
- package/web-ui/build/static/nevod-C_VRvbdf.js +0 -1
- package/web-ui/build/static/nginx-60SpLv4t.js +0 -1
- package/web-ui/build/static/nginx-DZLHid-q.js +0 -1
- package/web-ui/build/static/nim-BnrHdqGC.js +0 -1
- package/web-ui/build/static/nim-Ds3pmwtE.js +0 -1
- package/web-ui/build/static/nix-Dl-dS0w4.js +0 -1
- package/web-ui/build/static/nix-jL62FzTz.js +0 -1
- package/web-ui/build/static/node-repl-BAuDzNZd.js +0 -1
- package/web-ui/build/static/nsis-CEnFjfNr.js +0 -1
- package/web-ui/build/static/nsis-CcCz6HIu.js +0 -1
- package/web-ui/build/static/objectivec-CZXfVowS.js +0 -1
- package/web-ui/build/static/objectivec-CuaFU-Ef.js +0 -1
- package/web-ui/build/static/ocaml-BGAzfwAx.js +0 -1
- package/web-ui/build/static/ocaml-BoO1lU26.js +0 -1
- package/web-ui/build/static/opencl-DAnD5xP-.js +0 -1
- package/web-ui/build/static/openqasm-CO7gdVj9.js +0 -1
- package/web-ui/build/static/openscad-B2wMEMQR.js +0 -1
- package/web-ui/build/static/oxygene-1erv93gF.js +0 -1
- package/web-ui/build/static/oz-D3334gi7.js +0 -1
- package/web-ui/build/static/parigp-rQZTN8zi.js +0 -1
- package/web-ui/build/static/parser-B4ZSZ1ig.js +0 -1
- package/web-ui/build/static/parser3-CCCjkYLG.js +0 -1
- package/web-ui/build/static/pascal-DeC9Pvom.js +0 -1
- package/web-ui/build/static/pascaligo-CT2u6UpO.js +0 -1
- package/web-ui/build/static/pcaxis-CvlRg6t4.js +0 -1
- package/web-ui/build/static/peoplecode-BYahULz2.js +0 -1
- package/web-ui/build/static/perl-CKgvyY59.js +0 -1
- package/web-ui/build/static/perl-E7sx7Izv.js +0 -1
- package/web-ui/build/static/pf-D9wnFBt7.js +0 -1
- package/web-ui/build/static/pgsql-CrlBdRAn.js +0 -1
- package/web-ui/build/static/php-D2O-B3y7.js +0 -1
- package/web-ui/build/static/php-extras-BKqZuzgt.js +0 -1
- package/web-ui/build/static/php-nfXl9WfB.js +0 -1
- package/web-ui/build/static/php-template-Cg8ERLNQ.js +0 -1
- package/web-ui/build/static/phpdoc-Z1u90OwH.js +0 -1
- package/web-ui/build/static/plaintext-DkNVeXWx.js +0 -1
- package/web-ui/build/static/plsql-DO5fJNhS.js +0 -1
- package/web-ui/build/static/pony-DXIqq5Bk.js +0 -1
- package/web-ui/build/static/powerquery-B2ovxJZi.js +0 -1
- package/web-ui/build/static/powershell-BVeqqari.js +0 -1
- package/web-ui/build/static/powershell-CskV4qWh.js +0 -1
- package/web-ui/build/static/processing-D90SJpnq.js +0 -1
- package/web-ui/build/static/processing-DP2mf97Z.js +0 -1
- package/web-ui/build/static/profile-H6zk8v_f.js +0 -1
- package/web-ui/build/static/prolog-AUfxYiJV.js +0 -1
- package/web-ui/build/static/prolog-Dz2WdsVN.js +0 -1
- package/web-ui/build/static/promql-CloMJmMW.js +0 -1
- package/web-ui/build/static/properties-CTl3mnrP.js +0 -1
- package/web-ui/build/static/properties-D2RfteTZ.js +0 -1
- package/web-ui/build/static/protobuf-Be9oqQCu.js +0 -1
- package/web-ui/build/static/protobuf-BgG8zUnY.js +0 -1
- package/web-ui/build/static/psl-Bqx8iN9e.js +0 -1
- package/web-ui/build/static/pug-CHfFC0Wg.js +0 -1
- package/web-ui/build/static/puppet-__1ifzZS.js +0 -1
- package/web-ui/build/static/puppet-pbtRCMgd.js +0 -1
- package/web-ui/build/static/pure-B9STuf4F.js +0 -1
- package/web-ui/build/static/purebasic-7ADyn-Ce.js +0 -1
- package/web-ui/build/static/purebasic-Bc06YQcD.js +0 -1
- package/web-ui/build/static/purescript-CU-dDebr.js +0 -1
- package/web-ui/build/static/python-BEsXrEbi.js +0 -1
- package/web-ui/build/static/python-CZFrgH2X.js +0 -1
- package/web-ui/build/static/python-repl-CI9GmJce.js +0 -1
- package/web-ui/build/static/q-E7xvTGRo.js +0 -1
- package/web-ui/build/static/q-hvg9aQoY.js +0 -1
- package/web-ui/build/static/qml-DkZWcxEv.js +0 -1
- package/web-ui/build/static/qml-DpdWla8G.js +0 -1
- package/web-ui/build/static/qore-Dsm7ACR_.js +0 -1
- package/web-ui/build/static/qsharp-BBec6MJR.js +0 -1
- package/web-ui/build/static/r-CTVkq_Ky.js +0 -1
- package/web-ui/build/static/r-DHGNCupF.js +0 -1
- package/web-ui/build/static/racket-hoSh4YPx.js +0 -1
- package/web-ui/build/static/reason-CQPUIbsm.js +0 -1
- package/web-ui/build/static/reasonml-BXtFFSTZ.js +0 -1
- package/web-ui/build/static/regex-BNkF_ufb.js +0 -1
- package/web-ui/build/static/rego-BXHrjItC.js +0 -1
- package/web-ui/build/static/renpy-CBQvK_5t.js +0 -1
- package/web-ui/build/static/rest-Bf8hzmF1.js +0 -1
- package/web-ui/build/static/rib-D0a4KzlP.js +0 -1
- package/web-ui/build/static/rip-DchN4BQN.js +0 -1
- package/web-ui/build/static/roboconf-HXnyGNTm.js +0 -1
- package/web-ui/build/static/roboconf-zfK6mgmU.js +0 -1
- package/web-ui/build/static/robotframework-DnP-vXyd.js +0 -1
- package/web-ui/build/static/routeros-CDirYxZY.js +0 -1
- package/web-ui/build/static/rsl-BCK_msc-.js +0 -1
- package/web-ui/build/static/ruby--mXX6GNK.js +0 -1
- package/web-ui/build/static/ruby-BIdQYq0Y.js +0 -1
- package/web-ui/build/static/ruleslanguage-BD07s5RU.js +0 -1
- package/web-ui/build/static/rust-Bgni9V7U.js +0 -1
- package/web-ui/build/static/rust-OywmQ2ox.js +0 -1
- package/web-ui/build/static/sas-B6-82htH.js +0 -1
- package/web-ui/build/static/sas-k9XEScbR.js +0 -1
- package/web-ui/build/static/sass-BOvNBStT.js +0 -1
- package/web-ui/build/static/scala-At07fmMd.js +0 -1
- package/web-ui/build/static/scala-DUOfqSaU.js +0 -1
- package/web-ui/build/static/scheme-B87lC0bK.js +0 -1
- package/web-ui/build/static/scheme-BS7OzWRX.js +0 -1
- package/web-ui/build/static/scilab-Bmn4jjcu.js +0 -1
- package/web-ui/build/static/scss-DTeB95yE.js +0 -1
- package/web-ui/build/static/scss-xilnl6Dx.js +0 -1
- package/web-ui/build/static/shell-CKetyy4y.js +0 -1
- package/web-ui/build/static/shell-session-B6rat2c7.js +0 -1
- package/web-ui/build/static/smali-C9O9CXOD.js +0 -1
- package/web-ui/build/static/smali-CBkgbinS.js +0 -1
- package/web-ui/build/static/smalltalk-CuUjFHiz.js +0 -1
- package/web-ui/build/static/smalltalk-D0xhFL9b.js +0 -1
- package/web-ui/build/static/smarty-CY0N0d5x.js +0 -1
- package/web-ui/build/static/sml-BVAw3fjB.js +0 -1
- package/web-ui/build/static/sml-CO9XB1ax.js +0 -1
- package/web-ui/build/static/solidity-BNixD4Dx.js +0 -1
- package/web-ui/build/static/solution-file-DHyGXf2y.js +0 -1
- package/web-ui/build/static/soy-Cxgjntsl.js +0 -1
- package/web-ui/build/static/sparql-CDLqu9vy.js +0 -1
- package/web-ui/build/static/splunk-spl-Cmkl_Xmw.js +0 -1
- package/web-ui/build/static/sqf-CIGKolw3.js +0 -1
- package/web-ui/build/static/sqf-Cfp_lC6-.js +0 -1
- package/web-ui/build/static/sql-DHOGwYxe.js +0 -1
- package/web-ui/build/static/sql-QIw1Q2yi.js +0 -1
- package/web-ui/build/static/sql_more-C0b3-InT.js +0 -1
- package/web-ui/build/static/squirrel-DASToo1F.js +0 -1
- package/web-ui/build/static/stan-DHMkcFZg.js +0 -1
- package/web-ui/build/static/stan-No3nsdnQ.js +0 -1
- package/web-ui/build/static/stata-Brkzu5Nv.js +0 -1
- package/web-ui/build/static/step21-D2l5M5Ml.js +0 -1
- package/web-ui/build/static/stylus-Bx6FaZN_.js +0 -1
- package/web-ui/build/static/stylus-CVkTaPns.js +0 -1
- package/web-ui/build/static/subunit-CDrsAMuL.js +0 -1
- package/web-ui/build/static/swift-BSw_pS-l.js +0 -1
- package/web-ui/build/static/swift-BWyqwIo8.js +0 -1
- package/web-ui/build/static/systemd-BwqpYcJK.js +0 -1
- package/web-ui/build/static/t4-cs-CwsJLOxV.js +0 -1
- package/web-ui/build/static/t4-templating-BfxY01xf.js +0 -1
- package/web-ui/build/static/t4-vb-BhsKKFhp.js +0 -1
- package/web-ui/build/static/taggerscript-Bkew95or.js +0 -1
- package/web-ui/build/static/tap-DHovcHbS.js +0 -1
- package/web-ui/build/static/tap-DPl9uPo4.js +0 -1
- package/web-ui/build/static/tcl-BeozHO-f.js +0 -1
- package/web-ui/build/static/tcl-Df_8ItQH.js +0 -1
- package/web-ui/build/static/textile-B3m_f58b.js +0 -1
- package/web-ui/build/static/thrift-D20n-HpW.js +0 -1
- package/web-ui/build/static/toml-C-fTAonK.js +0 -1
- package/web-ui/build/static/tp-hGbXe5Eo.js +0 -1
- package/web-ui/build/static/tremor-BaVOtRFz.js +0 -1
- package/web-ui/build/static/tsx-ChPInNl0.js +0 -1
- package/web-ui/build/static/tt2-DAIJ8cpz.js +0 -1
- package/web-ui/build/static/turtle-B7z_y-PK.js +0 -1
- package/web-ui/build/static/twig-TUEkve6W.js +0 -1
- package/web-ui/build/static/twig-stKDItz7.js +0 -1
- package/web-ui/build/static/typescript-BPdM-QOM.js +0 -1
- package/web-ui/build/static/typescript-DjSY4MvL.js +0 -1
- package/web-ui/build/static/typoscript-BQHgQtEL.js +0 -1
- package/web-ui/build/static/unrealscript-g8yNPQQ5.js +0 -1
- package/web-ui/build/static/uorazor-CnuMiQz9.js +0 -1
- package/web-ui/build/static/uri-CfioiemU.js +0 -1
- package/web-ui/build/static/v-B69Oau14.js +0 -1
- package/web-ui/build/static/vala-C0PjlK3l.js +0 -1
- package/web-ui/build/static/vala-COgjD3gU.js +0 -1
- package/web-ui/build/static/vbnet-CklOnyuR.js +0 -1
- package/web-ui/build/static/vbnet-MxHUC5Mz.js +0 -1
- package/web-ui/build/static/vbscript-BxQnA97w.js +0 -1
- package/web-ui/build/static/vbscript-html-DOtde7dD.js +0 -1
- package/web-ui/build/static/velocity-l8B9m66X.js +0 -1
- package/web-ui/build/static/verilog-DF6dF-Vp.js +0 -1
- package/web-ui/build/static/verilog-Dgb9SDRX.js +0 -1
- package/web-ui/build/static/vhdl-0GarU_AK.js +0 -1
- package/web-ui/build/static/vhdl-BfPQnOdI.js +0 -1
- package/web-ui/build/static/vim-Likg_-II.js +0 -1
- package/web-ui/build/static/vim-k53Sj7A3.js +0 -1
- package/web-ui/build/static/visual-basic-BNVZCzlV.js +0 -1
- package/web-ui/build/static/warpscript-BkLK5iuW.js +0 -1
- package/web-ui/build/static/wasm-CQhA1ece.js +0 -1
- package/web-ui/build/static/web-idl-DmNsI0kE.js +0 -1
- package/web-ui/build/static/wiki-B3z4pmra.js +0 -1
- package/web-ui/build/static/wolfram-Dsf21d_g.js +0 -1
- package/web-ui/build/static/wren-BZXZlzrL.js +0 -1
- package/web-ui/build/static/x86asm-DpWGZhJU.js +0 -1
- package/web-ui/build/static/xeora-8xPZN4DH.js +0 -1
- package/web-ui/build/static/xl-XkdWYMGl.js +0 -1
- package/web-ui/build/static/xml-BBdROEWt.js +0 -1
- package/web-ui/build/static/xml-doc-Cjs4OpTe.js +0 -1
- package/web-ui/build/static/xojo-nCen1FPx.js +0 -1
- package/web-ui/build/static/xquery-CBFkAxo1.js +0 -1
- package/web-ui/build/static/xquery-Dwsc1weX.js +0 -1
- package/web-ui/build/static/yaml-DzSAh6jl.js +0 -1
- package/web-ui/build/static/yaml-Lg8gnEUU.js +0 -1
- package/web-ui/build/static/yang-Bd-v2b0k.js +0 -1
- package/web-ui/build/static/zephir-wbJOizIa.js +0 -1
- package/web-ui/build/static/zig-Cz384XjE.js +0 -1
package/bin/cli.js
CHANGED
|
@@ -17,10 +17,18 @@ import { dirname, join } from 'path';
|
|
|
17
17
|
import { spawn } from 'child_process';
|
|
18
18
|
import { readFileSync } from 'fs';
|
|
19
19
|
import http from 'http';
|
|
20
|
+
import { runUpdateCheck } from '../src/utilities/updateNotifier.js';
|
|
20
21
|
|
|
21
22
|
const __filename = fileURLToPath(import.meta.url);
|
|
22
23
|
const __dirname = dirname(__filename);
|
|
23
24
|
|
|
25
|
+
// Fire the update-notifier check as soon as the process starts. The
|
|
26
|
+
// helper is non-blocking (it schedules a background fetch and reads
|
|
27
|
+
// from a tiny on-disk cache for the next run) and silently skips
|
|
28
|
+
// every failure mode — missing dep, no network, kill-switch env,
|
|
29
|
+
// not-globally-installed. Worst case: the banner just doesn't appear.
|
|
30
|
+
runUpdateCheck().catch(() => { /* never propagate */ });
|
|
31
|
+
|
|
24
32
|
// Default configuration
|
|
25
33
|
const DEFAULT_PORT = 8080;
|
|
26
34
|
// Use 127.0.0.1 instead of 'localhost' to avoid IPv6 issues in WSL2
|
package/package.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tripwire for the auto-update configuration in package.json.
|
|
3
|
+
*
|
|
4
|
+
* Catches the class of regression where someone bumps deps or
|
|
5
|
+
* re-formats the build block and accidentally drops:
|
|
6
|
+
* - the `update-notifier` runtime dep (CLI banner stops working)
|
|
7
|
+
* - the `electron-updater` optional dep (Electron updates stop)
|
|
8
|
+
* - the `build.publish` block (electron-builder stops generating
|
|
9
|
+
* latest.yml + electron-updater has nothing to read)
|
|
10
|
+
*
|
|
11
|
+
* If you intentionally remove any of these, update this test in the
|
|
12
|
+
* SAME commit and explain in the test diff why.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { describe, test, expect } from '@jest/globals';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { join, dirname } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
|
|
20
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const REPO_ROOT = join(__dirname, '..', '..');
|
|
22
|
+
const pkg = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8'));
|
|
23
|
+
|
|
24
|
+
describe('package.json — auto-update presence', () => {
|
|
25
|
+
test('update-notifier is in dependencies (CLI banner)', () => {
|
|
26
|
+
expect(pkg.dependencies).toBeDefined();
|
|
27
|
+
expect(pkg.dependencies['update-notifier']).toBeTruthy();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('electron-updater is in optionalDependencies (Electron build only)', () => {
|
|
31
|
+
expect(pkg.optionalDependencies?.['electron-updater']).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('electron-builder has a publish provider configured', () => {
|
|
35
|
+
expect(pkg.build).toBeDefined();
|
|
36
|
+
expect(Array.isArray(pkg.build.publish) || typeof pkg.build.publish === 'object').toBe(true);
|
|
37
|
+
const entries = Array.isArray(pkg.build.publish) ? pkg.build.publish : [pkg.build.publish];
|
|
38
|
+
expect(entries.length).toBeGreaterThan(0);
|
|
39
|
+
// electron-updater requires a `provider` field on each publish entry.
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
expect(entry.provider).toBeTruthy();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tripwire: the npm-publish workflow must NOT re-introduce
|
|
3
|
+
* `javascript-obfuscator` or any other source-modifying step that
|
|
4
|
+
* would defeat the explicit decision in commit removing obfuscation.
|
|
5
|
+
*
|
|
6
|
+
* If you genuinely want to bring obfuscation back, change this test
|
|
7
|
+
* AND record the rationale in the workflow's leading comment block.
|
|
8
|
+
* Don't just delete the test.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, test, expect } from '@jest/globals';
|
|
12
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
13
|
+
import { join, dirname } from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const REPO_ROOT = join(__dirname, '..', '..');
|
|
18
|
+
const WORKFLOWS_DIR = join(REPO_ROOT, '.github', 'workflows');
|
|
19
|
+
|
|
20
|
+
const FORBIDDEN_IN_PUBLISH = [
|
|
21
|
+
'javascript-obfuscator',
|
|
22
|
+
'javascript_obfuscator',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
describe('release workflows — obfuscation absence', () => {
|
|
26
|
+
test('publish-npm-trusted.yml contains no obfuscator install or invocation', () => {
|
|
27
|
+
const yaml = readFileSync(join(WORKFLOWS_DIR, 'publish-npm-trusted.yml'), 'utf8');
|
|
28
|
+
for (const needle of FORBIDDEN_IN_PUBLISH) {
|
|
29
|
+
// Tolerate the literal mention inside a comment block that
|
|
30
|
+
// documents the removal — but not in any other context.
|
|
31
|
+
const lines = yaml.split('\n');
|
|
32
|
+
const offending = lines
|
|
33
|
+
.map((line, idx) => ({ line, idx }))
|
|
34
|
+
.filter(({ line }) => line.includes(needle))
|
|
35
|
+
.filter(({ line }) => !/^\s*#/.test(line) && !/^\s*\/\//.test(line));
|
|
36
|
+
expect(offending).toEqual([]);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('workflow YAML is syntactically valid (no orphaned steps)', () => {
|
|
41
|
+
const yaml = readFileSync(join(WORKFLOWS_DIR, 'publish-npm-trusted.yml'), 'utf8');
|
|
42
|
+
// We don't bundle a YAML parser into the CLI repo; a structural
|
|
43
|
+
// smoke test is enough to catch the most common form of breakage
|
|
44
|
+
// (deleting a step without removing the leading `- name:`).
|
|
45
|
+
const stepCount = (yaml.match(/^\s{4,6}- name:/gm) || []).length;
|
|
46
|
+
expect(stepCount).toBeGreaterThan(5);
|
|
47
|
+
// Each top-level step name should be followed by either `run:` or `uses:`
|
|
48
|
+
const lines = yaml.split('\n');
|
|
49
|
+
let pendingStepLine = null;
|
|
50
|
+
for (let i = 0; i < lines.length; i++) {
|
|
51
|
+
if (/^\s{4,6}- name:/.test(lines[i])) {
|
|
52
|
+
pendingStepLine = i;
|
|
53
|
+
} else if (pendingStepLine != null && /^\s{6,8}(run|uses):/.test(lines[i])) {
|
|
54
|
+
pendingStepLine = null;
|
|
55
|
+
} else if (pendingStepLine != null && /^\s{4,6}- /.test(lines[i])) {
|
|
56
|
+
throw new Error(`step at line ${pendingStepLine + 1} has no run/uses`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('every yml file in .github/workflows parses (basic balance check)', () => {
|
|
62
|
+
const files = readdirSync(WORKFLOWS_DIR).filter(f => f.endsWith('.yml') || f.endsWith('.yaml'));
|
|
63
|
+
expect(files.length).toBeGreaterThan(0);
|
|
64
|
+
for (const f of files) {
|
|
65
|
+
const yaml = readFileSync(join(WORKFLOWS_DIR, f), 'utf8');
|
|
66
|
+
// Naive but useful: every workflow should have `jobs:` and at
|
|
67
|
+
// least one step.
|
|
68
|
+
expect(yaml).toMatch(/^jobs:/m);
|
|
69
|
+
expect(yaml).toMatch(/^\s+steps:/m);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the account-proxy router on the local CLI server.
|
|
3
|
+
*
|
|
4
|
+
* These tests cover three categories of behavior:
|
|
5
|
+
*
|
|
6
|
+
* 1. Auth gating — every route MUST return 401 + `not_signed_in`
|
|
7
|
+
* when there's no JWT, never silently fall through to the
|
|
8
|
+
* backend with no auth.
|
|
9
|
+
*
|
|
10
|
+
* 2. JWT forwarding + envelope normalisation — when a JWT is
|
|
11
|
+
* present, the backend is called with a Bearer header, and
|
|
12
|
+
* every response (200, 404, 503, JSON-shape variations) lands
|
|
13
|
+
* in our standard `{ success, error?, code? }` envelope.
|
|
14
|
+
*
|
|
15
|
+
* 3. Handoff URL building — the FE never gets to pick which
|
|
16
|
+
* portal we redirect to, and the handoff is only ever the
|
|
17
|
+
* short-lived token, never the long-lived JWT.
|
|
18
|
+
*
|
|
19
|
+
* The router is constructed with injected `getJwt`, `getBrand`, and
|
|
20
|
+
* `fetchImpl` — no real HTTP, no real `lastAuthResult` plumbing.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { describe, test, expect, jest } from '@jest/globals';
|
|
24
|
+
import express from 'express';
|
|
25
|
+
import { createServer } from 'http';
|
|
26
|
+
import { createAccountRouter, ERROR_CODES, __test__ } from '../accountRoutes.js';
|
|
27
|
+
|
|
28
|
+
const SAMPLE_JWT = 'eyJ.sample.jwt';
|
|
29
|
+
const BACKEND_URL = 'https://backend.test';
|
|
30
|
+
|
|
31
|
+
async function startApp(handler) {
|
|
32
|
+
const app = express();
|
|
33
|
+
app.use(express.json());
|
|
34
|
+
handler(app);
|
|
35
|
+
const server = createServer(app);
|
|
36
|
+
await new Promise(r => server.listen(0, r));
|
|
37
|
+
return { server, baseUrl: `http://127.0.0.1:${server.address().port}` };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function stop(server) { if (server) await new Promise(r => server.close(r)); }
|
|
41
|
+
|
|
42
|
+
function mountRouter({ jwt = SAMPLE_JWT, brand = 'autopilot', fetchImpl, logger = { warn: () => {} } } = {}) {
|
|
43
|
+
const router = createAccountRouter({
|
|
44
|
+
getJwt: () => jwt,
|
|
45
|
+
getBrand: () => brand,
|
|
46
|
+
backendBaseUrl: BACKEND_URL,
|
|
47
|
+
fetchImpl,
|
|
48
|
+
logger,
|
|
49
|
+
});
|
|
50
|
+
return async () => {
|
|
51
|
+
return startApp(app => app.use('/api/account', router));
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ────────────────────────────────────────────────────────────────────
|
|
56
|
+
// Constructor guards
|
|
57
|
+
// ────────────────────────────────────────────────────────────────────
|
|
58
|
+
describe('createAccountRouter — constructor', () => {
|
|
59
|
+
test('throws when getJwt is missing', () => {
|
|
60
|
+
expect(() => createAccountRouter({ getBrand: () => 'autopilot' })).toThrow(/getJwt/);
|
|
61
|
+
});
|
|
62
|
+
test('throws when getBrand is missing', () => {
|
|
63
|
+
expect(() => createAccountRouter({ getJwt: () => null })).toThrow(/getBrand/);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ────────────────────────────────────────────────────────────────────
|
|
68
|
+
// Auth gating
|
|
69
|
+
// ────────────────────────────────────────────────────────────────────
|
|
70
|
+
describe('account routes — auth gating', () => {
|
|
71
|
+
test.each([
|
|
72
|
+
['GET', '/api/account/profile', undefined],
|
|
73
|
+
['GET', '/api/account/balance', undefined],
|
|
74
|
+
['GET', '/api/account/keys', undefined],
|
|
75
|
+
['POST', '/api/account/keys', { name: 'CI key' }],
|
|
76
|
+
['DELETE', '/api/account/keys/some-id', undefined],
|
|
77
|
+
['POST', '/api/account/handoff', {}],
|
|
78
|
+
])('%s %s returns 401 not_signed_in when JWT is absent', async (method, path, body) => {
|
|
79
|
+
const startServer = mountRouter({ jwt: null, fetchImpl: jest.fn() });
|
|
80
|
+
const { server, baseUrl } = await startServer();
|
|
81
|
+
try {
|
|
82
|
+
const r = await fetch(`${baseUrl}${path}`, {
|
|
83
|
+
method,
|
|
84
|
+
headers: { 'Content-Type': 'application/json' },
|
|
85
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
86
|
+
});
|
|
87
|
+
expect(r.status).toBe(401);
|
|
88
|
+
const json = await r.json();
|
|
89
|
+
expect(json.success).toBe(false);
|
|
90
|
+
expect(json.code).toBe(ERROR_CODES.NOT_SIGNED_IN);
|
|
91
|
+
} finally {
|
|
92
|
+
await stop(server);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('backend is never called when JWT is absent', async () => {
|
|
97
|
+
const fetchImpl = jest.fn();
|
|
98
|
+
const startServer = mountRouter({ jwt: null, fetchImpl });
|
|
99
|
+
const { server, baseUrl } = await startServer();
|
|
100
|
+
try {
|
|
101
|
+
await fetch(`${baseUrl}/api/account/profile`);
|
|
102
|
+
expect(fetchImpl).not.toHaveBeenCalled();
|
|
103
|
+
} finally {
|
|
104
|
+
await stop(server);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// ────────────────────────────────────────────────────────────────────
|
|
110
|
+
// Profile + balance + keys list
|
|
111
|
+
// ────────────────────────────────────────────────────────────────────
|
|
112
|
+
describe('GET /api/account/profile', () => {
|
|
113
|
+
test('forwards JWT and returns normalized { user } even when backend returns flat user object', async () => {
|
|
114
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
115
|
+
ok: true, status: 200,
|
|
116
|
+
text: async () => JSON.stringify({ id: 'u-1', email: 'a@b.com' }),
|
|
117
|
+
});
|
|
118
|
+
const startServer = mountRouter({ fetchImpl });
|
|
119
|
+
const { server, baseUrl } = await startServer();
|
|
120
|
+
try {
|
|
121
|
+
const r = await fetch(`${baseUrl}/api/account/profile`);
|
|
122
|
+
expect(r.status).toBe(200);
|
|
123
|
+
const json = await r.json();
|
|
124
|
+
expect(json).toEqual({ success: true, user: { id: 'u-1', email: 'a@b.com' } });
|
|
125
|
+
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
|
126
|
+
const [url, opts] = fetchImpl.mock.calls[0];
|
|
127
|
+
expect(url).toBe(`${BACKEND_URL}/auth/me`);
|
|
128
|
+
expect(opts.headers.Authorization).toBe(`Bearer ${SAMPLE_JWT}`);
|
|
129
|
+
} finally {
|
|
130
|
+
await stop(server);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('passes nested { user } through unchanged', async () => {
|
|
135
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
136
|
+
ok: true, status: 200,
|
|
137
|
+
text: async () => JSON.stringify({ user: { id: 'u-2', email: 'c@d.com' } }),
|
|
138
|
+
});
|
|
139
|
+
const startServer = mountRouter({ fetchImpl });
|
|
140
|
+
const { server, baseUrl } = await startServer();
|
|
141
|
+
try {
|
|
142
|
+
const json = await (await fetch(`${baseUrl}/api/account/profile`)).json();
|
|
143
|
+
expect(json.user).toEqual({ id: 'u-2', email: 'c@d.com' });
|
|
144
|
+
} finally {
|
|
145
|
+
await stop(server);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('GET /api/account/balance', () => {
|
|
151
|
+
test('proxies to /account/profile and returns the body verbatim', async () => {
|
|
152
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
153
|
+
ok: true, status: 200,
|
|
154
|
+
text: async () => JSON.stringify({ balance: 12.34, plan: 'pro' }),
|
|
155
|
+
});
|
|
156
|
+
const startServer = mountRouter({ fetchImpl });
|
|
157
|
+
const { server, baseUrl } = await startServer();
|
|
158
|
+
try {
|
|
159
|
+
const r = await fetch(`${baseUrl}/api/account/balance`);
|
|
160
|
+
const json = await r.json();
|
|
161
|
+
expect(json).toEqual({ balance: 12.34, plan: 'pro' });
|
|
162
|
+
expect(fetchImpl.mock.calls[0][0]).toBe(`${BACKEND_URL}/account/profile`);
|
|
163
|
+
} finally {
|
|
164
|
+
await stop(server);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('GET /api/account/keys', () => {
|
|
170
|
+
test('returns the backend response verbatim', async () => {
|
|
171
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
172
|
+
ok: true, status: 200,
|
|
173
|
+
text: async () => JSON.stringify({ apiKeys: [{ id: 'k1', name: 'CI', status: 'active' }] }),
|
|
174
|
+
});
|
|
175
|
+
const startServer = mountRouter({ fetchImpl });
|
|
176
|
+
const { server, baseUrl } = await startServer();
|
|
177
|
+
try {
|
|
178
|
+
const r = await fetch(`${baseUrl}/api/account/keys`);
|
|
179
|
+
const json = await r.json();
|
|
180
|
+
expect(json.apiKeys).toHaveLength(1);
|
|
181
|
+
expect(fetchImpl.mock.calls[0][0]).toBe(`${BACKEND_URL}/auth/apikeys`);
|
|
182
|
+
} finally {
|
|
183
|
+
await stop(server);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// ────────────────────────────────────────────────────────────────────
|
|
189
|
+
// Key create — input validation + one-time-reveal pass-through
|
|
190
|
+
// ────────────────────────────────────────────────────────────────────
|
|
191
|
+
describe('POST /api/account/keys', () => {
|
|
192
|
+
test('400 + bad_request when name is missing', async () => {
|
|
193
|
+
const fetchImpl = jest.fn();
|
|
194
|
+
const startServer = mountRouter({ fetchImpl });
|
|
195
|
+
const { server, baseUrl } = await startServer();
|
|
196
|
+
try {
|
|
197
|
+
const r = await fetch(`${baseUrl}/api/account/keys`, {
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers: { 'Content-Type': 'application/json' },
|
|
200
|
+
body: JSON.stringify({}),
|
|
201
|
+
});
|
|
202
|
+
expect(r.status).toBe(400);
|
|
203
|
+
const json = await r.json();
|
|
204
|
+
expect(json.code).toBe(ERROR_CODES.BAD_REQUEST);
|
|
205
|
+
expect(fetchImpl).not.toHaveBeenCalled();
|
|
206
|
+
} finally {
|
|
207
|
+
await stop(server);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('400 + bad_request when name is whitespace-only', async () => {
|
|
212
|
+
const startServer = mountRouter({ fetchImpl: jest.fn() });
|
|
213
|
+
const { server, baseUrl } = await startServer();
|
|
214
|
+
try {
|
|
215
|
+
const r = await fetch(`${baseUrl}/api/account/keys`, {
|
|
216
|
+
method: 'POST',
|
|
217
|
+
headers: { 'Content-Type': 'application/json' },
|
|
218
|
+
body: JSON.stringify({ name: ' ' }),
|
|
219
|
+
});
|
|
220
|
+
expect(r.status).toBe(400);
|
|
221
|
+
} finally {
|
|
222
|
+
await stop(server);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test('forwards trimmed name + optional expiresIn, returns one-time key', async () => {
|
|
227
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
228
|
+
ok: true, status: 201,
|
|
229
|
+
text: async () => JSON.stringify({
|
|
230
|
+
message: 'API key generated successfully',
|
|
231
|
+
apiKey: { id: 'k-new', name: 'mykey', key: 'lx_secretvalue', createdAt: '2026-05-11', expiresAt: null },
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
const startServer = mountRouter({ fetchImpl });
|
|
235
|
+
const { server, baseUrl } = await startServer();
|
|
236
|
+
try {
|
|
237
|
+
const r = await fetch(`${baseUrl}/api/account/keys`, {
|
|
238
|
+
method: 'POST',
|
|
239
|
+
headers: { 'Content-Type': 'application/json' },
|
|
240
|
+
body: JSON.stringify({ name: ' mykey ', expiresIn: 30 }),
|
|
241
|
+
});
|
|
242
|
+
expect(r.status).toBe(201);
|
|
243
|
+
const json = await r.json();
|
|
244
|
+
expect(json.apiKey.key).toBe('lx_secretvalue');
|
|
245
|
+
const sentBody = JSON.parse(fetchImpl.mock.calls[0][1].body);
|
|
246
|
+
expect(sentBody.name).toBe('mykey');
|
|
247
|
+
expect(sentBody.expiresIn).toBe(30);
|
|
248
|
+
} finally {
|
|
249
|
+
await stop(server);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// ────────────────────────────────────────────────────────────────────
|
|
255
|
+
// Key revoke
|
|
256
|
+
// ────────────────────────────────────────────────────────────────────
|
|
257
|
+
describe('DELETE /api/account/keys/:id', () => {
|
|
258
|
+
test('rejects an id with unsafe characters before hitting the backend', async () => {
|
|
259
|
+
const fetchImpl = jest.fn();
|
|
260
|
+
const startServer = mountRouter({ fetchImpl });
|
|
261
|
+
const { server, baseUrl } = await startServer();
|
|
262
|
+
try {
|
|
263
|
+
// Express routes won't let `..` through directly, but
|
|
264
|
+
// `<script>` would. Either way, our regex blocks it.
|
|
265
|
+
const r = await fetch(`${baseUrl}/api/account/keys/bad%20id%21`, { method: 'DELETE' });
|
|
266
|
+
expect(r.status).toBe(400);
|
|
267
|
+
expect(fetchImpl).not.toHaveBeenCalled();
|
|
268
|
+
} finally {
|
|
269
|
+
await stop(server);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test('happy path proxies the revoke', async () => {
|
|
274
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
275
|
+
ok: true, status: 200,
|
|
276
|
+
text: async () => JSON.stringify({ message: 'API key revoked successfully' }),
|
|
277
|
+
});
|
|
278
|
+
const startServer = mountRouter({ fetchImpl });
|
|
279
|
+
const { server, baseUrl } = await startServer();
|
|
280
|
+
try {
|
|
281
|
+
const r = await fetch(`${baseUrl}/api/account/keys/abc-123_XYZ`, { method: 'DELETE' });
|
|
282
|
+
expect(r.status).toBe(200);
|
|
283
|
+
const [url, opts] = fetchImpl.mock.calls[0];
|
|
284
|
+
expect(url).toBe(`${BACKEND_URL}/auth/apikey/abc-123_XYZ`);
|
|
285
|
+
expect(opts.method).toBe('DELETE');
|
|
286
|
+
} finally {
|
|
287
|
+
await stop(server);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// ────────────────────────────────────────────────────────────────────
|
|
293
|
+
// Handoff URL
|
|
294
|
+
// ────────────────────────────────────────────────────────────────────
|
|
295
|
+
describe('POST /api/account/handoff', () => {
|
|
296
|
+
test('mints token via backend and returns autopilot portal URL with handoff query', async () => {
|
|
297
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
298
|
+
ok: true, status: 200,
|
|
299
|
+
text: async () => JSON.stringify({ handoff: 'handoff-token-xyz' }),
|
|
300
|
+
});
|
|
301
|
+
const startServer = mountRouter({ brand: 'autopilot', fetchImpl });
|
|
302
|
+
const { server, baseUrl } = await startServer();
|
|
303
|
+
try {
|
|
304
|
+
const r = await fetch(`${baseUrl}/api/account/handoff`, {
|
|
305
|
+
method: 'POST',
|
|
306
|
+
headers: { 'Content-Type': 'application/json' },
|
|
307
|
+
body: JSON.stringify({ destination: 'payment' }),
|
|
308
|
+
});
|
|
309
|
+
expect(r.status).toBe(200);
|
|
310
|
+
const json = await r.json();
|
|
311
|
+
expect(json.url).toBe('https://autopilot.loxia.ai/payment?handoff=handoff-token-xyz');
|
|
312
|
+
const fetchOpts = fetchImpl.mock.calls[0][1];
|
|
313
|
+
expect(fetchOpts.method).toBe('POST');
|
|
314
|
+
expect(JSON.parse(fetchOpts.body).purpose).toBe('portal-payment');
|
|
315
|
+
} finally {
|
|
316
|
+
await stop(server);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test('switches portal host for OnBuzz brand', async () => {
|
|
321
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
322
|
+
ok: true, status: 200,
|
|
323
|
+
text: async () => JSON.stringify({ handoff: 'tok' }),
|
|
324
|
+
});
|
|
325
|
+
const startServer = mountRouter({ brand: 'onbuzz', fetchImpl });
|
|
326
|
+
const { server, baseUrl } = await startServer();
|
|
327
|
+
try {
|
|
328
|
+
const json = await (await fetch(`${baseUrl}/api/account/handoff`, {
|
|
329
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}',
|
|
330
|
+
})).json();
|
|
331
|
+
expect(json.url.startsWith(__test__.PORTAL_URLS_BY_BRAND.onbuzz)).toBe(true);
|
|
332
|
+
} finally {
|
|
333
|
+
await stop(server);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test('falls back to "payment" when destination is unknown (closed allowlist)', async () => {
|
|
338
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
339
|
+
ok: true, status: 200,
|
|
340
|
+
text: async () => JSON.stringify({ handoff: 'tok' }),
|
|
341
|
+
});
|
|
342
|
+
const startServer = mountRouter({ fetchImpl });
|
|
343
|
+
const { server, baseUrl } = await startServer();
|
|
344
|
+
try {
|
|
345
|
+
const json = await (await fetch(`${baseUrl}/api/account/handoff`, {
|
|
346
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
347
|
+
body: JSON.stringify({ destination: '../evil' }),
|
|
348
|
+
})).json();
|
|
349
|
+
// Unknown destination falls back to /payment, NOT echoed as /../evil
|
|
350
|
+
expect(json.url).toContain('/payment?handoff=');
|
|
351
|
+
expect(json.url).not.toContain('evil');
|
|
352
|
+
} finally {
|
|
353
|
+
await stop(server);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test('502 when backend response lacks handoff field', async () => {
|
|
358
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
359
|
+
ok: true, status: 200, text: async () => JSON.stringify({ something_else: 'x' }),
|
|
360
|
+
});
|
|
361
|
+
const startServer = mountRouter({ fetchImpl });
|
|
362
|
+
const { server, baseUrl } = await startServer();
|
|
363
|
+
try {
|
|
364
|
+
const r = await fetch(`${baseUrl}/api/account/handoff`, {
|
|
365
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}',
|
|
366
|
+
});
|
|
367
|
+
expect(r.status).toBe(502);
|
|
368
|
+
} finally {
|
|
369
|
+
await stop(server);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// ────────────────────────────────────────────────────────────────────
|
|
375
|
+
// Backend error translation
|
|
376
|
+
// ────────────────────────────────────────────────────────────────────
|
|
377
|
+
describe('proxy error envelopes', () => {
|
|
378
|
+
test('non-OK response is converted to { success:false, code:backend_error }', async () => {
|
|
379
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
380
|
+
ok: false, status: 500,
|
|
381
|
+
text: async () => JSON.stringify({ error: 'something broke' }),
|
|
382
|
+
});
|
|
383
|
+
const startServer = mountRouter({ fetchImpl });
|
|
384
|
+
const { server, baseUrl } = await startServer();
|
|
385
|
+
try {
|
|
386
|
+
const r = await fetch(`${baseUrl}/api/account/profile`);
|
|
387
|
+
expect(r.status).toBe(500);
|
|
388
|
+
const json = await r.json();
|
|
389
|
+
expect(json).toEqual({
|
|
390
|
+
success: false,
|
|
391
|
+
error: 'something broke',
|
|
392
|
+
code: ERROR_CODES.BACKEND_ERROR,
|
|
393
|
+
});
|
|
394
|
+
} finally {
|
|
395
|
+
await stop(server);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test('404 maps to code:not_found', async () => {
|
|
400
|
+
const fetchImpl = jest.fn().mockResolvedValue({
|
|
401
|
+
ok: false, status: 404,
|
|
402
|
+
text: async () => JSON.stringify({ error: 'nope' }),
|
|
403
|
+
});
|
|
404
|
+
const startServer = mountRouter({ fetchImpl });
|
|
405
|
+
const { server, baseUrl } = await startServer();
|
|
406
|
+
try {
|
|
407
|
+
const r = await fetch(`${baseUrl}/api/account/keys`);
|
|
408
|
+
expect(r.status).toBe(404);
|
|
409
|
+
const json = await r.json();
|
|
410
|
+
expect(json.code).toBe(ERROR_CODES.NOT_FOUND);
|
|
411
|
+
} finally {
|
|
412
|
+
await stop(server);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test('network failure becomes 503 + code:network_error', async () => {
|
|
417
|
+
const fetchImpl = jest.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
418
|
+
const startServer = mountRouter({ fetchImpl });
|
|
419
|
+
const { server, baseUrl } = await startServer();
|
|
420
|
+
try {
|
|
421
|
+
const r = await fetch(`${baseUrl}/api/account/profile`);
|
|
422
|
+
expect(r.status).toBe(503);
|
|
423
|
+
const json = await r.json();
|
|
424
|
+
expect(json.code).toBe(ERROR_CODES.NETWORK_ERROR);
|
|
425
|
+
} finally {
|
|
426
|
+
await stop(server);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract test: methods that `webServer.js` calls on `ApiKeyManager`
|
|
3
|
+
* MUST exist on the real class.
|
|
4
|
+
*
|
|
5
|
+
* Bug history this guards against:
|
|
6
|
+
* - 2026-05: webServer's /api/auth/signout called
|
|
7
|
+
* `apiKeyManager.removeKeys(null)` but the real method is
|
|
8
|
+
* `removeSessionKeys`. Sign-out 500'd at runtime. The existing
|
|
9
|
+
* `authRoutes.test.js` happened to pass because it built its own
|
|
10
|
+
* mock `apiKeyManager` with the wrong method names — the mock and
|
|
11
|
+
* the production caller agreed with each other, but neither agreed
|
|
12
|
+
* with the real class. Same drift hit /auth/callback's `setKeys`
|
|
13
|
+
* call, which silently failed to persist API keys from OAuth.
|
|
14
|
+
*
|
|
15
|
+
* This file imports the REAL ApiKeyManager and asserts each method
|
|
16
|
+
* webServer.js calls is a function on it. Cheap to maintain — when
|
|
17
|
+
* webServer starts calling a new method, add it here.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { describe, test, expect } from '@jest/globals';
|
|
21
|
+
import ApiKeyManager from '../../services/apiKeyManager.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Every ApiKeyManager method invoked from webServer.js production paths.
|
|
25
|
+
* Update this list when webServer.js starts using a new method.
|
|
26
|
+
*/
|
|
27
|
+
const REQUIRED_METHODS = Object.freeze([
|
|
28
|
+
'setSessionKeys', // /auth/callback, remote-session bootstrap
|
|
29
|
+
'removeSessionKeys', // /api/auth/signout
|
|
30
|
+
'getKeysForRequest', // /api/auth/status, /api/auth/resolve, every AI call
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
describe('ApiKeyManager contract (methods called by webServer.js)', () => {
|
|
34
|
+
const instance = new ApiKeyManager(/* logger */ null);
|
|
35
|
+
|
|
36
|
+
test.each(REQUIRED_METHODS)('exposes %s as a function', (methodName) => {
|
|
37
|
+
expect(typeof instance[methodName]).toBe('function');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -53,7 +53,7 @@ function buildAuthApp({ apiKeyManager, broadcastToSession, config, logger, fetch
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (apiKey && apiKeyManager) {
|
|
56
|
-
await apiKeyManager.
|
|
56
|
+
await apiKeyManager.setSessionKeys(null, { loxiaApiKey: apiKey });
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
ctx.lastAuthResult = {
|
|
@@ -137,7 +137,7 @@ function buildAuthApp({ apiKeyManager, broadcastToSession, config, logger, fetch
|
|
|
137
137
|
app.post('/api/auth/signout', async (req, res) => {
|
|
138
138
|
try {
|
|
139
139
|
if (apiKeyManager) {
|
|
140
|
-
await apiKeyManager.
|
|
140
|
+
await apiKeyManager.removeSessionKeys(null);
|
|
141
141
|
}
|
|
142
142
|
ctx.lastAuthResult = null;
|
|
143
143
|
broadcastToSession(null, {
|
|
@@ -177,8 +177,8 @@ function buildAuthApp({ apiKeyManager, broadcastToSession, config, logger, fetch
|
|
|
177
177
|
function makeApiKeyManager(initialKey = null) {
|
|
178
178
|
let storedKey = initialKey;
|
|
179
179
|
return {
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
setSessionKeys: jest.fn(async (sessionId, keys) => { storedKey = keys.loxiaApiKey; }),
|
|
181
|
+
removeSessionKeys: jest.fn(async () => { storedKey = null; }),
|
|
182
182
|
getKeysForRequest: jest.fn(() => storedKey ? { loxiaApiKey: storedKey } : {}),
|
|
183
183
|
_peek: () => storedKey
|
|
184
184
|
};
|
|
@@ -254,7 +254,7 @@ describe('Auth Routes (webServer.js)', () => {
|
|
|
254
254
|
expect(await res.text()).toContain('Authenticated!');
|
|
255
255
|
|
|
256
256
|
// Verify API key was stored
|
|
257
|
-
expect(apiKeyManager.
|
|
257
|
+
expect(apiKeyManager.setSessionKeys).toHaveBeenCalledWith(null, { loxiaApiKey: 'lx_generated_key_123' });
|
|
258
258
|
|
|
259
259
|
// Verify broadcast
|
|
260
260
|
const broadcast = broadcasts[0];
|
|
@@ -438,14 +438,14 @@ describe('Auth Routes (webServer.js)', () => {
|
|
|
438
438
|
|
|
439
439
|
const body = await (await fetch(`${baseUrl}/api/auth/signout`, { method: 'POST' })).json();
|
|
440
440
|
expect(body.success).toBe(true);
|
|
441
|
-
expect(apiKeyManager.
|
|
441
|
+
expect(apiKeyManager.removeSessionKeys).toHaveBeenCalledWith(null);
|
|
442
442
|
expect(apiKeyManager._peek()).toBeNull();
|
|
443
443
|
expect(ctx.lastAuthResult).toBeNull();
|
|
444
444
|
expect(broadcasts[0].msg.type).toBe('auth_signout');
|
|
445
445
|
});
|
|
446
446
|
|
|
447
|
-
it('returns 500 when
|
|
448
|
-
const apiKeyManager = {
|
|
447
|
+
it('returns 500 when removeSessionKeys throws', async () => {
|
|
448
|
+
const apiKeyManager = { removeSessionKeys: jest.fn().mockRejectedValue(new Error('vault locked')) };
|
|
449
449
|
const app = buildAuthApp({ apiKeyManager, broadcastToSession, config: {}, logger, fetchImpl: mockFetch, ctx });
|
|
450
450
|
const { server: s, baseUrl } = await startServer(app);
|
|
451
451
|
server = s;
|