commit
84557a8405
|
@ -0,0 +1,48 @@
|
|||
## [2.1.1](https://github.com/TriPSs/conventional-changelog-action/compare/v2.1.0...v2.1.1) (2020-04-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed git being called incorrectly ([6bfb377](https://github.com/TriPSs/conventional-changelog-action/commit/6bfb377c32c27e881a77139109c1d40afed12415))
|
||||
* Fixed tagPrefix being provided as context instead of option ([e66c42b](https://github.com/TriPSs/conventional-changelog-action/commit/e66c42b7603eadc663e120f1355b7da328301ece))
|
||||
* Fixed tagPrefix not being provided to bumper ([5b65653](https://github.com/TriPSs/conventional-changelog-action/commit/5b65653fe8cedf1219e523bf44ee0a7453dcc8d2))
|
||||
* Pull full history so it works with checkout@v2 ([50ab4fa](https://github.com/TriPSs/conventional-changelog-action/commit/50ab4fa80a641d1a198fb5fe17536a5db6a39a3a))
|
||||
|
||||
|
||||
|
||||
# [2.1.0](https://github.com/TriPSs/conventional-changelog-action/compare/v2.0.1...v2.1.0) (2020-04-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Added the option to provide the location of the packge.json ([c18a89e](https://github.com/TriPSs/conventional-changelog-action/commit/c18a89eed164e4414b30da38013938f498abef11))
|
||||
|
||||
|
||||
|
||||
## [2.0.1](https://github.com/TriPSs/conventional-changelog-action/compare/v2.0.0...v2.0.1) (2020-04-16)
|
||||
|
||||
|
||||
|
||||
# [2.0.0](https://github.com/TriPSs/conventional-changelog-action/compare/v1.3.0...v2.0.0) (2020-04-16)
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* Changed int 5 to string 5 as default value ([b7d2808](https://github.com/TriPSs/conventional-changelog-action/commit/b7d28084e6d04b3b171793bfb8b28e47efb23025))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Changed changelog-release-count to release-count
|
||||
|
||||
|
||||
|
||||
# [1.3.0](https://github.com/TriPSs/conventional-changelog-action/compare/v1.2.0...v1.3.0) (2020-02-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Make the releaseCount configurable ([da75f59](https://github.com/TriPSs/conventional-changelog-action/commit/da75f5939add67131c5c804a1e2973ba6667957b))
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
../JSONStream/bin.js
|
|
@ -0,0 +1 @@
|
|||
../conventional-changelog-writer/cli.js
|
|
@ -0,0 +1 @@
|
|||
../conventional-commits-parser/cli.js
|
|
@ -0,0 +1 @@
|
|||
../conventional-recommended-bump/cli.js
|
|
@ -0,0 +1 @@
|
|||
../get-pkg-repo/cli.js
|
|
@ -0,0 +1 @@
|
|||
../git-raw-commits/cli.js
|
|
@ -0,0 +1 @@
|
|||
../git-semver-tags/cli.js
|
|
@ -0,0 +1 @@
|
|||
../handlebars/bin/handlebars
|
|
@ -0,0 +1 @@
|
|||
../normalize-package-data/node_modules/semver/bin/semver
|
|
@ -0,0 +1 @@
|
|||
../get-pkg-repo/node_modules/strip-indent/cli.js
|
|
@ -0,0 +1 @@
|
|||
../uglify-js/bin/uglifyjs
|
|
@ -0,0 +1,182 @@
|
|||
{
|
||||
"systemParams": "linux-x64-72",
|
||||
"modulesFolders": [
|
||||
"node_modules"
|
||||
],
|
||||
"flags": [
|
||||
"production"
|
||||
],
|
||||
"linkedModules": [],
|
||||
"topLevelPatterns": [
|
||||
"@actions/core@1.2.3",
|
||||
"@actions/exec@1.0.4",
|
||||
"conventional-changelog@3.1.18",
|
||||
"conventional-recommended-bump@6.0.5"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"@actions/core@1.2.3": "https://registry.yarnpkg.com/@actions/core/-/core-1.2.3.tgz#e844b4fa0820e206075445079130868f95bfca95",
|
||||
"@actions/exec@1.0.4": "https://registry.yarnpkg.com/@actions/exec/-/exec-1.0.4.tgz#99d75310e62e59fc37d2ee6dcff6d4bffadd3a5d",
|
||||
"@actions/io@^1.0.1": "https://registry.yarnpkg.com/@actions/io/-/io-1.0.2.tgz#2f614b6e69ce14d191180451eb38e6576a6e6b27",
|
||||
"JSONStream@^1.0.4": "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0",
|
||||
"add-stream@^1.0.0": "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa",
|
||||
"array-find-index@^1.0.1": "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1",
|
||||
"array-ify@^1.0.0": "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece",
|
||||
"arrify@^1.0.1": "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d",
|
||||
"buffer-from@^1.0.0": "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef",
|
||||
"camelcase-keys@^2.0.0": "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7",
|
||||
"camelcase-keys@^4.0.0": "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77",
|
||||
"camelcase@^2.0.0": "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f",
|
||||
"camelcase@^4.1.0": "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd",
|
||||
"commander@2.20.0": "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422",
|
||||
"compare-func@^1.3.1": "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648",
|
||||
"concat-stream@^2.0.0": "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1",
|
||||
"conventional-changelog-angular@^5.0.6": "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz#269540c624553aded809c29a3508fdc2b544c059",
|
||||
"conventional-changelog-atom@^2.0.3": "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-2.0.3.tgz#3bd14280aa09fe3ec49a0e8fe97b5002db02aad4",
|
||||
"conventional-changelog-codemirror@^2.0.3": "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.3.tgz#ebc088154684f8f5171446b8d546ba6b460d46f2",
|
||||
"conventional-changelog-conventionalcommits@^4.2.3": "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.3.tgz#22855b32d57d0328951c1c2dc01b172a5f24ea37",
|
||||
"conventional-changelog-core@^4.1.4": "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.1.4.tgz#39be27fca6ef20a0f998d7a3a1e97cfa8a055cb6",
|
||||
"conventional-changelog-ember@^2.0.4": "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-2.0.4.tgz#c29b78e4af7825cbecb6c3fd6086ca5c09471ac1",
|
||||
"conventional-changelog-eslint@^3.0.4": "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.4.tgz#8f4736a23e0cd97e890e76fccc287db2f205f2ff",
|
||||
"conventional-changelog-express@^2.0.1": "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-2.0.1.tgz#fea2231d99a5381b4e6badb0c1c40a41fcacb755",
|
||||
"conventional-changelog-jquery@^3.0.6": "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.6.tgz#460236ad8fb1d29ff932a14fe4e3a45379b63c5e",
|
||||
"conventional-changelog-jshint@^2.0.3": "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.3.tgz#ef6e2caf2ee6ffdfda78fcdf7ce87cf6c512d728",
|
||||
"conventional-changelog-preset-loader@^2.3.0": "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.0.tgz#580fa8ab02cef22c24294d25e52d7ccd247a9a6a",
|
||||
"conventional-changelog-writer@^4.0.11": "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.11.tgz#9f56d2122d20c96eb48baae0bf1deffaed1edba4",
|
||||
"conventional-changelog@3.1.18": "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.18.tgz#7da0a5ab34a604b920b8bf71c6cf5d952f0e805e",
|
||||
"conventional-commits-filter@^2.0.2": "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1",
|
||||
"conventional-commits-parser@^3.0.8": "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz#23310a9bda6c93c874224375e72b09fb275fe710",
|
||||
"conventional-recommended-bump@6.0.5": "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.0.5.tgz#be7ec24b43bef57108042ea1d49758b58beabc03",
|
||||
"core-util-is@~1.0.0": "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7",
|
||||
"currently-unhandled@^0.4.1": "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea",
|
||||
"dargs@^4.0.1": "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17",
|
||||
"dateformat@^3.0.0": "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae",
|
||||
"decamelize-keys@^1.0.0": "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9",
|
||||
"decamelize@^1.1.0": "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290",
|
||||
"decamelize@^1.1.2": "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290",
|
||||
"dot-prop@^3.0.0": "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177",
|
||||
"error-ex@^1.2.0": "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf",
|
||||
"error-ex@^1.3.1": "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf",
|
||||
"find-up@^1.0.0": "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f",
|
||||
"find-up@^2.0.0": "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7",
|
||||
"get-pkg-repo@^1.0.0": "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d",
|
||||
"get-stdin@^4.0.1": "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe",
|
||||
"git-raw-commits@2.0.0": "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5",
|
||||
"git-remote-origin-url@^2.0.0": "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f",
|
||||
"git-semver-tags@^3.0.1": "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-3.0.1.tgz#9cb9e4974437de1f71f32da3bfe74f4d35afb1b9",
|
||||
"gitconfiglocal@^1.0.0": "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b",
|
||||
"graceful-fs@^4.1.2": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02",
|
||||
"handlebars@^4.4.0": "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.3.tgz#180bae52c1d0e9ec0c15d7e82a4362d662762f6e",
|
||||
"hosted-git-info@^2.1.4": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c",
|
||||
"indent-string@^2.1.0": "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80",
|
||||
"indent-string@^3.0.0": "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289",
|
||||
"inherits@^2.0.3": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c",
|
||||
"inherits@~2.0.3": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c",
|
||||
"ini@^1.3.2": "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927",
|
||||
"is-arrayish@^0.2.1": "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d",
|
||||
"is-finite@^1.0.0": "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa",
|
||||
"is-obj@^1.0.0": "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f",
|
||||
"is-plain-obj@^1.1.0": "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e",
|
||||
"is-text-path@^1.0.1": "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e",
|
||||
"is-utf8@^0.2.0": "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72",
|
||||
"isarray@~1.0.0": "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11",
|
||||
"json-parse-better-errors@^1.0.1": "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9",
|
||||
"json-stringify-safe@^5.0.1": "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb",
|
||||
"jsonparse@^1.2.0": "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280",
|
||||
"load-json-file@^1.0.0": "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0",
|
||||
"load-json-file@^4.0.0": "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b",
|
||||
"locate-path@^2.0.0": "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e",
|
||||
"lodash._reinterpolate@^3.0.0": "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d",
|
||||
"lodash.ismatch@^4.4.0": "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37",
|
||||
"lodash.template@^4.0.2": "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab",
|
||||
"lodash.templatesettings@^4.0.0": "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33",
|
||||
"lodash@^4.17.15": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548",
|
||||
"loud-rejection@^1.0.0": "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f",
|
||||
"map-obj@^1.0.0": "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d",
|
||||
"map-obj@^1.0.1": "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d",
|
||||
"map-obj@^2.0.0": "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9",
|
||||
"meow@^3.3.0": "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb",
|
||||
"meow@^4.0.0": "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975",
|
||||
"meow@^5.0.0": "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4",
|
||||
"minimist-options@^3.0.1": "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954",
|
||||
"minimist@^1.1.3": "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284",
|
||||
"minimist@~0.0.1": "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf",
|
||||
"modify-values@^1.0.0": "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022",
|
||||
"neo-async@^2.6.0": "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c",
|
||||
"normalize-package-data@^2.3.0": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8",
|
||||
"normalize-package-data@^2.3.2": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8",
|
||||
"normalize-package-data@^2.3.4": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8",
|
||||
"normalize-package-data@^2.3.5": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8",
|
||||
"number-is-nan@^1.0.0": "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d",
|
||||
"object-assign@^4.0.1": "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863",
|
||||
"optimist@^0.6.1": "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686",
|
||||
"p-limit@^1.1.0": "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8",
|
||||
"p-locate@^2.0.0": "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43",
|
||||
"p-try@^1.0.0": "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3",
|
||||
"parse-github-repo-url@^1.3.0": "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50",
|
||||
"parse-json@^2.2.0": "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9",
|
||||
"parse-json@^4.0.0": "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0",
|
||||
"path-exists@^2.0.0": "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b",
|
||||
"path-exists@^3.0.0": "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515",
|
||||
"path-parse@^1.0.6": "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c",
|
||||
"path-type@^1.0.0": "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441",
|
||||
"path-type@^3.0.0": "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f",
|
||||
"pify@^2.0.0": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c",
|
||||
"pify@^2.3.0": "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c",
|
||||
"pify@^3.0.0": "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176",
|
||||
"pinkie-promise@^2.0.0": "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa",
|
||||
"pinkie@^2.0.0": "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870",
|
||||
"process-nextick-args@~2.0.0": "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2",
|
||||
"q@^1.5.1": "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7",
|
||||
"quick-lru@^1.0.0": "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8",
|
||||
"read-pkg-up@^1.0.1": "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02",
|
||||
"read-pkg-up@^3.0.0": "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07",
|
||||
"read-pkg@^1.0.0": "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28",
|
||||
"read-pkg@^3.0.0": "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389",
|
||||
"readable-stream@2 || 3": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc",
|
||||
"readable-stream@^3.0.2": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc",
|
||||
"readable-stream@~2.3.6": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf",
|
||||
"redent@^1.0.0": "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde",
|
||||
"redent@^2.0.0": "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa",
|
||||
"repeating@^2.0.0": "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda",
|
||||
"resolve@^1.10.0": "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6",
|
||||
"safe-buffer@~5.1.0": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d",
|
||||
"safe-buffer@~5.1.1": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d",
|
||||
"safe-buffer@~5.2.0": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519",
|
||||
"semver@2 || 3 || 4 || 5": "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7",
|
||||
"semver@^6.0.0": "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
|
||||
"signal-exit@^3.0.0": "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d",
|
||||
"source-map@^0.6.1": "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263",
|
||||
"source-map@~0.6.1": "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263",
|
||||
"spdx-correct@^3.0.0": "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4",
|
||||
"spdx-exceptions@^2.1.0": "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977",
|
||||
"spdx-expression-parse@^3.0.0": "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0",
|
||||
"spdx-license-ids@^3.0.0": "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654",
|
||||
"split2@^2.0.0": "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493",
|
||||
"split@^1.0.0": "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9",
|
||||
"string_decoder@^1.1.1": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e",
|
||||
"string_decoder@~1.1.1": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8",
|
||||
"strip-bom@^2.0.0": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e",
|
||||
"strip-bom@^3.0.0": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3",
|
||||
"strip-indent@^1.0.1": "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2",
|
||||
"strip-indent@^2.0.0": "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68",
|
||||
"text-extensions@^1.0.0": "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26",
|
||||
"through2@^2.0.0": "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd",
|
||||
"through2@^2.0.2": "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd",
|
||||
"through2@^3.0.0": "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a",
|
||||
"through@2": "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5",
|
||||
"through@>=2.2.7 <3": "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5",
|
||||
"trim-newlines@^1.0.0": "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613",
|
||||
"trim-newlines@^2.0.0": "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20",
|
||||
"trim-off-newlines@^1.0.0": "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3",
|
||||
"typedarray@^0.0.6": "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777",
|
||||
"uglify-js@^3.1.4": "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.2.tgz#fd8048c86d990ddd29fe99d3300e0cb329103f4d",
|
||||
"util-deprecate@^1.0.1": "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf",
|
||||
"util-deprecate@~1.0.1": "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf",
|
||||
"validate-npm-package-license@^3.0.1": "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a",
|
||||
"wordwrap@~0.0.2": "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107",
|
||||
"xtend@~4.0.1": "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54",
|
||||
"yargs-parser@^10.0.0": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
|
||||
},
|
||||
"files": [],
|
||||
"artifacts": {}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
# `@actions/core`
|
||||
|
||||
> Core functions for setting results, logging, registering secrets and exporting variables across actions
|
||||
|
||||
## Usage
|
||||
|
||||
### Import the package
|
||||
|
||||
```js
|
||||
// javascript
|
||||
const core = require('@actions/core');
|
||||
|
||||
// typescript
|
||||
import * as core from '@actions/core';
|
||||
```
|
||||
|
||||
#### Inputs/Outputs
|
||||
|
||||
Action inputs can be read with `getInput`. Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
|
||||
|
||||
```js
|
||||
const myInput = core.getInput('inputName', { required: true });
|
||||
|
||||
core.setOutput('outputKey', 'outputVal');
|
||||
```
|
||||
|
||||
#### Exporting variables
|
||||
|
||||
Since each step runs in a separate process, you can use `exportVariable` to add it to this step and future steps environment blocks.
|
||||
|
||||
```js
|
||||
core.exportVariable('envVar', 'Val');
|
||||
```
|
||||
|
||||
#### Setting a secret
|
||||
|
||||
Setting a secret registers the secret with the runner to ensure it is masked in logs.
|
||||
|
||||
```js
|
||||
core.setSecret('myPassword');
|
||||
```
|
||||
|
||||
#### PATH Manipulation
|
||||
|
||||
To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `addPath`. The runner will prepend the path given to the jobs PATH.
|
||||
|
||||
```js
|
||||
core.addPath('/path/to/mytool');
|
||||
```
|
||||
|
||||
#### Exit codes
|
||||
|
||||
You should use this library to set the failing exit code for your action. If status is not set and the script runs to completion, that will lead to a success.
|
||||
|
||||
```js
|
||||
const core = require('@actions/core');
|
||||
|
||||
try {
|
||||
// Do stuff
|
||||
}
|
||||
catch (err) {
|
||||
// setFailed logs the message and sets a failing exit code
|
||||
core.setFailed(`Action failed with error ${err}`);
|
||||
}
|
||||
|
||||
Note that `setNeutral` is not yet implemented in actions V2 but equivalent functionality is being planned.
|
||||
|
||||
```
|
||||
|
||||
#### Logging
|
||||
|
||||
Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs).
|
||||
|
||||
```js
|
||||
const core = require('@actions/core');
|
||||
|
||||
const myInput = core.getInput('input');
|
||||
try {
|
||||
core.debug('Inside try block');
|
||||
|
||||
if (!myInput) {
|
||||
core.warning('myInput was not set');
|
||||
}
|
||||
|
||||
if (core.isDebug()) {
|
||||
// curl -v https://github.com
|
||||
} else {
|
||||
// curl https://github.com
|
||||
}
|
||||
|
||||
// Do stuff
|
||||
}
|
||||
catch (err) {
|
||||
core.error(`Error ${err}, action may still succeed though`);
|
||||
}
|
||||
```
|
||||
|
||||
This library can also wrap chunks of output in foldable groups.
|
||||
|
||||
```js
|
||||
const core = require('@actions/core')
|
||||
|
||||
// Manually wrap output
|
||||
core.startGroup('Do some function')
|
||||
doSomeFunction()
|
||||
core.endGroup()
|
||||
|
||||
// Wrap an asynchronous function call
|
||||
const result = await core.group('Do something async', async () => {
|
||||
const response = await doSomeHTTPRequest()
|
||||
return response
|
||||
})
|
||||
```
|
||||
|
||||
#### Action state
|
||||
|
||||
You can use this library to save state and get state for sharing information between a given wrapper action:
|
||||
|
||||
**action.yml**
|
||||
```yaml
|
||||
name: 'Wrapper action sample'
|
||||
inputs:
|
||||
name:
|
||||
default: 'GitHub'
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'main.js'
|
||||
post: 'cleanup.js'
|
||||
```
|
||||
|
||||
In action's `main.js`:
|
||||
|
||||
```js
|
||||
const core = require('@actions/core');
|
||||
|
||||
core.saveState("pidToKill", 12345);
|
||||
```
|
||||
|
||||
In action's `cleanup.js`:
|
||||
```js
|
||||
const core = require('@actions/core');
|
||||
|
||||
var pid = core.getState("pidToKill");
|
||||
|
||||
process.kill(pid);
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
interface CommandProperties {
|
||||
[key: string]: string;
|
||||
}
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
*/
|
||||
export declare function issueCommand(command: string, properties: CommandProperties, message: string): void;
|
||||
export declare function issue(name: string, message?: string): void;
|
||||
export {};
|
|
@ -0,0 +1,78 @@
|
|||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __importStar(require("os"));
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
process.stdout.write(cmd.toString() + os.EOL);
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
if (!command) {
|
||||
command = 'missing.command';
|
||||
}
|
||||
this.command = command;
|
||||
this.properties = properties;
|
||||
this.message = message;
|
||||
}
|
||||
toString() {
|
||||
let cmdStr = CMD_STRING + this.command;
|
||||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||||
cmdStr += ' ';
|
||||
let first = true;
|
||||
for (const key in this.properties) {
|
||||
if (this.properties.hasOwnProperty(key)) {
|
||||
const val = this.properties[key];
|
||||
if (val) {
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
cmdStr += ',';
|
||||
}
|
||||
cmdStr += `${key}=${escapeProperty(val)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
|
||||
return cmdStr;
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return (s || '')
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A');
|
||||
}
|
||||
function escapeProperty(s) {
|
||||
return (s || '')
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/:/g, '%3A')
|
||||
.replace(/,/g, '%2C');
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAwB;AAQxB;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,UAAkB,EAAE;IACtD,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"}
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* Interface for getInput options
|
||||
*/
|
||||
export interface InputOptions {
|
||||
/** Optional. Whether the input is required. If required and not present, will throw. Defaults to false */
|
||||
required?: boolean;
|
||||
}
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
export declare enum ExitCode {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
Success = 0,
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
Failure = 1
|
||||
}
|
||||
/**
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable
|
||||
*/
|
||||
export declare function exportVariable(name: string, val: string): void;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
export declare function setSecret(secret: string): void;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
export declare function addPath(inputPath: string): void;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
export declare function getInput(name: string, options?: InputOptions): string;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store
|
||||
*/
|
||||
export declare function setOutput(name: string, value: string): void;
|
||||
/**
|
||||
* Sets the action status to failed.
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
export declare function setFailed(message: string): void;
|
||||
/**
|
||||
* Gets whether Actions Step Debug is on or not
|
||||
*/
|
||||
export declare function isDebug(): boolean;
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
export declare function debug(message: string): void;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message
|
||||
*/
|
||||
export declare function error(message: string): void;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message
|
||||
*/
|
||||
export declare function warning(message: string): void;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
export declare function info(message: string): void;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
* Output until the next `groupEnd` will be foldable in this group
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
export declare function startGroup(name: string): void;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
export declare function endGroup(): void;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
* Returns the same type as the function itself.
|
||||
*
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
export declare function group<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store
|
||||
*/
|
||||
export declare function saveState(name: string, value: string): void;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
export declare function getState(name: string): string;
|
|
@ -0,0 +1,209 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const command_1 = require("./command");
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
//-----------------------------------------------------------------------
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable
|
||||
*/
|
||||
function exportVariable(name, val) {
|
||||
process.env[name] = val;
|
||||
command_1.issueCommand('set-env', { name }, val);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
function setSecret(secret) {
|
||||
command_1.issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store
|
||||
*/
|
||||
function setOutput(name, value) {
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets the action status to failed.
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
function setFailed(message) {
|
||||
process.exitCode = ExitCode.Failure;
|
||||
error(message);
|
||||
}
|
||||
exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Gets whether Actions Step Debug is on or not
|
||||
*/
|
||||
function isDebug() {
|
||||
return process.env['RUNNER_DEBUG'] === '1';
|
||||
}
|
||||
exports.isDebug = isDebug;
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
function debug(message) {
|
||||
command_1.issueCommand('debug', {}, message);
|
||||
}
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
* Output until the next `groupEnd` will be foldable in this group
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
function startGroup(name) {
|
||||
command_1.issue('group', name);
|
||||
}
|
||||
exports.startGroup = startGroup;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
function endGroup() {
|
||||
command_1.issue('endgroup');
|
||||
}
|
||||
exports.endGroup = endGroup;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
* Returns the same type as the function itself.
|
||||
*
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
function group(name, fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
startGroup(name);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn();
|
||||
}
|
||||
finally {
|
||||
endGroup();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store
|
||||
*/
|
||||
function saveState(name, value) {
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
//# sourceMappingURL=core.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,uCAA6C;AAE7C,uCAAwB;AACxB,2CAA4B;AAU5B;;GAEG;AACH,IAAY,QAUX;AAVD,WAAY,QAAQ;IAClB;;OAEG;IACH,6CAAW,CAAA;IAEX;;OAEG;IACH,6CAAW,CAAA;AACb,CAAC,EAVW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAUnB;AAED,yEAAyE;AACzE,YAAY;AACZ,yEAAyE;AAEzE;;;;GAIG;AACH,SAAgB,cAAc,CAAC,IAAY,EAAE,GAAW;IACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAA;IACvB,sBAAY,CAAC,SAAS,EAAE,EAAC,IAAI,EAAC,EAAE,GAAG,CAAC,CAAA;AACtC,CAAC;AAHD,wCAGC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,MAAc;IACtC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AACtC,CAAC;AAFD,8BAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,SAAiB;IACvC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;IACvC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAA;AAC7E,CAAC;AAHD,0BAGC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CAAC,IAAY,EAAE,OAAsB;IAC3D,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;IACrE,IAAI,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAA;KAC5D;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;AACnB,CAAC;AARD,4BAQC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED,yEAAyE;AACzE,UAAU;AACV,yEAAyE;AAEzE;;;;GAIG;AACH,SAAgB,SAAS,CAAC,OAAe;IACvC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAA;IACnC,KAAK,CAAC,OAAO,CAAC,CAAA;AAChB,CAAC;AAHD,8BAGC;AAED,yEAAyE;AACzE,mBAAmB;AACnB,yEAAyE;AAEzE;;GAEG;AACH,SAAgB,OAAO;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,CAAA;AAC5C,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAe;IACnC,sBAAY,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACpC,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAe;IACnC,eAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACzB,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,OAAe;IACrC,eAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC;AAFD,oBAEC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,eAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACtB,CAAC;AAFD,gCAEC;AAED;;GAEG;AACH,SAAgB,QAAQ;IACtB,eAAK,CAAC,UAAU,CAAC,CAAA;AACnB,CAAC;AAFD,4BAEC;AAED;;;;;;;GAOG;AACH,SAAsB,KAAK,CAAI,IAAY,EAAE,EAAoB;;QAC/D,UAAU,CAAC,IAAI,CAAC,CAAA;QAEhB,IAAI,MAAS,CAAA;QAEb,IAAI;YACF,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;SACpB;gBAAS;YACR,QAAQ,EAAE,CAAA;SACX;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CAAA;AAZD,sBAYC;AAED,yEAAyE;AACzE,uBAAuB;AACvB,yEAAyE;AAEzE;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAY;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;AAC3C,CAAC;AAFD,4BAEC"}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "@actions/core",
|
||||
"version": "1.2.3",
|
||||
"description": "Actions core lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
"actions",
|
||||
"core"
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
|
||||
"license": "MIT",
|
||||
"main": "lib/core.js",
|
||||
"types": "lib/core.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/toolkit.git",
|
||||
"directory": "packages/core"
|
||||
},
|
||||
"scripts": {
|
||||
"audit-moderate": "npm install && npm audit --audit-level=moderate",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.0.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
# `@actions/exec`
|
||||
|
||||
## Usage
|
||||
|
||||
#### Basic
|
||||
|
||||
You can use this package to execute tools in a cross platform way:
|
||||
|
||||
```js
|
||||
const exec = require('@actions/exec');
|
||||
|
||||
await exec.exec('node index.js');
|
||||
```
|
||||
|
||||
#### Args
|
||||
|
||||
You can also pass in arg arrays:
|
||||
|
||||
```js
|
||||
const exec = require('@actions/exec');
|
||||
|
||||
await exec.exec('node', ['index.js', 'foo=bar']);
|
||||
```
|
||||
|
||||
#### Output/options
|
||||
|
||||
Capture output or specify [other options](https://github.com/actions/toolkit/blob/d9347d4ab99fd507c0b9104b2cf79fb44fcc827d/packages/exec/src/interfaces.ts#L5):
|
||||
|
||||
```js
|
||||
const exec = require('@actions/exec');
|
||||
|
||||
let myOutput = '';
|
||||
let myError = '';
|
||||
|
||||
const options = {};
|
||||
options.listeners = {
|
||||
stdout: (data: Buffer) => {
|
||||
myOutput += data.toString();
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
myError += data.toString();
|
||||
}
|
||||
};
|
||||
options.cwd = './lib';
|
||||
|
||||
await exec.exec('node', ['index.js', 'foo=bar'], options);
|
||||
```
|
||||
|
||||
#### Exec tools not in the PATH
|
||||
|
||||
You can specify the full path for tools not in the PATH:
|
||||
|
||||
```js
|
||||
const exec = require('@actions/exec');
|
||||
|
||||
await exec.exec('"/path/to/my-tool"', ['arg1']);
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
import { ExecOptions } from './interfaces';
|
||||
export { ExecOptions };
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
export declare function exec(commandLine: string, args?: string[], options?: ExecOptions): Promise<number>;
|
|
@ -0,0 +1,44 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tr = __importStar(require("./toolrunner"));
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
||||
}
|
||||
// Path to tool to execute should be first arg
|
||||
const toolPath = commandArgs[0];
|
||||
args = commandArgs.slice(1).concat(args || []);
|
||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
//# sourceMappingURL=exec.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AACA,iDAAkC;AAIlC;;;;;;;;;GASG;AACH,SAAsB,IAAI,CACxB,WAAmB,EACnB,IAAe,EACf,OAAqB;;QAErB,MAAM,WAAW,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;SACpE;QACD,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC/B,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAkB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QACxE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;CAAA;AAdD,oBAcC"}
|
|
@ -0,0 +1,37 @@
|
|||
/// <reference types="node" />
|
||||
import * as stream from 'stream';
|
||||
/**
|
||||
* Interface for exec options
|
||||
*/
|
||||
export interface ExecOptions {
|
||||
/** optional working directory. defaults to current */
|
||||
cwd?: string;
|
||||
/** optional envvar dictionary. defaults to current process's env */
|
||||
env?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** optional. defaults to false */
|
||||
silent?: boolean;
|
||||
/** optional out stream to use. Defaults to process.stdout */
|
||||
outStream?: stream.Writable;
|
||||
/** optional err stream to use. Defaults to process.stderr */
|
||||
errStream?: stream.Writable;
|
||||
/** optional. whether to skip quoting/escaping arguments if needed. defaults to false. */
|
||||
windowsVerbatimArguments?: boolean;
|
||||
/** optional. whether to fail if output to stderr. defaults to false */
|
||||
failOnStdErr?: boolean;
|
||||
/** optional. defaults to failing on non zero. ignore will not fail leaving it up to the caller */
|
||||
ignoreReturnCode?: boolean;
|
||||
/** optional. How long in ms to wait for STDIO streams to close after the exit event of the process before terminating. defaults to 10000 */
|
||||
delay?: number;
|
||||
/** optional. input to write to the process on STDIN. */
|
||||
input?: Buffer;
|
||||
/** optional. Listeners for output. Callback functions that will be called on these events */
|
||||
listeners?: {
|
||||
stdout?: (data: Buffer) => void;
|
||||
stderr?: (data: Buffer) => void;
|
||||
stdline?: (data: string) => void;
|
||||
errline?: (data: string) => void;
|
||||
debug?: (data: string) => void;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=interfaces.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""}
|
|
@ -0,0 +1,37 @@
|
|||
/// <reference types="node" />
|
||||
import * as events from 'events';
|
||||
import * as im from './interfaces';
|
||||
export declare class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath: string, args?: string[], options?: im.ExecOptions);
|
||||
private toolPath;
|
||||
private args;
|
||||
private options;
|
||||
private _debug;
|
||||
private _getCommandString;
|
||||
private _processLineBuffer;
|
||||
private _getSpawnFileName;
|
||||
private _getSpawnArgs;
|
||||
private _endsWith;
|
||||
private _isCmdFile;
|
||||
private _windowsQuoteCmdArg;
|
||||
private _uvQuoteCmdArg;
|
||||
private _cloneExecOptions;
|
||||
private _getSpawnOptions;
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec(): Promise<number>;
|
||||
}
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
export declare function argStringToArray(argString: string): string[];
|
|
@ -0,0 +1,600 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __importStar(require("os"));
|
||||
const events = __importStar(require("events"));
|
||||
const child = __importStar(require("child_process"));
|
||||
const path = __importStar(require("path"));
|
||||
const io = __importStar(require("@actions/io"));
|
||||
const ioUtil = __importStar(require("@actions/io/lib/io-util"));
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
/*
|
||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
||||
*/
|
||||
class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath, args, options) {
|
||||
super();
|
||||
if (!toolPath) {
|
||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
||||
}
|
||||
this.toolPath = toolPath;
|
||||
this.args = args || [];
|
||||
this.options = options || {};
|
||||
}
|
||||
_debug(message) {
|
||||
if (this.options.listeners && this.options.listeners.debug) {
|
||||
this.options.listeners.debug(message);
|
||||
}
|
||||
}
|
||||
_getCommandString(options, noPrefix) {
|
||||
const toolPath = this._getSpawnFileName();
|
||||
const args = this._getSpawnArgs(options);
|
||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
||||
if (IS_WINDOWS) {
|
||||
// Windows + cmd file
|
||||
if (this._isCmdFile()) {
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows + verbatim
|
||||
else if (options.windowsVerbatimArguments) {
|
||||
cmd += `"${toolPath}"`;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows (regular)
|
||||
else {
|
||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
||||
for (const a of args) {
|
||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
||||
// creating processes on Unix is fundamentally different than Windows.
|
||||
// on Unix, execvp() takes an arg array.
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
_processLineBuffer(data, strBuffer, onLine) {
|
||||
try {
|
||||
let s = strBuffer + data.toString();
|
||||
let n = s.indexOf(os.EOL);
|
||||
while (n > -1) {
|
||||
const line = s.substring(0, n);
|
||||
onLine(line);
|
||||
// the rest of the string ...
|
||||
s = s.substring(n + os.EOL.length);
|
||||
n = s.indexOf(os.EOL);
|
||||
}
|
||||
strBuffer = s;
|
||||
}
|
||||
catch (err) {
|
||||
// streaming lines to console is best effort. Don't fail a build.
|
||||
this._debug(`error processing line. Failed with error ${err}`);
|
||||
}
|
||||
}
|
||||
_getSpawnFileName() {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
return process.env['COMSPEC'] || 'cmd.exe';
|
||||
}
|
||||
}
|
||||
return this.toolPath;
|
||||
}
|
||||
_getSpawnArgs(options) {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
||||
for (const a of this.args) {
|
||||
argline += ' ';
|
||||
argline += options.windowsVerbatimArguments
|
||||
? a
|
||||
: this._windowsQuoteCmdArg(a);
|
||||
}
|
||||
argline += '"';
|
||||
return [argline];
|
||||
}
|
||||
}
|
||||
return this.args;
|
||||
}
|
||||
_endsWith(str, end) {
|
||||
return str.endsWith(end);
|
||||
}
|
||||
_isCmdFile() {
|
||||
const upperToolPath = this.toolPath.toUpperCase();
|
||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
||||
this._endsWith(upperToolPath, '.BAT'));
|
||||
}
|
||||
_windowsQuoteCmdArg(arg) {
|
||||
// for .exe, apply the normal quoting rules that libuv applies
|
||||
if (!this._isCmdFile()) {
|
||||
return this._uvQuoteCmdArg(arg);
|
||||
}
|
||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
||||
// command line parser.
|
||||
//
|
||||
// for a detailed description of the cmd.exe command line parser, refer to
|
||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
||||
// need quotes for empty arg
|
||||
if (!arg) {
|
||||
return '""';
|
||||
}
|
||||
// determine whether the arg needs to be quoted
|
||||
const cmdSpecialChars = [
|
||||
' ',
|
||||
'\t',
|
||||
'&',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'^',
|
||||
'=',
|
||||
';',
|
||||
'!',
|
||||
"'",
|
||||
'+',
|
||||
',',
|
||||
'`',
|
||||
'~',
|
||||
'|',
|
||||
'<',
|
||||
'>',
|
||||
'"'
|
||||
];
|
||||
let needsQuotes = false;
|
||||
for (const char of arg) {
|
||||
if (cmdSpecialChars.some(x => x === char)) {
|
||||
needsQuotes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// short-circuit if quotes not needed
|
||||
if (!needsQuotes) {
|
||||
return arg;
|
||||
}
|
||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
||||
//
|
||||
// 1) wrap the string in quotes
|
||||
//
|
||||
// 2) double-up quotes - i.e. " => ""
|
||||
//
|
||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
||||
// doesn't work well with a cmd.exe command line.
|
||||
//
|
||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
||||
// for example, the command line:
|
||||
// foo.exe "myarg:""my val"""
|
||||
// is parsed by a .NET console app into an arg array:
|
||||
// [ "myarg:\"my val\"" ]
|
||||
// which is the same end result when applying libuv quoting rules. although the actual
|
||||
// command line from libuv quoting rules would look like:
|
||||
// foo.exe "myarg:\"my val\""
|
||||
//
|
||||
// 3) double-up slashes that precede a quote,
|
||||
// e.g. hello \world => "hello \world"
|
||||
// hello\"world => "hello\\""world"
|
||||
// hello\\"world => "hello\\\\""world"
|
||||
// hello world\ => "hello world\\"
|
||||
//
|
||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
||||
// the reasons for including this as a .cmd quoting rule are:
|
||||
//
|
||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
||||
//
|
||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
||||
// haven't heard any complaints about that aspect.
|
||||
//
|
||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
||||
// by using %%.
|
||||
//
|
||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
||||
//
|
||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
||||
// to an external program.
|
||||
//
|
||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
||||
// % can be escaped within a .cmd file.
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\'; // double the slash
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '"'; // double the quote
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_uvQuoteCmdArg(arg) {
|
||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
||||
// is used.
|
||||
//
|
||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
||||
// pasting copyright notice from Node within this function:
|
||||
//
|
||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
if (!arg) {
|
||||
// Need double quotation for empty argument
|
||||
return '""';
|
||||
}
|
||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
||||
// No quotation needed
|
||||
return arg;
|
||||
}
|
||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
||||
// No embedded double quotes or backslashes, so I can just wrap
|
||||
// quote marks around the whole thing.
|
||||
return `"${arg}"`;
|
||||
}
|
||||
// Expected input/output:
|
||||
// input : hello"world
|
||||
// output: "hello\"world"
|
||||
// input : hello""world
|
||||
// output: "hello\"\"world"
|
||||
// input : hello\world
|
||||
// output: hello\world
|
||||
// input : hello\\world
|
||||
// output: hello\\world
|
||||
// input : hello\"world
|
||||
// output: "hello\\\"world"
|
||||
// input : hello\\"world
|
||||
// output: "hello\\\\\"world"
|
||||
// input : hello world\
|
||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
||||
// but it appears the comment is wrong, it should be "hello world\\"
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\';
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '\\';
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_cloneExecOptions(options) {
|
||||
options = options || {};
|
||||
const result = {
|
||||
cwd: options.cwd || process.cwd(),
|
||||
env: options.env || process.env,
|
||||
silent: options.silent || false,
|
||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
||||
failOnStdErr: options.failOnStdErr || false,
|
||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
||||
delay: options.delay || 10000
|
||||
};
|
||||
result.outStream = options.outStream || process.stdout;
|
||||
result.errStream = options.errStream || process.stderr;
|
||||
return result;
|
||||
}
|
||||
_getSpawnOptions(options, toolPath) {
|
||||
options = options || {};
|
||||
const result = {};
|
||||
result.cwd = options.cwd;
|
||||
result.env = options.env;
|
||||
result['windowsVerbatimArguments'] =
|
||||
options.windowsVerbatimArguments || this._isCmdFile();
|
||||
if (options.windowsVerbatimArguments) {
|
||||
result.argv0 = `"${toolPath}"`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// root the tool path if it is unrooted and contains relative pathing
|
||||
if (!ioUtil.isRooted(this.toolPath) &&
|
||||
(this.toolPath.includes('/') ||
|
||||
(IS_WINDOWS && this.toolPath.includes('\\')))) {
|
||||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted
|
||||
this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
|
||||
}
|
||||
// if the tool is only a file name, then resolve it from the PATH
|
||||
// otherwise verify it exists (add extension on Windows if necessary)
|
||||
this.toolPath = yield io.which(this.toolPath, true);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._debug(`exec tool: ${this.toolPath}`);
|
||||
this._debug('arguments:');
|
||||
for (const arg of this.args) {
|
||||
this._debug(` ${arg}`);
|
||||
}
|
||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||||
}
|
||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
||||
state.on('debug', (message) => {
|
||||
this._debug(message);
|
||||
});
|
||||
const fileName = this._getSpawnFileName();
|
||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
||||
const stdbuffer = '';
|
||||
if (cp.stdout) {
|
||||
cp.stdout.on('data', (data) => {
|
||||
if (this.options.listeners && this.options.listeners.stdout) {
|
||||
this.options.listeners.stdout(data);
|
||||
}
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, stdbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.stdline) {
|
||||
this.options.listeners.stdline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
const errbuffer = '';
|
||||
if (cp.stderr) {
|
||||
cp.stderr.on('data', (data) => {
|
||||
state.processStderr = true;
|
||||
if (this.options.listeners && this.options.listeners.stderr) {
|
||||
this.options.listeners.stderr(data);
|
||||
}
|
||||
if (!optionsNonNull.silent &&
|
||||
optionsNonNull.errStream &&
|
||||
optionsNonNull.outStream) {
|
||||
const s = optionsNonNull.failOnStdErr
|
||||
? optionsNonNull.errStream
|
||||
: optionsNonNull.outStream;
|
||||
s.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, errbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.errline) {
|
||||
this.options.listeners.errline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
cp.on('error', (err) => {
|
||||
state.processError = err.message;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('exit', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('close', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
state.on('done', (error, exitCode) => {
|
||||
if (stdbuffer.length > 0) {
|
||||
this.emit('stdline', stdbuffer);
|
||||
}
|
||||
if (errbuffer.length > 0) {
|
||||
this.emit('errline', errbuffer);
|
||||
}
|
||||
cp.removeAllListeners();
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(exitCode);
|
||||
}
|
||||
});
|
||||
if (this.options.input) {
|
||||
if (!cp.stdin) {
|
||||
throw new Error('child process missing stdin');
|
||||
}
|
||||
cp.stdin.end(this.options.input);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ToolRunner = ToolRunner;
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
function argStringToArray(argString) {
|
||||
const args = [];
|
||||
let inQuotes = false;
|
||||
let escaped = false;
|
||||
let arg = '';
|
||||
function append(c) {
|
||||
// we only escape double quotes.
|
||||
if (escaped && c !== '"') {
|
||||
arg += '\\';
|
||||
}
|
||||
arg += c;
|
||||
escaped = false;
|
||||
}
|
||||
for (let i = 0; i < argString.length; i++) {
|
||||
const c = argString.charAt(i);
|
||||
if (c === '"') {
|
||||
if (!escaped) {
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else {
|
||||
append(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && escaped) {
|
||||
append(c);
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && inQuotes) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (c === ' ' && !inQuotes) {
|
||||
if (arg.length > 0) {
|
||||
args.push(arg);
|
||||
arg = '';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
append(c);
|
||||
}
|
||||
if (arg.length > 0) {
|
||||
args.push(arg.trim());
|
||||
}
|
||||
return args;
|
||||
}
|
||||
exports.argStringToArray = argStringToArray;
|
||||
class ExecState extends events.EventEmitter {
|
||||
constructor(options, toolPath) {
|
||||
super();
|
||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
||||
this.processError = '';
|
||||
this.processExitCode = 0;
|
||||
this.processExited = false; // tracks whether the process has exited
|
||||
this.processStderr = false; // tracks whether stderr was written to
|
||||
this.delay = 10000; // 10 seconds
|
||||
this.done = false;
|
||||
this.timeout = null;
|
||||
if (!toolPath) {
|
||||
throw new Error('toolPath must not be empty');
|
||||
}
|
||||
this.options = options;
|
||||
this.toolPath = toolPath;
|
||||
if (options.delay) {
|
||||
this.delay = options.delay;
|
||||
}
|
||||
}
|
||||
CheckComplete() {
|
||||
if (this.done) {
|
||||
return;
|
||||
}
|
||||
if (this.processClosed) {
|
||||
this._setResult();
|
||||
}
|
||||
else if (this.processExited) {
|
||||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||||
}
|
||||
}
|
||||
_debug(message) {
|
||||
this.emit('debug', message);
|
||||
}
|
||||
_setResult() {
|
||||
// determine whether there is an error
|
||||
let error;
|
||||
if (this.processExited) {
|
||||
if (this.processError) {
|
||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
||||
}
|
||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
||||
}
|
||||
else if (this.processStderr && this.options.failOnStdErr) {
|
||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
||||
}
|
||||
}
|
||||
// clear the timeout
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
this.done = true;
|
||||
this.emit('done', error, this.processExitCode);
|
||||
}
|
||||
static HandleTimeout(state) {
|
||||
if (state.done) {
|
||||
return;
|
||||
}
|
||||
if (!state.processClosed && state.processExited) {
|
||||
const message = `The STDIO streams did not close within ${state.delay /
|
||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
||||
state._debug(message);
|
||||
}
|
||||
state._setResult();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=toolrunner.js.map
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "@actions/exec",
|
||||
"version": "1.0.4",
|
||||
"description": "Actions exec lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
"actions",
|
||||
"exec"
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
|
||||
"license": "MIT",
|
||||
"main": "lib/exec.js",
|
||||
"types": "lib/exec.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/toolkit.git",
|
||||
"directory": "packages/exec"
|
||||
},
|
||||
"scripts": {
|
||||
"audit-moderate": "npm install && npm audit --audit-level=moderate",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
# `@actions/io`
|
||||
|
||||
> Core functions for cli filesystem scenarios
|
||||
|
||||
## Usage
|
||||
|
||||
#### mkdir -p
|
||||
|
||||
Recursively make a directory. Follows rules specified in [man mkdir](https://linux.die.net/man/1/mkdir) with the `-p` option specified:
|
||||
|
||||
```js
|
||||
const io = require('@actions/io');
|
||||
|
||||
await io.mkdirP('path/to/make');
|
||||
```
|
||||
|
||||
#### cp/mv
|
||||
|
||||
Copy or move files or folders. Follows rules specified in [man cp](https://linux.die.net/man/1/cp) and [man mv](https://linux.die.net/man/1/mv):
|
||||
|
||||
```js
|
||||
const io = require('@actions/io');
|
||||
|
||||
// Recursive must be true for directories
|
||||
const options = { recursive: true, force: false }
|
||||
|
||||
await io.cp('path/to/directory', 'path/to/dest', options);
|
||||
await io.mv('path/to/file', 'path/to/dest');
|
||||
```
|
||||
|
||||
#### rm -rf
|
||||
|
||||
Remove a file or folder recursively. Follows rules specified in [man rm](https://linux.die.net/man/1/rm) with the `-r` and `-f` rules specified.
|
||||
|
||||
```js
|
||||
const io = require('@actions/io');
|
||||
|
||||
await io.rmRF('path/to/directory');
|
||||
await io.rmRF('path/to/file');
|
||||
```
|
||||
|
||||
#### which
|
||||
|
||||
Get the path to a tool and resolves via paths. Follows the rules specified in [man which](https://linux.die.net/man/1/which).
|
||||
|
||||
```js
|
||||
const exec = require('@actions/exec');
|
||||
const io = require('@actions/io');
|
||||
|
||||
const pythonPath: string = await io.which('python', true)
|
||||
|
||||
await exec.exec(`"${pythonPath}"`, ['main.py']);
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
/// <reference types="node" />
|
||||
import * as fs from 'fs';
|
||||
export declare const chmod: typeof fs.promises.chmod, copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, readdir: typeof fs.promises.readdir, readlink: typeof fs.promises.readlink, rename: typeof fs.promises.rename, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, symlink: typeof fs.promises.symlink, unlink: typeof fs.promises.unlink;
|
||||
export declare const IS_WINDOWS: boolean;
|
||||
export declare function exists(fsPath: string): Promise<boolean>;
|
||||
export declare function isDirectory(fsPath: string, useStat?: boolean): Promise<boolean>;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
export declare function isRooted(p: string): boolean;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string, maxDepth?: number, depth?: number): Promise<void>;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
export declare function tryGetExecutablePath(filePath: string, extensions: string[]): Promise<string>;
|
|
@ -0,0 +1,195 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
fsPath = path.resolve(fsPath);
|
||||
if (depth >= maxDepth)
|
||||
return exports.mkdir(fsPath);
|
||||
try {
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
catch (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT': {
|
||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
let stats;
|
||||
try {
|
||||
stats = yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err2) {
|
||||
throw err;
|
||||
}
|
||||
if (!stats.isDirectory())
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try each extension
|
||||
const originalFilePath = filePath;
|
||||
for (const extension of extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
return p.replace(/\\\\+/g, '\\');
|
||||
}
|
||||
// remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
}
|
||||
// on Mac/Linux, test the execute bit
|
||||
// R W X R W X R W X
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
}
|
||||
//# sourceMappingURL=io-util.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"io-util.js","sourceRoot":"","sources":["../src/io-util.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mCAAyB;AACzB,yBAAwB;AACxB,6BAA4B;AAEf,gBAYE,qTAAA;AAEF,QAAA,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAA;AAEtD,SAAsB,MAAM,CAAC,MAAc;;QACzC,IAAI;YACF,MAAM,YAAI,CAAC,MAAM,CAAC,CAAA;SACnB;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE;gBACzB,OAAO,KAAK,CAAA;aACb;YAED,MAAM,GAAG,CAAA;SACV;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CAAA;AAZD,wBAYC;AAED,SAAsB,WAAW,CAC/B,MAAc,EACd,UAAmB,KAAK;;QAExB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,YAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,aAAK,CAAC,MAAM,CAAC,CAAA;QAChE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAA;IAC5B,CAAC;CAAA;AAND,kCAMC;AAED;;;GAGG;AACH,SAAgB,QAAQ,CAAC,CAAS;IAChC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,CAAC,CAAC,EAAE;QACN,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;KAC5D;IAED,IAAI,kBAAU,EAAE;QACd,OAAO,CACL,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,8BAA8B;SACxE,CAAA,CAAC,sBAAsB;KACzB;IAED,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC1B,CAAC;AAbD,4BAaC;AAED;;;;;;;;;GASG;AACH,SAAsB,MAAM,CAC1B,MAAc,EACd,WAAmB,IAAI,EACvB,QAAgB,CAAC;;QAEjB,WAAE,CAAC,MAAM,EAAE,kCAAkC,CAAC,CAAA;QAE9C,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAE7B,IAAI,KAAK,IAAI,QAAQ;YAAE,OAAO,aAAK,CAAC,MAAM,CAAC,CAAA;QAE3C,IAAI;YACF,MAAM,aAAK,CAAC,MAAM,CAAC,CAAA;YACnB,OAAM;SACP;QAAC,OAAO,GAAG,EAAE;YACZ,QAAQ,GAAG,CAAC,IAAI,EAAE;gBAChB,KAAK,QAAQ,CAAC,CAAC;oBACb,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;oBACvD,MAAM,aAAK,CAAC,MAAM,CAAC,CAAA;oBACnB,OAAM;iBACP;gBACD,OAAO,CAAC,CAAC;oBACP,IAAI,KAAe,CAAA;oBAEnB,IAAI;wBACF,KAAK,GAAG,MAAM,YAAI,CAAC,MAAM,CAAC,CAAA;qBAC3B;oBAAC,OAAO,IAAI,EAAE;wBACb,MAAM,GAAG,CAAA;qBACV;oBAED,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;wBAAE,MAAM,GAAG,CAAA;iBACpC;aACF;SACF;IACH,CAAC;CAAA;AAlCD,wBAkCC;AAED;;;;;GAKG;AACH,SAAsB,oBAAoB,CACxC,QAAgB,EAChB,UAAoB;;QAEpB,IAAI,KAAK,GAAyB,SAAS,CAAA;QAC3C,IAAI;YACF,mBAAmB;YACnB,KAAK,GAAG,MAAM,YAAI,CAAC,QAAQ,CAAC,CAAA;SAC7B;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE;gBACzB,sCAAsC;gBACtC,OAAO,CAAC,GAAG,CACT,uEAAuE,QAAQ,MAAM,GAAG,EAAE,CAC3F,CAAA;aACF;SACF;QACD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;YAC3B,IAAI,kBAAU,EAAE;gBACd,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;gBACrD,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,EAAE;oBACpE,OAAO,QAAQ,CAAA;iBAChB;aACF;iBAAM;gBACL,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;oBAC3B,OAAO,QAAQ,CAAA;iBAChB;aACF;SACF;QAED,qBAAqB;QACrB,MAAM,gBAAgB,GAAG,QAAQ,CAAA;QACjC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;YAClC,QAAQ,GAAG,gBAAgB,GAAG,SAAS,CAAA;YAEvC,KAAK,GAAG,SAAS,CAAA;YACjB,IAAI;gBACF,KAAK,GAAG,MAAM,YAAI,CAAC,QAAQ,CAAC,CAAA;aAC7B;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE;oBACzB,sCAAsC;oBACtC,OAAO,CAAC,GAAG,CACT,uEAAuE,QAAQ,MAAM,GAAG,EAAE,CAC3F,CAAA;iBACF;aACF;YAED,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;gBAC3B,IAAI,kBAAU,EAAE;oBACd,yEAAyE;oBACzE,IAAI;wBACF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;wBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;wBACvD,KAAK,MAAM,UAAU,IAAI,MAAM,eAAO,CAAC,SAAS,CAAC,EAAE;4BACjD,IAAI,SAAS,KAAK,UAAU,CAAC,WAAW,EAAE,EAAE;gCAC1C,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;gCAC3C,MAAK;6BACN;yBACF;qBACF;oBAAC,OAAO,GAAG,EAAE;wBACZ,sCAAsC;wBACtC,OAAO,CAAC,GAAG,CACT,yEAAyE,QAAQ,MAAM,GAAG,EAAE,CAC7F,CAAA;qBACF;oBAED,OAAO,QAAQ,CAAA;iBAChB;qBAAM;oBACL,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;wBAC3B,OAAO,QAAQ,CAAA;qBAChB;iBACF;aACF;SACF;QAED,OAAO,EAAE,CAAA;IACX,CAAC;CAAA;AA5ED,oDA4EC;AAED,SAAS,mBAAmB,CAAC,CAAS;IACpC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;IACX,IAAI,kBAAU,EAAE;QACd,6BAA6B;QAC7B,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAE1B,2BAA2B;QAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;KACjC;IAED,2BAA2B;IAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,qCAAqC;AACrC,6BAA6B;AAC7B,6BAA6B;AAC7B,SAAS,gBAAgB,CAAC,KAAe;IACvC,OAAO,CACL,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;QACpB,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;QACxD,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAC1D,CAAA;AACH,CAAC"}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Interface for cp/mv options
|
||||
*/
|
||||
export interface CopyOptions {
|
||||
/** Optional. Whether to recursively copy all subdirectories. Defaults to false */
|
||||
recursive?: boolean;
|
||||
/** Optional. Whether to overwrite existing files in the destination. Defaults to true */
|
||||
force?: boolean;
|
||||
}
|
||||
/**
|
||||
* Interface for cp/mv options
|
||||
*/
|
||||
export interface MoveOptions {
|
||||
/** Optional. Whether to overwrite existing files in the destination. Defaults to true */
|
||||
force?: boolean;
|
||||
}
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export declare function cp(source: string, dest: string, options?: CopyOptions): Promise<void>;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See MoveOptions.
|
||||
*/
|
||||
export declare function mv(source: string, dest: string, options?: MoveOptions): Promise<void>;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
export declare function rmRF(inputPath: string): Promise<void>;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string): Promise<void>;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
export declare function which(tool: string, check?: boolean): Promise<string>;
|
|
@ -0,0 +1,290 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const childProcess = require("child_process");
|
||||
const path = require("path");
|
||||
const util_1 = require("util");
|
||||
const ioUtil = require("./io-util");
|
||||
const exec = util_1.promisify(childProcess.exec);
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { force, recursive } = readCopyOptions(options);
|
||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
||||
// Dest is an existing file, but not forcing
|
||||
if (destStat && destStat.isFile() && !force) {
|
||||
return;
|
||||
}
|
||||
// If dest is an existing directory, should copy inside.
|
||||
const newDest = destStat && destStat.isDirectory()
|
||||
? path.join(dest, path.basename(source))
|
||||
: dest;
|
||||
if (!(yield ioUtil.exists(source))) {
|
||||
throw new Error(`no such file or directory: ${source}`);
|
||||
}
|
||||
const sourceStat = yield ioUtil.stat(source);
|
||||
if (sourceStat.isDirectory()) {
|
||||
if (!recursive) {
|
||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
||||
}
|
||||
else {
|
||||
yield cpDirRecursive(source, newDest, 0, force);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (path.relative(source, newDest) === '') {
|
||||
// a file cannot be copied to itself
|
||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
||||
}
|
||||
yield copyFile(source, newDest, force);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See MoveOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
let destExists = true;
|
||||
if (yield ioUtil.isDirectory(dest)) {
|
||||
// If dest is directory copy src into dest
|
||||
dest = path.join(dest, path.basename(source));
|
||||
destExists = yield ioUtil.exists(dest);
|
||||
}
|
||||
if (destExists) {
|
||||
if (options.force == null || options.force) {
|
||||
yield rmRF(dest);
|
||||
}
|
||||
else {
|
||||
throw new Error('Destination already exists');
|
||||
}
|
||||
}
|
||||
}
|
||||
yield mkdirP(path.dirname(dest));
|
||||
yield ioUtil.rename(source, dest);
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||
try {
|
||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||
yield exec(`rd /s /q "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield exec(`del /f /a "${inputPath}"`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||||
try {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isDir = false;
|
||||
try {
|
||||
isDir = yield ioUtil.isDirectory(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
return;
|
||||
}
|
||||
if (isDir) {
|
||||
yield exec(`rm -rf "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield ioUtil.mkdirP(fsPath);
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
}
|
||||
// recursive when check=true
|
||||
if (check) {
|
||||
const result = yield which(tool, false);
|
||||
if (!result) {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// build the list of extensions to try
|
||||
const extensions = [];
|
||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's rooted, return it if exists. otherwise return empty.
|
||||
if (ioUtil.isRooted(tool)) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// if any path separators, return empty
|
||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
||||
return '';
|
||||
}
|
||||
// build the list of directories
|
||||
//
|
||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
||||
// across platforms.
|
||||
const directories = [];
|
||||
if (process.env.PATH) {
|
||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||
if (p) {
|
||||
directories.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the first match
|
||||
for (const directory of directories) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`which failed with message ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
return { force, recursive };
|
||||
}
|
||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Ensure there is not a run away recursive copy
|
||||
if (currentDepth >= 255)
|
||||
return;
|
||||
currentDepth++;
|
||||
yield mkdirP(destDir);
|
||||
const files = yield ioUtil.readdir(sourceDir);
|
||||
for (const fileName of files) {
|
||||
const srcFile = `${sourceDir}/${fileName}`;
|
||||
const destFile = `${destDir}/${fileName}`;
|
||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
||||
if (srcFileStat.isDirectory()) {
|
||||
// Recurse
|
||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
||||
}
|
||||
else {
|
||||
yield copyFile(srcFile, destFile, force);
|
||||
}
|
||||
}
|
||||
// Change the mode for the newly created directory
|
||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
||||
});
|
||||
}
|
||||
// Buffered file copy
|
||||
function copyFile(srcFile, destFile, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
||||
// unlink/re-link it
|
||||
try {
|
||||
yield ioUtil.lstat(destFile);
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
catch (e) {
|
||||
// Try to override file permission
|
||||
if (e.code === 'EPERM') {
|
||||
yield ioUtil.chmod(destFile, '0666');
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
// other errors = it doesn't exist, no work to do
|
||||
}
|
||||
// Copy over symlink
|
||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
||||
}
|
||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
||||
yield ioUtil.copyFile(srcFile, destFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=io.js.map
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "@actions/io",
|
||||
"version": "1.0.2",
|
||||
"description": "Actions io lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
"actions",
|
||||
"io"
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/master/packages/io",
|
||||
"license": "MIT",
|
||||
"main": "lib/io.js",
|
||||
"types": "lib/io.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/toolkit.git",
|
||||
"directory": "packages/io"
|
||||
},
|
||||
"scripts": {
|
||||
"audit-moderate": "npm install && npm audit --audit-level=moderate",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
sudo: false
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
Apache License, Version 2.0
|
||||
|
||||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,24 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,12 @@
|
|||
#! /usr/bin/env node
|
||||
|
||||
var JSONStream = require('./')
|
||||
|
||||
if(!module.parent && process.title !== 'browser') {
|
||||
process.stdin
|
||||
.pipe(JSONStream.parse(process.argv[2]))
|
||||
.pipe(JSONStream.stringify('[', ',\n', ']\n', 2))
|
||||
.pipe(process.stdout)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
var request = require('request')
|
||||
, JSONStream = require('JSONStream')
|
||||
, es = require('event-stream')
|
||||
|
||||
var parser = JSONStream.parse(['rows', true]) //emit parts that match this path (any element of the rows array)
|
||||
, req = request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
|
||||
, logger = es.mapSync(function (data) { //create a stream that logs to stderr,
|
||||
console.error(data)
|
||||
return data
|
||||
})
|
||||
|
||||
req.pipe(parser)
|
||||
parser.pipe(logger)
|
|
@ -0,0 +1,247 @@
|
|||
'use strict'
|
||||
|
||||
var Parser = require('jsonparse')
|
||||
, through = require('through')
|
||||
|
||||
var bufferFrom = Buffer.from && Buffer.from !== Uint8Array.from
|
||||
|
||||
/*
|
||||
|
||||
the value of this.stack that creationix's jsonparse has is weird.
|
||||
|
||||
it makes this code ugly, but his problem is way harder that mine,
|
||||
so i'll forgive him.
|
||||
|
||||
*/
|
||||
|
||||
exports.parse = function (path, map) {
|
||||
var header, footer
|
||||
var parser = new Parser()
|
||||
var stream = through(function (chunk) {
|
||||
if('string' === typeof chunk)
|
||||
chunk = bufferFrom ? Buffer.from(chunk) : new Buffer(chunk)
|
||||
parser.write(chunk)
|
||||
},
|
||||
function (data) {
|
||||
if(data)
|
||||
stream.write(data)
|
||||
if (header)
|
||||
stream.emit('header', header)
|
||||
if (footer)
|
||||
stream.emit('footer', footer)
|
||||
stream.queue(null)
|
||||
})
|
||||
|
||||
if('string' === typeof path)
|
||||
path = path.split('.').map(function (e) {
|
||||
if (e === '$*')
|
||||
return {emitKey: true}
|
||||
else if (e === '*')
|
||||
return true
|
||||
else if (e === '') // '..'.split('.') returns an empty string
|
||||
return {recurse: true}
|
||||
else
|
||||
return e
|
||||
})
|
||||
|
||||
|
||||
var count = 0, _key
|
||||
if(!path || !path.length)
|
||||
path = null
|
||||
|
||||
parser.onValue = function (value) {
|
||||
if (!this.root)
|
||||
stream.root = value
|
||||
|
||||
if(! path) return
|
||||
|
||||
var i = 0 // iterates on path
|
||||
var j = 0 // iterates on stack
|
||||
var emitKey = false;
|
||||
var emitPath = false;
|
||||
while (i < path.length) {
|
||||
var key = path[i]
|
||||
var c
|
||||
j++
|
||||
|
||||
if (key && !key.recurse) {
|
||||
c = (j === this.stack.length) ? this : this.stack[j]
|
||||
if (!c) return
|
||||
if (! check(key, c.key)) {
|
||||
setHeaderFooter(c.key, value)
|
||||
return
|
||||
}
|
||||
emitKey = !!key.emitKey;
|
||||
emitPath = !!key.emitPath;
|
||||
i++
|
||||
} else {
|
||||
i++
|
||||
var nextKey = path[i]
|
||||
if (! nextKey) return
|
||||
while (true) {
|
||||
c = (j === this.stack.length) ? this : this.stack[j]
|
||||
if (!c) return
|
||||
if (check(nextKey, c.key)) {
|
||||
i++;
|
||||
if (!Object.isFrozen(this.stack[j]))
|
||||
this.stack[j].value = null
|
||||
break
|
||||
} else {
|
||||
setHeaderFooter(c.key, value)
|
||||
}
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// emit header
|
||||
if (header) {
|
||||
stream.emit('header', header);
|
||||
header = false;
|
||||
}
|
||||
if (j !== this.stack.length) return
|
||||
|
||||
count ++
|
||||
var actualPath = this.stack.slice(1).map(function(element) { return element.key }).concat([this.key])
|
||||
var data = value
|
||||
if(null != data)
|
||||
if(null != (data = map ? map(data, actualPath) : data)) {
|
||||
if (emitKey || emitPath) {
|
||||
data = { value: data };
|
||||
if (emitKey)
|
||||
data["key"] = this.key;
|
||||
if (emitPath)
|
||||
data["path"] = actualPath;
|
||||
}
|
||||
|
||||
stream.queue(data)
|
||||
}
|
||||
if (this.value) delete this.value[this.key]
|
||||
for(var k in this.stack)
|
||||
if (!Object.isFrozen(this.stack[k]))
|
||||
this.stack[k].value = null
|
||||
}
|
||||
parser._onToken = parser.onToken;
|
||||
|
||||
parser.onToken = function (token, value) {
|
||||
parser._onToken(token, value);
|
||||
if (this.stack.length === 0) {
|
||||
if (stream.root) {
|
||||
if(!path)
|
||||
stream.queue(stream.root)
|
||||
count = 0;
|
||||
stream.root = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parser.onError = function (err) {
|
||||
if(err.message.indexOf("at position") > -1)
|
||||
err.message = "Invalid JSON (" + err.message + ")";
|
||||
stream.emit('error', err)
|
||||
}
|
||||
|
||||
return stream
|
||||
|
||||
function setHeaderFooter(key, value) {
|
||||
// header has not been emitted yet
|
||||
if (header !== false) {
|
||||
header = header || {}
|
||||
header[key] = value
|
||||
}
|
||||
|
||||
// footer has not been emitted yet but header has
|
||||
if (footer !== false && header === false) {
|
||||
footer = footer || {}
|
||||
footer[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function check (x, y) {
|
||||
if ('string' === typeof x)
|
||||
return y == x
|
||||
else if (x && 'function' === typeof x.exec)
|
||||
return x.exec(y)
|
||||
else if ('boolean' === typeof x || 'object' === typeof x)
|
||||
return x
|
||||
else if ('function' === typeof x)
|
||||
return x(y)
|
||||
return false
|
||||
}
|
||||
|
||||
exports.stringify = function (op, sep, cl, indent) {
|
||||
indent = indent || 0
|
||||
if (op === false){
|
||||
op = ''
|
||||
sep = '\n'
|
||||
cl = ''
|
||||
} else if (op == null) {
|
||||
|
||||
op = '[\n'
|
||||
sep = '\n,\n'
|
||||
cl = '\n]\n'
|
||||
|
||||
}
|
||||
|
||||
//else, what ever you like
|
||||
|
||||
var stream
|
||||
, first = true
|
||||
, anyData = false
|
||||
stream = through(function (data) {
|
||||
anyData = true
|
||||
try {
|
||||
var json = JSON.stringify(data, null, indent)
|
||||
} catch (err) {
|
||||
return stream.emit('error', err)
|
||||
}
|
||||
if(first) { first = false ; stream.queue(op + json)}
|
||||
else stream.queue(sep + json)
|
||||
},
|
||||
function (data) {
|
||||
if(!anyData)
|
||||
stream.queue(op)
|
||||
stream.queue(cl)
|
||||
stream.queue(null)
|
||||
})
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
exports.stringifyObject = function (op, sep, cl, indent) {
|
||||
indent = indent || 0
|
||||
if (op === false){
|
||||
op = ''
|
||||
sep = '\n'
|
||||
cl = ''
|
||||
} else if (op == null) {
|
||||
|
||||
op = '{\n'
|
||||
sep = '\n,\n'
|
||||
cl = '\n}\n'
|
||||
|
||||
}
|
||||
|
||||
//else, what ever you like
|
||||
|
||||
var first = true
|
||||
var anyData = false
|
||||
var stream = through(function (data) {
|
||||
anyData = true
|
||||
var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1], null, indent)
|
||||
if(first) { first = false ; this.queue(op + json)}
|
||||
else this.queue(sep + json)
|
||||
},
|
||||
function (data) {
|
||||
if(!anyData) this.queue(op)
|
||||
this.queue(cl)
|
||||
|
||||
this.queue(null)
|
||||
})
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "JSONStream",
|
||||
"version": "1.3.5",
|
||||
"description": "rawStream.pipe(JSONStream.parse()).pipe(streamOfObjects)",
|
||||
"homepage": "http://github.com/dominictarr/JSONStream",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/JSONStream.git"
|
||||
},
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"keywords": [
|
||||
"json",
|
||||
"stream",
|
||||
"streaming",
|
||||
"parser",
|
||||
"async",
|
||||
"parsing"
|
||||
],
|
||||
"dependencies": {
|
||||
"jsonparse": "^1.2.0",
|
||||
"through": ">=2.2.7 <3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"it-is": "~1",
|
||||
"assertions": "~2.2.2",
|
||||
"render": "~0.1.1",
|
||||
"trees": "~0.0.3",
|
||||
"event-stream": "~0.7.0",
|
||||
"tape": "~2.12.3"
|
||||
},
|
||||
"bin": "./bin.js",
|
||||
"author": "Dominic Tarr <dominic.tarr@gmail.com> (http://bit.ly/dominictarr)",
|
||||
"scripts": {
|
||||
"test": "node test/run.js"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
# JSONStream
|
||||
|
||||
streaming JSON.parse and stringify
|
||||
|
||||

|
||||
|
||||
## install
|
||||
```npm install JSONStream```
|
||||
|
||||
## example
|
||||
|
||||
``` js
|
||||
|
||||
var request = require('request')
|
||||
, JSONStream = require('JSONStream')
|
||||
, es = require('event-stream')
|
||||
|
||||
request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
|
||||
.pipe(JSONStream.parse('rows.*'))
|
||||
.pipe(es.mapSync(function (data) {
|
||||
console.error(data)
|
||||
return data
|
||||
}))
|
||||
```
|
||||
|
||||
## JSONStream.parse(path)
|
||||
|
||||
parse stream of values that match a path
|
||||
|
||||
``` js
|
||||
JSONStream.parse('rows.*.doc')
|
||||
```
|
||||
|
||||
The `..` operator is the recursive descent operator from [JSONPath](http://goessner.net/articles/JsonPath/), which will match a child at any depth (see examples below).
|
||||
|
||||
If your keys have keys that include `.` or `*` etc, use an array instead.
|
||||
`['row', true, /^doc/]`.
|
||||
|
||||
If you use an array, `RegExp`s, booleans, and/or functions. The `..` operator is also available in array representation, using `{recurse: true}`.
|
||||
any object that matches the path will be emitted as 'data' (and `pipe`d down stream)
|
||||
|
||||
If `path` is empty or null, no 'data' events are emitted.
|
||||
|
||||
If you want to have keys emitted, you can prefix your `*` operator with `$`: `obj.$*` - in this case the data passed to the stream is an object with a `key` holding the key and a `value` property holding the data.
|
||||
|
||||
### Examples
|
||||
|
||||
query a couchdb view:
|
||||
|
||||
``` bash
|
||||
curl -sS localhost:5984/tests/_all_docs&include_docs=true
|
||||
```
|
||||
you will get something like this:
|
||||
|
||||
``` js
|
||||
{"total_rows":129,"offset":0,"rows":[
|
||||
{ "id":"change1_0.6995461115147918"
|
||||
, "key":"change1_0.6995461115147918"
|
||||
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
|
||||
, "doc":{
|
||||
"_id": "change1_0.6995461115147918"
|
||||
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
|
||||
},
|
||||
{ "id":"change2_0.6995461115147918"
|
||||
, "key":"change2_0.6995461115147918"
|
||||
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
|
||||
, "doc":{
|
||||
"_id":"change2_0.6995461115147918"
|
||||
, "_rev":"1-13677d36b98c0c075145bb8975105153"
|
||||
, "hello":2
|
||||
}
|
||||
},
|
||||
]}
|
||||
|
||||
```
|
||||
|
||||
we are probably most interested in the `rows.*.doc`
|
||||
|
||||
create a `Stream` that parses the documents from the feed like this:
|
||||
|
||||
``` js
|
||||
var stream = JSONStream.parse(['rows', true, 'doc']) //rows, ANYTHING, doc
|
||||
|
||||
stream.on('data', function(data) {
|
||||
console.log('received:', data);
|
||||
});
|
||||
//emits anything from _before_ the first match
|
||||
stream.on('header', function (data) {
|
||||
console.log('header:', data) // => {"total_rows":129,"offset":0}
|
||||
})
|
||||
|
||||
```
|
||||
awesome!
|
||||
|
||||
In case you wanted the contents the doc emitted:
|
||||
|
||||
``` js
|
||||
var stream = JSONStream.parse(['rows', true, 'doc', {emitKey: true}]) //rows, ANYTHING, doc, items in docs with keys
|
||||
|
||||
stream.on('data', function(data) {
|
||||
console.log('key:', data.key);
|
||||
console.log('value:', data.value);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You can also emit the path:
|
||||
|
||||
``` js
|
||||
var stream = JSONStream.parse(['rows', true, 'doc', {emitPath: true}]) //rows, ANYTHING, doc, items in docs with keys
|
||||
|
||||
stream.on('data', function(data) {
|
||||
console.log('path:', data.path);
|
||||
console.log('value:', data.value);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### recursive patterns (..)
|
||||
|
||||
`JSONStream.parse('docs..value')`
|
||||
(or `JSONStream.parse(['docs', {recurse: true}, 'value'])` using an array)
|
||||
will emit every `value` object that is a child, grand-child, etc. of the
|
||||
`docs` object. In this example, it will match exactly 5 times at various depth
|
||||
levels, emitting 0, 1, 2, 3 and 4 as results.
|
||||
|
||||
```js
|
||||
{
|
||||
"total": 5,
|
||||
"docs": [
|
||||
{
|
||||
"key": {
|
||||
"value": 0,
|
||||
"some": "property"
|
||||
}
|
||||
},
|
||||
{"value": 1},
|
||||
{"value": 2},
|
||||
{"blbl": [{}, {"a":0, "b":1, "value":3}, 10]},
|
||||
{"value": 4}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## JSONStream.parse(pattern, map)
|
||||
|
||||
provide a function that can be used to map or filter
|
||||
the json output. `map` is passed the value at that node of the pattern,
|
||||
if `map` return non-nullish (anything but `null` or `undefined`)
|
||||
that value will be emitted in the stream. If it returns a nullish value,
|
||||
nothing will be emitted.
|
||||
|
||||
`JSONStream` also emits `'header'` and `'footer'` events,
|
||||
the `'header'` event contains anything in the output that was before
|
||||
the first match, and the `'footer'`, is anything after the last match.
|
||||
|
||||
## JSONStream.stringify(open, sep, close)
|
||||
|
||||
Create a writable stream.
|
||||
|
||||
you may pass in custom `open`, `close`, and `seperator` strings.
|
||||
But, by default, `JSONStream.stringify()` will create an array,
|
||||
(with default options `open='[\n', sep='\n,\n', close='\n]\n'`)
|
||||
|
||||
If you call `JSONStream.stringify(false)`
|
||||
the elements will only be seperated by a newline.
|
||||
|
||||
If you only write one item this will be valid JSON.
|
||||
|
||||
If you write many items,
|
||||
you can use a `RegExp` to split it into valid chunks.
|
||||
|
||||
## JSONStream.stringifyObject(open, sep, close)
|
||||
|
||||
Very much like `JSONStream.stringify`,
|
||||
but creates a writable stream for objects instead of arrays.
|
||||
|
||||
Accordingly, `open='{\n', sep='\n,\n', close='\n}\n'`.
|
||||
|
||||
When you `.write()` to the stream you must supply an array with `[ key, data ]`
|
||||
as the first argument.
|
||||
|
||||
## unix tool
|
||||
|
||||
query npm to see all the modules that browserify has ever depended on.
|
||||
|
||||
``` bash
|
||||
curl https://registry.npmjs.org/browserify | JSONStream 'versions.*.dependencies'
|
||||
```
|
||||
|
||||
## numbers
|
||||
|
||||
numbers will be emitted as numbers.
|
||||
huge numbers that cannot be represented in memory as javascript numbers will be emitted as strings.
|
||||
cf https://github.com/creationix/jsonparse/commit/044b268f01c4b8f97fb936fc85d3bcfba179e5bb for details.
|
||||
|
||||
## Acknowlegements
|
||||
|
||||
this module depends on https://github.com/creationix/jsonparse
|
||||
by Tim Caswell
|
||||
and also thanks to Florent Jaby for teaching me about parsing with:
|
||||
https://github.com/Floby/node-json-streams
|
||||
|
||||
## license
|
||||
|
||||
Dual-licensed under the MIT License or the Apache License, version 2.0
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is').style('colour')
|
||||
|
||||
function randomObj () {
|
||||
return (
|
||||
Math.random () < 0.4
|
||||
? {hello: 'eonuhckmqjk',
|
||||
whatever: 236515,
|
||||
lies: true,
|
||||
nothing: [null],
|
||||
// stuff: [Math.random(),Math.random(),Math.random()]
|
||||
}
|
||||
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
|
||||
)
|
||||
}
|
||||
|
||||
var expected = []
|
||||
, stringify = JSONStream.stringify()
|
||||
, es = require('event-stream')
|
||||
, stringified = ''
|
||||
, called = 0
|
||||
, count = 10
|
||||
, ended = false
|
||||
|
||||
while (count --)
|
||||
expected.push(randomObj())
|
||||
|
||||
es.connect(
|
||||
es.readArray(expected),
|
||||
stringify,
|
||||
JSONStream.parse([true]),
|
||||
es.writeArray(function (err, lines) {
|
||||
|
||||
it(lines).has(expected)
|
||||
console.error('PASSED')
|
||||
})
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
var test = require('tape')
|
||||
var JSONStream = require('../')
|
||||
var testData = '{"rows":[{"hello":"world"}, {"foo": "bar"}]}'
|
||||
|
||||
test('basic parsing', function (t) {
|
||||
t.plan(2)
|
||||
var parsed = JSONStream.parse("rows.*")
|
||||
var parsedKeys = {}
|
||||
parsed.on('data', function(match) {
|
||||
parsedKeys[Object.keys(match)[0]] = true
|
||||
})
|
||||
parsed.on('end', function() {
|
||||
t.equal(!!parsedKeys['hello'], true)
|
||||
t.equal(!!parsedKeys['foo'], true)
|
||||
})
|
||||
parsed.write(testData)
|
||||
parsed.end()
|
||||
})
|
|
@ -0,0 +1,27 @@
|
|||
var fs = require ('fs');
|
||||
var net = require('net');
|
||||
var join = require('path').join;
|
||||
var file = join(__dirname, 'fixtures','all_npm.json');
|
||||
var JSONStream = require('../');
|
||||
|
||||
|
||||
var server = net.createServer(function(client) {
|
||||
var parser = JSONStream.parse([]);
|
||||
parser.on('end', function() {
|
||||
console.log('close')
|
||||
console.error('PASSED');
|
||||
server.close();
|
||||
});
|
||||
client.pipe(parser);
|
||||
var n = 4
|
||||
client.on('data', function () {
|
||||
if(--n) return
|
||||
client.end();
|
||||
})
|
||||
});
|
||||
server.listen(9999);
|
||||
|
||||
|
||||
var client = net.connect({ port : 9999 }, function() {
|
||||
fs.createReadStream(file).pipe(client).on('data', console.log) //.resume();
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse('rows..rev')
|
||||
, called = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(expected.rows.length)
|
||||
for (var i = 0 ; i < expected.rows.length ; i++)
|
||||
it(parsed[i]).deepEqual(expected.rows[i].value.rev)
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,30 @@
|
|||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','depth.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse(['docs', {recurse: true}, 'value'])
|
||||
, called = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
var expectedValues = [0, [1], {"a": 2}, "3", 4]
|
||||
it(called).equal(expectedValues.length)
|
||||
for (var i = 0 ; i < 5 ; i++)
|
||||
it(parsed[i]).deepEqual(expectedValues[i])
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,44 @@
|
|||
var JSONStream = require('../')
|
||||
, stream = require('stream')
|
||||
, it = require('it-is')
|
||||
|
||||
var output = [ [], [] ]
|
||||
|
||||
var parser1 = JSONStream.parse(['docs', /./])
|
||||
parser1.on('data', function(data) {
|
||||
output[0].push(data)
|
||||
})
|
||||
|
||||
var parser2 = JSONStream.parse(['docs', /./])
|
||||
parser2.on('data', function(data) {
|
||||
output[1].push(data)
|
||||
})
|
||||
|
||||
var pending = 2
|
||||
function onend () {
|
||||
if (--pending > 0) return
|
||||
it(output).deepEqual([
|
||||
[], [{hello: 'world'}]
|
||||
])
|
||||
console.error('PASSED')
|
||||
}
|
||||
parser1.on('end', onend)
|
||||
parser2.on('end', onend)
|
||||
|
||||
function makeReadableStream() {
|
||||
var readStream = new stream.Stream()
|
||||
readStream.readable = true
|
||||
readStream.write = function (data) { this.emit('data', data) }
|
||||
readStream.end = function (data) { this.emit('end') }
|
||||
return readStream
|
||||
}
|
||||
|
||||
var emptyArray = makeReadableStream()
|
||||
emptyArray.pipe(parser1)
|
||||
emptyArray.write('{"docs":[]}')
|
||||
emptyArray.end()
|
||||
|
||||
var objectArray = makeReadableStream()
|
||||
objectArray.pipe(parser2)
|
||||
objectArray.write('{"docs":[{"hello":"world"}]}')
|
||||
objectArray.end()
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','error.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse(['rows'])
|
||||
, called = 0
|
||||
, headerCalled = 0
|
||||
, footerCalled = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('header', function (data) {
|
||||
headerCalled ++
|
||||
it(data).deepEqual({
|
||||
error: 'error_code',
|
||||
message: 'this is an error message'
|
||||
})
|
||||
})
|
||||
|
||||
parser.on('footer', function (data) {
|
||||
footerCalled ++
|
||||
})
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(0)
|
||||
it(headerCalled).equal(1)
|
||||
it(footerCalled).equal(0)
|
||||
console.error('PASSED')
|
||||
})
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
|||
{"total_rows":129,"offset":0,"rows":[
|
||||
{ "id":"change1_0.6995461115147918"
|
||||
, "key":"change1_0.6995461115147918"
|
||||
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
|
||||
, "doc":{
|
||||
"_id": "change1_0.6995461115147918"
|
||||
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
|
||||
},
|
||||
{ "id":"change2_0.6995461115147918"
|
||||
, "key":"change2_0.6995461115147918"
|
||||
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
|
||||
, "doc":{
|
||||
"_id":"change2_0.6995461115147918"
|
||||
, "_rev":"1-13677d36b98c0c075145bb8975105153"
|
||||
, "hello":2
|
||||
}
|
||||
},
|
||||
]}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"total": 5,
|
||||
"docs": [
|
||||
{
|
||||
"key": {
|
||||
"value": 0,
|
||||
"some": "property"
|
||||
}
|
||||
},
|
||||
{"value": [1]},
|
||||
{"value": {"a":2}},
|
||||
{"blbl": [{}, {"a":0, "b":1, "value":"3"}, 10]},
|
||||
{"value": 4}
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"error": "error_code", "message": "this is an error message"}
|
|
@ -0,0 +1,19 @@
|
|||
{"total_rows":129,"offset":0,"rows":[
|
||||
{ "id":"change1_0.6995461115147918"
|
||||
, "key":"change1_0.6995461115147918"
|
||||
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
|
||||
, "doc":{
|
||||
"_id": "change1_0.6995461115147918"
|
||||
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
|
||||
},
|
||||
{ "id":"change2_0.6995461115147918"
|
||||
, "key":"change2_0.6995461115147918"
|
||||
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
|
||||
, "doc":{
|
||||
"_id":"change2_0.6995461115147918"
|
||||
, "_rev":"1-13677d36b98c0c075145bb8975105153"
|
||||
, "hello":2
|
||||
}
|
||||
}
|
||||
],
|
||||
"foo": {"bar": "baz"}}
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
function fn (s) {
|
||||
return !isNaN(parseInt(s, 10))
|
||||
}
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse(['rows', fn])
|
||||
, called = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
it.has({
|
||||
id: it.typeof('string'),
|
||||
value: {rev: it.typeof('string')},
|
||||
key:it.typeof('string')
|
||||
})
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(expected.rows.length)
|
||||
it(parsed).deepEqual(expected.rows)
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,135 @@
|
|||
return // dont run this test for now since tape is weird and broken on 0.10
|
||||
|
||||
var fs = require('fs')
|
||||
var JSONStream = require('../')
|
||||
var file = process.argv[2] || '/tmp/JSONStream-test-large.json'
|
||||
var size = Number(process.argv[3] || 100000)
|
||||
var tape = require('tape')
|
||||
// if (process.title !== 'browser') {
|
||||
tape('out of mem', function (t) {
|
||||
t.plan(1)
|
||||
//////////////////////////////////////////////////////
|
||||
// Produces a random number between arg1 and arg2
|
||||
//////////////////////////////////////////////////////
|
||||
var randomNumber = function (min, max) {
|
||||
var number = Math.floor(Math.random() * (max - min + 1) + min);
|
||||
return number;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Produces a random string of a length between arg1 and arg2
|
||||
//////////////////////////////////////////////////////
|
||||
var randomString = function (min, max) {
|
||||
|
||||
// add several spaces to increase chanses of creating 'words'
|
||||
var chars = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
var result = '';
|
||||
|
||||
var randomLength = randomNumber(min, max);
|
||||
|
||||
for (var i = randomLength; i > 0; --i) {
|
||||
result += chars[Math.round(Math.random() * (chars.length - 1))];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Produces a random JSON document, as a string
|
||||
//////////////////////////////////////////////////////
|
||||
var randomJsonDoc = function () {
|
||||
|
||||
var doc = {
|
||||
"CrashOccurenceID": randomNumber(10000, 50000),
|
||||
"CrashID": randomNumber(1000, 10000),
|
||||
"SiteName": randomString(10, 25),
|
||||
"MachineName": randomString(10, 25),
|
||||
"Date": randomString(26, 26),
|
||||
"ProcessDuration": randomString(18, 18),
|
||||
"ThreadIdentityName": null,
|
||||
"WindowsIdentityName": randomString(15, 40),
|
||||
"OperatingSystemName": randomString(35, 65),
|
||||
"DetailedExceptionInformation": randomString(100, 800)
|
||||
};
|
||||
|
||||
doc = JSON.stringify(doc);
|
||||
doc = doc.replace(/\,/g, ',\n'); // add new lines after each attribute
|
||||
return doc;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// generates test data
|
||||
//////////////////////////////////////////////////////
|
||||
var generateTestData = function (cb) {
|
||||
|
||||
console.log('generating large data file...');
|
||||
|
||||
var stream = fs.createWriteStream(file, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
|
||||
var i = 0;
|
||||
var max = size;
|
||||
var writing = false
|
||||
var split = ',\n';
|
||||
var doc = randomJsonDoc();
|
||||
stream.write('[');
|
||||
|
||||
function write () {
|
||||
if(writing) return
|
||||
writing = true
|
||||
while(++i < max) {
|
||||
if(Math.random() < 0.001)
|
||||
console.log('generate..', i + ' / ' + size)
|
||||
if(!stream.write(doc + split)) {
|
||||
writing = false
|
||||
return stream.once('drain', write)
|
||||
}
|
||||
}
|
||||
stream.write(doc + ']')
|
||||
stream.end();
|
||||
console.log('END')
|
||||
}
|
||||
write()
|
||||
stream.on('close', cb)
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Shows that parsing 100000 instances using JSONStream fails
|
||||
//
|
||||
// After several seconds, you will get this crash
|
||||
// FATAL ERROR: JS Allocation failed - process out of memory
|
||||
//////////////////////////////////////////////////////
|
||||
var testJSONStreamParse_causesOutOfMem = function (done) {
|
||||
var items = 0
|
||||
console.log('parsing data files using JSONStream...');
|
||||
|
||||
var parser = JSONStream.parse([true]);
|
||||
var stream = fs.createReadStream(file);
|
||||
stream.pipe(parser);
|
||||
|
||||
parser.on('data', function (data) {
|
||||
items++
|
||||
if(Math.random() < 0.01) console.log(items, '...')
|
||||
});
|
||||
|
||||
parser.on('end', function () {
|
||||
t.equal(items, size)
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// main
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
fs.stat(file, function (err, stat) {
|
||||
console.log(stat)
|
||||
if(err)
|
||||
generateTestData(testJSONStreamParse_causesOutOfMem);
|
||||
else
|
||||
testJSONStreamParse_causesOutOfMem()
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// }
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','header_footer.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse(['rows', /\d+/ /*, 'value'*/])
|
||||
, called = 0
|
||||
, headerCalled = 0
|
||||
, footerCalled = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('header', function (data) {
|
||||
headerCalled ++
|
||||
it(data).deepEqual({
|
||||
total_rows: 129,
|
||||
offset: 0
|
||||
})
|
||||
})
|
||||
|
||||
parser.on('footer', function (data) {
|
||||
footerCalled ++
|
||||
it(data).deepEqual({
|
||||
foo: { bar: 'baz' }
|
||||
})
|
||||
})
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
it.has({
|
||||
id: it.typeof('string'),
|
||||
value: {rev: it.typeof('string')},
|
||||
key:it.typeof('string')
|
||||
})
|
||||
it(headerCalled).equal(1)
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(expected.rows.length)
|
||||
it(headerCalled).equal(1)
|
||||
it(footerCalled).equal(1)
|
||||
it(parsed).deepEqual(expected.rows)
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,34 @@
|
|||
var JSONStream = require('../');
|
||||
var test = require('tape')
|
||||
|
||||
test('#66', function (t) {
|
||||
var error = 0;
|
||||
var stream = JSONStream
|
||||
.parse()
|
||||
.on('error', function (err) {
|
||||
t.ok(err);
|
||||
error++;
|
||||
})
|
||||
.on('end', function () {
|
||||
t.ok(error === 1);
|
||||
t.end();
|
||||
});
|
||||
|
||||
stream.write('["foo":bar[');
|
||||
stream.end();
|
||||
|
||||
});
|
||||
|
||||
test('#81 - failure to parse nested objects', function (t) {
|
||||
var stream = JSONStream
|
||||
.parse('.bar.foo')
|
||||
.on('error', function (err) {
|
||||
t.error(err);
|
||||
})
|
||||
.on('end', function () {
|
||||
t.end();
|
||||
});
|
||||
|
||||
stream.write('{"bar":{"foo":"baz"}}');
|
||||
stream.end();
|
||||
});
|
|
@ -0,0 +1,105 @@
|
|||
var test = require('tape');
|
||||
var fs = require ('fs');
|
||||
var join = require('path').join;
|
||||
var couch_sample_file = join(__dirname, 'fixtures','couch_sample.json');
|
||||
var JSONStream = require('../');
|
||||
|
||||
var fixture = {
|
||||
obj: {
|
||||
one: 1,
|
||||
two: 2,
|
||||
three: 3
|
||||
}
|
||||
};
|
||||
|
||||
function assertFixtureKeys(stream, t) {
|
||||
var keys = [];
|
||||
var values = [];
|
||||
stream.on('data', function(data) {
|
||||
keys.push(data.key);
|
||||
values.push(data.value);
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
t.deepEqual(keys, ['one', 'two', 'three']);
|
||||
t.deepEqual(values, [1,2,3]);
|
||||
t.end();
|
||||
});
|
||||
stream.write(JSON.stringify(fixture));
|
||||
stream.end();
|
||||
}
|
||||
|
||||
test('keys via string', function(t) {
|
||||
var stream = JSONStream.parse('obj.$*');
|
||||
assertFixtureKeys(stream, t);
|
||||
});
|
||||
|
||||
test('keys via array', function(t) {
|
||||
var stream = JSONStream.parse(['obj',{emitKey: true}]);
|
||||
assertFixtureKeys(stream, t);
|
||||
});
|
||||
|
||||
test('path via array', function(t) {
|
||||
var stream = JSONStream.parse(['obj',{emitPath: true}]);
|
||||
|
||||
var paths = [];
|
||||
var values = [];
|
||||
stream.on('data', function(data) {
|
||||
console.log(JSON.stringify(data));
|
||||
paths.push(data.path);
|
||||
values.push(data.value);
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
t.deepEqual(paths, [['obj', 'one'], ['obj', 'two'], ['obj', 'three']]);
|
||||
t.deepEqual(values, [1,2,3]);
|
||||
t.end();
|
||||
});
|
||||
stream.write(JSON.stringify(fixture));
|
||||
stream.end();
|
||||
});
|
||||
|
||||
test('advanced keys', function(t) {
|
||||
var advanced = fs.readFileSync(couch_sample_file);
|
||||
var stream = JSONStream.parse(['rows', true, 'doc', {emitKey: true}]);
|
||||
|
||||
var keys = [];
|
||||
var values = [];
|
||||
stream.on('data', function(data) {
|
||||
keys.push(data.key);
|
||||
values.push(data.value);
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
t.deepEqual(keys, [
|
||||
'_id', '_rev', 'hello',
|
||||
'_id', '_rev', 'hello'
|
||||
]);
|
||||
t.deepEqual(values, [
|
||||
"change1_0.6995461115147918", "1-e240bae28c7bb3667f02760f6398d508", 1,
|
||||
"change2_0.6995461115147918", "1-13677d36b98c0c075145bb8975105153", 2
|
||||
]);
|
||||
t.end();
|
||||
});
|
||||
stream.write(advanced);
|
||||
stream.end();
|
||||
});
|
||||
|
||||
test('parent keys', function(t) {
|
||||
var stream = JSONStream.parse('$*');
|
||||
var d = null;
|
||||
stream.on('data', function(data) {
|
||||
if(d) t.fail('should only be called once');
|
||||
d = data;
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
t.deepEqual(d,{
|
||||
key: 'obj',
|
||||
value: fixture.obj
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
stream.write(JSON.stringify(fixture));
|
||||
stream.end();
|
||||
})
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
var test = require('tape')
|
||||
|
||||
var JSONStream = require('../')
|
||||
|
||||
test('map function', function (t) {
|
||||
|
||||
var actual = []
|
||||
|
||||
stream = JSONStream.parse([true], function (e) { return e*10 })
|
||||
stream.on('data', function (v) { actual.push(v)})
|
||||
stream.on('end', function () {
|
||||
t.deepEqual(actual, [10,20,30,40,50,60])
|
||||
t.end()
|
||||
|
||||
})
|
||||
|
||||
stream.write(JSON.stringify([1,2,3,4,5,6], null, 2))
|
||||
stream.end()
|
||||
|
||||
})
|
||||
|
||||
test('filter function', function (t) {
|
||||
|
||||
var actual = []
|
||||
|
||||
stream = JSONStream
|
||||
.parse([true], function (e) { return e%2 ? e : null})
|
||||
.on('data', function (v) { actual.push(v)})
|
||||
.on('end', function () {
|
||||
t.deepEqual(actual, [1,3,5])
|
||||
t.end()
|
||||
|
||||
})
|
||||
|
||||
stream.write(JSON.stringify([1,2,3,4,5,6], null, 2))
|
||||
stream.end()
|
||||
|
||||
})
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
var fs = require ('fs');
|
||||
var net = require('net');
|
||||
var join = require('path').join;
|
||||
var file = join(__dirname, 'fixtures','all_npm.json');
|
||||
var it = require('it-is');
|
||||
var JSONStream = require('../');
|
||||
|
||||
var str = fs.readFileSync(file);
|
||||
|
||||
var datas = {}
|
||||
|
||||
var server = net.createServer(function(client) {
|
||||
var data_calls = 0;
|
||||
var parser = JSONStream.parse(['rows', true, 'key']);
|
||||
parser.on('data', function(data) {
|
||||
++ data_calls;
|
||||
datas[data] = (datas[data] || 0) + 1
|
||||
it(data).typeof('string')
|
||||
});
|
||||
|
||||
parser.on('end', function() {
|
||||
console.log('END')
|
||||
var min = Infinity
|
||||
for (var d in datas)
|
||||
min = min > datas[d] ? datas[d] : min
|
||||
it(min).equal(3);
|
||||
server.close();
|
||||
});
|
||||
client.pipe(parser);
|
||||
});
|
||||
server.listen(9999);
|
||||
|
||||
var client = net.connect({ port : 9999 }, function() {
|
||||
var msgs = str + ' ' + str + '\n\n' + str
|
||||
client.end(msgs);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
var fs = require ('fs');
|
||||
var net = require('net');
|
||||
var join = require('path').join;
|
||||
var file = join(__dirname, 'fixtures','all_npm.json');
|
||||
var it = require('it-is');
|
||||
var JSONStream = require('../');
|
||||
|
||||
var str = fs.readFileSync(file);
|
||||
|
||||
var server = net.createServer(function(client) {
|
||||
var data_calls = 0;
|
||||
var parser = JSONStream.parse();
|
||||
parser.on('error', function(err) {
|
||||
console.log(err);
|
||||
server.close();
|
||||
});
|
||||
|
||||
parser.on('end', function() {
|
||||
console.log('END');
|
||||
server.close();
|
||||
});
|
||||
client.pipe(parser);
|
||||
});
|
||||
server.listen(9999);
|
||||
|
||||
var client = net.connect({ port : 9999 }, function() {
|
||||
var msgs = str + '}';
|
||||
client.end(msgs);
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
var JSONStream = require('../')
|
||||
|
||||
var data = [
|
||||
{ID: 1, optional: null},
|
||||
{ID: 2, optional: null},
|
||||
{ID: 3, optional: 20},
|
||||
{ID: 4, optional: null},
|
||||
{ID: 5, optional: 'hello'},
|
||||
{ID: 6, optional: null}
|
||||
]
|
||||
|
||||
|
||||
var test = require('tape')
|
||||
|
||||
test ('null properties', function (t) {
|
||||
var actual = []
|
||||
var stream =
|
||||
|
||||
JSONStream.parse('*.optional')
|
||||
.on('data', function (v) { actual.push(v) })
|
||||
.on('end', function () {
|
||||
t.deepEqual(actual, [20, 'hello'])
|
||||
t.end()
|
||||
})
|
||||
|
||||
stream.write(JSON.stringify(data, null, 2))
|
||||
stream.end()
|
||||
})
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
|
||||
/*
|
||||
sometimes jsonparse changes numbers slightly.
|
||||
*/
|
||||
|
||||
var r = Math.random()
|
||||
, Parser = require('jsonparse')
|
||||
, p = new Parser()
|
||||
, assert = require('assert')
|
||||
, times = 20
|
||||
, bufferFrom = Buffer.from && Buffer.from !== Uint8Array.from
|
||||
, str
|
||||
|
||||
while (times --) {
|
||||
|
||||
assert.equal(JSON.parse(JSON.stringify(r)), r, 'core JSON')
|
||||
|
||||
p.onValue = function (v) {
|
||||
console.error('parsed', v)
|
||||
assert.equal(v,r)
|
||||
}
|
||||
console.error('correct', r)
|
||||
str = JSON.stringify([r])
|
||||
p.write (bufferFrom ? Buffer.from(str) : new Buffer(str))
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
var readdirSync = require('fs').readdirSync
|
||||
var spawnSync = require('child_process').spawnSync
|
||||
var extname = require('path').extname
|
||||
|
||||
var files = readdirSync(__dirname)
|
||||
files.forEach(function(file){
|
||||
if (extname(file) !== '.js' || file === 'run.js')
|
||||
return
|
||||
console.log(`*** ${file} ***`)
|
||||
var result = spawnSync(process.argv0, [file], { stdio: 'inherit', cwd: __dirname} )
|
||||
if (result.status !== 0)
|
||||
process.exit(result.status)
|
||||
})
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is').style('colour')
|
||||
|
||||
function randomObj () {
|
||||
return (
|
||||
Math.random () < 0.4
|
||||
? {hello: 'eonuhckmqjk',
|
||||
whatever: 236515,
|
||||
lies: true,
|
||||
nothing: [null],
|
||||
stuff: [Math.random(),Math.random(),Math.random()]
|
||||
}
|
||||
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
|
||||
)
|
||||
}
|
||||
|
||||
var expected = []
|
||||
, stringify = JSONStream.stringify()
|
||||
, es = require('event-stream')
|
||||
, stringified = ''
|
||||
, called = 0
|
||||
, count = 10
|
||||
, ended = false
|
||||
|
||||
while (count --)
|
||||
expected.push(randomObj())
|
||||
|
||||
es.connect(
|
||||
es.readArray(expected),
|
||||
stringify,
|
||||
//JSONStream.parse([/./]),
|
||||
es.writeArray(function (err, lines) {
|
||||
|
||||
it(JSON.parse(lines.join(''))).deepEqual(expected)
|
||||
console.error('PASSED')
|
||||
})
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is').style('colour')
|
||||
, es = require('event-stream')
|
||||
, pending = 10
|
||||
, passed = true
|
||||
|
||||
function randomObj () {
|
||||
return (
|
||||
Math.random () < 0.4
|
||||
? {hello: 'eonuhckmqjk',
|
||||
whatever: 236515,
|
||||
lies: true,
|
||||
nothing: [null],
|
||||
stuff: [Math.random(),Math.random(),Math.random()]
|
||||
}
|
||||
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
|
||||
)
|
||||
}
|
||||
|
||||
for (var ix = 0; ix < pending; ix++) (function (count) {
|
||||
var expected = {}
|
||||
, stringify = JSONStream.stringifyObject()
|
||||
|
||||
es.connect(
|
||||
stringify,
|
||||
es.writeArray(function (err, lines) {
|
||||
it(JSON.parse(lines.join(''))).deepEqual(expected)
|
||||
if (--pending === 0) {
|
||||
console.error('PASSED')
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
while (count --) {
|
||||
var key = Math.random().toString(16).slice(2)
|
||||
expected[key] = randomObj()
|
||||
stringify.write([ key, expected[key] ])
|
||||
}
|
||||
|
||||
process.nextTick(function () {
|
||||
stringify.end()
|
||||
})
|
||||
})(ix)
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse(['rows', /\d+/ /*, 'value'*/])
|
||||
, called = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
it.has({
|
||||
id: it.typeof('string'),
|
||||
value: {rev: it.typeof('string')},
|
||||
key:it.typeof('string')
|
||||
})
|
||||
parsed.push(data)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(expected.rows.length)
|
||||
it(parsed).deepEqual(expected.rows)
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, '..','package.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is')
|
||||
|
||||
var expected = JSON.parse(fs.readFileSync(file))
|
||||
, parser = JSONStream.parse([])
|
||||
, called = 0
|
||||
, ended = false
|
||||
, parsed = []
|
||||
|
||||
fs.createReadStream(file).pipe(parser)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
called ++
|
||||
it(data).deepEqual(expected)
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
it(called).equal(1)
|
||||
console.error('PASSED')
|
||||
})
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
var fs = require ('fs')
|
||||
, join = require('path').join
|
||||
, file = join(__dirname, 'fixtures','all_npm.json')
|
||||
, JSONStream = require('../')
|
||||
, it = require('it-is').style('colour')
|
||||
|
||||
function randomObj () {
|
||||
return (
|
||||
Math.random () < 0.4
|
||||
? {hello: 'eonuhckmqjk',
|
||||
whatever: 236515,
|
||||
lies: true,
|
||||
nothing: [null],
|
||||
// stuff: [Math.random(),Math.random(),Math.random()]
|
||||
}
|
||||
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
|
||||
)
|
||||
}
|
||||
|
||||
var expected = []
|
||||
, stringify = JSONStream.stringify()
|
||||
, es = require('event-stream')
|
||||
, stringified = ''
|
||||
, called = 0
|
||||
, count = 10
|
||||
, ended = false
|
||||
|
||||
while (count --)
|
||||
expected.push(randomObj())
|
||||
|
||||
es.connect(
|
||||
es.readArray(expected),
|
||||
stringify,
|
||||
JSONStream.parse([/./]),
|
||||
es.writeArray(function (err, lines) {
|
||||
|
||||
it(lines).has(expected)
|
||||
console.error('PASSED')
|
||||
})
|
||||
)
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"node": true,
|
||||
"bitwise": false,
|
||||
"camelcase": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"indent": 4,
|
||||
"latedef": "nofunc",
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"quotmark": "single",
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"strict": true,
|
||||
"trailing": true,
|
||||
"smarttabs": true,
|
||||
"globals": {
|
||||
"describe": false,
|
||||
"it": false,
|
||||
"beforeEach": false,
|
||||
"afterEach": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/.idea
|
||||
/atlassian-ide-plugin.xml
|
||||
*.iml
|
||||
.DS_Store
|
||||
|
||||
/node_modules
|
||||
/coverage
|
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
|
@ -0,0 +1,38 @@
|
|||
# add-stream [](https://travis-ci.org/wilsonjackson/add-stream)
|
||||
|
||||
> Append the contents of one stream onto another.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var fs = require('fs');
|
||||
var es = require('event-stream');
|
||||
var addStream = require('add-stream');
|
||||
|
||||
// Append strings/buffers
|
||||
fs.createReadStream('1.txt') // 1.txt contains: number1
|
||||
.pipe(addStream(fs.createReadStream('2.txt'))) // 2.txt contains: number2
|
||||
.pipe(fs.createWriteStream('appended.txt')); // appended.txt contains: number1number2
|
||||
|
||||
// Append object streams
|
||||
es.readArray([1, 2, 3])
|
||||
.pipe(addStream.obj(es.readArray([4, 5, 6])))
|
||||
.pipe(es.writeArray(function (err, array) {
|
||||
console.log(array); // [ 1, 2, 3, 4, 5, 6 ]
|
||||
}));
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### var transformStream = addStream(stream, opts = {})
|
||||
|
||||
Create a transform stream that appends the contents of `stream` onto whatever
|
||||
is piped into it. Options are passed to the transform stream's constructor.
|
||||
|
||||
### var transformStream = addStream.obj(stream, opts = {})
|
||||
|
||||
A convenient shortcut for `addStream(stream, {objectMode: true})`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
var PassThrough = require('stream').PassThrough;
|
||||
var Writable = require('stream').Writable;
|
||||
var util = require('util');
|
||||
|
||||
util.inherits(Appendee, PassThrough);
|
||||
util.inherits(Appender, Writable);
|
||||
|
||||
function Appendee(factory, opts) {
|
||||
PassThrough.call(this, opts);
|
||||
this.factory = factory;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
//noinspection JSUnusedGlobalSymbols
|
||||
Appendee.prototype._flush = function (end) {
|
||||
var stream = this.factory();
|
||||
stream.pipe(new Appender(this, this.opts))
|
||||
.on('finish', end);
|
||||
stream.resume();
|
||||
};
|
||||
|
||||
function Appender(target, opts) {
|
||||
Writable.call(this, opts);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
//noinspection JSUnusedGlobalSymbols
|
||||
Appender.prototype._write = function (chunk, enc, cb) {
|
||||
this.target.push(chunk);
|
||||
cb();
|
||||
};
|
||||
|
||||
function addStream(stream, opts) {
|
||||
opts = opts || {};
|
||||
var factory;
|
||||
if (typeof stream === 'function') {
|
||||
factory = stream;
|
||||
}
|
||||
else {
|
||||
stream.pause();
|
||||
factory = function () {
|
||||
return stream;
|
||||
};
|
||||
}
|
||||
return new Appendee(factory, opts);
|
||||
}
|
||||
|
||||
addStream.obj = function (stream, opts) {
|
||||
opts = opts || {};
|
||||
opts.objectMode = true;
|
||||
return addStream(stream, opts);
|
||||
};
|
||||
|
||||
module.exports = addStream;
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "add-stream",
|
||||
"version": "1.0.0",
|
||||
"description": "Append the contents of one stream onto another.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"cover": "istanbul cover node_modules/.bin/_mocha -- -u exports -R spec"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/wilsonjackson/add-stream"
|
||||
},
|
||||
"keywords": [
|
||||
"stream",
|
||||
"append",
|
||||
"add",
|
||||
"concat",
|
||||
"gulpfriendly"
|
||||
],
|
||||
"author": "Majid Burney <moocow@euphoricsoup.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/wilsonjackson/add-stream/issues"
|
||||
},
|
||||
"homepage": "https://github.com/wilsonjackson/add-stream",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"chai": "^1.10.0",
|
||||
"event-stream": "^3.1.7",
|
||||
"istanbul": "^0.3.4",
|
||||
"mocha": "^2.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
'use strict';
|
||||
|
||||
var chai = require('chai');
|
||||
var expect = chai.expect;
|
||||
var es = require('event-stream');
|
||||
var addStream = require('../');
|
||||
|
||||
describe('add-stream', function () {
|
||||
function emit(chunks) {
|
||||
var mutableChunks = [].concat(chunks);
|
||||
return es.readable(function (count, callback) {
|
||||
if (mutableChunks.length === 0) {
|
||||
return this.emit('end');
|
||||
}
|
||||
callback(null, mutableChunks.shift());
|
||||
});
|
||||
}
|
||||
|
||||
describe('buffer mode', function () {
|
||||
it('should append a stream', function (done) {
|
||||
var firstChunks = ['abc', 'def'];
|
||||
var secondChunks = ['ghi', 'jkl'];
|
||||
emit(firstChunks)
|
||||
.pipe(addStream(emit(secondChunks)))
|
||||
.pipe(es.wait(function (err, buffer) {
|
||||
expect(buffer.toString()).to.equal(firstChunks.concat(secondChunks).join(''));
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
it('should append a stream from a factory function', function (done) {
|
||||
var firstChunks = ['abc', 'def'];
|
||||
var secondChunks = ['ghi', 'jkl'];
|
||||
emit(firstChunks)
|
||||
.pipe(addStream(function () {
|
||||
return emit(secondChunks);
|
||||
}))
|
||||
.pipe(es.wait(function (err, buffer) {
|
||||
expect(buffer.toString()).to.equal(firstChunks.concat(secondChunks).join(''));
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('object mode', function () {
|
||||
it('should append a stream', function (done) {
|
||||
es.readArray([{p: 1}, {p: 2}, {p: 3}])
|
||||
.pipe(addStream.obj(es.readArray([{p: 4}, {p: 5}, {p: 6}])))
|
||||
.pipe(es.writeArray(function (err, array) {
|
||||
expect(array).to.eql([{p: 1}, {p: 2}, {p: 3}, {p: 4}, {p: 5}, {p: 6}]);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
it('should append a stream from a factory function', function (done) {
|
||||
es.readArray([{p: 1}, {p: 2}, {p: 3}])
|
||||
.pipe(addStream.obj(function () {return es.readArray([{p: 4}, {p: 5}, {p: 6}])}))
|
||||
.pipe(es.writeArray(function (err, array) {
|
||||
expect(array).to.eql([{p: 1}, {p: 2}, {p: 3}, {p: 4}, {p: 5}, {p: 6}]);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
'use strict';
|
||||
module.exports = function (arr, predicate, ctx) {
|
||||
if (typeof Array.prototype.findIndex === 'function') {
|
||||
return arr.findIndex(predicate, ctx);
|
||||
}
|
||||
|
||||
if (typeof predicate !== 'function') {
|
||||
throw new TypeError('predicate must be a function');
|
||||
}
|
||||
|
||||
var list = Object(arr);
|
||||
var len = list.length;
|
||||
|
||||
if (len === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (predicate.call(ctx, list[i], i, list)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "array-find-index",
|
||||
"version": "1.0.2",
|
||||
"description": "ES2015 `Array#findIndex()` ponyfill",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/array-find-index",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"es2015",
|
||||
"ponyfill",
|
||||
"polyfill",
|
||||
"shim",
|
||||
"find",
|
||||
"index",
|
||||
"findindex",
|
||||
"array"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "*",
|
||||
"xo": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
# array-find-index [](https://travis-ci.org/sindresorhus/array-find-index)
|
||||
|
||||
> ES2015 [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) [ponyfill](https://ponyfill.com)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save array-find-index
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const arrayFindIndex = require('array-find-index');
|
||||
|
||||
arrayFindIndex(['rainbow', 'unicorn', 'pony'], x => x === 'unicorn');
|
||||
//=> 1
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
Same as `Array#findIndex()`, but with the input array as the first argument.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](https://sindresorhus.com)
|
|
@ -0,0 +1,51 @@
|
|||
# [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage Status][coveralls-image]][coveralls-url]
|
||||
|
||||
> Turn anything into an array
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save array-ify
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var arrayify = require('array-ify');
|
||||
|
||||
arrayify('unicorn');
|
||||
//=> ['unicorn']
|
||||
|
||||
arrayify(['unicorn']);
|
||||
//=> ['unicorn']
|
||||
|
||||
arrayify(null);
|
||||
//=> [null]
|
||||
|
||||
arrayify(undefined);
|
||||
//=> [undefined]
|
||||
```
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [arrify](https://github.com/sindresorhus/arrify) - Convert a value to an array
|
||||
|
||||
The difference that is this module does **NOT** turn `null` or `undefined` to an empty array.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Steve Mao](https://github.com/stevemao)
|
||||
|
||||
|
||||
[npm-image]: https://badge.fury.io/js/array-ify.svg
|
||||
[npm-url]: https://npmjs.org/package/array-ify
|
||||
[travis-image]: https://travis-ci.org/stevemao/array-ify.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/stevemao/array-ify
|
||||
[daviddm-image]: https://david-dm.org/stevemao/array-ify.svg?theme=shields.io
|
||||
[daviddm-url]: https://david-dm.org/stevemao/array-ify
|
||||
[coveralls-image]: https://coveralls.io/repos/stevemao/array-ify/badge.svg
|
||||
[coveralls-url]: https://coveralls.io/r/stevemao/array-ify
|
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
module.exports = function(val) {
|
||||
return Array.isArray(val) ? val : [val];
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "array-ify",
|
||||
"version": "1.0.0",
|
||||
"description": "Turn anything into an array",
|
||||
"homepage": "https://github.com/stevemao/array-ify",
|
||||
"author": {
|
||||
"name": "Steve Mao",
|
||||
"email": "maochenyan@gmail.com",
|
||||
"url": "https://github.com/stevemao"
|
||||
},
|
||||
"repository": "stevemao/array-ify",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"array-ify",
|
||||
"array",
|
||||
"arr",
|
||||
"arrify",
|
||||
"arrayify",
|
||||
"convert",
|
||||
"value"
|
||||
],
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.2",
|
||||
"istanbul": "^0.3.8",
|
||||
"jscs": "^1.11.3",
|
||||
"jshint": "^2.6.3",
|
||||
"mocha": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"coverage": "istanbul cover _mocha -- -R spec && rm -rf ./coverage",
|
||||
"lint": "jshint *.js --exclude node_modules && jscs *.js",
|
||||
"test": "npm run-script lint && mocha"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
'use strict';
|
||||
module.exports = function (val) {
|
||||
if (val === null || val === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Array.isArray(val) ? val : [val];
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "arrify",
|
||||
"version": "1.0.1",
|
||||
"description": "Convert a value to an array",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/arrify",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"array",
|
||||
"arr",
|
||||
"arrify",
|
||||
"arrayify",
|
||||
"convert",
|
||||
"value"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "*",
|
||||
"xo": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
# arrify [](https://travis-ci.org/sindresorhus/arrify)
|
||||
|
||||
> Convert a value to an array
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save arrify
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const arrify = require('arrify');
|
||||
|
||||
arrify('unicorn');
|
||||
//=> ['unicorn']
|
||||
|
||||
arrify(['unicorn']);
|
||||
//=> ['unicorn']
|
||||
|
||||
arrify(null);
|
||||
//=> []
|
||||
|
||||
arrify(undefined);
|
||||
//=> []
|
||||
```
|
||||
|
||||
*Supplying `null` or `undefined` results in an empty array.*
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016, 2018 Linus Unnebäck
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,69 @@
|
|||
var toString = Object.prototype.toString
|
||||
|
||||
var isModern = (
|
||||
typeof Buffer.alloc === 'function' &&
|
||||
typeof Buffer.allocUnsafe === 'function' &&
|
||||
typeof Buffer.from === 'function'
|
||||
)
|
||||
|
||||
function isArrayBuffer (input) {
|
||||
return toString.call(input).slice(8, -1) === 'ArrayBuffer'
|
||||
}
|
||||
|
||||
function fromArrayBuffer (obj, byteOffset, length) {
|
||||
byteOffset >>>= 0
|
||||
|
||||
var maxLength = obj.byteLength - byteOffset
|
||||
|
||||
if (maxLength < 0) {
|
||||
throw new RangeError("'offset' is out of bounds")
|
||||
}
|
||||
|
||||
if (length === undefined) {
|
||||
length = maxLength
|
||||
} else {
|
||||
length >>>= 0
|
||||
|
||||
if (length > maxLength) {
|
||||
throw new RangeError("'length' is out of bounds")
|
||||
}
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(obj.slice(byteOffset, byteOffset + length))
|
||||
: new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
|
||||
}
|
||||
|
||||
function fromString (string, encoding) {
|
||||
if (typeof encoding !== 'string' || encoding === '') {
|
||||
encoding = 'utf8'
|
||||
}
|
||||
|
||||
if (!Buffer.isEncoding(encoding)) {
|
||||
throw new TypeError('"encoding" must be a valid string encoding')
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(string, encoding)
|
||||
: new Buffer(string, encoding)
|
||||
}
|
||||
|
||||
function bufferFrom (value, encodingOrOffset, length) {
|
||||
if (typeof value === 'number') {
|
||||
throw new TypeError('"value" argument must not be a number')
|
||||
}
|
||||
|
||||
if (isArrayBuffer(value)) {
|
||||
return fromArrayBuffer(value, encodingOrOffset, length)
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return fromString(value, encodingOrOffset)
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(value)
|
||||
: new Buffer(value)
|
||||
}
|
||||
|
||||
module.exports = bufferFrom
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "buffer-from",
|
||||
"version": "1.1.1",
|
||||
"license": "MIT",
|
||||
"repository": "LinusU/buffer-from",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "standard && node test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^7.1.2"
|
||||
},
|
||||
"keywords": [
|
||||
"buffer",
|
||||
"buffer from"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
# Buffer From
|
||||
|
||||
A [ponyfill](https://ponyfill.com) for `Buffer.from`, uses native implementation if available.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save buffer-from
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const bufferFrom = require('buffer-from')
|
||||
|
||||
console.log(bufferFrom([1, 2, 3, 4]))
|
||||
//=> <Buffer 01 02 03 04>
|
||||
|
||||
const arr = new Uint8Array([1, 2, 3, 4])
|
||||
console.log(bufferFrom(arr.buffer, 1, 2))
|
||||
//=> <Buffer 02 03>
|
||||
|
||||
console.log(bufferFrom('test', 'utf8'))
|
||||
//=> <Buffer 74 65 73 74>
|
||||
|
||||
const buf = bufferFrom('test')
|
||||
console.log(bufferFrom(buf))
|
||||
//=> <Buffer 74 65 73 74>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### bufferFrom(array)
|
||||
|
||||
- `array` <Array>
|
||||
|
||||
Allocates a new `Buffer` using an `array` of octets.
|
||||
|
||||
### bufferFrom(arrayBuffer[, byteOffset[, length]])
|
||||
|
||||
- `arrayBuffer` <ArrayBuffer> The `.buffer` property of a TypedArray or ArrayBuffer
|
||||
- `byteOffset` <Integer> Where to start copying from `arrayBuffer`. **Default:** `0`
|
||||
- `length` <Integer> How many bytes to copy from `arrayBuffer`. **Default:** `arrayBuffer.length - byteOffset`
|
||||
|
||||
When passed a reference to the `.buffer` property of a TypedArray instance, the
|
||||
newly created `Buffer` will share the same allocated memory as the TypedArray.
|
||||
|
||||
The optional `byteOffset` and `length` arguments specify a memory range within
|
||||
the `arrayBuffer` that will be shared by the `Buffer`.
|
||||
|
||||
### bufferFrom(buffer)
|
||||
|
||||
- `buffer` <Buffer> An existing `Buffer` to copy data from
|
||||
|
||||
Copies the passed `buffer` data onto a new `Buffer` instance.
|
||||
|
||||
### bufferFrom(string[, encoding])
|
||||
|
||||
- `string` <String> A string to encode.
|
||||
- `encoding` <String> The encoding of `string`. **Default:** `'utf8'`
|
||||
|
||||
Creates a new `Buffer` containing the given JavaScript string `string`. If
|
||||
provided, the `encoding` parameter identifies the character encoding of
|
||||
`string`.
|
||||
|
||||
## See also
|
||||
|
||||
- [buffer-alloc](https://github.com/LinusU/buffer-alloc) A ponyfill for `Buffer.alloc`
|
||||
- [buffer-alloc-unsafe](https://github.com/LinusU/buffer-alloc-unsafe) A ponyfill for `Buffer.allocUnsafe`
|
|
@ -0,0 +1,41 @@
|
|||
'use strict';
|
||||
const mapObj = require('map-obj');
|
||||
const camelCase = require('camelcase');
|
||||
const QuickLru = require('quick-lru');
|
||||
|
||||
const has = (arr, key) => arr.some(x => typeof x === 'string' ? x === key : x.test(key));
|
||||
const cache = new QuickLru({maxSize: 100000});
|
||||
|
||||
const camelCaseConvert = (input, opts) => {
|
||||
opts = Object.assign({
|
||||
deep: false
|
||||
}, opts);
|
||||
|
||||
const exclude = opts.exclude;
|
||||
|
||||
return mapObj(input, (key, val) => {
|
||||
if (!(exclude && has(exclude, key))) {
|
||||
if (cache.has(key)) {
|
||||
key = cache.get(key);
|
||||
} else {
|
||||
const ret = camelCase(key);
|
||||
|
||||
if (key.length < 100) { // Prevent abuse
|
||||
cache.set(key, ret);
|
||||
}
|
||||
|
||||
key = ret;
|
||||
}
|
||||
}
|
||||
|
||||
return [key, val];
|
||||
}, {deep: opts.deep});
|
||||
};
|
||||
|
||||
module.exports = (input, opts) => {
|
||||
if (Array.isArray(input)) {
|
||||
return Object.keys(input).map(key => camelCaseConvert(input[key], opts));
|
||||
}
|
||||
return camelCaseConvert(input, opts);
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue