@dotenvx/dotenvx-vlt 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +652 -0
  2. package/LICENSE +71 -0
  3. package/README.md +11 -0
  4. package/package.json +77 -0
  5. package/src/cli/actions/armor/down.js +37 -0
  6. package/src/cli/actions/armor/move.js +42 -0
  7. package/src/cli/actions/armor/pull.js +37 -0
  8. package/src/cli/actions/armor/push.js +37 -0
  9. package/src/cli/actions/armor/rotate.js +25 -0
  10. package/src/cli/actions/armor/up.js +37 -0
  11. package/src/cli/actions/backup.js +93 -0
  12. package/src/cli/actions/gateway/start.js +17 -0
  13. package/src/cli/actions/get.js +34 -0
  14. package/src/cli/actions/keypair.js +59 -0
  15. package/src/cli/actions/login.js +110 -0
  16. package/src/cli/actions/logout.js +36 -0
  17. package/src/cli/actions/observe.js +36 -0
  18. package/src/cli/actions/open.js +37 -0
  19. package/src/cli/actions/rotate/github/connect.js +84 -0
  20. package/src/cli/actions/rotate/npm/connect.js +84 -0
  21. package/src/cli/actions/rotate/openai/connect.js +84 -0
  22. package/src/cli/actions/rotate.js +44 -0
  23. package/src/cli/actions/set.js +34 -0
  24. package/src/cli/actions/settings/device.js +24 -0
  25. package/src/cli/actions/settings/hostname.js +20 -0
  26. package/src/cli/actions/settings/off.js +17 -0
  27. package/src/cli/actions/settings/on.js +17 -0
  28. package/src/cli/actions/settings/path.js +21 -0
  29. package/src/cli/actions/settings/token.js +24 -0
  30. package/src/cli/actions/settings/username.js +22 -0
  31. package/src/cli/actions/status.js +13 -0
  32. package/src/cli/actions/sync.js +104 -0
  33. package/src/cli/commands/armor.js +73 -0
  34. package/src/cli/commands/gateway.js +16 -0
  35. package/src/cli/commands/rotate/github.js +26 -0
  36. package/src/cli/commands/rotate/npm.js +26 -0
  37. package/src/cli/commands/rotate/openai.js +26 -0
  38. package/src/cli/commands/rotate.js +32 -0
  39. package/src/cli/commands/settings.js +60 -0
  40. package/src/cli/dotenvx-ops.js +163 -0
  41. package/src/cli/postinstall.js +16 -0
  42. package/src/db/device.js +73 -0
  43. package/src/db/session.js +193 -0
  44. package/src/lib/api/getAccount.js +32 -0
  45. package/src/lib/api/getSynchronization.js +34 -0
  46. package/src/lib/api/getVersion.js +24 -0
  47. package/src/lib/api/postArmorDown.js +48 -0
  48. package/src/lib/api/postArmorMove.js +48 -0
  49. package/src/lib/api/postArmorPull.js +48 -0
  50. package/src/lib/api/postArmorPush.js +48 -0
  51. package/src/lib/api/postArmorUp.js +51 -0
  52. package/src/lib/api/postBackup.js +68 -0
  53. package/src/lib/api/postGet.js +37 -0
  54. package/src/lib/api/postKeypair.js +60 -0
  55. package/src/lib/api/postLogout.js +34 -0
  56. package/src/lib/api/postOauthDeviceCode.js +45 -0
  57. package/src/lib/api/postOauthToken.js +38 -0
  58. package/src/lib/api/postObserve.js +62 -0
  59. package/src/lib/api/postRotate.js +39 -0
  60. package/src/lib/api/postRotateConnect.js +54 -0
  61. package/src/lib/api/postSet.js +43 -0
  62. package/src/lib/api/postSync.js +68 -0
  63. package/src/lib/helpers/armoredKeyDisplay.js +10 -0
  64. package/src/lib/helpers/buildApiError.js +16 -0
  65. package/src/lib/helpers/buildOauthError.js +13 -0
  66. package/src/lib/helpers/canonicalEnvFilename.js +13 -0
  67. package/src/lib/helpers/clipboardy/fallbacks/linux/xsel +0 -0
  68. package/src/lib/helpers/clipboardy/fallbacks/windows/clipboard_i686.exe +0 -0
  69. package/src/lib/helpers/clipboardy/fallbacks/windows/clipboard_x86_64.exe +0 -0
  70. package/src/lib/helpers/clipboardy/linux.js +57 -0
  71. package/src/lib/helpers/clipboardy/macos.js +14 -0
  72. package/src/lib/helpers/clipboardy/termux.js +41 -0
  73. package/src/lib/helpers/clipboardy/windows.js +16 -0
  74. package/src/lib/helpers/clipboardy.js +51 -0
  75. package/src/lib/helpers/confirm.js +17 -0
  76. package/src/lib/helpers/createSpinner.js +101 -0
  77. package/src/lib/helpers/createSpinner2.js +24 -0
  78. package/src/lib/helpers/decryptValue.js +10 -0
  79. package/src/lib/helpers/dotenvxProjectId.js +36 -0
  80. package/src/lib/helpers/encryptValue.js +9 -0
  81. package/src/lib/helpers/errors.js +30 -0
  82. package/src/lib/helpers/formatCode.js +11 -0
  83. package/src/lib/helpers/gitBranch.js +13 -0
  84. package/src/lib/helpers/gitUrl.js +13 -0
  85. package/src/lib/helpers/http.js +17 -0
  86. package/src/lib/helpers/jsonToEnv.js +7 -0
  87. package/src/lib/helpers/keyNamesForEnvFile.js +43 -0
  88. package/src/lib/helpers/keypairMetadata.js +88 -0
  89. package/src/lib/helpers/likelyUpdateCommand.js +33 -0
  90. package/src/lib/helpers/localKeypair.js +12 -0
  91. package/src/lib/helpers/mask.js +12 -0
  92. package/src/lib/helpers/normalizePath.js +5 -0
  93. package/src/lib/helpers/normalizeToken.js +5 -0
  94. package/src/lib/helpers/openUrl.js +7 -0
  95. package/src/lib/helpers/packageJson.js +3 -0
  96. package/src/lib/helpers/playwrightConnect.js +29 -0
  97. package/src/lib/helpers/pluralize.js +10 -0
  98. package/src/lib/helpers/prompts.js +68 -0
  99. package/src/lib/helpers/removeEnvKey.js +50 -0
  100. package/src/lib/helpers/safeRealpath.js +13 -0
  101. package/src/lib/helpers/sha256File.js +9 -0
  102. package/src/lib/helpers/smartMask.js +11 -0
  103. package/src/lib/helpers/truncate.js +10 -0
  104. package/src/lib/helpers/upsertEnvKey.js +61 -0
  105. package/src/lib/main.d.ts +152 -0
  106. package/src/lib/main.js +114 -0
  107. package/src/lib/services/armorDown.js +77 -0
  108. package/src/lib/services/armorMove.js +54 -0
  109. package/src/lib/services/armorPull.js +77 -0
  110. package/src/lib/services/armorPush.js +82 -0
  111. package/src/lib/services/armorUp.js +79 -0
  112. package/src/lib/services/backup.js +105 -0
  113. package/src/lib/services/gatewayStart.js +132 -0
  114. package/src/lib/services/keypair.js +59 -0
  115. package/src/lib/services/loggedIn.js +24 -0
  116. package/src/lib/services/login.js +28 -0
  117. package/src/lib/services/loginPoll.js +43 -0
  118. package/src/lib/services/logout.js +28 -0
  119. package/src/lib/services/rotate.js +28 -0
  120. package/src/lib/services/rotateGithubConnect.js +56 -0
  121. package/src/lib/services/rotateNpmConnect.js +56 -0
  122. package/src/lib/services/rotateOpenaiConnect.js +60 -0
  123. package/src/lib/services/status.js +11 -0
  124. package/src/lib/services/sync.js +70 -0
  125. package/src/lib/services/syncConflict.js +36 -0
@@ -0,0 +1,34 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+ const normalizeToken = require('../../lib/helpers/normalizeToken')
4
+
5
+ class PostLogout {
6
+ constructor (hostname, token) {
7
+ this.hostname = hostname
8
+ this.token = token
9
+ }
10
+
11
+ async run () {
12
+ const token = normalizeToken(this.token)
13
+ const url = `${this.hostname}/api/logout`
14
+
15
+ const resp = await http(url, {
16
+ method: 'POST',
17
+ headers: {
18
+ Authorization: `Bearer ${token}`,
19
+ 'Content-Type': 'application/json'
20
+ },
21
+ body: JSON.stringify({})
22
+ })
23
+
24
+ const json = await resp.body.json()
25
+
26
+ if (resp.statusCode >= 400) {
27
+ throw buildApiError(resp.statusCode, json)
28
+ }
29
+
30
+ return json
31
+ }
32
+ }
33
+
34
+ module.exports = PostLogout
@@ -0,0 +1,45 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+
3
+ // const Device = require('../../db/device')
4
+ const buildOauthError = require('../../lib/helpers/buildOauthError')
5
+
6
+ const OAUTH_CLIENT_ID = 'oac_dotenvxcli'
7
+
8
+ class PostOauthDeviceCode {
9
+ constructor (hostname, devicePublicKey, systemInformation, dotenvxProjectId = null) {
10
+ this.hostname = hostname
11
+ this.devicePublicKey = devicePublicKey
12
+ this.systemInformation = systemInformation
13
+ this.dotenvxProjectId = dotenvxProjectId
14
+ }
15
+
16
+ async run () {
17
+ const url = `${this.hostname}/oauth/device/code`
18
+ const devicePublicKey = this.devicePublicKey
19
+ const systemInformation = this.systemInformation
20
+ const dotenvxProjectId = this.dotenvxProjectId
21
+
22
+ const resp = await http(url, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json'
26
+ },
27
+ body: JSON.stringify({
28
+ client_id: OAUTH_CLIENT_ID,
29
+ device_public_key: devicePublicKey,
30
+ system_information: systemInformation,
31
+ dotenvx_project_id: dotenvxProjectId
32
+ })
33
+ })
34
+
35
+ const json = await resp.body.json()
36
+
37
+ if (resp.statusCode >= 400) {
38
+ throw buildOauthError(resp.statusCode, json)
39
+ }
40
+
41
+ return json
42
+ }
43
+ }
44
+
45
+ module.exports = PostOauthDeviceCode
@@ -0,0 +1,38 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+
3
+ const buildOauthError = require('../../lib/helpers/buildOauthError')
4
+
5
+ const OAUTH_CLIENT_ID = 'oac_dotenvxcli'
6
+
7
+ class PostOauthToken {
8
+ constructor (hostname, deviceCode) {
9
+ this.hostname = hostname
10
+ this.deviceCode = deviceCode
11
+ }
12
+
13
+ async run () {
14
+ const url = `${this.hostname}/oauth/token`
15
+
16
+ const resp = await http(url, {
17
+ method: 'POST',
18
+ headers: {
19
+ 'Content-Type': 'application/json'
20
+ },
21
+ body: JSON.stringify({
22
+ client_id: OAUTH_CLIENT_ID,
23
+ device_code: this.deviceCode,
24
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code'
25
+ })
26
+ })
27
+
28
+ const json = await resp.body.json()
29
+
30
+ if (resp.statusCode >= 400) {
31
+ throw buildOauthError(resp.statusCode, json)
32
+ }
33
+
34
+ return json
35
+ }
36
+ }
37
+
38
+ module.exports = PostOauthToken
@@ -0,0 +1,62 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+ const packageJson = require('../../lib/helpers/packageJson')
4
+
5
+ class PostObserve {
6
+ constructor (hostname, token, encoded, pwd = null, gitUrl = null, gitBranch = null, systemUuid = null, osPlatform = null, osArch = null, dotenvxProjectId = null) {
7
+ this.hostname = hostname || 'https://ops.dotenvx.com'
8
+ this.token = token
9
+ this.encoded = encoded
10
+ this.pwd = pwd
11
+ this.gitUrl = gitUrl
12
+ this.gitBranch = gitBranch
13
+ this.systemUuid = systemUuid
14
+ this.osPlatform = osPlatform
15
+ this.osArch = osArch
16
+ this.dotenvxProjectId = dotenvxProjectId
17
+ }
18
+
19
+ async run () {
20
+ const token = this.token
21
+ const url = `${this.hostname}/api/observe`
22
+ const encoded = this.encoded
23
+ const observedAt = new Date().toISOString()
24
+ const pwd = this.pwd
25
+ const gitUrl = this.gitUrl
26
+ const gitBranch = this.gitBranch
27
+ const systemUuid = this.systemUuid
28
+ const osPlatform = this.osPlatform
29
+ const osArch = this.osArch
30
+ const dotenvxProjectId = this.dotenvxProjectId
31
+
32
+ const resp = await http(url, {
33
+ method: 'POST',
34
+ headers: {
35
+ Authorization: `Bearer ${token}`,
36
+ 'Content-Type': 'application/json'
37
+ },
38
+ body: JSON.stringify({
39
+ encoded,
40
+ observed_at: observedAt,
41
+ pwd,
42
+ git_url: gitUrl,
43
+ git_branch: gitBranch,
44
+ system_uuid: systemUuid,
45
+ os_platform: osPlatform,
46
+ os_arch: osArch,
47
+ cli_version: packageJson.version,
48
+ dotenvx_project_id: dotenvxProjectId
49
+ })
50
+ })
51
+
52
+ const json = await resp.body.json()
53
+
54
+ if (resp.statusCode >= 400) {
55
+ throw buildApiError(resp.statusCode, json)
56
+ }
57
+
58
+ return json
59
+ }
60
+ }
61
+
62
+ module.exports = PostObserve
@@ -0,0 +1,39 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+
4
+ class PostRotate {
5
+ constructor (hostname, token, uri) {
6
+ this.hostname = hostname || 'https://ops.dotenvx.com'
7
+ this.token = token
8
+
9
+ this.uri = uri
10
+ }
11
+
12
+ async run () {
13
+ const token = this.token
14
+ const url = `${this.hostname}/api/rotate`
15
+
16
+ const uri = this.uri
17
+
18
+ const resp = await http(url, {
19
+ method: 'POST',
20
+ headers: {
21
+ Authorization: `Bearer ${token}`,
22
+ 'Content-Type': 'application/json'
23
+ },
24
+ body: JSON.stringify({
25
+ uri
26
+ })
27
+ })
28
+
29
+ const json = await resp.body.json()
30
+
31
+ if (resp.statusCode >= 400) {
32
+ throw buildApiError(resp.statusCode, json)
33
+ }
34
+
35
+ return json
36
+ }
37
+ }
38
+
39
+ module.exports = PostRotate
@@ -0,0 +1,54 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+
4
+ class PostRotateConnect {
5
+ constructor (hostname, token, org, slug, username, password, email = null, playwrightStorageStateStringified) {
6
+ this.hostname = hostname || 'https://ops.dotenvx.com'
7
+ this.token = token
8
+
9
+ this.org = org
10
+ this.slug = slug
11
+ this.username = username
12
+ this.password = password
13
+ this.email = email
14
+ this.playwrightStorageStateStringified = playwrightStorageStateStringified
15
+ }
16
+
17
+ async run () {
18
+ const token = this.token
19
+ const url = `${this.hostname}/api/rotate/connect`
20
+
21
+ const org = this.org
22
+ const slug = this.slug
23
+ const username = this.username
24
+ const password = this.password
25
+ const email = this.email
26
+ const playwrightStorageStateStringified = this.playwrightStorageStateStringified
27
+
28
+ const resp = await http(url, {
29
+ method: 'POST',
30
+ headers: {
31
+ Authorization: `Bearer ${token}`,
32
+ 'Content-Type': 'application/json'
33
+ },
34
+ body: JSON.stringify({
35
+ org,
36
+ slug,
37
+ username,
38
+ password,
39
+ email,
40
+ playwright_storage_state: playwrightStorageStateStringified
41
+ })
42
+ })
43
+
44
+ const json = await resp.body.json()
45
+
46
+ if (resp.statusCode >= 400) {
47
+ throw buildApiError(resp.statusCode, json)
48
+ }
49
+
50
+ return json
51
+ }
52
+ }
53
+
54
+ module.exports = PostRotateConnect
@@ -0,0 +1,43 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+
4
+ class PostSet {
5
+ constructor (hostname, token, devicePublicKey, uri, value) {
6
+ this.hostname = hostname || 'https://ops.dotenvx.com'
7
+ this.token = token
8
+ this.devicePublicKey = devicePublicKey
9
+ this.uri = uri
10
+ this.value = value
11
+ }
12
+
13
+ async run () {
14
+ const token = this.token
15
+ const devicePublicKey = this.devicePublicKey
16
+ const uri = this.uri
17
+ const value = this.value
18
+ const url = `${this.hostname}/api/set`
19
+
20
+ const resp = await http(url, {
21
+ method: 'POST',
22
+ headers: {
23
+ Authorization: `Bearer ${token}`,
24
+ 'Content-Type': 'application/json'
25
+ },
26
+ body: JSON.stringify({
27
+ device_public_key: devicePublicKey,
28
+ uri,
29
+ value
30
+ })
31
+ })
32
+
33
+ if (resp.statusCode >= 400) {
34
+ const json = await resp.body.json()
35
+ throw buildApiError(resp.statusCode, json)
36
+ }
37
+
38
+ const text = await resp.body.text()
39
+ return text
40
+ }
41
+ }
42
+
43
+ module.exports = PostSet
@@ -0,0 +1,68 @@
1
+ const { http } = require('../../lib/helpers/http')
2
+ const buildApiError = require('../../lib/helpers/buildApiError')
3
+ const packageJson = require('../../lib/helpers/packageJson')
4
+
5
+ class PostSync {
6
+ constructor (hostname, token, devicePublicKey, encoded, dotenvxProjectId, pwd = null, gitUrl = null, gitBranch = null, systemUuid = null, osPlatform = null, osArch = null, force = false) {
7
+ this.hostname = hostname || 'https://ops.dotenvx.com'
8
+ this.token = token
9
+ this.devicePublicKey = devicePublicKey
10
+ this.encoded = encoded
11
+ this.dotenvxProjectId = dotenvxProjectId
12
+ this.pwd = pwd
13
+ this.gitUrl = gitUrl
14
+ this.gitBranch = gitBranch
15
+ this.systemUuid = systemUuid
16
+ this.osPlatform = osPlatform
17
+ this.osArch = osArch
18
+ this.force = force
19
+ }
20
+
21
+ async run () {
22
+ const token = this.token
23
+ const devicePublicKey = this.devicePublicKey
24
+ const url = `${this.hostname}/api/sync`
25
+ const encoded = this.encoded
26
+ const dotenvxProjectId = this.dotenvxProjectId
27
+ const syncedAt = new Date().toISOString()
28
+ const pwd = this.pwd
29
+ const gitUrl = this.gitUrl
30
+ const gitBranch = this.gitBranch
31
+ const systemUuid = this.systemUuid
32
+ const osPlatform = this.osPlatform
33
+ const osArch = this.osArch
34
+ const force = this.force
35
+
36
+ const resp = await http(url, {
37
+ method: 'POST',
38
+ headers: {
39
+ Authorization: `Bearer ${token}`,
40
+ 'Content-Type': 'application/json'
41
+ },
42
+ body: JSON.stringify({
43
+ device_public_key: devicePublicKey,
44
+ encoded,
45
+ dotenvx_project_id: dotenvxProjectId,
46
+ synced_at: syncedAt,
47
+ pwd,
48
+ git_url: gitUrl,
49
+ git_branch: gitBranch,
50
+ system_uuid: systemUuid,
51
+ os_platform: osPlatform,
52
+ os_arch: osArch,
53
+ cli_version: packageJson.version,
54
+ force
55
+ })
56
+ })
57
+
58
+ const json = await resp.body.json()
59
+
60
+ if (resp.statusCode >= 400) {
61
+ throw buildApiError(resp.statusCode, json)
62
+ }
63
+
64
+ return json
65
+ }
66
+ }
67
+
68
+ module.exports = PostSync
@@ -0,0 +1,10 @@
1
+ function armoredKeyDisplay (publicKey) {
2
+ if (!publicKey) return ''
3
+
4
+ const prefix = String(publicKey).slice(0, 6).toUpperCase()
5
+ if (prefix.length <= 3) return prefix
6
+
7
+ return `${prefix.slice(0, 3)} ${prefix.slice(3)}`
8
+ }
9
+
10
+ module.exports = armoredKeyDisplay
@@ -0,0 +1,16 @@
1
+ function buildApiError (statusCode, json) {
2
+ const code = json.error.code || statusCode.toString()
3
+ const message = `[${code}] ${json.error.message}`
4
+ const help = `[${code}] ${json.error.help || JSON.stringify(json)}`
5
+ const meta = json.error.meta
6
+
7
+ const error = new Error(message)
8
+ error.code = code
9
+ error.help = help
10
+ error.meta = meta
11
+ error.json = json
12
+
13
+ return error
14
+ }
15
+
16
+ module.exports = buildApiError
@@ -0,0 +1,13 @@
1
+ function buildOauthError (statusCode, json) {
2
+ const code = json.error // TAKE CAUTION CHANGING THIS. the polling for an oauth token relies on it
3
+ const message = `[${code}] ${json.error_description}`
4
+ const help = `[${code}] ${JSON.stringify(json)}`
5
+
6
+ const error = new Error(message)
7
+ error.code = code
8
+ error.help = help
9
+
10
+ return error
11
+ }
12
+
13
+ module.exports = buildOauthError
@@ -0,0 +1,13 @@
1
+ const path = require('path')
2
+
3
+ function canonicalEnvFilename (filepath) {
4
+ let filename = path.basename(filepath).toLowerCase()
5
+
6
+ if (filename.startsWith('.env') && filename.endsWith('.txt')) {
7
+ filename = filename.slice(0, -4)
8
+ }
9
+
10
+ return filename
11
+ }
12
+
13
+ module.exports = canonicalEnvFilename
@@ -0,0 +1,57 @@
1
+ 'use strict'
2
+ const path = require('path')
3
+ const execa = require('execa')
4
+
5
+ const xsel = 'xsel'
6
+ const xselFallback = path.join(__dirname, './fallbacks/linux/xsel')
7
+
8
+ const copyArguments = ['--clipboard', '--input']
9
+ const pasteArguments = ['--clipboard', '--output']
10
+
11
+ const makeError = (xselError, fallbackError) => {
12
+ let error
13
+ if (xselError.code === 'ENOENT') {
14
+ error = new Error('Couldn\'t find the `xsel` binary and fallback didn\'t work. On Debian/Ubuntu you can install xsel with: sudo apt install xsel')
15
+ } else {
16
+ error = new Error('Both xsel and fallback failed')
17
+ error.xselError = xselError
18
+ }
19
+
20
+ error.fallbackError = fallbackError
21
+ return error
22
+ }
23
+
24
+ const xselWithFallback = async (argumentList, options) => {
25
+ try {
26
+ return await execa.stdout(xsel, argumentList, options)
27
+ } catch (xselError) {
28
+ try {
29
+ return await execa.stdout(xselFallback, argumentList, options)
30
+ } catch (fallbackError) {
31
+ throw makeError(xselError, fallbackError)
32
+ }
33
+ }
34
+ }
35
+
36
+ const xselWithFallbackSync = (argumentList, options) => {
37
+ try {
38
+ return execa.sync(xsel, argumentList, options)
39
+ } catch (xselError) {
40
+ try {
41
+ return execa.sync(xselFallback, argumentList, options)
42
+ } catch (fallbackError) {
43
+ throw makeError(xselError, fallbackError)
44
+ }
45
+ }
46
+ }
47
+
48
+ module.exports = {
49
+ copy: async options => {
50
+ await xselWithFallback(copyArguments, options)
51
+ },
52
+ copySync: options => {
53
+ xselWithFallbackSync(copyArguments, options)
54
+ },
55
+ paste: options => xselWithFallback(pasteArguments, options),
56
+ pasteSync: options => xselWithFallbackSync(pasteArguments, options)
57
+ }
@@ -0,0 +1,14 @@
1
+ 'use strict'
2
+ const execa = require('execa')
3
+
4
+ const env = {
5
+ ...process.env,
6
+ LC_CTYPE: 'UTF-8'
7
+ }
8
+
9
+ module.exports = {
10
+ copy: async options => execa('pbcopy', { ...options, env }),
11
+ paste: async options => execa.stdout('pbpaste', { ...options, env }),
12
+ copySync: options => execa.sync('pbcopy', { ...options, env }),
13
+ pasteSync: options => execa.sync('pbpaste', { ...options, env })
14
+ }
@@ -0,0 +1,41 @@
1
+ 'use strict'
2
+ const execa = require('execa')
3
+
4
+ const handler = error => {
5
+ if (error.code === 'ENOENT') {
6
+ throw new Error('Couldn\'t find the termux-api scripts. You can install them with: apt install termux-api')
7
+ }
8
+
9
+ throw error
10
+ }
11
+
12
+ module.exports = {
13
+ copy: async options => {
14
+ try {
15
+ await execa('termux-clipboard-set', options)
16
+ } catch (error) {
17
+ handler(error)
18
+ }
19
+ },
20
+ paste: async options => {
21
+ try {
22
+ return await execa.stdout('termux-clipboard-get', options)
23
+ } catch (error) {
24
+ handler(error)
25
+ }
26
+ },
27
+ copySync: options => {
28
+ try {
29
+ execa.sync('termux-clipboard-set', options)
30
+ } catch (error) {
31
+ handler(error)
32
+ }
33
+ },
34
+ pasteSync: options => {
35
+ try {
36
+ return execa.sync('termux-clipboard-get', options)
37
+ } catch (error) {
38
+ handler(error)
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,16 @@
1
+ 'use strict'
2
+ const path = require('path')
3
+ const execa = require('execa')
4
+ const arch = require('arch')
5
+
6
+ // Binaries from: https://github.com/sindresorhus/clipboardy/tree/v2.3.0
7
+ const windowBinaryPath = arch() === 'x64'
8
+ ? path.join(__dirname, './fallbacks/windows/clipboard_x86_64.exe')
9
+ : path.join(__dirname, './fallbacks/windows/clipboard_i686.exe')
10
+
11
+ module.exports = {
12
+ copy: async options => execa(windowBinaryPath, ['--copy'], options),
13
+ paste: async options => execa.stdout(windowBinaryPath, ['--paste'], options),
14
+ copySync: options => execa.sync(windowBinaryPath, ['--copy'], options),
15
+ pasteSync: options => execa.sync(windowBinaryPath, ['--paste'], options)
16
+ }
@@ -0,0 +1,51 @@
1
+ // based on "clipboardy" by Sindre Sorhus (https://github.com/sindresorhus/clipboardy)
2
+ // licensed under the MIT License (see [license](https://github.com/sindresorhus/clipboardy/blob/v2.3.0/license) file for details).
3
+
4
+ 'use strict'
5
+ const isWSL = require('is-wsl')
6
+ const termux = require('./clipboardy/termux.js')
7
+ const linux = require('./clipboardy/linux.js')
8
+ const macos = require('./clipboardy/macos.js')
9
+ const windows = require('./clipboardy/windows.js')
10
+
11
+ const platformLib = (() => {
12
+ switch (process.platform) {
13
+ case 'darwin':
14
+ return macos
15
+ case 'win32':
16
+ return windows
17
+ case 'android':
18
+ if (process.env.PREFIX !== '/data/data/com.termux/files/usr') {
19
+ throw new Error('You need to install Termux for this module to work on Android: https://termux.com')
20
+ }
21
+
22
+ return termux
23
+ default:
24
+ // `process.platform === 'linux'` for WSL.
25
+ if (isWSL) {
26
+ return windows
27
+ }
28
+
29
+ return linux
30
+ }
31
+ })()
32
+
33
+ exports.write = async text => {
34
+ if (typeof text !== 'string') {
35
+ throw new TypeError(`Expected a string, got ${typeof text}`)
36
+ }
37
+
38
+ await platformLib.copy({ input: text })
39
+ }
40
+
41
+ exports.read = async () => platformLib.paste({ stripEof: false })
42
+
43
+ exports.writeSync = text => {
44
+ if (typeof text !== 'string') {
45
+ throw new TypeError(`Expected a string, got ${typeof text}`)
46
+ }
47
+
48
+ platformLib.copySync({ input: text })
49
+ }
50
+
51
+ exports.readSync = () => platformLib.pasteSync({ stripEof: false }).stdout
@@ -0,0 +1,17 @@
1
+ const { ConfirmPrompt, isCancel } = require('@clack/core')
2
+
3
+ module.exports = async (opts) => {
4
+ const prompt = new ConfirmPrompt({
5
+ active: 'Y',
6
+ inactive: 'N',
7
+ initialValue: true,
8
+ render () {
9
+ return `${opts.message} (Y/n)`
10
+ }
11
+ })
12
+
13
+ const result = await prompt.prompt()
14
+ if (isCancel(result)) process.exit(0)
15
+
16
+ return result
17
+ }