{"_id":"npx-import","_rev":"16-22e18a309e10ee85414564572bb7e94f","name":"npx-import","dist-tags":{"latest":"1.1.4","wip":"1.0.5-0"},"versions":{"0.0.0":{"name":"npx-import","version":"0.0.0","description":"NPX import: dynamically install & import packages at runtime, using NPX.","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/import-on-demand","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7"},"types":"./lib/index.d.ts","gitHead":"211c4eb22e84b89835c9e79d64a5e4d7a7ead6e4","_id":"npx-import@0.0.0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-yARGfyhC0tjU6DnjDQESWfw5+Kx4736vEMrV2nVwFTbl6iIdyXuv7uA/nn2rkQUlobSqT/VjawJAYwfqzq53wA==","shasum":"32d378dff9a6963fc45e27812fb19b90d8844341","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-0.0.0.tgz","fileCount":18,"unpackedSize":33446,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICeEzntwAaiLQFTApUdDeEijCXi6GkBO3Qz+/E8kG9x4AiBZeumJIR1WzqVG4RxY640rNSs9p/ZsG2bR4ad5vC8jhw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6rVnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqJvhAAlpx5uDzMChUdfptKQ/sAbyAZEpINKVSyf65naCiAo05sO66k\r\nzEXyJ4XV8wngt9+/eZMzgFEb6Y65aQuOHJSEmFZCvMU6SWneOZ+EvzAVH4PH\r\neLYdajN+Kp2apUardHtD2mrujlR4rtSL4w/vMIHNbGEF6EVK74GfnL57dgfg\r\nqftviaNC093CG1Us+IsUNaNRilK1/E/9LPt4uGxpGQulSOIWKXYlt2TGzdsN\r\nhkvmsyar4F8JMg2Ay7uQO0mAmtPzFBpAyIwO6iJtJ6nu/2ZMkGkL6PynV8Aj\r\nsLigEsFYlnDZ1I9ajvVJvvfHMZ3ZrzE+BRBDmsbKbNBjCcOUj/g0xLlHLSDQ\r\nzycd9RCLqoKB4EA9GWl0wliYGVitJJggyVOGqydCHe4p52yKp6l1gUsaoFBH\r\nX5xM5oV6kDRjJXrG4yP4SrEOJfqaCDkiL6dmhAK8zb8vDuUyWUrNP6zagkyL\r\n2J5EdatbIb+xdexiV7w6Xn87I/z5x8li+Xx6U/deWuQcXOZBKKVNlwtOPeod\r\n3EiItD5PjQWwuJ4s5aHYf2WE4NWRzw1ArjmmIawBw8nygdSGIIUmqmMqYhVD\r\nULDjEd1M4ut93cprzSeXJg40etJPrVU8B0neeRE/Ilo9TILFtmcAUgt0O1PH\r\ncUpH9My4h2zPsCmvZ8BTqn0cyvRqYSoy1B8=\r\n=w0GV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_0.0.0_1659549031695_0.7802911418441354"},"_hasShrinkwrap":false},"0.0.1":{"name":"npx-import","version":"0.0.1","description":"NPX import: dynamically install & import packages at runtime, using NPX.","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/import-on-demand","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"78176b425295e4023cb3aa29f83df534c2c36f96","_id":"npx-import@0.0.1","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-qNtbYu82iI0KPzcNWcnFh2fbfKu1d1wqSfuMVKnxnOv8fUISVMWvMXODx+sGkUxZ76x5DxYQQGJGZTmeM/ADwg==","shasum":"79b209e853f08550ac3d77baa3992045b6a01324","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-0.0.1.tgz","fileCount":18,"unpackedSize":50198,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEjlD0oFXhX2IL0++ObjGGa9z2rbMmstinsk6Hbv3lS7AiA+Ns6dYNqcJtNYHqApSXF/IcnvrQw8KWq2rOlAa4U3LQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi666VACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpCAw//SebJP4xukqLv3s1rYuTqtu6uyWyZKsaQ2XLGmMBtH8i4zUQD\r\nAwH2lsPHdSrTjEIpxWrEwOKH1Tvo98aQRRQCcebz3XpY9be3s8zr8/OOtzG/\r\nIoTNFiiYeg4c1BS9e31yx0npKL/cS0h/MtBTDmZlj6qT2tI47l0J1LhrVp2g\r\n595XD/6zFZ0XtAJIdechDGLXs3bpl6TFXW3Y1z7M7vwZUAeT8M2Q0rORu7Yp\r\nCc3gx4z6IoFwtpCkiUd5e365TCdendxG4Axt3Y1oU3Cwu19LiYeV8EuuYFIJ\r\nG7Pb2HbVWWcm/b6vqRScPs2q8PUtEuxSj5wKNP7ER0YHkMvf45iO1VmjB4VA\r\nELzRKpa0mXYKpM8LPKqAHvIwZYBgSkrU8lEW5d3utngzkbsXplERBJdWPmcN\r\nn9/LdvQ5o196oIGa/poW5uWb4Ut6ThvWws6tK0SzGXxV5YwL40mGz+Vi/1fk\r\nn7Nh7/3Jeopy2CPfPol2tgCRTO2cHOT9ttrsII1WzPEn25ksDD0/5RU/xcEQ\r\nck+Xyqa0sGUZYj4dXl66WCtIvfPBv0+ACTLsX9Rxswjknw+Rlz6SymZpHRQy\r\n/gMu3CzJC3WDax8g+1SOHdbOvsLF9b556eHcJ/3mNnQ8pc6MKIS4FO5v3PFg\r\nQ4IljW4Sw4Pgdw9JYO0ssZ0yvV76Knz1kfc=\r\n=Nw46\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_0.0.1_1659612821274_0.2189957559168627"},"_hasShrinkwrap":false},"0.0.2":{"name":"npx-import","version":"0.0.2","description":"NPX import: dynamically install & import packages at runtime, using NPX.","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/import-on-demand","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"49c7862852b5cab9fd97654ff6690fed073609ad","_id":"npx-import@0.0.2","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-RvOUomyn07E8KcBcfddoYuS07SJda5aqJ9kdAIyBlldL2yuCMJRMJ1kb2hPi+EJ2FFgtn5cv/NvFKw8wZmTakw==","shasum":"ba63e95428f6fc377fe489dd2e7cdae188c173d4","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-0.0.2.tgz","fileCount":18,"unpackedSize":55062,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDpNiJJ2kPKRVQIYiSpCJ9jbjvbmDWan+a+vXrObBzMZAiBGvJurgQ7O0Yn7RKVbuL0j1J3GM23FHiLJuqc5Qz8nZA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi68z9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrP7A//RrH6YYs6FmDwtgVZ1LZtFxFu77x/sh9gpKpjo2hEeHxu9LDa\r\nI3v0VwhqemVpreptgalKqhUrtFSedvvXW49VzNbmyb4pdFBZ82xiKC/qwleW\r\nXswYjAo+MIoBGHEYTWf7w2Kpy1dDVOSg06JAeARh9Xc4GtcysA78QxM1bA7d\r\nrn8ukj/zW1FPDYRSqKONLBjXApvEm3pjZJAX4zLqrAoiMVpYcR1q1/ktPQJF\r\nTuJ3NLdewH4s1faZqYqAuwuSk7/s2n01i+RSL7mb/l9Zt7iHVi1TxvSPGdPC\r\n195Hwlk0YXSWmpGbrzTR+JYQ0k8kSVt7eNUEEQHQUDs40k+4LfBtJhl2vtim\r\ny9PNg9332f+pJ3cdv6N52AUJUR2fdYrPtt+VjgsPbXMAd4+JKjg5jCx3JjNt\r\nRMiTc3jZWSYJDAy1FihpQsufeCCnSnDLcHIaQtla6HfOw3Vo5qoe6zCMiF7O\r\nHZRIOolawdAV4ccSMFJA40L3LcgImppKJYWCqajlkDAgbbUOJXvea09JaYta\r\nSzMpFzYBVYuzZ1OB1H+esT6RxGWuv7TnpNjztuvy3BIreYXkcDKq+RF61mOm\r\nR1hXqGQDwiIOHZEmu7ft/UrIYRhwCHwtFAJS54jASYv0CB5KeQbIR5IXLx6t\r\nWbymbbQSzPdJByAHwbU22M45+r4J7HtmSJw=\r\n=kiDW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_0.0.2_1659620605410_0.05607450394557745"},"_hasShrinkwrap":false},"1.0.0":{"name":"npx-import","version":"1.0.0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"e27a6def89350892477a53121a78d736dadc31bd","_id":"npx-import@1.0.0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-hxUjLjCpXEHEWazNBhwzAF1JG29rVYy9s3ED89r73E+KTQoG0Mr0LP//YCvcVd0WPQoE3cHSl4kxyKkv3tqwhw==","shasum":"50856ca50c18a276a5257773ea105978733bd588","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.0.tgz","fileCount":18,"unpackedSize":55097,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFOnHUf+5sFVt/yJ9bpIHyGBz+y+ErAXucfb6e7fMeSBAiB3Th9pVD4CWjYdrm+AOSe7v8rQZJCvp1dGIJjyq1nivQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi692iACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqJERAAkBSblMsdSFSZD9ykkNad/P/Aubiypxt0aafOzqjMYjOhN1Xl\r\nqLS2LDwWPAUIFebfwy+ohpacm61FxVL6K/xRe0iQ3ayaUJ2YUcd7ETHQ1eAQ\r\n/y1U8eJ5mTv+hYHchUgzG3pDv60LtVoNhtRq7lfxkxZgQcZISu+HWObotJ3t\r\nOaxRq3JnV9wD7ViOEOcZgUwOK9KetbiqpE/Ny7FWj9tT6rM/4BdOkX9SA2aH\r\nJEnPuCbiu62RylE+/Yo59aybaSouaAkNHg/Q8U9BWaK/OKTSobSdzJXC2gvc\r\nv13T+nwfD5Ya5TF6PkPCvfCcsm/C6GIjzQoKZmgmWtztuBmk+v4MdQUHp8ok\r\nhSkP9m9wjb1HsB2wn0B0glirL96vVZZN4SoEx8HtEeUReM6lTba1CDjGBPbK\r\n4y5hpnZlvs7k7VyK4+gLz9b2EMVZibBu8J8ycRGMfdr8kbXC7eRteAmmIoYP\r\nAqjet6pezTQKQSCW7R8Vuhs70c1+KT6DE4gE5gKSZ//LrsLJDOKESSjlIzci\r\narsHnU8JXp1iBsaUExEDxGPxtEJbbw7MTlYHUDXEzqGX8gLoJT+OC91Tmu2t\r\nqDhTtYyFP/xaKIjjloHGkbYcelYIoKnDoD5+lIBp+vmpmIGlJ9yOOgjQ+v8C\r\nTrZXlKkIloZvEDDuPpOVc/BbhqfJuo9etN8=\r\n=zS/t\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.0_1659624866654_0.0617971704296143"},"_hasShrinkwrap":false},"1.0.1":{"name":"npx-import","version":"1.0.1","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"777ce2b20bf03d2c737e2cd1b5dfbb2d9c1adb7f","_id":"npx-import@1.0.1","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-18VBe1C7T4pPv/eojvIcll8cgfS0G6mN+WmpGi5rDrB6YUqriwWShpt+uGUytY/KKpu3VgnjRvfbkpwX2FNe2Q==","shasum":"c8a1f58725c2acd328e2b8b0f3b9604bcc644273","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.1.tgz","fileCount":18,"unpackedSize":58005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDBUjErrJGko71jjvbWMHGm6houiNCK4HoZamxKrtHbLAIgFL0+vBUZ/X9BpMyW0r6kBj6ejbzHscHvh+maF6/FVSo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi7PyIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmro4xAAlhF26mjDyUpeP3g3ofYvpQxDFCkytrmMDm610y9Og3Q1aEsF\r\nMvJNzrwWXW3dGSy57aEEv1KqJHDPwc/R+N7QWoMOtNQHjqKXPpCP9hf8HY4k\r\nne8vcbns+XEC5Q7L+1qkET/ppBxsZ5pqGCYRdP9er2Fz/933YR0imG0lFZVo\r\ntYHg6Z0CAzfYPZsHacuAvtJt1HuVJfllVGRCRyRnfZpv18/4wV65WneUA+8l\r\nf6u/1CRJAW46TtkvhTrxScDsjdAv2HA6w5GohVJKGxhPKqaGv19xpqIK3oAt\r\ncLuBApkjDBkgIekIFaaRIMRUHTFL8QlJNzuT+Wb/gyTIfNnltMoASlbQK11Z\r\n+HlQn/MEMgoSkiXjazajNqoJLeso2MkJB5Xuc5UajxX9LsFbUF+MmbQO6i+I\r\noD7714RKyF7hgOorR9cxWecTfLrc0Fx5Tcnl7DUJPDX5YgOsIvs2wXSjeJvC\r\nvvBlDeS5IMMD7iWB1bWfGyrpvDs9cwYOSZ2zYYZsDMDQr1I6loa0q7d/vEVH\r\neABSwaJzEKFYk2wZzAjSlS6ySrR/9QQ5e1LGQkHtBj3IpXKw5T0WncIpOwaQ\r\nnRSVSG9cK2Mc5/4a8Fp5LsbyjJu0i5IRO8oDwLvNLfYB5JX3LN26DDLYIWhz\r\nswH28K5ewqg6ceelM65I8krH8sQux7aDD1E=\r\n=pmuA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.1_1659698312222_0.11080637141781668"},"_hasShrinkwrap":false},"1.0.2":{"name":"npx-import","version":"1.0.2","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"237eec8bcd59f4ed7bfbeea4907083f56e4c516e","_id":"npx-import@1.0.2","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-T5h3UmkdaGsLrS5rMug7PeWNMmXbe2Cz3BOdA4AorBVANRh0ZFUE+/Fcm34wFleXEx6kFJBo1BGvmsqWn6mW3Q==","shasum":"73c644afc1bc5f3df16b392ec486a28fdbb8ddce","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.2.tgz","fileCount":18,"unpackedSize":58017,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHh4Vq+c4lsXuO/DCOe5GJY+xK5T4O0H5TRPiJq3vWfEAiAWKfirnobupGaLGBvgkvKBzk0j54TILgpyP8FFaX2LGw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi8kA3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrrpA//RYVCg40A35eMoAbySTbAZthD7tNkcp1l53G77cxpilNoBPuh\r\nYPW6QhXsLVHsGNl8nzAVPXAogQnMaJrjtr9S9nh6eFWFiKzXYwLYS/tcmxGN\r\nGHYpfze+hdvi+uzBB/AoByG2KVOFvOVnNUiDmbjirKNOk5UU//tGMvCuH1wC\r\n4n6Uig3DJmmn3hPIBRm06VzRNFjmCGUO8Bhb8mjtUtEO31e6QxdMVARvoJEm\r\nyhLIqYj//lb3pb2iNmIBRhnC7GzNEKf/monaEO6Rwk4FXRYjuBcIilJQo0T9\r\nJbrxKCIUayaU8bEO9qBwW78FMgALgZnfWqMMqEBSHqU66BsOp5c6HL0gW4n9\r\nivdmJjYivQTeRyrE8z+B9KIHQij411SPyb8kCa/BTjc/LO9lPLNBn3Bwi4OF\r\nQZUmHz7bRnumS+qMIKhbFqHU9gg7RbYIX7oAqcRmxN9vzQ5Bi8FeDGEg1aR4\r\nJYrPzQ1+VJQYB7fOvAtqIE9gK0ggLQIDCCupGHiLKmDqoHEQGDu4slYHkaZ6\r\nubbqGqFW1AlSjWZkXXcsU70e29t53oE646WJDcFnNOx+HmDB1joMVDT5Rvci\r\nsQTQRKOBB1XIX7tJXk4v+bR0X9qa3WX2etkurTtmM0lfrlQ0NjKC3rcBaZLL\r\nXvWRwLo+W5MWzmwMjlmwJnhgxwD2Bfh5+Wk=\r\n=+Rak\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.2_1660043319696_0.2283248731466212"},"_hasShrinkwrap":false},"1.0.3-0":{"name":"npx-import","version":"1.0.3-0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","readme":"# 🧙‍♂️ `npx-import` 🧙‍♀️\n\n### Runtime dependencies, installed _as if by magic_ ✨\n\n[![twitter](https://img.shields.io/badge/@glenmaddern-blue.svg?style=flat&logo=twitter&label=​)](https://twitter.com/glenmaddern)&nbsp; [![GitHub last commit](https://img.shields.io/github/last-commit/geelen/npx-import?logo=github&style=flat&label=​)](https://github.com/geelen/npx-import)&nbsp; [![npm](https://img.shields.io/npm/v/npx-import?label=​&logo=npm)](https://www.npmjs.com/package/npx-import) \n\n`npx-import` can be used as a drop-in replacement for [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import):\n\n```ts\nimport { npxImport } from 'npx-import'\n\n// If big-dep isn't installed locally, npxImport will try\n// to download, install & load it, completely seamlessly.\nconst dependency = await npxImport('big-dep')\n```\n\nIt's exactly like [`npx`](https://docs.npmjs.com/cli/v8/commands/npx), but for `import()`! <sub><sub><sup>(hence the name)</sup></sub></sub>\n\nIs this a good idea? See [FAQ](#faq) below.\n\n## Usage\n\n`npx-import` is ideal for deferring installation for dependencies that are unexpectedly large, require native compilation, or not used very often (or some combination thereof), for example:\n\n```ts\n// Statically import small/common deps as normal\nimport textRenderer from 'tiny-text-renderer'\n\n// Use npxImport to defer\nimport { npxImport } from 'npx-import'\n\nexport async function writeToFile(report: Report, filename: string) {\n\n  if (filename.endsWith('.png')) {\n    console.log(`This is a PNG! We'll have to compile imagemagick!`)\n    const { default: magick } = await npxImport('imagemagick-utils@^1.1.0')\n    await magick.renderToPNG(report, filename)\n\n  } else if (filename.endsWith('.pdf')) {\n    console.log(`Argh, a PDF!? Go make a cuppa, this'll take a while...`)\n    const { default: pdfBoi } = await npxImport('chonk-pdf-boi@3.1.4')\n    await pdfBoi.generate(report, filename)\n\n  } else {\n    console.log(`Writing to ${filename}...`)\n    await textRenderer.write(report, filename)\n  }\n  console.log(`Done!`)\n}\n```\n\nWhen run, `npx-import` will log out some explanation, as well as instructions for installing the dependency locally & skipping this step in future:\n\n```\n❯ node ./index.js --filename=image.png\n\nThis is a PNG! We'll have to compile imagemagick!\n[NPXI] imagemagick-utils not available locally. Attempting to use npx to install temporarily.\n[NPXI] Installing... (npx -y -p imagemagick-utils@^1.1.0)\n[NPXI] Installed into /Users/glen/.npm/_npx/8cac855b1579fd07/node_modules.\n[NPXI] To skip this step in future, run: pnpm add -D imagemagick-utils@^1.1.0\nDone!\n```\n\nFor some types of dependencies, this is a much better UX than the alternatives:\n\n- You either add `imagemagick-utils` & `chonk-pdf-boi` as dependencies, slowing down initial install.\n- The first time a user tries to export a PNG/PDF, you error out with instructions to install the relevant package and retry.\n- You pause, prompt the user for confirmation, then try to detect which package manager they're using and auto-install the dependency for them.\n\nThe last of these generally works well but `npx-import` has slightly different properties:\n\n- The user doesn't need to be prompted—if the dependency can be sourced, installed & transparently included, the program doesn't need to be interrupted.\n- Your user's current project directory is never altered as a side-effect of running a program.\n\nMost importantly, though, **it's compatible with `npx`!** For example, `npx some-cli --help` can be super fast but `npx some-cli export --type=pdf` can transparently download the required dependencies during execution. It's super neat!\n\n## Installation\n\n```\nnpm install --save npx-import\npnpm add -P npx-import\nyarn add npx-import\n```\n\n## Typescript\n\nJust like `import()`, the return type default to `any`. But you can import the types of a devDependency without any consumers of your package needing to download it at installation time.\n\n```\npnpm add -D big-dep\n```\n\n```ts\nimport { npxImport } from 'npx-import'\ntype BigDepType = typeof import('big-dep')\n\nconst bigDep = await npxImport<BigDepType>('big-dep')\n```\n\n## API\n\n* Since package versions are no longer tracked in your `package.json`, we recommend being explicit:\n\n```ts\nconst lazyDep = await npxImport('left-pad@1.3.0')\n```\n\nAny package specifier that's valid in `package.json` will work here: e.g. `^1.0.0`, `~2.3.0`, `>4.0.0`, `@latest`, `@next`, etc.\n\nNote: there is a speed benefit from using exact versions. `npxImport(pkg-a@1.2.3)` will run `npx --prefer-offline` under the hood, making it faster after the first run (since it doesn't first check the NPM registry for newer versions).\n\n* You can also install multiple packages at once:\n\n```ts\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'])\n```\n\n`npx-import` also takes a third argument, which lets you customise, or silence, the log output. Each line that would normally be printed is passed to the logger function:\n\n```ts\nconst grayLog = (line: string) => console.log(chalk.gray(line))\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'], grayLog)\n```\n\n* Use `npxResolve` instead of `require.resolve` to get the path (local or temporary)\n\n```ts\nexport function getSQLiteNativeBindingLocation() {\n  return path.resolve(\n    path.dirname(npxResolve(\"better-sqlite3\")),\n    \"../build/Release/better_sqlite3.node\"\n  );\n}\n```\n\nNote, `npxResolve` requires that you'd previously called `npxImport` for the same package.\n\n## FAQ\n\n### 🤔 Isn't this, like, a heroically bad idea?\n\nNah it's good actually.\n\n### 🤨 No but seriously, isn't using `npx` a big security hole?\n\nInitially, `npx` didn't prompt before downloading and executing a package, which was _definitely_ a security risk. But that's been [fixed since version 7](https://github.com/npm/npx/issues/9#issuecomment-786940691). Now, if you're intending to write `npx prettier` to format your code and accidentally type `npx prettomghackmycomputerpls`, you'll get a helpful prompt:\n\n```\n❯ npx prettier@latest\nNeed to install the following packages:\n  prettomghackmycomputerpls@6.6.6\nOk to proceed? (y)\n```\n\nThis gives the user a chance to see their mistake and prevent being hacked to bits.\n\n### 😠 But hang on, you're never prompting the user to confirm!\n\nAh yes, that seems to go against the previous point. But `npx-import` isn't being triggered from a potentially clumsy human on a keyboard, it's running inside some source code you've (by definition) already authorised to run on your machine.\n\n`npx-import` is an alternative to publishing these as normal dependencies of your project and having your users download them at install time. `npm install` doesn't prompt the user to approve every transitive dependency of what's being installed/run, so `npx-import` doesn't either.\n\n### 🧐 What if the user has already installed the dependency somewhere?\n\nThen `npxImport` short-circuits, returning the local version without logging anything out. This is what the user is instructed to do to \"skip this step in future\". In other words, `npxImport()` first tries to call your native `import()`, and only does anything if that fails.\n\nNote that this also works for multiple dependencies, `npxImport(['pkg-a', 'pkg-b', 'pkg-c'])` will only fetch & install those that are missing.\n\n### 🤪 Doesn't this mean dependencies gets repeatedly downloaded & installed?\n\nNo! `npx` maintains a cache in the user's home directory. If a cached package is found, `npx` will (by default) hit NPM to check if there's any new versions for that specifier, and if not, return the cache. `npxImport` adds a small optimisation—if you specify an exact package version (e.g. `@7.8.2`), it'll run `npx --prefer-offline` to skip the NPM check.\n\nSo new packages are only downloaded & installed when:\n\n* It's the first time a particular package/version combo is seen (see next section)\n* No locked version was provided and there's a new version on NPM\n\n### 😵‍💫 What about multiple projects? Doesn't the cache mean projects can clobber/overwrite/conflict with each other?\n\nAs it turns out, no! While I wasn't paying attention, `npx` got really smart! To understand why, we need to look at how `npx` works:\n\nFor starters, `npx some-pkg` is a shorthand for `npx -p some-pkg <command>`, where `<command>` is whatever `bin` that `some-pkg` declares. Often, the `<command>` and the package name are the same (e.g. `npx prettier`), but it's the `bin` field inside the package that's really being used. Otherwise, scoped packages (like `npx @11ty/eleventy`) would never work. If there's no `bin` field declared (e.g. for `chokidar`, you need `npx chokidar-cli`), or if there's more than one (e.g. for `typescript`, you need `npx -p typescript tsc`), you have to use the expanded form.\n\nBut there's no requirement that `<command>` is a `bin` inside the package at all! It can be any command (at least for `npx`, `pnpm dlx` and `yarn dlx` have different restrictions), for example, we can inject a `node -e` command and start to learn about what's going on:\n\n```\n❯ npx -y -p is-odd node -e 'console.log(process.env.PATH.split(\":\"))' | grep .npm/_npx\n  '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin',\n```\n\nUsing `process.env.PATH` and searching for `.npm/_npx` is, on OSX with NPX v8+, a reliable way to find out where `npx` is installing these temporary packages. Let's look inside:\n\n```\n❯ ll2 /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/\ndrwxr-xr-x    - glen  4 Aug 11:07  /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc\ndrwxr-xr-x    - glen  4 Aug 11:07 ├──  node_modules\n.rw-r--r--  780 glen  4 Aug 11:07 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:07 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:07 │  └──  is-odd\n.rw-r--r-- 1.4k glen  4 Aug 11:07 ├──  package-lock.json\n.rw-r--r--   51 glen  4 Aug 11:07 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/package.json\n{\n  \"dependencies\": {\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nThat looks like a pretty normal project directory to me!\n\n> Aside, `ll2` is my super rad alias for `exa --icons -laTL 2`. See [exa](https://github.com/ogham/exa).\n\nNow, the crucial bit: **every time `npx` runs for some unique set of packages it creates a new directory**. That goes for installing multiple deps at once but also for different named/pinned versions/tags for individual packages:\n\n```\n❯ export LOG_NPX_DIR=\"node -e 'console.log(process.env.PATH.split(\\\":\\\").filter(p => p.match(/\\.npm\\/_npx/)))'\"\n\n❯ npx -y -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@latest $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/ecc6e2260c717fec/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/c41e9ab9d1d9c43f/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@\\^3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e86896689f5aebbb/node_modules/.bin' ]\n```\n\nNote that **every one of these commands downloaded the same version of `is-odd`**, but because they were referenced using different identifiers, `_` vs `latest` vs `3.0.1` vs `>3.0.1`, `npx` played it safe and made a new temporary directory.\n\nFor multiple packages, the same rule applies, although order is not important:\n\n```\n❯ npx -y -p is-odd -p is-even $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ npx -y -p is-even -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ ll2 /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37  /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37 ├──  node_modules\n.rw-r--r-- 2.6k glen  4 Aug 11:37 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-buffer\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-even\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-odd\ndrwxr-xr-x    - glen  4 Aug 11:37 │  └──  kind-of\n.rw-r--r-- 4.8k glen  4 Aug 11:37 ├──  package-lock.json\n.rw-r--r--   76 glen  4 Aug 11:37 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/f9af4fded130fd33/package.json\n{\n  \"dependencies\": {\n    \"is-even\": \"^1.0.0\",\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nSo `npx` is doing exactly the same as an `npm install`, with a `package.json`, `package-lock.json`, `node_modules` etc. It's just dynamically creating directories based on some hash of its inputs. So the only way two projects can use the same package in the cache is if they _both_ ask for _exactly_ the same packages & versions. It's super clever!\n\n### 😐 But what about transitive deps? Won't you get duplication?\n\nSadly, yes. If both your package `main-pkg` and `util-a` depend on `util-b`, then calling `npxImport('util-a')` from within `main-pkg` will create a new directory with a second copy of `util-b`. If there are globals in that package, or if the version specifiers are slightly different, you could potentially have problems.\n\nIt's probably possible to [detect this in future](https://github.com/geelen/npx-import/issues/2) and warn/error out. But for now, I recommend using `npxImport` for mostly self-contained dependencies.\n\n### 🫤 What about version mismatch with local files?\n\nIf a user has `pkg-a` version `1.0.0` installed, but one of their packages calls `npxImport('pkg-a@^2.0.0')`, `npxImport` isn't smart enough ([yet](https://github.com/geelen/npx-import/issues/3)) to know that the local version of `pkg-a` doesn't match the version range specified (since it's using native `import()` under the hood). Without `npxImport`, the `npm install` step would have had a chance to bump the installed version of `pkg-a` to meet the requirements of _all_ packages being used, but we're bypassing that.\n\nThis will be fixed in a future version.\n\n### 🫠 What kind of packages would you use this for?\n\n- Anything with native extensions needing building (do that when you need it)\n- Packages with large downloads (e.g. puppeteer, sqlite-node)\n- CLI packages that want to make `npx my-cli --help` or `npx my-cli init` really fast and dependency-free, but also allow `npx my-cli <cmd>` to pull in arbitrary deps on-demand, without forcing the user to stop, create a local directory, and install dev dependencies.\n- Anything already making heavy use of `npx`. You're in the jungle, baby.\n\n---\n\nBuilt with <3 during a massive yak shave by Glen Maddern.\n","readmeFilename":"README.md","gitHead":"20d6ebaa4f1aa8c9d0547504b103e96c90758d13","_id":"npx-import@1.0.3-0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-vSUfxMxQkIK66Nw0iRjvtayuJPbodArRM3WXGZZoZXTTUtwlM1bAQILmcPIx9ZRqFXrgzWr5M7hdXHbzYE6x8A==","shasum":"5e9b43cb606afeb2146903653e7e3875f4c6f123","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.3-0.tgz","fileCount":18,"unpackedSize":62155,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkE1Hko1SUWVX8/65NfW2T1FXmNQme0W3PbmiopAOqugIhAIfKM1scSWd04lqbc2xUeBklylYf5U2h6KHWZqNiX5bI"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi83TyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo+ig//adxLZRSlFZjzyCf79H9MXWvpg7jT129b5r9/RkRfNXr6R18g\r\n+nazTC993emC9JqK2UuweQJGMKNPSnucs6/uTLQNz0pFq489vNCJBEyRxQX6\r\nawz7ixOU2+QTandDWjBG+2VGAT15sKKphOcWuL1xwWZACVQeQT0S8ZyYwPew\r\nCxUQ9eLej7pQlQhOKeNQYFs/d1BqkfQyWpM/w6OjQo/0A6inpkkB2mM1H8/q\r\njJVnfaPQptES4BTRZdhm/xQ06nV6s3Z+3U6r6FgOvKMFOZ9BdLo4ByD9PxQd\r\nL+JPrud216LZYm/IEwXPa1muALUOAro3BGKEAImofMyUtE0TrSfWNln25CrV\r\n0XKgAFQnpxSelLHiqG8xbEhwoMVc+16QLE1V/yrdRGY3Vmmidc1qaqksa6UB\r\n4Kj8yozKba7ONvq6nhP8kf4K4gzpKbSR2YjSHi4Zhw81p/C9Q/8rqtUWEI2V\r\nfbs0Q5lsEgrLSMYKa0Fr9BUFPMdiEZxqxIkVaY+8zR5hCi/FnYp5G0aVeOrM\r\n96c2vUtsyKhw2nCqM/L1lksdM1XrPINYNptFJgNKZhC8AgkfQlmkM/EFmHcA\r\n0cm5+2lXEmgVEcIJ3m/vhxglpd7VIMCT4jeR1yu+Xbgcsb71AkWSpAzR/rrq\r\nJKK1yZwFQpN7MTBlM0m+f3x3r9f2wFk2E+w=\r\n=su6v\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.3-0_1660122354584_0.21847533008469644"},"_hasShrinkwrap":false},"1.0.3":{"name":"npx-import","version":"1.0.3","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"fa038f44d64ac3000510b9ee2cdef653fecf2926","_id":"npx-import@1.0.3","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-5ni6Sdl//55TehjDGzNQU5fEBtY2hyslX8ail1CBKu4pQ/+VcM/vam/elw2m02oPtEKpM3Zpp5h7Hb9q89V9Tw==","shasum":"3dcbf482a3d15a5bc90665643f399d55ab19cff7","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.3.tgz","fileCount":18,"unpackedSize":58017,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGoMN4O8IJIIrp29WP1T9qPkqP/kx+PJq8/oo6UuB45CAiEA7KdspUhn7SlcDYaYY2U3a2aBWDV+4+zw4TMG4R//fiU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi9oXEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpRug/+P+l1tWlPavbdhOh4hWZ5PaLlWFelG3OPIOJbhdICK9ZbLqIp\r\nDpwXrjqqYujPOmXkC960g7pnj3gQssqsaRcSwpg7BUWXIu2NbN+k/ZrwW9DZ\r\nu25IWjFHgJqM/e+OtrbnnbHjgfQ2vgcZJPhw3wD7X+jAvEKMrRraZBdaTOxH\r\n6zALqFPPqq3cx++DPanYPhI3KZtdoS5WaZTB2us+BwshyHCEZgO3O08/9PdO\r\nSyZRK6m91kSbQbEPmA/N1mIftT3hLHRxjWOCJu72IiJMaj4I4dhEP2uxQCyn\r\n8g5LTAulY96qDm1FW+mI4KIsWXevDvXQLU8Xl4zcyRR7/VjcBxq3kIk/JQzM\r\nR2R9cpTMiOQC9QfXjQOYxO0OeTLQi/3HGcdf1IhpEYmi7KsbwymEa87piQam\r\n+HRSBNZnqUeg+yP8jUjyOOJuG1YZmN5RASLxkyz49lI6KRBWx0i1gRSr60aq\r\nnERoOK4HrlpbfNde+5ndovHmps4+4qPCveyGbMpFPXo1NX8sNv07JlWflVPU\r\nrKHs0B8ade3UyezpXAarStz3PrIDHSdd6fGOtYOfbMG1ws5dsDh5HR6MYwAx\r\nIqUhxVnKFAc/gerJsRY/dD4S+/Kd7aszaGhb4GvtUukoX0khPrFuWwILliqf\r\neA4PLRgFIH0mE9hbqUrIB3veEwgPdY86sS4=\r\n=EHLv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.3_1660323267997_0.8316212061851216"},"_hasShrinkwrap":false},"1.0.4-0":{"name":"npx-import","version":"1.0.4-0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","readme":"# 🧙‍♂️ `npx-import` 🧙‍♀️\n\n### Runtime dependencies, installed _as if by magic_ ✨\n\n[![twitter](https://img.shields.io/badge/@glenmaddern-blue.svg?style=flat&logo=twitter&label=​)](https://twitter.com/glenmaddern)&nbsp; [![GitHub last commit](https://img.shields.io/github/last-commit/geelen/npx-import?logo=github&style=flat&label=​)](https://github.com/geelen/npx-import)&nbsp; [![npm](https://img.shields.io/npm/v/npx-import?label=​&logo=npm)](https://www.npmjs.com/package/npx-import) \n\n`npx-import` can be used as a drop-in replacement for [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import):\n\n```ts\nimport { npxImport } from 'npx-import'\n\n// If big-dep isn't installed locally, npxImport will try\n// to download, install & load it, completely seamlessly.\nconst dependency = await npxImport('big-dep')\n```\n\nIt's exactly like [`npx`](https://docs.npmjs.com/cli/v8/commands/npx), but for `import()`! <sub><sub><sup>(hence the name)</sup></sub></sub>\n\nIs this a good idea? See [FAQ](#faq) below.\n\n## Usage\n\n`npx-import` is ideal for deferring installation for dependencies that are unexpectedly large, require native compilation, or not used very often (or some combination thereof), for example:\n\n```ts\n// Statically import small/common deps as normal\nimport textRenderer from 'tiny-text-renderer'\n\n// Use npxImport to defer\nimport { npxImport } from 'npx-import'\n\nexport async function writeToFile(report: Report, filename: string) {\n\n  if (filename.endsWith('.png')) {\n    console.log(`This is a PNG! We'll have to compile imagemagick!`)\n    const { default: magick } = await npxImport('imagemagick-utils@^1.1.0')\n    await magick.renderToPNG(report, filename)\n\n  } else if (filename.endsWith('.pdf')) {\n    console.log(`Argh, a PDF!? Go make a cuppa, this'll take a while...`)\n    const { default: pdfBoi } = await npxImport('chonk-pdf-boi@3.1.4')\n    await pdfBoi.generate(report, filename)\n\n  } else {\n    console.log(`Writing to ${filename}...`)\n    await textRenderer.write(report, filename)\n  }\n  console.log(`Done!`)\n}\n```\n\nWhen run, `npx-import` will log out some explanation, as well as instructions for installing the dependency locally & skipping this step in future:\n\n```\n❯ node ./index.js --filename=image.png\n\nThis is a PNG! We'll have to compile imagemagick!\n[NPXI] imagemagick-utils not available locally. Attempting to use npx to install temporarily.\n[NPXI] Installing... (npx -y -p imagemagick-utils@^1.1.0)\n[NPXI] Installed into /Users/glen/.npm/_npx/8cac855b1579fd07/node_modules.\n[NPXI] To skip this step in future, run: pnpm add -D imagemagick-utils@^1.1.0\nDone!\n```\n\nFor some types of dependencies, this is a much better UX than the alternatives:\n\n- You either add `imagemagick-utils` & `chonk-pdf-boi` as dependencies, slowing down initial install.\n- The first time a user tries to export a PNG/PDF, you error out with instructions to install the relevant package and retry.\n- You pause, prompt the user for confirmation, then try to detect which package manager they're using and auto-install the dependency for them.\n\nThe last of these generally works well but `npx-import` has slightly different properties:\n\n- The user doesn't need to be prompted—if the dependency can be sourced, installed & transparently included, the program doesn't need to be interrupted.\n- Your user's current project directory is never altered as a side-effect of running a program.\n\nMost importantly, though, **it's compatible with `npx`!** For example, `npx some-cli --help` can be super fast but `npx some-cli export --type=pdf` can transparently download the required dependencies during execution. It's super neat!\n\n## Installation\n\n```\nnpm install --save npx-import\npnpm add -P npx-import\nyarn add npx-import\n```\n\n## Typescript\n\nJust like `import()`, the return type default to `any`. But you can import the types of a devDependency without any consumers of your package needing to download it at installation time.\n\n```\npnpm add -D big-dep\n```\n\n```ts\nimport { npxImport } from 'npx-import'\ntype BigDepType = typeof import('big-dep')\n\nconst bigDep = await npxImport<BigDepType>('big-dep')\n```\n\n## API\n\n* Since package versions are no longer tracked in your `package.json`, we recommend being explicit:\n\n```ts\nconst lazyDep = await npxImport('left-pad@1.3.0')\n```\n\nAny package specifier that's valid in `package.json` will work here: e.g. `^1.0.0`, `~2.3.0`, `>4.0.0`, `@latest`, `@next`, etc.\n\nNote: there is a speed benefit from using exact versions. `npxImport(pkg-a@1.2.3)` will run `npx --prefer-offline` under the hood, making it faster after the first run (since it doesn't first check the NPM registry for newer versions).\n\n* You can also install multiple packages at once:\n\n```ts\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'])\n```\n\n`npx-import` also takes a third argument, which lets you customise, or silence, the log output. Each line that would normally be printed is passed to the logger function:\n\n```ts\nconst grayLog = (line: string) => console.log(chalk.gray(line))\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'], grayLog)\n```\n\n* Use `npxResolve` instead of `require.resolve` to get the path (local or temporary)\n\n```ts\nexport function getSQLiteNativeBindingLocation() {\n  return path.resolve(\n    path.dirname(npxResolve(\"better-sqlite3\")),\n    \"../build/Release/better_sqlite3.node\"\n  );\n}\n```\n\nNote, `npxResolve` requires that you'd previously called `npxImport` for the same package.\n\n## FAQ\n\n### 🤔 Isn't this, like, a heroically bad idea?\n\nNah it's good actually.\n\n### 🤨 No but seriously, isn't using `npx` a big security hole?\n\nInitially, `npx` didn't prompt before downloading and executing a package, which was _definitely_ a security risk. But that's been [fixed since version 7](https://github.com/npm/npx/issues/9#issuecomment-786940691). Now, if you're intending to write `npx prettier` to format your code and accidentally type `npx prettomghackmycomputerpls`, you'll get a helpful prompt:\n\n```\n❯ npx prettier@latest\nNeed to install the following packages:\n  prettomghackmycomputerpls@6.6.6\nOk to proceed? (y)\n```\n\nThis gives the user a chance to see their mistake and prevent being hacked to bits.\n\n### 😠 But hang on, you're never prompting the user to confirm!\n\nAh yes, that seems to go against the previous point. But `npx-import` isn't being triggered from a potentially clumsy human on a keyboard, it's running inside some source code you've (by definition) already authorised to run on your machine.\n\n`npx-import` is an alternative to publishing these as normal dependencies of your project and having your users download them at install time. `npm install` doesn't prompt the user to approve every transitive dependency of what's being installed/run, so `npx-import` doesn't either.\n\n### 🧐 What if the user has already installed the dependency somewhere?\n\nThen `npxImport` short-circuits, returning the local version without logging anything out. This is what the user is instructed to do to \"skip this step in future\". In other words, `npxImport()` first tries to call your native `import()`, and only does anything if that fails.\n\nNote that this also works for multiple dependencies, `npxImport(['pkg-a', 'pkg-b', 'pkg-c'])` will only fetch & install those that are missing.\n\n### 🤪 Doesn't this mean dependencies gets repeatedly downloaded & installed?\n\nNo! `npx` maintains a cache in the user's home directory. If a cached package is found, `npx` will (by default) hit NPM to check if there's any new versions for that specifier, and if not, return the cache. `npxImport` adds a small optimisation—if you specify an exact package version (e.g. `@7.8.2`), it'll run `npx --prefer-offline` to skip the NPM check.\n\nSo new packages are only downloaded & installed when:\n\n* It's the first time a particular package/version combo is seen (see next section)\n* No locked version was provided and there's a new version on NPM\n\n### 😵‍💫 What about multiple projects? Doesn't the cache mean projects can clobber/overwrite/conflict with each other?\n\nAs it turns out, no! While I wasn't paying attention, `npx` got really smart! To understand why, we need to look at how `npx` works:\n\nFor starters, `npx some-pkg` is a shorthand for `npx -p some-pkg <command>`, where `<command>` is whatever `bin` that `some-pkg` declares. Often, the `<command>` and the package name are the same (e.g. `npx prettier`), but it's the `bin` field inside the package that's really being used. Otherwise, scoped packages (like `npx @11ty/eleventy`) would never work. If there's no `bin` field declared (e.g. for `chokidar`, you need `npx chokidar-cli`), or if there's more than one (e.g. for `typescript`, you need `npx -p typescript tsc`), you have to use the expanded form.\n\nBut there's no requirement that `<command>` is a `bin` inside the package at all! It can be any command (at least for `npx`, `pnpm dlx` and `yarn dlx` have different restrictions), for example, we can inject a `node -e` command and start to learn about what's going on:\n\n```\n❯ npx -y -p is-odd node -e 'console.log(process.env.PATH.split(\":\"))' | grep .npm/_npx\n  '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin',\n```\n\nUsing `process.env.PATH` and searching for `.npm/_npx` is, on OSX with NPX v8+, a reliable way to find out where `npx` is installing these temporary packages. Let's look inside:\n\n```\n❯ ll2 /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/\ndrwxr-xr-x    - glen  4 Aug 11:07  /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc\ndrwxr-xr-x    - glen  4 Aug 11:07 ├──  node_modules\n.rw-r--r--  780 glen  4 Aug 11:07 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:07 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:07 │  └──  is-odd\n.rw-r--r-- 1.4k glen  4 Aug 11:07 ├──  package-lock.json\n.rw-r--r--   51 glen  4 Aug 11:07 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/package.json\n{\n  \"dependencies\": {\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nThat looks like a pretty normal project directory to me!\n\n> Aside, `ll2` is my super rad alias for `exa --icons -laTL 2`. See [exa](https://github.com/ogham/exa).\n\nNow, the crucial bit: **every time `npx` runs for some unique set of packages it creates a new directory**. That goes for installing multiple deps at once but also for different named/pinned versions/tags for individual packages:\n\n```\n❯ export LOG_NPX_DIR=\"node -e 'console.log(process.env.PATH.split(\\\":\\\").filter(p => p.match(/\\.npm\\/_npx/)))'\"\n\n❯ npx -y -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@latest $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/ecc6e2260c717fec/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/c41e9ab9d1d9c43f/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@\\^3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e86896689f5aebbb/node_modules/.bin' ]\n```\n\nNote that **every one of these commands downloaded the same version of `is-odd`**, but because they were referenced using different identifiers, `_` vs `latest` vs `3.0.1` vs `>3.0.1`, `npx` played it safe and made a new temporary directory.\n\nFor multiple packages, the same rule applies, although order is not important:\n\n```\n❯ npx -y -p is-odd -p is-even $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ npx -y -p is-even -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ ll2 /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37  /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37 ├──  node_modules\n.rw-r--r-- 2.6k glen  4 Aug 11:37 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-buffer\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-even\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-odd\ndrwxr-xr-x    - glen  4 Aug 11:37 │  └──  kind-of\n.rw-r--r-- 4.8k glen  4 Aug 11:37 ├──  package-lock.json\n.rw-r--r--   76 glen  4 Aug 11:37 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/f9af4fded130fd33/package.json\n{\n  \"dependencies\": {\n    \"is-even\": \"^1.0.0\",\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nSo `npx` is doing exactly the same as an `npm install`, with a `package.json`, `package-lock.json`, `node_modules` etc. It's just dynamically creating directories based on some hash of its inputs. So the only way two projects can use the same package in the cache is if they _both_ ask for _exactly_ the same packages & versions. It's super clever!\n\n### 😐 But what about transitive deps? Won't you get duplication?\n\nSadly, yes. If both your package `main-pkg` and `util-a` depend on `util-b`, then calling `npxImport('util-a')` from within `main-pkg` will create a new directory with a second copy of `util-b`. If there are globals in that package, or if the version specifiers are slightly different, you could potentially have problems.\n\nIt's probably possible to [detect this in future](https://github.com/geelen/npx-import/issues/2) and warn/error out. But for now, I recommend using `npxImport` for mostly self-contained dependencies.\n\n### 🫤 What about version mismatch with local files?\n\nIf a user has `pkg-a` version `1.0.0` installed, but one of their packages calls `npxImport('pkg-a@^2.0.0')`, `npxImport` isn't smart enough ([yet](https://github.com/geelen/npx-import/issues/3)) to know that the local version of `pkg-a` doesn't match the version range specified (since it's using native `import()` under the hood). Without `npxImport`, the `npm install` step would have had a chance to bump the installed version of `pkg-a` to meet the requirements of _all_ packages being used, but we're bypassing that.\n\nThis will be fixed in a future version.\n\n### 🫠 What kind of packages would you use this for?\n\n- Anything with native extensions needing building (do that when you need it)\n- Packages with large downloads (e.g. puppeteer, sqlite-node)\n- CLI packages that want to make `npx my-cli --help` or `npx my-cli init` really fast and dependency-free, but also allow `npx my-cli <cmd>` to pull in arbitrary deps on-demand, without forcing the user to stop, create a local directory, and install dev dependencies.\n- Anything already making heavy use of `npx`. You're in the jungle, baby.\n\n---\n\nBuilt with <3 during a massive yak shave by Glen Maddern.\n","readmeFilename":"README.md","gitHead":"f9c096912197c76e2683bf4413d86b46859dac1f","_id":"npx-import@1.0.4-0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-rltiZ5KVyT/PKDFY1k/+C1vMxMlMjJ30ZmzYhYYkErK04U8oKdCEX2u9rMp+JqH7dISjMxuLdKQ5jwLDhCqNWw==","shasum":"fa69283ccd8a5e323448257855e33a45f2ae24fe","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.4-0.tgz","fileCount":18,"unpackedSize":58224,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAI5Yr2rd9HC3LCfExsJuBessgAplo1g/rW8vdD8ZepWAiAcCzDzAXX/Q8Len+ICZEulLy6z6gh7hongOnt0Y7cglA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi9osJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoJSg//f9peaMoBPWItHmhFnzV4Dp4uXWjLJjQufUX6hHLi3+hJICqR\r\nbV7GSPsXqBo/LJpil43xN+RivyBVceT0bDA9ymxIoMkLpizeW3zoxZJJox+d\r\n4J6KqZdUQrkrQdEnEzibcTN0iqRcaoBBCOXzDqpggrqKMGXTqbosIya3FkrV\r\nAV3Ttu65U0ihWbedTR4/AsH30GYYtypwSapi46wiFGwmDrqsFq8moI63W3JI\r\nV1u6ycV/Re1iJynqxQSxP6yVYlJxxoKf+gswRFyTZUBDAQtp/BHMFBKWX3xh\r\n2M4MA2oyEgGUT17HNm26xQ6Wjkggu/KuSsr6ghCMWlmiUvsZACHMuFRWxWT6\r\nUGxPJeIgS8PgDOatZN9haRjc9/JLP0XgL+XLWuD22BiEiLLgRCTaBPZlk2tv\r\nxdgIuXD+x/hxCBvGuXO1PgHFuVILzF/M7MT6vFyI89KjUJtQwSRXCrlXhfBv\r\nQRfeu6Cql7a2R1+mQO0/JdXaKk8quC++Ks4IentSJfSn1AzSgirhMffmrwdq\r\nBf+bk/hgrr5fzXFKMGYMkHi00GlwZH0SAIQEWb+59V2TOSuflw9ze3zUGJyh\r\ni2wl4nsG94G+sVOIzdxRZTyIX5Tcz9YVNhvfonABmcawbEgLl9KQ/T30kIz/\r\nYFnxJA7Z12tKM9RnU0utCYlig7PfhqgnPNU=\r\n=cWJw\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.4-0_1660324616897_0.7775051054477242"},"_hasShrinkwrap":false},"1.0.5-0":{"name":"npx-import","version":"1.0.5-0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","readme":"# 🧙‍♂️ `npx-import` 🧙‍♀️\n\n### Runtime dependencies, installed _as if by magic_ ✨\n\n[![twitter](https://img.shields.io/badge/@glenmaddern-blue.svg?style=flat&logo=twitter&label=​)](https://twitter.com/glenmaddern)&nbsp; [![GitHub last commit](https://img.shields.io/github/last-commit/geelen/npx-import?logo=github&style=flat&label=​)](https://github.com/geelen/npx-import)&nbsp; [![npm](https://img.shields.io/npm/v/npx-import?label=​&logo=npm)](https://www.npmjs.com/package/npx-import) \n\n`npx-import` can be used as a drop-in replacement for [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import):\n\n```ts\nimport { npxImport } from 'npx-import'\n\n// If big-dep isn't installed locally, npxImport will try\n// to download, install & load it, completely seamlessly.\nconst dependency = await npxImport('big-dep')\n```\n\nIt's exactly like [`npx`](https://docs.npmjs.com/cli/v8/commands/npx), but for `import()`! <sub><sub><sup>(hence the name)</sup></sub></sub>\n\nIs this a good idea? See [FAQ](#faq) below.\n\n## Usage\n\n`npx-import` is ideal for deferring installation for dependencies that are unexpectedly large, require native compilation, or not used very often (or some combination thereof), for example:\n\n```ts\n// Statically import small/common deps as normal\nimport textRenderer from 'tiny-text-renderer'\n\n// Use npxImport to defer\nimport { npxImport } from 'npx-import'\n\nexport async function writeToFile(report: Report, filename: string) {\n\n  if (filename.endsWith('.png')) {\n    console.log(`This is a PNG! We'll have to compile imagemagick!`)\n    const { default: magick } = await npxImport('imagemagick-utils@^1.1.0')\n    await magick.renderToPNG(report, filename)\n\n  } else if (filename.endsWith('.pdf')) {\n    console.log(`Argh, a PDF!? Go make a cuppa, this'll take a while...`)\n    const { default: pdfBoi } = await npxImport('chonk-pdf-boi@3.1.4')\n    await pdfBoi.generate(report, filename)\n\n  } else {\n    console.log(`Writing to ${filename}...`)\n    await textRenderer.write(report, filename)\n  }\n  console.log(`Done!`)\n}\n```\n\nWhen run, `npx-import` will log out some explanation, as well as instructions for installing the dependency locally & skipping this step in future:\n\n```\n❯ node ./index.js --filename=image.png\n\nThis is a PNG! We'll have to compile imagemagick!\n[NPXI] imagemagick-utils not available locally. Attempting to use npx to install temporarily.\n[NPXI] Installing... (npx -y -p imagemagick-utils@^1.1.0)\n[NPXI] Installed into /Users/glen/.npm/_npx/8cac855b1579fd07/node_modules.\n[NPXI] To skip this step in future, run: pnpm add -D imagemagick-utils@^1.1.0\nDone!\n```\n\nFor some types of dependencies, this is a much better UX than the alternatives:\n\n- You either add `imagemagick-utils` & `chonk-pdf-boi` as dependencies, slowing down initial install.\n- The first time a user tries to export a PNG/PDF, you error out with instructions to install the relevant package and retry.\n- You pause, prompt the user for confirmation, then try to detect which package manager they're using and auto-install the dependency for them.\n\nThe last of these generally works well but `npx-import` has slightly different properties:\n\n- The user doesn't need to be prompted—if the dependency can be sourced, installed & transparently included, the program doesn't need to be interrupted.\n- Your user's current project directory is never altered as a side-effect of running a program.\n\nMost importantly, though, **it's compatible with `npx`!** For example, `npx some-cli --help` can be super fast but `npx some-cli export --type=pdf` can transparently download the required dependencies during execution. It's super neat!\n\n## Installation\n\n```\nnpm install --save npx-import\npnpm add -P npx-import\nyarn add npx-import\n```\n\n## Typescript\n\nJust like `import()`, the return type default to `any`. But you can import the types of a devDependency without any consumers of your package needing to download it at installation time.\n\n```\npnpm add -D big-dep\n```\n\n```ts\nimport { npxImport } from 'npx-import'\ntype BigDepType = typeof import('big-dep')\n\nconst bigDep = await npxImport<BigDepType>('big-dep')\n```\n\n## API\n\n* Since package versions are no longer tracked in your `package.json`, we recommend being explicit:\n\n```ts\nconst lazyDep = await npxImport('left-pad@1.3.0')\n```\n\nAny package specifier that's valid in `package.json` will work here: e.g. `^1.0.0`, `~2.3.0`, `>4.0.0`, `@latest`, `@next`, etc.\n\nNote: there is a speed benefit from using exact versions. `npxImport(pkg-a@1.2.3)` will run `npx --prefer-offline` under the hood, making it faster after the first run (since it doesn't first check the NPM registry for newer versions).\n\n* You can also install multiple packages at once:\n\n```ts\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'])\n```\n\n`npx-import` also takes a third argument, which lets you customise, or silence, the log output. Each line that would normally be printed is passed to the logger function:\n\n```ts\nconst grayLog = (line: string) => console.log(chalk.gray(line))\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'], grayLog)\n```\n\n* Use `npxResolve` instead of `require.resolve` to get the path (local or temporary)\n\n```ts\nexport function getSQLiteNativeBindingLocation() {\n  return path.resolve(\n    path.dirname(npxResolve(\"better-sqlite3\")),\n    \"../build/Release/better_sqlite3.node\"\n  );\n}\n```\n\nNote, `npxResolve` requires that you'd previously called `npxImport` for the same package.\n\n## FAQ\n\n### 🤔 Isn't this, like, a heroically bad idea?\n\nNah it's good actually.\n\n### 🤨 No but seriously, isn't using `npx` a big security hole?\n\nInitially, `npx` didn't prompt before downloading and executing a package, which was _definitely_ a security risk. But that's been [fixed since version 7](https://github.com/npm/npx/issues/9#issuecomment-786940691). Now, if you're intending to write `npx prettier` to format your code and accidentally type `npx prettomghackmycomputerpls`, you'll get a helpful prompt:\n\n```\n❯ npx prettier@latest\nNeed to install the following packages:\n  prettomghackmycomputerpls@6.6.6\nOk to proceed? (y)\n```\n\nThis gives the user a chance to see their mistake and prevent being hacked to bits.\n\n### 😠 But hang on, you're never prompting the user to confirm!\n\nAh yes, that seems to go against the previous point. But `npx-import` isn't being triggered from a potentially clumsy human on a keyboard, it's running inside some source code you've (by definition) already authorised to run on your machine.\n\n`npx-import` is an alternative to publishing these as normal dependencies of your project and having your users download them at install time. `npm install` doesn't prompt the user to approve every transitive dependency of what's being installed/run, so `npx-import` doesn't either.\n\n### 🧐 What if the user has already installed the dependency somewhere?\n\nThen `npxImport` short-circuits, returning the local version without logging anything out. This is what the user is instructed to do to \"skip this step in future\". In other words, `npxImport()` first tries to call your native `import()`, and only does anything if that fails.\n\nNote that this also works for multiple dependencies, `npxImport(['pkg-a', 'pkg-b', 'pkg-c'])` will only fetch & install those that are missing.\n\n### 🤪 Doesn't this mean dependencies gets repeatedly downloaded & installed?\n\nNo! `npx` maintains a cache in the user's home directory. If a cached package is found, `npx` will (by default) hit NPM to check if there's any new versions for that specifier, and if not, return the cache. `npxImport` adds a small optimisation—if you specify an exact package version (e.g. `@7.8.2`), it'll run `npx --prefer-offline` to skip the NPM check.\n\nSo new packages are only downloaded & installed when:\n\n* It's the first time a particular package/version combo is seen (see next section)\n* No locked version was provided and there's a new version on NPM\n\n### 😵‍💫 What about multiple projects? Doesn't the cache mean projects can clobber/overwrite/conflict with each other?\n\nAs it turns out, no! While I wasn't paying attention, `npx` got really smart! To understand why, we need to look at how `npx` works:\n\nFor starters, `npx some-pkg` is a shorthand for `npx -p some-pkg <command>`, where `<command>` is whatever `bin` that `some-pkg` declares. Often, the `<command>` and the package name are the same (e.g. `npx prettier`), but it's the `bin` field inside the package that's really being used. Otherwise, scoped packages (like `npx @11ty/eleventy`) would never work. If there's no `bin` field declared (e.g. for `chokidar`, you need `npx chokidar-cli`), or if there's more than one (e.g. for `typescript`, you need `npx -p typescript tsc`), you have to use the expanded form.\n\nBut there's no requirement that `<command>` is a `bin` inside the package at all! It can be any command (at least for `npx`, `pnpm dlx` and `yarn dlx` have different restrictions), for example, we can inject a `node -e` command and start to learn about what's going on:\n\n```\n❯ npx -y -p is-odd node -e 'console.log(process.env.PATH.split(\":\"))' | grep .npm/_npx\n  '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin',\n```\n\nUsing `process.env.PATH` and searching for `.npm/_npx` is, on OSX with NPX v8+, a reliable way to find out where `npx` is installing these temporary packages. Let's look inside:\n\n```\n❯ ll2 /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/\ndrwxr-xr-x    - glen  4 Aug 11:07  /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc\ndrwxr-xr-x    - glen  4 Aug 11:07 ├──  node_modules\n.rw-r--r--  780 glen  4 Aug 11:07 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:07 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:07 │  └──  is-odd\n.rw-r--r-- 1.4k glen  4 Aug 11:07 ├──  package-lock.json\n.rw-r--r--   51 glen  4 Aug 11:07 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/package.json\n{\n  \"dependencies\": {\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nThat looks like a pretty normal project directory to me!\n\n> Aside, `ll2` is my super rad alias for `exa --icons -laTL 2`. See [exa](https://github.com/ogham/exa).\n\nNow, the crucial bit: **every time `npx` runs for some unique set of packages it creates a new directory**. That goes for installing multiple deps at once but also for different named/pinned versions/tags for individual packages:\n\n```\n❯ export LOG_NPX_DIR=\"node -e 'console.log(process.env.PATH.split(\\\":\\\").filter(p => p.match(/\\.npm\\/_npx/)))'\"\n\n❯ npx -y -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@latest $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/ecc6e2260c717fec/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/c41e9ab9d1d9c43f/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@\\^3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e86896689f5aebbb/node_modules/.bin' ]\n```\n\nNote that **every one of these commands downloaded the same version of `is-odd`**, but because they were referenced using different identifiers, `_` vs `latest` vs `3.0.1` vs `>3.0.1`, `npx` played it safe and made a new temporary directory.\n\nFor multiple packages, the same rule applies, although order is not important:\n\n```\n❯ npx -y -p is-odd -p is-even $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ npx -y -p is-even -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ ll2 /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37  /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37 ├──  node_modules\n.rw-r--r-- 2.6k glen  4 Aug 11:37 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-buffer\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-even\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-odd\ndrwxr-xr-x    - glen  4 Aug 11:37 │  └──  kind-of\n.rw-r--r-- 4.8k glen  4 Aug 11:37 ├──  package-lock.json\n.rw-r--r--   76 glen  4 Aug 11:37 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/f9af4fded130fd33/package.json\n{\n  \"dependencies\": {\n    \"is-even\": \"^1.0.0\",\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nSo `npx` is doing exactly the same as an `npm install`, with a `package.json`, `package-lock.json`, `node_modules` etc. It's just dynamically creating directories based on some hash of its inputs. So the only way two projects can use the same package in the cache is if they _both_ ask for _exactly_ the same packages & versions. It's super clever!\n\n### 😐 But what about transitive deps? Won't you get duplication?\n\nSadly, yes. If both your package `main-pkg` and `util-a` depend on `util-b`, then calling `npxImport('util-a')` from within `main-pkg` will create a new directory with a second copy of `util-b`. If there are globals in that package, or if the version specifiers are slightly different, you could potentially have problems.\n\nIt's probably possible to [detect this in future](https://github.com/geelen/npx-import/issues/2) and warn/error out. But for now, I recommend using `npxImport` for mostly self-contained dependencies.\n\n### 🫤 What about version mismatch with local files?\n\nIf a user has `pkg-a` version `1.0.0` installed, but one of their packages calls `npxImport('pkg-a@^2.0.0')`, `npxImport` isn't smart enough ([yet](https://github.com/geelen/npx-import/issues/3)) to know that the local version of `pkg-a` doesn't match the version range specified (since it's using native `import()` under the hood). Without `npxImport`, the `npm install` step would have had a chance to bump the installed version of `pkg-a` to meet the requirements of _all_ packages being used, but we're bypassing that.\n\nThis will be fixed in a future version.\n\n### 🫠 What kind of packages would you use this for?\n\n- Anything with native extensions needing building (do that when you need it)\n- Packages with large downloads (e.g. puppeteer, sqlite-node)\n- CLI packages that want to make `npx my-cli --help` or `npx my-cli init` really fast and dependency-free, but also allow `npx my-cli <cmd>` to pull in arbitrary deps on-demand, without forcing the user to stop, create a local directory, and install dev dependencies.\n- Anything already making heavy use of `npx`. You're in the jungle, baby.\n\n---\n\nBuilt with <3 during a massive yak shave by Glen Maddern.\n","readmeFilename":"README.md","gitHead":"52b5db5252751e2ec05c74b6d3553fade7c249b0","_id":"npx-import@1.0.5-0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-tuERsE1gjO9xZRnoPROzEoZVoU8Xnpz8+B+yuvQNGFP8h49HviPuzPk5K2XTZATsdVTfkcLOXCIEpKrcxQa9sg==","shasum":"3f573822f796902ef6161e3f810f46b21a6891db","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.0.5-0.tgz","fileCount":18,"unpackedSize":58843,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCx4y2a3SUL3E+3PATX9WriL5jQfSCTx/cVfmZ/4t5IBQIgfdz5zovk90y6emz8tZwuV6kLhW8C9XjxjQFnKeSHLrU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi9oysACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmquHA//R3R9GGVcp12DZVlVoK0xEX8fDnETI2ZtCJuGhnhX1g8DZitH\r\nBf0CtDstMpUzhs1uPIkAgEmlOnar0RwmJXLIbzUaIj5QwkKg4laiWSOzuFLv\r\nwcvHDAULIHBI7SI7Z9xXtSJTvpV8yEuCKNr/ESjeZinPtWjntVRAXVCpYfSm\r\nSWH9dFDzv0g77jGtG8rF2JOZ1rzUHD2wEj43er39luazzgs2rDoDVl4c2cGL\r\noTDy7p5v7M4ghnXqBi/Y0SmU1LEb9W/bMXByW1+OVfVvacskQXEhRbJ0qBNX\r\ntbRjd8+VubzGxQKQplVx8CYaeqWDWbDJU3ToIE2BxVkBaUF7NBL1MiFJ4jT9\r\nxS8nMEC71UOAIptLJ9nbfBjdeJEq7w73s5FXfv+hVUB/LEieIqwWksOszXsm\r\nq5utJgxKUiXAMD0EloXTeUiiE7WO6MaVzeHHyDqUQeZbY/xZKZEBbatA/IpR\r\nxlqQxqmLPnEphdsUWXl+tKHPx/PqPijG9iXHcvV22FF9HB4XBrcgw1eh0QxF\r\nmb+tZo4/jnYGZBEPPRPZfvp2wVbYdeMcvJnupA0kGt0E1QISp1MZhaGvZIMW\r\nNXptWc/PhOxWGfgjnkZ3eEB4V7zoenjG3bqa3t/JeJHNQcQ4nm6P3KT619hw\r\nqZWOSL3nwQms1G/LVhGaV4oHSz7HJReHiPw=\r\n=Zbep\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.0.5-0_1660325036578_0.14029203781545618"},"_hasShrinkwrap":false},"1.1.0":{"name":"npx-import","version":"1.1.0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"37869e954f55c128359a7eb49f3e17acc04447c1","_id":"npx-import@1.1.0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-Duo36DvOrkb7H+tHzdoKnrjM3WI4+XEt35pcQ87LXxKWxQK3yOnKRCyskTO28ReYKRtqyfAKROs4GkYzwED/uA==","shasum":"4a246b17f1d974dbdb61b47187c48a1604eac2ac","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.0.tgz","fileCount":18,"unpackedSize":61144,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDeK+6VbH8DMXH5/RnOAS/AHXRrQwsJ84sZC4mwJKOjYAIga9xssLI9jq3M/Jltsis6nTXsVx5JF5ZswNvkjBh6QM0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHxL1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqv9g//akHHOl6w9HLR1zd6HMGFircbp82UyejdH3vBRigv91WTHMVU\r\nRakZyEx/fW+mi2u0LZ30wIwWhZJelk5XipCp2DU9wo7KEmK7Vz1Q+olim14v\r\nj326g/SQ49bRxuONfPpx6kyLDY0wx0+B4N+umSZWVmPoY0GnWg4mtsyulkcm\r\npyGDDo6SI9T4O3ORVfXVHtJL2H42QqVnTzr+osFC4qrIQUcDca8VlXM7XeE3\r\nlUP69eGLVFvqr1GLVVGd04xtB/M9E/AzNT7y7xnxeuPHxKtCYJ0iSBVx3W/L\r\nlef5jmIoqmo7eEqeE0bHBNzvrZKw1f4tNNWvxPXCtzmy2zEW0gczNKl9D+5X\r\nORUgwE3fEp5Q/LvF1uNLP5vCwt2p6AM4TlAva6lFXjnh7iQpKTQs+Q+V740V\r\n/oboETlaKXCL1CEfo8MX8xrVpQGPFcmgXDaj1HV16tyYNQU5Cgh68t87jEQa\r\nH0WkqFoMukB/7BTudZsE4knmSPqOLStrpIbV2R0aK1KHf1IeBCIo302TOPap\r\nx69OPrPWAWXXc44WrYx2inj5rPlVkm4IJqw0LbLHqqg27SaaxPwTjr04BN4w\r\nYy8hPrLeMdo0fchyQD6CT6/HHb3L2m6BVQJyvPRLoXRsDBCjxlVEiibhaHxg\r\nF0cuaJGgHLu3JjvNwlhuD/xYH/kglJYAu6Q=\r\n=3iBy\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.0_1662980853120_0.16299420731193703"},"_hasShrinkwrap":false},"1.1.1":{"name":"npx-import","version":"1.1.1","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"f36d85573a54304a15341a2e64a7dfccd8c6c299","_id":"npx-import@1.1.1","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-YtMYllizkuP6TjhbnZFyL9ZwhGEsPj/ZKu9bInsK8t2KhDnTWWGdEhc3p/gSSN1BIZnzQSFsNuKcBAVEJOxu8g==","shasum":"df5e7aae024fd1179bcbd31810ecfcb00fb40187","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.1.tgz","fileCount":18,"unpackedSize":61149,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDlOLrqNjbnoEd90MU4AjL7Wf+wxidkTkOvmD8q0Lqb4AIgGjToabS1SCp8S+F2JpamP0D1HZZh5QCe00rlGL6YjaY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHxwwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqeiw/+Mg++WobiBPWmsbh1AkwkzWqv4dt9b0mij7X3Ntfc8vDEdMVx\r\nrCmMD7GGUWeSlgXftjo9/NaImN5W6dZ1aGGiUbFuLt2hMFxPYtrumv6qZ8lc\r\n7S5cHGBjGnXpMr8UVK4rCp1ATLBC0mLFimsMQ/qGNiBi5sPp7tFIdTCFOMYW\r\nxvOWQTKAqxI3+1nhQC9mIl5uXub3LiT0316FVFqD/cFiaXMcYn9ceBTy2v+v\r\ngkKu5D+YVHAgS55HUCMVmFT9tqQuWTnwYfu4GuZGYZvtKKFvnGld5Yk+trcf\r\nQaI7DkIAn7hF2v3+HxRNA4zxCBuAHYxzskTlpORqmsAXVyNQQZvvGCUB3Q6b\r\n0qCMCeT+8a5sHjIlOCvWpGEgXK45ipvt/alTwlQRgncWgT7t8Mz9rh1Wu8hl\r\nUW3fwHl59vbzvAAaJli4n/AlvkpxnlS4Y1bRxV8SIwI+H2v1t+q6UudP01ru\r\n4map5ni3l170dCz9AmQ/BYkw+hmQPtjYXoYiE3tpq3zY79cPgUHJpYJVikX2\r\n/AQQnNUQBGGmqeOiVdrsthBLpWSZ+rpl2bHl7Lp9vadeEx6npczTcoQ1f80i\r\nh5MOtM5Pns30bgdzTzWI4RsJTDZj92y/qcPYApKyKxw3YGtPRw3TUjp7wzGX\r\nuQEbuApHrh9HDYa23GwdlUEn31YqRQdyyns=\r\n=0usV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.1_1662983216780_0.427465065091281"},"_hasShrinkwrap":false},"1.1.2-0":{"name":"npx-import","version":"1.1.2-0","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"938a286337870cbea7601af1fda25beccfaf78c9","_id":"npx-import@1.1.2-0","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-eYZSVdW0mil3o51N9WNq9WhgDG84YvSwiicigogpvJTwpicqSV6y59WxKPtauP7vpcduCqT1Ril0xADRQ4tcJw==","shasum":"9b359f2144da2d76f710afffdf30587a6048bb5e","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.2-0.tgz","fileCount":18,"unpackedSize":61232,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC2a5fQnygvxE1dRqNiftiB5R9CAFSKM+jfSfSPDFXDBgIhAK98fCxpvhG0jVl8XHb+YHaLv2G0W+Lk5iinX0zBejzH"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHx87ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpcqg/+OZGXYF70M2hWx+tJX6FICT+UJRG83IgKABh8Gesmjp8RU+80\r\nsg3GVkvUa8BQ75JthB5XQ6Y7uUHnM+9CJ7snL8bfDvc7u+rJ3u9konfCo8Si\r\n5DIozeQjJOQKvKh5v2R/dNwDeoke0Px7UavAtzcrLbNjY+lAH734oFUKRgXq\r\nOvf3N9vemA7hOuUwY6sqWp+t9y9jzZjPu5GGNbCRlPL+mt9qwGAFn1Xaxb+3\r\n6R5WoDpgOEpAQjefdJ4sgkiCbmip8HKkC/H3Mc2wgDDVTW5j+UFcQKShhPsS\r\nJAymOoqoQh5rzm4h5sFVo7yOVVFwD1sbXjUHfElbJ1HNi2k7obVpXJ9uSdGa\r\nfDenJxjh0T7DzdgG8ybqBziO59B0tp6No5JMiSbhdZH97CMaPkY163fyynDD\r\n9Vo6uO63O6sQVhz8RHI1JJZhu3rkqMWLsZztId7RHxXccUltEyulmHNNgfMI\r\nozEr8eMMxSmQg97id1SjRigaLwMzipeO+qSy05M9miKVtUt6dYwyVdcrvW52\r\n8gO4+GkAmsjzxG62zgJ4bjGWAaI7/TO2Jrn+lBir0hEuw/j26pwHrgne25PU\r\nNtiuMvYjJirSQxIXzzrPk0s9Ve5R7zWSrhqsKC0AzdMn7023zbFxlgEyt9J3\r\n+b3jizKBxQYmYxru0XcXTIx9jXoTQWyU/NY=\r\n=+d+a\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.2-0_1662983995012_0.16959446926524624"},"_hasShrinkwrap":false},"1.1.2-1":{"name":"npx-import","version":"1.1.2-1","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"d9ea575381f2e2500293cba0016335f488eec21b","_id":"npx-import@1.1.2-1","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-mVgdDbawMfJgSMV/4nc/rLKAcKHgL+ccdb3t9SM2GygzVUGPdjFO1CqE07x4N6N4hzPwodmts8GzL0s1PaVLFw==","shasum":"6f593e785ee82677606d754735e7b3f407ac8c14","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.2-1.tgz","fileCount":18,"unpackedSize":61342,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEAG2oJ5uxp6i5YzEM3sjp4W413Mfhr5qJvwsjtrSHIRAiADyvK7Imqk4kTergRc68GpLrfz761Ydnzl7XRD6ZUduw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHyQaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqvtA/+MYP1Lla50Y+xIcdPuQVNJA417lIxi0P9QTqHJbR+QkZmbFPk\r\np/HFU8mMhUDZ7NWcYJUR8qsHH1ck+DsAum/Nj9mHGlGgLYzWm4R9Zlx33hbg\r\nVpZ2L5D2n8nUjGBP26YJBdZFIGwBDc89WDfDthOdBeHJsAWihZlCsqrv/1GE\r\nImnGb4HlZOI8+vRABg8Gmr4u/9oWlsjH0HV1WTws64GvzXf0hd3J/zpMzj+n\r\nvK7WYIv7btpgfaizkSgp1O0Qvz6GdhsOfmbg8K5gM95WS4cHQhs6kB4Cy93F\r\nz97WBkpZPEL8EyOBYZRZewiSjxoS0M1vasM3PyU8gi4WE9l1v/qeuT2LXl/K\r\neCSD2ksHZtKnnv3+TapIYw2P3mack+chprKY40+IPK3kQTCan8Gi69JzBwXj\r\nc2pqtyBsBFLdvto9MQ2SGLQ9h9AXsvSQQDyHC58wvZqDl3QYz8us93g9hyKt\r\nfFkSJkrHqmAM4YDcQwiallsKvww29QCE+we6d+vxsxjX1vPIr6mqv/pLi3Db\r\nkQfFtDtEnlLP+TsJxpfRqDTdr4WyDA4qgKdUwZjWfrz6rS9rk1uDkKKVKRyG\r\nD/GRuhVwqB7PzM+RdAlrF4tZ/uWpDPNdRog/x4opfqcMRMS10Xumb5UNNPNs\r\n/GdLoDApPpUrmWtPq5vggJ6xCmdzota59ak=\r\n=apaN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.2-1_1662985242121_0.8751346231739217"},"_hasShrinkwrap":false},"1.1.2":{"name":"npx-import","version":"1.1.2","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"2b136829a4643f614b41ad254b05dcadfda6c310","_id":"npx-import@1.1.2","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-W/DCVEA7FQSK8vyphTLmT7LtGsZ8RJ85kRtAqhYediFCls9asiAebiKC9Y4S45u5e711fvDArC8UkbmX8nTwyg==","shasum":"4d68f5e78ee1283ae96bd57d513e6198b8a4d25a","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.2.tgz","fileCount":18,"unpackedSize":61340,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCSCLHNpWgssYlrCNMEGMRkmHWioSw27oWwpDmuIgx5fgIgZBQvOIZLvA+ln++7h39g8JsbtIYewhhHR3CJ9GKWavc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHyl3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpOeg//TEVrXzdMbiSG3a+rOoTuCChGvSEeq8ZVaw/+hlpMxULd4YcR\r\nwNlijBcebXPKeu9hVGbueAnWjvzO0dao1bgvicrlmuvw0NVzqVPluDaDmVps\r\nLVH4cpaockhBmkNc//X3qHLwzPdaxh6P/wY3kmH5QtfIBZA+gV0vVhm6LOnu\r\nQPk09I4h4/oZu3nufaVo5VIGhMH2l5ekoH8be0uurpGDRfqEZO9Jyjenu3Fh\r\nXog/jIwJYHcQuxwkcdHWVFCEaVmVHyaBOZZ+fwD2LMsebOGz4aShoNbZmc8f\r\nJJ5AVhTABaBeUbWzldWWp9RepqIzm3mOlMdIhEysKISGUFsgVH+VAXz/Flf7\r\nc6mK0ApJrlzIV1SuCZeKCUyuwtIn38QM6r3CkhA3qIPIGu9vvH1R/albC/fZ\r\nTxgsn90kf5a1x2b83XVTa9q+yyJrZc6KCBbHhG71na3vv9Q07art/rm4oe+R\r\nGZwzpjmuuaBZarojR1JR8VMBC2m7lZIn7hih2jKSIpWvkmZYzvId9zz0/GhQ\r\n+YGIMO7bFKb+Pb8I+PYp7kd5+cmGTt14dLZlWA7UC2hUkrMLq+W5vhL8XTHT\r\nHzf0Hb4ElCJxO3sp0PkRbMz+n8XSyNrh9rbZD19t2yzZggs4EqNGqNrRUmOb\r\n2zvAEDcjOOSVgiWqMTBAlY/Ilmnr0EXcVWc=\r\n=aXqN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.2_1662986615358_0.7177439178423959"},"_hasShrinkwrap":false},"1.1.3":{"name":"npx-import","version":"1.1.3","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"8cfb7144034bda6ab71a449279d77baf20bdcf1f","_id":"npx-import@1.1.3","_nodeVersion":"18.3.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-zy6249FJ81OtPsvz2y0+rgis31EN5wbdwBG2umtEh65W/4onYArHuoUSZ+W+T7BQYK7YF+h9G4CuGPusMCcLOw==","shasum":"680dff2be6cd635ec67fae91c1da544f7303da5c","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.3.tgz","fileCount":18,"unpackedSize":61515,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDSiPrHbcaN9nMfxAEyemk7hqHZpYO2GklJ7b1wC0aOdgIhAMFFqDUP/31RdZAbjWztiq6tuuJ7HP7AO4mVUxXxjNQ6"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjI1kqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp7dw//Q5D7o7zVA7Nzd1R76yqRQZYbh/kpi/5GyiMDa3hY04geP1fR\r\nkHWasGUV7fBuXyIYM53KZehhYFJgdPlHLa6zrB0ClbgLJCRba7LksEmZEk3J\r\nuckSykyhQ/Y39aGMX0TIa0ymkRUNsdlQnskM7zxQSLQXwH63YNlYZSZDpJoK\r\nUzzQicT4iZaO4qdAAjikF1gO4EBM0pIXXmGzi2+/4Y/UingiJuQlPLLl19Hz\r\nu7B2yvHuwmp8T7Z6cxN/l2Hae/DmRek/8aKJVDXh3/53d7lwvqkXh9iq0G9v\r\nUYppDYt8GlK72cXQgYnI3gUBoWGc8lu4k72IBBwfEg5dBnSTyNDkcfJIxFE7\r\nZWKhINu4TxjmQqdEqdWJjDu1qV2jGoxzfg38bAMCejwzTh6290QoF7xW8i8R\r\nDcKI0WroU9svQMn2d/wU1bQ4bV9rfz4jZqU4yx2dqaH0LpO5nuYmKaFSc0K+\r\nEK93lY41E4RXBlyUh7sx5uzp1RXehgr0e2arqpSFWKVvBgFG7paFhrRCMcxK\r\nGHUASZzxJou3tN2Jf75Lj+N+fiNWAlbW7x2fX1ixszVqwHR3bwFgkM6TY9F3\r\nUN+UVq4/+PNzOFD8jTxJmenUNmKgtg/jQDTIU57RkVp1FcG8h+HHQAhCOWKA\r\nSPQnBkhcJD99rcBjQsnkEYc0+tLUN862woQ=\r\n=EDUB\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.3_1663260970187_0.7704642030224411"},"_hasShrinkwrap":false},"1.1.4":{"name":"npx-import","version":"1.1.4","description":"Runtime dependencies, installed as if by magic ✨","main":"lib/index.js","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","go":"node --experimental-vm-modules test/go.js","test":"pnpm build && vitest","test:watch":"vitest --watch"},"keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","homepage":"https://github.com/geelen/npx-import","devDependencies":{"@types/node":"^18.6.3","@types/semver":"^7.3.10","@types/validate-npm-package-name":"^4.0.0","chalk":"^5.0.1","prettier":"^2.7.1","typescript":"^4.7.4","vitest":"^0.20.3"},"dependencies":{"execa":"^6.1.0","parse-package-name":"^1.0.0","semver":"^7.3.7","validate-npm-package-name":"^4.0.0"},"types":"./lib/index.d.ts","gitHead":"b66f9991399212a4b0b00bb688ff1ab7d57aacb0","_id":"npx-import@1.1.4","_nodeVersion":"18.3.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==","shasum":"0ee9a27484c633255528f7ec2e4c2adeaa1fcda3","tarball":"https://registry.npmjs.org/npx-import/-/npx-import-1.1.4.tgz","fileCount":18,"unpackedSize":61616,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD3+VTg8q6lZabcXBufMWDCZJUaSUvBXY4OpPIg2fG9UwIgBibme0A7MVazotA9kNs4CWnsnExApcQj0OD/hcL0WEM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjSQfuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoJAw/+JJM+jOKz31Ao7X5zCX39ia4FSZPYbl5Pr+/l/l2E9UfBsOa4\r\nkF8hrCZlyGIhVcFlmX6k+XbUeuy5BN2Fpr9HCZypYYQFMm3+ESM6Le85UMxH\r\nRg6tfHEoOF+hzJ5mOH2pWXOxnLFjuVmwRnkcQL0dLNLmTHjXS9P4pyFUYITq\r\ny5POO2RwIyQAhSHEjfhkjl3m8slKPkgr+KECPN4/krXsdLwhozw3DEw2mahq\r\ngImNpfMKj7Wd+NFEidll4fLZGq1/8xToXkoJ3pDzqcARSotpAE5CR82YKX8C\r\nvJexHH0LcsGf1Z4iKSMOi9pYdXaYC36ocZCymDPcgGKZsZqydL1lMafFy8oI\r\n7WoEESUbG+b99xSgPzCsCzf8abi908yaE0ZO/JeDnJWi5UeuNo89C4y8MVUj\r\nSIdiojyCsJAj/t9oNO8T+etgFJdtInVw1ntzqKet+4CR3RFfKv40KZJaiSEX\r\ntD0NiziDFIJ+IzzC6oX9TRG/GWKJyF5PhEpSBWUhAk4o+8EPapy34l7NDOKT\r\neTDg/yc79Ygt0cg/dj4dHv6J69OTlVHgkIT6cLFFRQmz+UdoQXd4bceuezbQ\r\ngfqne+8JPjincHsg48zTIHuew7BRwoib64wwFINzgnetfnpArGIvP9H96N6w\r\nFcdp1vMf29kt5+nA7GNtTgoUIqikyAthI30=\r\n=vegI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"geelen","email":"glen@glenmaddern.com"},"directories":{},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/npx-import_1.1.4_1665730542629_0.7079187789454524"},"_hasShrinkwrap":false}},"time":{"created":"2022-08-03T17:50:31.694Z","0.0.0":"2022-08-03T17:50:31.900Z","modified":"2022-10-14T06:55:42.973Z","0.0.1":"2022-08-04T11:33:41.413Z","0.0.2":"2022-08-04T13:43:25.593Z","1.0.0":"2022-08-04T14:54:26.788Z","1.0.1":"2022-08-05T11:18:32.394Z","1.0.2":"2022-08-09T11:08:39.945Z","1.0.3-0":"2022-08-10T09:05:54.773Z","1.0.3":"2022-08-12T16:54:28.260Z","1.0.4-0":"2022-08-12T17:16:57.152Z","1.0.5-0":"2022-08-12T17:23:56.947Z","1.1.0":"2022-09-12T11:07:33.306Z","1.1.1":"2022-09-12T11:46:56.958Z","1.1.2-0":"2022-09-12T11:59:55.283Z","1.1.2-1":"2022-09-12T12:20:42.303Z","1.1.2":"2022-09-12T12:43:35.525Z","1.1.3":"2022-09-15T16:56:10.379Z","1.1.4":"2022-10-14T06:55:42.887Z"},"maintainers":[{"name":"geelen","email":"glen@glenmaddern.com"}],"description":"Runtime dependencies, installed as if by magic ✨","homepage":"https://github.com/geelen/npx-import","keywords":[],"author":{"name":"Glen Maddern","email":"glenmaddern@gmail.com"},"license":"ISC","readme":"# 🧙‍♂️ `npx-import` 🧙‍♀️\n\n### Runtime dependencies, installed _as if by magic_ ✨\n\n[![twitter](https://img.shields.io/badge/@glenmaddern-blue.svg?style=flat&logo=twitter&label=​)](https://twitter.com/glenmaddern)&nbsp; [![GitHub last commit](https://img.shields.io/github/last-commit/geelen/npx-import?logo=github&style=flat&label=​)](https://github.com/geelen/npx-import)&nbsp; [![npm](https://img.shields.io/npm/v/npx-import?label=​&logo=npm)](https://www.npmjs.com/package/npx-import) \n\n`npx-import` can be used as a drop-in replacement for [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import):\n\n```ts\nimport { npxImport } from 'npx-import'\n\n// If big-dep isn't installed locally, npxImport will try\n// to download, install & load it, completely seamlessly.\nconst dependency = await npxImport('big-dep')\n```\n\nIt's exactly like [`npx`](https://docs.npmjs.com/cli/v8/commands/npx), but for `import()`! <sub><sub><sup>(hence the name)</sup></sub></sub>\n\nIs this a good idea? See [FAQ](#faq) below.\n\n## Usage\n\n`npx-import` is ideal for deferring installation for dependencies that are unexpectedly large, require native compilation, or not used very often (or some combination thereof), for example:\n\n```ts\n// Statically import small/common deps as normal\nimport textRenderer from 'tiny-text-renderer'\n\n// Use npxImport to defer\nimport { npxImport } from 'npx-import'\n\nexport async function writeToFile(report: Report, filename: string) {\n\n  if (filename.endsWith('.png')) {\n    console.log(`This is a PNG! We'll have to compile imagemagick!`)\n    const { default: magick } = await npxImport('imagemagick-utils@^1.1.0')\n    await magick.renderToPNG(report, filename)\n\n  } else if (filename.endsWith('.pdf')) {\n    console.log(`Argh, a PDF!? Go make a cuppa, this'll take a while...`)\n    const { default: pdfBoi } = await npxImport('chonk-pdf-boi@3.1.4')\n    await pdfBoi.generate(report, filename)\n\n  } else {\n    console.log(`Writing to ${filename}...`)\n    await textRenderer.write(report, filename)\n  }\n  console.log(`Done!`)\n}\n```\n\nWhen run, `npx-import` will log out some explanation, as well as instructions for installing the dependency locally & skipping this step in future:\n\n```\n❯ node ./index.js --filename=image.png\n\nThis is a PNG! We'll have to compile imagemagick!\n[NPXI] imagemagick-utils not available locally. Attempting to use npx to install temporarily.\n[NPXI] Installing... (npx -y -p imagemagick-utils@^1.1.0)\n[NPXI] Installed into /Users/glen/.npm/_npx/8cac855b1579fd07/node_modules.\n[NPXI] To skip this step in future, run: pnpm add -D imagemagick-utils@^1.1.0\nDone!\n```\n\nFor some types of dependencies, this is a much better UX than the alternatives:\n\n- You either add `imagemagick-utils` & `chonk-pdf-boi` as dependencies, slowing down initial install.\n- The first time a user tries to export a PNG/PDF, you error out with instructions to install the relevant package and retry.\n- You pause, prompt the user for confirmation, then try to detect which package manager they're using and auto-install the dependency for them.\n\nThe last of these generally works well but `npx-import` has slightly different properties:\n\n- The user doesn't need to be prompted—if the dependency can be sourced, installed & transparently included, the program doesn't need to be interrupted.\n- Your user's current project directory is never altered as a side-effect of running a program.\n\nMost importantly, though, **it's compatible with `npx`!** For example, `npx some-cli --help` can be super fast but `npx some-cli export --type=pdf` can transparently download the required dependencies during execution. It's super neat!\n\n## Installation\n\n```\nnpm install --save npx-import\npnpm add -P npx-import\nyarn add npx-import\n```\n\n## Typescript\n\nJust like `import()`, the return type default to `any`. But you can import the types of a devDependency without any consumers of your package needing to download it at installation time.\n\n```\npnpm add -D big-dep\n```\n\n```ts\nimport { npxImport } from 'npx-import'\ntype BigDepType = typeof import('big-dep')\n\nconst bigDep = await npxImport<BigDepType>('big-dep')\n```\n\n## API\n\n* Since package versions are no longer tracked in your `package.json`, we recommend being explicit:\n\n```ts\nconst lazyDep = await npxImport('left-pad@1.3.0')\n```\n\nAny package specifier that's valid in `package.json` will work here: e.g. `^1.0.0`, `~2.3.0`, `>4.0.0`, `@latest`, `@next`, etc.\n\nNote: there is a speed benefit from using exact versions. `npxImport(pkg-a@1.2.3)` will run `npx --prefer-offline` under the hood, making it faster after the first run (since it doesn't first check the NPM registry for newer versions).\n\n* You can also install multiple packages at once:\n\n```ts\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'])\n```\n\n`npx-import` also takes a third argument, which lets you customise, or silence, the log output. Each line that would normally be printed is passed to the logger function:\n\n```ts\nconst grayLog = (line: string) => console.log(chalk.gray(line))\nconst [depA, depB] = await npxImport(['dep-a@7.8.2', 'dep-b@7.8.2'], grayLog)\n```\n\n* Use `npxResolve` instead of `require.resolve` to get the path (local or temporary)\n\n```ts\nexport function getSQLiteNativeBindingLocation() {\n  return path.resolve(\n    path.dirname(npxResolve(\"better-sqlite3\")),\n    \"../build/Release/better_sqlite3.node\"\n  );\n}\n```\n\nNote, `npxResolve` requires that you'd previously called `npxImport` for the same package.\n\n## FAQ\n\n### 🤔 Isn't this, like, a heroically bad idea?\n\nNah it's good actually.\n\n### 🤨 No but seriously, isn't using `npx` a big security hole?\n\nInitially, `npx` didn't prompt before downloading and executing a package, which was _definitely_ a security risk. But that's been [fixed since version 7](https://github.com/npm/npx/issues/9#issuecomment-786940691). Now, if you're intending to write `npx prettier` to format your code and accidentally type `npx prettomghackmycomputerpls`, you'll get a helpful prompt:\n\n```\n❯ npx prettier@latest\nNeed to install the following packages:\n  prettomghackmycomputerpls@6.6.6\nOk to proceed? (y)\n```\n\nThis gives the user a chance to see their mistake and prevent being hacked to bits.\n\n### 😠 But hang on, you're never prompting the user to confirm!\n\nAh yes, that seems to go against the previous point. But `npx-import` isn't being triggered from a potentially clumsy human on a keyboard, it's running inside some source code you've (by definition) already authorised to run on your machine.\n\n`npx-import` is an alternative to publishing these as normal dependencies of your project and having your users download them at install time. `npm install` doesn't prompt the user to approve every transitive dependency of what's being installed/run, so `npx-import` doesn't either.\n\n### 🧐 What if the user has already installed the dependency somewhere?\n\nThen `npxImport` short-circuits, returning the local version without logging anything out. This is what the user is instructed to do to \"skip this step in future\". In other words, `npxImport()` first tries to call your native `import()`, and only does anything if that fails.\n\nNote that this also works for multiple dependencies, `npxImport(['pkg-a', 'pkg-b', 'pkg-c'])` will only fetch & install those that are missing.\n\n### 🤪 Doesn't this mean dependencies gets repeatedly downloaded & installed?\n\nNo! `npx` maintains a cache in the user's home directory. If a cached package is found, `npx` will (by default) hit NPM to check if there's any new versions for that specifier, and if not, return the cache. `npxImport` adds a small optimisation—if you specify an exact package version (e.g. `@7.8.2`), it'll run `npx --prefer-offline` to skip the NPM check.\n\nSo new packages are only downloaded & installed when:\n\n* It's the first time a particular package/version combo is seen (see next section)\n* No locked version was provided and there's a new version on NPM\n\n### 😵‍💫 What about multiple projects? Doesn't the cache mean projects can clobber/overwrite/conflict with each other?\n\nAs it turns out, no! While I wasn't paying attention, `npx` got really smart! To understand why, we need to look at how `npx` works:\n\nFor starters, `npx some-pkg` is a shorthand for `npx -p some-pkg <command>`, where `<command>` is whatever `bin` that `some-pkg` declares. Often, the `<command>` and the package name are the same (e.g. `npx prettier`), but it's the `bin` field inside the package that's really being used. Otherwise, scoped packages (like `npx @11ty/eleventy`) would never work. If there's no `bin` field declared (e.g. for `chokidar`, you need `npx chokidar-cli`), or if there's more than one (e.g. for `typescript`, you need `npx -p typescript tsc`), you have to use the expanded form.\n\nBut there's no requirement that `<command>` is a `bin` inside the package at all! It can be any command (at least for `npx`, `pnpm dlx` and `yarn dlx` have different restrictions), for example, we can inject a `node -e` command and start to learn about what's going on:\n\n```\n❯ npx -y -p is-odd node -e 'console.log(process.env.PATH.split(\":\"))' | grep .npm/_npx\n  '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin',\n```\n\nUsing `process.env.PATH` and searching for `.npm/_npx` is, on OSX with NPX v8+, a reliable way to find out where `npx` is installing these temporary packages. Let's look inside:\n\n```\n❯ ll2 /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/\ndrwxr-xr-x    - glen  4 Aug 11:07  /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc\ndrwxr-xr-x    - glen  4 Aug 11:07 ├──  node_modules\n.rw-r--r--  780 glen  4 Aug 11:07 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:07 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:07 │  └──  is-odd\n.rw-r--r-- 1.4k glen  4 Aug 11:07 ├──  package-lock.json\n.rw-r--r--   51 glen  4 Aug 11:07 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/package.json\n{\n  \"dependencies\": {\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nThat looks like a pretty normal project directory to me!\n\n> Aside, `ll2` is my super rad alias for `exa --icons -laTL 2`. See [exa](https://github.com/ogham/exa).\n\nNow, the crucial bit: **every time `npx` runs for some unique set of packages it creates a new directory**. That goes for installing multiple deps at once but also for different named/pinned versions/tags for individual packages:\n\n```\n❯ export LOG_NPX_DIR=\"node -e 'console.log(process.env.PATH.split(\\\":\\\").filter(p => p.match(/\\.npm\\/_npx/)))'\"\n\n❯ npx -y -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e1b5bd0eb9f99fbc/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@latest $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/ecc6e2260c717fec/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/c41e9ab9d1d9c43f/node_modules/.bin' ]\n\n❯ npx -y -p is-odd@\\^3.0.1 $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/e86896689f5aebbb/node_modules/.bin' ]\n```\n\nNote that **every one of these commands downloaded the same version of `is-odd`**, but because they were referenced using different identifiers, `_` vs `latest` vs `3.0.1` vs `>3.0.1`, `npx` played it safe and made a new temporary directory.\n\nFor multiple packages, the same rule applies, although order is not important:\n\n```\n❯ npx -y -p is-odd -p is-even $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ npx -y -p is-even -p is-odd $LOG_NPX_DIR\n[ '/Users/glen/.npm/_npx/f9af4fded130fd33/node_modules/.bin' ]\n\n❯ ll2 /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37  /Users/glen/.npm/_npx/f9af4fded130fd33\ndrwxr-xr-x    - glen  4 Aug 11:37 ├──  node_modules\n.rw-r--r-- 2.6k glen  4 Aug 11:37 │  ├──  .package-lock.json\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-buffer\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-even\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-number\ndrwxr-xr-x    - glen  4 Aug 11:37 │  ├──  is-odd\ndrwxr-xr-x    - glen  4 Aug 11:37 │  └──  kind-of\n.rw-r--r-- 4.8k glen  4 Aug 11:37 ├──  package-lock.json\n.rw-r--r--   76 glen  4 Aug 11:37 └──  package.json\n\n❯ cat /Users/glen/.npm/_npx/f9af4fded130fd33/package.json\n{\n  \"dependencies\": {\n    \"is-even\": \"^1.0.0\",\n    \"is-odd\": \"^3.0.1\"\n  }\n}\n```\n\nSo `npx` is doing exactly the same as an `npm install`, with a `package.json`, `package-lock.json`, `node_modules` etc. It's just dynamically creating directories based on some hash of its inputs. So the only way two projects can use the same package in the cache is if they _both_ ask for _exactly_ the same packages & versions. It's super clever!\n\n### 😐 But what about transitive deps? Won't you get duplication?\n\nSadly, yes. If both your package `main-pkg` and `util-a` depend on `util-b`, then calling `npxImport('util-a')` from within `main-pkg` will create a new directory with a second copy of `util-b`. If there are globals in that package, or if the version specifiers are slightly different, you could potentially have problems.\n\nIt's probably possible to [detect this in future](https://github.com/geelen/npx-import/issues/2) and warn/error out. But for now, I recommend using `npxImport` for mostly self-contained dependencies.\n\n### 🫤 What about version mismatch with local files?\n\nIf a user has `pkg-a` version `1.0.0` installed, but one of their packages calls `npxImport('pkg-a@^2.0.0')`, `npxImport` isn't smart enough ([yet](https://github.com/geelen/npx-import/issues/3)) to know that the local version of `pkg-a` doesn't match the version range specified (since it's using native `import()` under the hood). Without `npxImport`, the `npm install` step would have had a chance to bump the installed version of `pkg-a` to meet the requirements of _all_ packages being used, but we're bypassing that.\n\nThis will be fixed in a future version.\n\n### 🫠 What kind of packages would you use this for?\n\n- Anything with native extensions needing building (do that when you need it)\n- Packages with large downloads (e.g. puppeteer, sqlite-node)\n- CLI packages that want to make `npx my-cli --help` or `npx my-cli init` really fast and dependency-free, but also allow `npx my-cli <cmd>` to pull in arbitrary deps on-demand, without forcing the user to stop, create a local directory, and install dev dependencies.\n- Anything already making heavy use of `npx`. You're in the jungle, baby.\n\n---\n\nBuilt with <3 during a massive yak shave by Glen Maddern.\n","readmeFilename":"README.md"}