@automattic/vip 4.1.6 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/assets/dev-env.lando.template.yml.ejs +1 -1
  2. package/dist/bin/vip-app-deploy-token-generate.js +110 -78
  3. package/dist/bin/vip-app-deploy-token.js +24 -16
  4. package/dist/bin/vip-app-deploy-validate.js +45 -41
  5. package/dist/bin/vip-app-deploy.js +222 -215
  6. package/dist/bin/vip-app-list.js +59 -43
  7. package/dist/bin/vip-app.js +97 -66
  8. package/dist/bin/vip-backup-db.js +36 -29
  9. package/dist/bin/vip-backup.js +16 -9
  10. package/dist/bin/vip-cache-purge-url.js +93 -55
  11. package/dist/bin/vip-cache.js +23 -14
  12. package/dist/bin/vip-config-envvar-delete.js +74 -73
  13. package/dist/bin/vip-config-envvar-get-all.js +68 -68
  14. package/dist/bin/vip-config-envvar-get.js +46 -46
  15. package/dist/bin/vip-config-envvar-list.js +54 -57
  16. package/dist/bin/vip-config-envvar-set.js +102 -96
  17. package/dist/bin/vip-config-envvar.js +38 -24
  18. package/dist/bin/vip-config-software-get.js +88 -75
  19. package/dist/bin/vip-config-software-update.js +116 -120
  20. package/dist/bin/vip-config-software.js +31 -21
  21. package/dist/bin/vip-config.js +25 -17
  22. package/dist/bin/vip-db-phpmyadmin.js +40 -39
  23. package/dist/bin/vip-db.js +13 -12
  24. package/dist/bin/vip-defensive-mode-configure.js +197 -197
  25. package/dist/bin/vip-defensive-mode-disable.js +43 -35
  26. package/dist/bin/vip-defensive-mode-enable.js +47 -38
  27. package/dist/bin/vip-defensive-mode.js +28 -17
  28. package/dist/bin/vip-dev-env-create.js +147 -104
  29. package/dist/bin/vip-dev-env-destroy.js +48 -39
  30. package/dist/bin/vip-dev-env-envvar-delete.js +60 -49
  31. package/dist/bin/vip-dev-env-envvar-get-all.js +52 -45
  32. package/dist/bin/vip-dev-env-envvar-get.js +48 -37
  33. package/dist/bin/vip-dev-env-envvar-list.js +48 -41
  34. package/dist/bin/vip-dev-env-envvar-set.js +83 -70
  35. package/dist/bin/vip-dev-env-envvar.js +38 -23
  36. package/dist/bin/vip-dev-env-exec.js +81 -74
  37. package/dist/bin/vip-dev-env-import-media.js +34 -26
  38. package/dist/bin/vip-dev-env-import-sql.js +65 -51
  39. package/dist/bin/vip-dev-env-import.js +23 -14
  40. package/dist/bin/vip-dev-env-info.js +59 -50
  41. package/dist/bin/vip-dev-env-list.js +34 -31
  42. package/dist/bin/vip-dev-env-logs.js +59 -49
  43. package/dist/bin/vip-dev-env-purge.js +71 -63
  44. package/dist/bin/vip-dev-env-shell.js +82 -71
  45. package/dist/bin/vip-dev-env-start.js +77 -65
  46. package/dist/bin/vip-dev-env-stop.js +80 -74
  47. package/dist/bin/vip-dev-env-sync-sql.js +80 -72
  48. package/dist/bin/vip-dev-env-sync.js +18 -11
  49. package/dist/bin/vip-dev-env-update.js +93 -84
  50. package/dist/bin/vip-dev-env.js +25 -8
  51. package/dist/bin/vip-edge-workers-build.js +82 -54
  52. package/dist/bin/vip-edge-workers-delete.js +84 -52
  53. package/dist/bin/vip-edge-workers-deploy.js +186 -126
  54. package/dist/bin/vip-edge-workers-disable.js +75 -44
  55. package/dist/bin/vip-edge-workers-enable.js +86 -54
  56. package/dist/bin/vip-edge-workers-get.js +108 -88
  57. package/dist/bin/vip-edge-workers-init.js +83 -53
  58. package/dist/bin/vip-edge-workers-list.js +89 -54
  59. package/dist/bin/vip-edge-workers-new.js +98 -69
  60. package/dist/bin/vip-edge-workers-validate.js +123 -82
  61. package/dist/bin/vip-edge-workers.js +19 -6
  62. package/dist/bin/vip-export-sql.js +75 -69
  63. package/dist/bin/vip-export.js +12 -7
  64. package/dist/bin/vip-import-media-abort.js +99 -73
  65. package/dist/bin/vip-import-media-status.js +83 -51
  66. package/dist/bin/vip-import-media.js +165 -166
  67. package/dist/bin/vip-import-sql-status.js +75 -45
  68. package/dist/bin/vip-import-sql.js +536 -596
  69. package/dist/bin/vip-import-validate-files.js +122 -141
  70. package/dist/bin/vip-import-validate-sql.js +52 -16
  71. package/dist/bin/vip-import.js +16 -7
  72. package/dist/bin/vip-logout.js +17 -13
  73. package/dist/bin/vip-logs.js +209 -183
  74. package/dist/bin/vip-search-replace.js +85 -53
  75. package/dist/bin/vip-slowlogs.js +168 -147
  76. package/dist/bin/vip-sync.js +163 -133
  77. package/dist/bin/vip-whoami.js +71 -35
  78. package/dist/bin/vip-wp.js +506 -549
  79. package/dist/bin/vip.js +161 -116
  80. package/dist/commands/backup-db.js +183 -149
  81. package/dist/commands/dev-env-import-sql.js +162 -117
  82. package/dist/commands/dev-env-sync-sql.js +372 -330
  83. package/dist/commands/export-sql.js +441 -425
  84. package/dist/commands/phpmyadmin.js +232 -212
  85. package/dist/commands/wp-ssh.js +218 -187
  86. package/dist/lib/analytics/clients/tracks.js +84 -91
  87. package/dist/lib/analytics/index.js +27 -27
  88. package/dist/lib/api/app.js +37 -36
  89. package/dist/lib/api/cache-purge.js +17 -20
  90. package/dist/lib/api/constants.js +5 -6
  91. package/dist/lib/api/edge-workers.js +84 -135
  92. package/dist/lib/api/error-debug.js +10 -13
  93. package/dist/lib/api/feature-flags.js +16 -17
  94. package/dist/lib/api/http.js +47 -48
  95. package/dist/lib/api/user.js +17 -18
  96. package/dist/lib/api.js +107 -116
  97. package/dist/lib/app-logs/app-logs.js +24 -25
  98. package/dist/lib/app-slowlogs/app-slowlogs.js +23 -24
  99. package/dist/lib/app-slowlogs/types.js +2 -1
  100. package/dist/lib/app.js +6 -8
  101. package/dist/lib/backup-storage-availability/backup-storage-availability.js +119 -119
  102. package/dist/lib/backup-storage-availability/docker-machine-not-found-error.js +5 -6
  103. package/dist/lib/cli/apiConfig.js +71 -41
  104. package/dist/lib/cli/command.js +1120 -873
  105. package/dist/lib/cli/config.js +29 -29
  106. package/dist/lib/cli/envAlias.js +35 -50
  107. package/dist/lib/cli/exit.js +19 -19
  108. package/dist/lib/cli/format.js +172 -172
  109. package/dist/lib/cli/progress.js +193 -236
  110. package/dist/lib/cli/prompt.js +14 -15
  111. package/dist/lib/cli/runtime-mode.js +5 -6
  112. package/dist/lib/client-file-uploader.js +489 -641
  113. package/dist/lib/config/software.js +206 -212
  114. package/dist/lib/constants/dev-environment.js +40 -37
  115. package/dist/lib/constants/file-size.js +6 -7
  116. package/dist/lib/constants/vipgo.js +24 -12
  117. package/dist/lib/custom-deploy/custom-deploy.js +138 -120
  118. package/dist/lib/database.js +88 -85
  119. package/dist/lib/defensive-mode/api.js +41 -46
  120. package/dist/lib/defensive-mode/cli-helpers.js +40 -40
  121. package/dist/lib/dev-environment/dev-environment-cli.js +776 -735
  122. package/dist/lib/dev-environment/dev-environment-configuration-file.js +224 -191
  123. package/dist/lib/dev-environment/dev-environment-core.js +697 -732
  124. package/dist/lib/dev-environment/dev-environment-database.js +57 -41
  125. package/dist/lib/dev-environment/dev-environment-lando.js +734 -666
  126. package/dist/lib/dev-environment/docker-utils.js +96 -90
  127. package/dist/lib/dev-environment/env-vars.js +61 -59
  128. package/dist/lib/dev-environment/lando-loader.js +6 -7
  129. package/dist/lib/dev-environment/types.js +2 -1
  130. package/dist/lib/edge-workers/confirmation.js +42 -36
  131. package/dist/lib/edge-workers/deployment.js +150 -159
  132. package/dist/lib/edge-workers/index.js +68 -85
  133. package/dist/lib/edge-workers/location.js +26 -26
  134. package/dist/lib/edge-workers/output.js +14 -15
  135. package/dist/lib/edge-workers/project.js +123 -132
  136. package/dist/lib/edge-workers/toolchains/assemblyscript/constants.js +6 -8
  137. package/dist/lib/edge-workers/toolchains/assemblyscript/index.js +100 -101
  138. package/dist/lib/edge-workers/toolchains/assemblyscript/templates.js +31 -33
  139. package/dist/lib/edge-workers/toolchains/index.js +15 -15
  140. package/dist/lib/edge-workers/types.js +10 -38
  141. package/dist/lib/edge-workers/validation.js +161 -150
  142. package/dist/lib/env.js +16 -17
  143. package/dist/lib/envvar/api-delete.js +16 -18
  144. package/dist/lib/envvar/api-get-all.js +15 -19
  145. package/dist/lib/envvar/api-get.js +8 -9
  146. package/dist/lib/envvar/api-list.js +16 -21
  147. package/dist/lib/envvar/api-set.js +20 -19
  148. package/dist/lib/envvar/api.js +34 -29
  149. package/dist/lib/envvar/input.js +29 -34
  150. package/dist/lib/envvar/logging.js +9 -11
  151. package/dist/lib/envvar/read-file.js +6 -7
  152. package/dist/lib/http/download-file.js +76 -44
  153. package/dist/lib/http/proxy-agent.js +37 -40
  154. package/dist/lib/http/proxy-dispatcher.js +69 -71
  155. package/dist/lib/keychain/insecure.js +40 -36
  156. package/dist/lib/keychain/keychain.js +2 -1
  157. package/dist/lib/keychain/secure.js +16 -15
  158. package/dist/lib/keychain.js +22 -22
  159. package/dist/lib/live-backup-copy.js +117 -115
  160. package/dist/lib/logout.js +17 -19
  161. package/dist/lib/media-import/config.js +15 -14
  162. package/dist/lib/media-import/media-file-import.js +9 -13
  163. package/dist/lib/media-import/progress.js +53 -65
  164. package/dist/lib/media-import/status.js +241 -256
  165. package/dist/lib/media-import/utils.js +15 -15
  166. package/dist/lib/node-version-check.js +16 -16
  167. package/dist/lib/promise.js +16 -17
  168. package/dist/lib/read-file.js +48 -16
  169. package/dist/lib/rechallenge/client.js +37 -43
  170. package/dist/lib/rechallenge/errors.js +38 -37
  171. package/dist/lib/rechallenge/flow.js +148 -123
  172. package/dist/lib/rechallenge/index.js +23 -24
  173. package/dist/lib/rechallenge/link.js +153 -151
  174. package/dist/lib/rechallenge/open-browser.js +14 -17
  175. package/dist/lib/rechallenge/token-cache.js +83 -86
  176. package/dist/lib/rechallenge/types.js +5 -14
  177. package/dist/lib/retry.js +93 -129
  178. package/dist/lib/search-and-replace.js +164 -148
  179. package/dist/lib/site-import/db-file-import.js +12 -16
  180. package/dist/lib/site-import/status.js +291 -291
  181. package/dist/lib/token.js +86 -87
  182. package/dist/lib/tracker.js +51 -62
  183. package/dist/lib/types/graphql/rate-limit-exceeded-error.js +2 -1
  184. package/dist/lib/types.js +2 -1
  185. package/dist/lib/user-error.js +6 -8
  186. package/dist/lib/utils.js +81 -87
  187. package/dist/lib/validations/custom-deploy.js +218 -186
  188. package/dist/lib/validations/is-multi-site-sql-dump.js +6 -6
  189. package/dist/lib/validations/is-multi-site.js +83 -50
  190. package/dist/lib/validations/is-multisite-domain-mapped.js +92 -62
  191. package/dist/lib/validations/line-by-line.js +78 -46
  192. package/dist/lib/validations/site-type.js +59 -63
  193. package/dist/lib/validations/sql-insert-parser.js +415 -0
  194. package/dist/lib/validations/sql.js +551 -431
  195. package/dist/lib/validations/utils.js +27 -29
  196. package/dist/lib/vip-import-validate-files.js +481 -490
  197. package/dist/lib/wp/helpers.js +41 -45
  198. package/dist/lib/wp/readline.js +21 -57
  199. package/dist/lib/xdg-data.js +11 -12
  200. package/helpers/mark-cli-executable.js +9 -0
  201. package/node_modules/@apollo/client/CHANGELOG.md +10 -0
  202. package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs +5 -0
  203. package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs.map +1 -1
  204. package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs +2 -1
  205. package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  206. package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs +14 -2
  207. package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs.map +1 -1
  208. package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs +16 -0
  209. package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs.map +1 -1
  210. package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.d.cts +2 -0
  211. package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs +3 -2
  212. package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  213. package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs +9 -1
  214. package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs.map +1 -1
  215. package/node_modules/@apollo/client/__cjs/core/QueryInfo.d.cts +1 -1
  216. package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs +10 -3
  217. package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs.map +1 -1
  218. package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.cjs.map +1 -1
  219. package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.d.cts +42 -43
  220. package/node_modules/@apollo/client/__cjs/version.cjs +1 -1
  221. package/node_modules/@apollo/client/cache/inmemory/helpers.js +5 -0
  222. package/node_modules/@apollo/client/cache/inmemory/helpers.js.map +1 -1
  223. package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js +2 -1
  224. package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js.map +1 -1
  225. package/node_modules/@apollo/client/cache/inmemory/key-extractor.js +14 -2
  226. package/node_modules/@apollo/client/cache/inmemory/key-extractor.js.map +1 -1
  227. package/node_modules/@apollo/client/cache/inmemory/policies.d.ts +2 -0
  228. package/node_modules/@apollo/client/cache/inmemory/policies.js +17 -1
  229. package/node_modules/@apollo/client/cache/inmemory/policies.js.map +1 -1
  230. package/node_modules/@apollo/client/cache/inmemory/writeToStore.js +3 -2
  231. package/node_modules/@apollo/client/cache/inmemory/writeToStore.js.map +1 -1
  232. package/node_modules/@apollo/client/core/QueryInfo.d.ts +1 -1
  233. package/node_modules/@apollo/client/core/QueryInfo.js +10 -2
  234. package/node_modules/@apollo/client/core/QueryInfo.js.map +1 -1
  235. package/node_modules/@apollo/client/core/QueryManager.js +10 -3
  236. package/node_modules/@apollo/client/core/QueryManager.js.map +1 -1
  237. package/node_modules/@apollo/client/package.json +1 -1
  238. package/node_modules/@apollo/client/react/hooks/useFragment.d.ts +42 -43
  239. package/node_modules/@apollo/client/react/hooks/useFragment.js.map +1 -1
  240. package/node_modules/@apollo/client/react/hooks-compiled/useFragment.d.ts +42 -43
  241. package/node_modules/@apollo/client/react/hooks-compiled/useFragment.js.map +1 -1
  242. package/node_modules/@apollo/client/version.js +1 -1
  243. package/node_modules/@automattic/vip-search-replace/README.md +6 -1
  244. package/node_modules/@automattic/vip-search-replace/lib/index.js +46 -14
  245. package/node_modules/@automattic/vip-search-replace/package.json +1 -1
  246. package/node_modules/@types/node/README.md +1 -1
  247. package/node_modules/@types/node/package.json +2 -2
  248. package/node_modules/@types/node/zlib.d.ts +752 -0
  249. package/node_modules/check-disk-space/README.md +92 -32
  250. package/node_modules/check-disk-space/dist/check-disk-space.d.mts +58 -0
  251. package/node_modules/check-disk-space/dist/check-disk-space.mjs +170 -190
  252. package/node_modules/check-disk-space/package.json +43 -71
  253. package/node_modules/cpu-features/build/Makefile +2 -2
  254. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/filesystem.o.d +1 -1
  255. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_linux_or_android.o.d +1 -1
  256. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.o.d +1 -1
  257. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_windows.o.d +1 -1
  258. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_arm_linux_or_android.o.d +1 -1
  259. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_mips_linux_or_android.o.d +1 -1
  260. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_ppc_linux.o.d +1 -1
  261. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_freebsd.o.d +1 -1
  262. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_linux_or_android.o.d +1 -1
  263. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_macos.o.d +1 -1
  264. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_windows.o.d +1 -1
  265. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/stack_line_reader.o.d +1 -1
  266. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/string_view.o.d +1 -1
  267. package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpufeatures/src/binding.o.d +157 -145
  268. package/node_modules/cpu-features/build/Release/cpufeatures.node +0 -0
  269. package/node_modules/cpu-features/build/Release/obj.target/cpufeatures/src/binding.o +0 -0
  270. package/node_modules/cpu-features/build/Release/obj.target/cpufeatures.node +0 -0
  271. package/node_modules/cpu-features/build/config.gypi +100 -31
  272. package/node_modules/cpu-features/build/cpufeatures.target.mk +14 -14
  273. package/node_modules/cpu-features/build/deps/cpu_features/cpu_features.target.mk +14 -14
  274. package/node_modules/ssh2/lib/protocol/crypto/build/Makefile +2 -2
  275. package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d.raw +136 -0
  276. package/node_modules/ssh2/lib/protocol/crypto/build/sshcrypto.target.mk +14 -14
  277. package/node_modules/undici/docs/docs/api/Interceptors.md +15 -2
  278. package/node_modules/undici/lib/dispatcher/client-h2.js +78 -3
  279. package/node_modules/undici/lib/dispatcher/pool-base.js +20 -3
  280. package/node_modules/undici/package.json +3 -3
  281. package/node_modules/undici/types/api.d.ts +1 -1
  282. package/node_modules/undici/types/utility.d.ts +4 -4
  283. package/package.json +44 -13
  284. package/dist/lib/analytics/clients/client.js +0 -1
  285. package/dist/lib/analytics/clients/pendo.js +0 -78
  286. package/helpers/check-version.js +0 -16
  287. package/node_modules/check-disk-space/dist/check-disk-space.cjs +0 -210
  288. package/node_modules/check-disk-space/dist/check-disk-space.d.ts +0 -53
  289. package/node_modules/fetch-retry/.eslintignore +0 -1
  290. package/node_modules/fetch-retry/.eslintrc.yml +0 -20
  291. package/node_modules/fetch-retry/.github/workflows/node.js.yml +0 -32
  292. package/node_modules/fetch-retry/.husky/pre-commit +0 -6
  293. package/node_modules/fetch-retry/.nycrc.json +0 -24
  294. package/node_modules/fetch-retry/.travis.yml +0 -3
  295. package/node_modules/fetch-retry/LICENSE +0 -21
  296. package/node_modules/fetch-retry/README.md +0 -128
  297. package/node_modules/fetch-retry/dist/fetch-retry.umd.js +0 -151
  298. package/node_modules/fetch-retry/index.d.ts +0 -29
  299. package/node_modules/fetch-retry/index.js +0 -143
  300. package/node_modules/fetch-retry/package.json +0 -41
  301. package/node_modules/fetch-retry/rollup.config.js +0 -12
  302. package/node_modules/fetch-retry/test/.eslintrc.yml +0 -7
  303. package/node_modules/fetch-retry/test/integration/index.js +0 -212
  304. package/node_modules/fetch-retry/test/integration/mock-api/index.js +0 -42
  305. package/node_modules/fetch-retry/test/unit/index.js +0 -1169
  306. package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d +0 -265
  307. package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto.node.d +0 -1
  308. package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/sshcrypto.node.d +0 -1
  309. package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto/src/binding.o +0 -0
  310. package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto.node +0 -0
  311. package/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node +0 -0
@@ -1,39 +1,39 @@
1
1
  "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.default = void 0;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
5
6
  exports.loadConfigFile = loadConfigFile;
6
- var _debug = _interopRequireDefault(require("debug"));
7
- var _nodeFs = _interopRequireDefault(require("node:fs"));
8
- var _nodePath = _interopRequireDefault(require("node:path"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- // I don't like using synchronous versions, but until we migrate to ESM, we have to.
11
-
12
- const debug = (0, _debug.default)('@automattic/vip:lib:cli:config');
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const node_fs_1 = __importDefault(require("node:fs")); // I don't like using synchronous versions, but until we migrate to ESM, we have to.
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const debug = (0, debug_1.default)('@automattic/vip:lib:cli:config');
13
11
  function loadConfigFile() {
14
- const paths = [
15
- // Get `local` config first; this will only exist in dev as it's npmignore-d.
16
- _nodePath.default.join(__dirname, '../../../config/config.local.json'), _nodePath.default.join(__dirname, '../../../config/config.publish.json')];
17
- for (const filePath of paths) {
18
- try {
19
- const data = _nodeFs.default.readFileSync(filePath, 'utf-8');
20
- debug(`Found config file at ${filePath}`);
21
- return JSON.parse(data);
22
- } catch (err) {
23
- const isEnoent = err instanceof Error && 'code' in err && err.code === 'ENOENT';
24
- if (!isEnoent) {
25
- debug(`Error reading config file at ${filePath}:`, err);
26
- }
12
+ const paths = [
13
+ // Get `local` config first; this will only exist in dev as it's npmignore-d.
14
+ node_path_1.default.join(__dirname, '../../../config/config.local.json'),
15
+ node_path_1.default.join(__dirname, '../../../config/config.publish.json'),
16
+ ];
17
+ for (const filePath of paths) {
18
+ try {
19
+ const data = node_fs_1.default.readFileSync(filePath, 'utf-8');
20
+ debug(`Found config file at ${filePath}`);
21
+ return JSON.parse(data);
22
+ }
23
+ catch (err) {
24
+ const isEnoent = err instanceof Error && 'code' in err && err.code === 'ENOENT';
25
+ if (!isEnoent) {
26
+ debug(`Error reading config file at ${filePath}:`, err);
27
+ }
28
+ }
27
29
  }
28
- }
29
- return null;
30
+ return null;
30
31
  }
31
32
  const configFromFile = loadConfigFile();
32
33
  if (null === configFromFile) {
33
- console.error('FATAL ERROR: Could not find a valid configuration file');
34
- process.exit(1);
34
+ console.error('FATAL ERROR: Could not find a valid configuration file');
35
+ process.exit(1);
35
36
  }
36
-
37
37
  // Without this, TypeScript will export `configFromFile` as `Config | null`.
38
38
  const exportedConfig = configFromFile;
39
- var _default = exports.default = exportedConfig;
39
+ exports.default = exportedConfig;
@@ -1,59 +1,44 @@
1
1
  "use strict";
2
-
3
- exports.__esModule = true;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.isAlias = isAlias;
5
4
  exports.parseEnvAlias = parseEnvAlias;
6
5
  exports.parseEnvAliasFromArgv = parseEnvAliasFromArgv;
7
6
  function isAlias(alias) {
8
- return /^@[A-Za-z0-9._-]+$/.test(alias);
7
+ return /^@[A-Za-z0-9._-]+$/.test(alias);
9
8
  }
10
9
  function parseEnvAlias(alias) {
11
- if (!isAlias(alias)) {
12
- throw new Error('Invalid environment alias. Aliases are in the format of @app-name or @app-name.environment-name');
13
- }
14
-
15
- // Remove the '@'
16
- const stripped = alias.slice(1).toLowerCase();
17
-
18
- // in JS, .split() with a limit discards the extra ones, so can't use it
19
- // Also convert to lowercase because mixed case environment names would cause problems
20
- const [app, ...rest] = stripped.split('.');
21
- let env;
22
-
23
- // Rejoin the env on '.' (if present), to handle instance names (env.instance-01)
24
- if (rest.length) {
25
- env = rest.join('.');
26
- }
27
- return {
28
- app,
29
- env
30
- };
10
+ if (!isAlias(alias)) {
11
+ throw new Error('Invalid environment alias. Aliases are in the format of @app-name or @app-name.environment-name');
12
+ }
13
+ // Remove the '@'
14
+ const stripped = alias.slice(1).toLowerCase();
15
+ // in JS, .split() with a limit discards the extra ones, so can't use it
16
+ // Also convert to lowercase because mixed case environment names would cause problems
17
+ const [app, ...rest] = stripped.split('.');
18
+ let env;
19
+ // Rejoin the env on '.' (if present), to handle instance names (env.instance-01)
20
+ if (rest.length) {
21
+ env = rest.join('.');
22
+ }
23
+ return { app, env };
31
24
  }
32
25
  function parseEnvAliasFromArgv(processArgv) {
33
- // Clone to not affect original arvg
34
- const argv = processArgv.slice(0);
35
-
36
- // If command included a `--` to indicate end of named args, lets only consider aliases
37
- // _before_ it, so that it can be passed to other commands directly
38
- const dashDashIndex = argv.indexOf('--');
39
- let argsBeforeDashDash = argv;
40
- if (dashDashIndex > -1) {
41
- argsBeforeDashDash = argv.slice(0, dashDashIndex);
42
- }
43
- const alias = argsBeforeDashDash.find(arg => isAlias(arg));
44
- if (!alias) {
45
- return {
46
- argv
47
- };
48
- }
49
-
50
- // If we did have an alias, split it up into app/env
51
- const parsedAlias = parseEnvAlias(alias);
52
-
53
- // Splice out the alias
54
- argv.splice(argv.indexOf(alias), 1);
55
- return {
56
- argv,
57
- ...parsedAlias
58
- };
59
- }
26
+ // Clone to not affect original arvg
27
+ const argv = processArgv.slice(0);
28
+ // If command included a `--` to indicate end of named args, lets only consider aliases
29
+ // _before_ it, so that it can be passed to other commands directly
30
+ const dashDashIndex = argv.indexOf('--');
31
+ let argsBeforeDashDash = argv;
32
+ if (dashDashIndex > -1) {
33
+ argsBeforeDashDash = argv.slice(0, dashDashIndex);
34
+ }
35
+ const alias = argsBeforeDashDash.find(arg => isAlias(arg));
36
+ if (!alias) {
37
+ return { argv };
38
+ }
39
+ // If we did have an alias, split it up into app/env
40
+ const parsedAlias = parseEnvAlias(alias);
41
+ // Splice out the alias
42
+ argv.splice(argv.indexOf(alias), 1);
43
+ return { argv, ...parsedAlias };
44
+ }
@@ -1,22 +1,22 @@
1
1
  "use strict";
2
-
3
- exports.__esModule = true;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
4
6
  exports.withError = withError;
5
- var _chalk = _interopRequireDefault(require("chalk"));
6
- var _debug = _interopRequireDefault(require("debug"));
7
- var _runtimeMode = require("./runtime-mode");
8
- var _env = _interopRequireDefault(require("../../lib/env"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const debug_1 = __importDefault(require("debug"));
9
+ const runtime_mode_1 = require("./runtime-mode");
10
+ const env_1 = __importDefault(require("../../lib/env"));
10
11
  function withError(message) {
11
- const msg = message instanceof Error ? message.message : message;
12
- console.error(`${_chalk.default.red('Error: ')} ${msg.replace(/^Error:\s*/, '')}`);
13
-
14
- // Debug ouput is printed below error output both for information
15
- // hierarchy and to make it more likely that the user copies it to their
16
- // clipboard when dragging across output.
17
- console.log(`${_chalk.default.yellow('Debug: ')} VIP-CLI v${_env.default.app.version}, Node ${_env.default.node.version}, ${_env.default.os.name} ${_env.default.os.version} ${_env.default.os.arch}, Runtime ${(0, _runtimeMode.getRuntimeModeLabel)()}`);
18
- if (_debug.default.names.length > 0 && message instanceof Error) {
19
- console.error(_chalk.default.yellow('Debug: '), message);
20
- }
21
- process.exit(1);
22
- }
12
+ const msg = message instanceof Error ? message.message : message;
13
+ console.error(`${chalk_1.default.red('Error: ')} ${msg.replace(/^Error:\s*/, '')}`);
14
+ // Debug ouput is printed below error output both for information
15
+ // hierarchy and to make it more likely that the user copies it to their
16
+ // clipboard when dragging across output.
17
+ console.log(`${chalk_1.default.yellow('Debug: ')} VIP-CLI v${env_1.default.app.version}, Node ${env_1.default.node.version}, ${env_1.default.os.name} ${env_1.default.os.version} ${env_1.default.os.arch}, Runtime ${(0, runtime_mode_1.getRuntimeModeLabel)()}`);
18
+ if (debug_1.default.names.length > 0 && message instanceof Error) {
19
+ console.error(chalk_1.default.yellow('Debug: '), message);
20
+ }
21
+ process.exit(1);
22
+ }
@@ -1,195 +1,195 @@
1
1
  "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.RunningSprite = exports.RUNNING_SPRITE_GLYPHS = void 0;
5
- exports.capitalize = capitalize;
6
- exports.formatBytes = void 0;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.formatMetricBytes = exports.formatBytes = exports.RunningSprite = exports.RUNNING_SPRITE_GLYPHS = void 0;
7
7
  exports.formatData = formatData;
8
- exports.formatDuration = formatDuration;
9
8
  exports.formatEnvironment = formatEnvironment;
10
- exports.formatMetricBytes = void 0;
11
- exports.formatSearchReplaceValues = formatSearchReplaceValues;
12
- exports.getGlyphForStatus = getGlyphForStatus;
9
+ exports.table = table;
13
10
  exports.keyValue = keyValue;
14
11
  exports.requoteArgs = requoteArgs;
15
- exports.table = table;
16
- var _plainjs = require("@json2csv/plainjs");
17
- var _chalk = _interopRequireDefault(require("chalk"));
18
- var _cliTable = _interopRequireDefault(require("cli-table3"));
19
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ exports.capitalize = capitalize;
13
+ exports.getGlyphForStatus = getGlyphForStatus;
14
+ exports.formatSearchReplaceValues = formatSearchReplaceValues;
15
+ exports.formatDuration = formatDuration;
16
+ const plainjs_1 = require("@json2csv/plainjs");
17
+ const chalk_1 = __importDefault(require("chalk"));
18
+ const cli_table3_1 = __importDefault(require("cli-table3"));
20
19
  function formatData(data, format) {
21
- if (!data.length) {
22
- return format === 'json' ? '[]' : '';
23
- }
24
- switch (format) {
25
- case 'ids':
26
- return ids(data);
27
- case 'json':
28
- return json(data);
29
- case 'csv':
30
- return csv(data);
31
- case 'keyValue':
32
- return keyValue(data);
33
- case 'table':
34
- default:
35
- return table(data);
36
- }
20
+ if (!data.length) {
21
+ return format === 'json' ? '[]' : '';
22
+ }
23
+ switch (format) {
24
+ case 'ids':
25
+ return ids(data);
26
+ case 'json':
27
+ return json(data);
28
+ case 'csv':
29
+ return csv(data);
30
+ case 'keyValue':
31
+ return keyValue(data);
32
+ case 'table':
33
+ default:
34
+ return table(data);
35
+ }
37
36
  }
38
37
  function escapeControlCharacter(character) {
39
- const codePoint = character.codePointAt(0);
40
- if (codePoint === undefined) {
41
- return '';
42
- }
43
- return String.raw`\u${codePoint.toString(16).padStart(4, '0')}`;
38
+ const codePoint = character.codePointAt(0);
39
+ if (codePoint === undefined) {
40
+ return '';
41
+ }
42
+ return String.raw `\u${codePoint.toString(16).padStart(4, '0')}`;
44
43
  }
45
44
  function json(data) {
46
- return JSON.stringify(data, null, '\t').replace(
47
- // JSON.stringify already escapes C0 controls, but not DEL or C1 controls.
48
- /[\u007f-\u009f]/g, escapeControlCharacter);
45
+ return JSON.stringify(data, null, '\t').replace(
46
+ // JSON.stringify already escapes C0 controls, but not DEL or C1 controls.
47
+ /[\u007f-\u009f]/g, escapeControlCharacter);
49
48
  }
50
49
  function formatEnvironment(environment) {
51
- if ('production' === environment.toLowerCase()) {
52
- return _chalk.default.red(environment.toUpperCase());
53
- }
54
- return _chalk.default.blueBright(environment.toLowerCase());
50
+ if ('production' === environment.toLowerCase()) {
51
+ return chalk_1.default.red(environment.toUpperCase());
52
+ }
53
+ return chalk_1.default.blueBright(environment.toLowerCase());
55
54
  }
56
55
  function ids(data) {
57
- const fields = Object.keys(data[0]).map(key => key.toLowerCase());
58
- if (0 > fields.indexOf('id')) {
59
- return 'No ID field found';
60
- }
61
- const id = data.map(datum => datum.id);
62
- return id.join(' ');
56
+ const fields = Object.keys(data[0]).map(key => key.toLowerCase());
57
+ if (0 > fields.indexOf('id')) {
58
+ return 'No ID field found';
59
+ }
60
+ const id = data.map(datum => datum.id);
61
+ return id.join(' ');
63
62
  }
64
63
  function csv(data) {
65
- const fields = Object.keys(data[0]);
66
- const parser = new _plainjs.Parser({
67
- formatters: {
68
- header: value => {
69
- return `"${value.split(/(?=[A-Z])/).join(' ').toLowerCase()}"`;
70
- }
71
- },
72
- fields
73
- });
74
- return parser.parse(data);
64
+ const fields = Object.keys(data[0]);
65
+ const parser = new plainjs_1.Parser({
66
+ formatters: {
67
+ header: (value) => {
68
+ return `"${value
69
+ .split(/(?=[A-Z])/)
70
+ .join(' ')
71
+ .toLowerCase()}"`;
72
+ },
73
+ },
74
+ fields,
75
+ });
76
+ return parser.parse(data);
75
77
  }
76
78
  function table(data) {
77
- const fields = Object.keys(data[0]);
78
- const dataTable = new _cliTable.default({
79
- head: formatFields(fields),
80
- style: {
81
- head: ['brightBlue']
82
- }
83
- });
84
- data.forEach(datum => {
85
- const row = fields.map(field => String(datum[field]));
86
- dataTable.push(row);
87
- });
88
- return dataTable.toString();
79
+ const fields = Object.keys(data[0]);
80
+ const dataTable = new cli_table3_1.default({
81
+ head: formatFields(fields),
82
+ style: {
83
+ head: ['brightBlue'],
84
+ },
85
+ });
86
+ data.forEach(datum => {
87
+ const row = fields.map(field => String(datum[field]));
88
+ dataTable.push(row);
89
+ });
90
+ return dataTable.toString();
89
91
  }
90
92
  function formatFields(fields) {
91
- return fields.map(field => {
92
- return field.split(/(?=[A-Z])/).join(' ').toLowerCase();
93
- });
93
+ return fields.map(field => {
94
+ return field
95
+ .split(/(?=[A-Z])/)
96
+ .join(' ')
97
+ .toLowerCase();
98
+ });
94
99
  }
95
100
  function keyValue(values) {
96
- const lines = [];
97
- const pairs = values.length > 0;
98
- if (pairs) {
101
+ const lines = [];
102
+ const pairs = values.length > 0;
103
+ if (pairs) {
104
+ lines.push('===================================');
105
+ }
106
+ for (const { key, value } of values) {
107
+ let formattedValue;
108
+ if (key.toLowerCase() === 'environment') {
109
+ formattedValue = formatEnvironment(value);
110
+ }
111
+ else {
112
+ formattedValue = value;
113
+ }
114
+ lines.push(`+ ${key}: ${formattedValue}`);
115
+ }
99
116
  lines.push('===================================');
100
- }
101
- for (const {
102
- key,
103
- value
104
- } of values) {
105
- let formattedValue;
106
- if (key.toLowerCase() === 'environment') {
107
- formattedValue = formatEnvironment(value);
108
- } else {
109
- formattedValue = value;
110
- }
111
- lines.push(`+ ${key}: ${formattedValue}`);
112
- }
113
- lines.push('===================================');
114
- return lines.join('\n');
117
+ return lines.join('\n');
115
118
  }
116
119
  function requoteArgs(args) {
117
- return args.map(arg => `"${arg.replace(/"/g, '\\"')}"`);
120
+ return args.map(arg => `"${arg.replace(/"/g, '\\"')}"`);
118
121
  }
119
122
  function capitalize(str) {
120
- if (typeof str !== 'string' || !str.length) {
121
- return '';
122
- }
123
- return str[0].toUpperCase() + str.slice(1);
123
+ if (typeof str !== 'string' || !str.length) {
124
+ return '';
125
+ }
126
+ return str[0].toUpperCase() + str.slice(1);
124
127
  }
125
- const RUNNING_SPRITE_GLYPHS = exports.RUNNING_SPRITE_GLYPHS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
128
+ exports.RUNNING_SPRITE_GLYPHS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
126
129
  class RunningSprite {
127
- count;
128
- constructor() {
129
- this.count = 0;
130
- }
131
- next() {
132
- if (++this.count >= RUNNING_SPRITE_GLYPHS.length) {
133
- this.count = 0;
134
- }
135
- }
136
- toString() {
137
- const glyph = RUNNING_SPRITE_GLYPHS[this.count];
138
- this.next(); // TODO: throttle
139
- return glyph;
140
- }
130
+ count;
131
+ constructor() {
132
+ this.count = 0;
133
+ }
134
+ next() {
135
+ if (++this.count >= exports.RUNNING_SPRITE_GLYPHS.length) {
136
+ this.count = 0;
137
+ }
138
+ }
139
+ toString() {
140
+ const glyph = exports.RUNNING_SPRITE_GLYPHS[this.count];
141
+ this.next(); // TODO: throttle
142
+ return glyph;
143
+ }
141
144
  }
142
145
  exports.RunningSprite = RunningSprite;
143
146
  function getGlyphForStatus(status, runningSprite) {
144
- switch (status) {
145
- case 'pending':
146
- return '○';
147
- case 'running':
148
- return _chalk.default.blueBright(runningSprite);
149
- case 'success':
150
- return _chalk.default.green('✓');
151
- case 'failed':
152
- return _chalk.default.red('✕');
153
- case 'unknown':
154
- return _chalk.default.yellow('✕');
155
- case 'skipped':
156
- return _chalk.default.green('-');
157
- default:
158
- return '';
159
- }
147
+ switch (status) {
148
+ case 'pending':
149
+ return '○';
150
+ case 'running':
151
+ return chalk_1.default.blueBright(runningSprite);
152
+ case 'success':
153
+ return chalk_1.default.green('✓');
154
+ case 'failed':
155
+ return chalk_1.default.red('✕');
156
+ case 'unknown':
157
+ return chalk_1.default.yellow('✕');
158
+ case 'skipped':
159
+ return chalk_1.default.green('-');
160
+ default:
161
+ return '';
162
+ }
160
163
  }
161
-
162
164
  // Format Search and Replace values to output
163
165
  function formatSearchReplaceValues(values, message) {
164
- // Convert single pair S-R values to arrays
165
- const searchReplaceValues = typeof values === 'string' ? [values] : values;
166
- return searchReplaceValues.map(pairs => {
167
- // Turn each S-R pair into its own array, then trim away whitespace
168
- const [from, to] = pairs.split(',').map(pair => pair.trim());
169
- return message(from, to);
170
- });
166
+ // Convert single pair S-R values to arrays
167
+ const searchReplaceValues = typeof values === 'string' ? [values] : values;
168
+ return searchReplaceValues.map(pairs => {
169
+ // Turn each S-R pair into its own array, then trim away whitespace
170
+ const [from, to] = pairs.split(',').map(pair => pair.trim());
171
+ return message(from, to);
172
+ });
171
173
  }
172
-
173
174
  // Format bytes into kilobytes, megabytes, etc based on the size
174
175
  // for historical reasons, this uses KB instead of KiB, MB instead of MiB and so on.
175
176
  const formatBytes = (bytes, decimals = 2, bytesMultiplier = 1024, sizes = ['bytes', 'KB', 'MB', 'GB', 'TB']) => {
176
- if (0 === bytes) {
177
- return '0 Bytes';
178
- }
179
- const dm = decimals < 0 ? 0 : decimals;
180
- const idx = Math.floor(Math.log(bytes) / Math.log(bytesMultiplier));
181
- return `${parseFloat((bytes / Math.pow(bytesMultiplier, idx)).toFixed(dm))} ${sizes[idx]}`;
177
+ if (0 === bytes) {
178
+ return '0 Bytes';
179
+ }
180
+ const dm = decimals < 0 ? 0 : decimals;
181
+ const idx = Math.floor(Math.log(bytes) / Math.log(bytesMultiplier));
182
+ return `${parseFloat((bytes / Math.pow(bytesMultiplier, idx)).toFixed(dm))} ${sizes[idx]}`;
182
183
  };
183
-
184
+ exports.formatBytes = formatBytes;
184
185
  /**
185
186
  * Format bytes in powers of 1000, based on the size
186
187
  * This is how it's displayed on Macs
187
188
  */
188
- exports.formatBytes = formatBytes;
189
189
  const formatMetricBytes = (bytes, decimals = 2) => {
190
- return formatBytes(bytes, decimals, 1000);
190
+ return (0, exports.formatBytes)(bytes, decimals, 1000);
191
191
  };
192
-
192
+ exports.formatMetricBytes = formatMetricBytes;
193
193
  /*
194
194
  * Get the duration between two dates
195
195
  *
@@ -197,30 +197,30 @@ const formatMetricBytes = (bytes, decimals = 2) => {
197
197
  * @param {Date} to The end date
198
198
  * @returns {string} The duration between the two dates
199
199
  */
200
- exports.formatMetricBytes = formatMetricBytes;
201
200
  function formatDuration(from, to) {
202
- const millisecondsPerSecond = 1000;
203
- const millisecondsPerMinute = 60 * millisecondsPerSecond;
204
- const millisecondsPerHour = 60 * millisecondsPerMinute;
205
- const millisecondsPerDay = 24 * millisecondsPerHour;
206
- const duration = to.getTime() - from.getTime();
207
- if (duration < 1000) return '0 second';
208
- const days = Math.floor(duration / millisecondsPerDay);
209
- const hours = Math.floor(duration % millisecondsPerDay / millisecondsPerHour);
210
- const minutes = Math.floor(duration % millisecondsPerHour / millisecondsPerMinute);
211
- const seconds = Math.floor(duration % millisecondsPerMinute / millisecondsPerSecond);
212
- let durationString = '';
213
- if (days > 0) {
214
- durationString += `${days} day${days > 1 ? 's' : ''} `;
215
- }
216
- if (hours > 0) {
217
- durationString += `${hours} hour${hours > 1 ? 's' : ''} `;
218
- }
219
- if (minutes > 0) {
220
- durationString += `${minutes} minute${minutes > 1 ? 's' : ''} `;
221
- }
222
- if (seconds > 0) {
223
- durationString += `${seconds} second${seconds > 1 ? 's' : ''}`;
224
- }
225
- return durationString.trim();
226
- }
201
+ const millisecondsPerSecond = 1000;
202
+ const millisecondsPerMinute = 60 * millisecondsPerSecond;
203
+ const millisecondsPerHour = 60 * millisecondsPerMinute;
204
+ const millisecondsPerDay = 24 * millisecondsPerHour;
205
+ const duration = to.getTime() - from.getTime();
206
+ if (duration < 1000)
207
+ return '0 second';
208
+ const days = Math.floor(duration / millisecondsPerDay);
209
+ const hours = Math.floor((duration % millisecondsPerDay) / millisecondsPerHour);
210
+ const minutes = Math.floor((duration % millisecondsPerHour) / millisecondsPerMinute);
211
+ const seconds = Math.floor((duration % millisecondsPerMinute) / millisecondsPerSecond);
212
+ let durationString = '';
213
+ if (days > 0) {
214
+ durationString += `${days} day${days > 1 ? 's' : ''} `;
215
+ }
216
+ if (hours > 0) {
217
+ durationString += `${hours} hour${hours > 1 ? 's' : ''} `;
218
+ }
219
+ if (minutes > 0) {
220
+ durationString += `${minutes} minute${minutes > 1 ? 's' : ''} `;
221
+ }
222
+ if (seconds > 0) {
223
+ durationString += `${seconds} second${seconds > 1 ? 's' : ''}`;
224
+ }
225
+ return durationString.trim();
226
+ }