@shopify/cli-kit 3.34.0 → 3.36.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 (241) hide show
  1. package/dist/content-tokens.js +1 -1
  2. package/dist/content-tokens.js.map +1 -1
  3. package/dist/error.js +2 -2
  4. package/dist/error.js.map +1 -1
  5. package/dist/git.js +2 -2
  6. package/dist/git.js.map +1 -1
  7. package/dist/index.d.ts +0 -6
  8. package/dist/index.js +0 -6
  9. package/dist/index.js.map +1 -1
  10. package/dist/metadata.d.ts +1 -1
  11. package/dist/metadata.js.map +1 -1
  12. package/dist/monorail.d.ts +1 -1
  13. package/dist/monorail.js +1 -1
  14. package/dist/monorail.js.map +1 -1
  15. package/dist/output.js +3 -7
  16. package/dist/output.js.map +1 -1
  17. package/dist/plugins.d.ts +1 -1
  18. package/dist/plugins.js.map +1 -1
  19. package/dist/{typing → private/common/ts}/deep-required.d.ts +3 -3
  20. package/dist/{typing → private/common/ts}/deep-required.js +0 -0
  21. package/dist/private/common/ts/deep-required.js.map +1 -0
  22. package/dist/{typing → private/common/ts}/overloaded-parameters.d.ts +0 -0
  23. package/dist/{typing → private/common/ts}/overloaded-parameters.js +0 -0
  24. package/dist/private/common/ts/overloaded-parameters.js.map +1 -0
  25. package/dist/private/node/api/graphql.js +2 -3
  26. package/dist/private/node/api/graphql.js.map +1 -1
  27. package/dist/private/node/api/headers.d.ts +11 -2
  28. package/dist/private/node/api/headers.js +29 -3
  29. package/dist/private/node/api/headers.js.map +1 -1
  30. package/dist/private/node/api/rest.d.ts +5 -3
  31. package/dist/private/node/api/rest.js +8 -7
  32. package/dist/private/node/api/rest.js.map +1 -1
  33. package/dist/private/node/constants.d.ts +42 -0
  34. package/dist/private/node/constants.js +58 -0
  35. package/dist/private/node/constants.js.map +1 -0
  36. package/dist/private/node/environment/service.js +2 -2
  37. package/dist/private/node/environment/service.js.map +1 -1
  38. package/dist/private/node/session/device-authorization.js +1 -1
  39. package/dist/private/node/session/device-authorization.js.map +1 -1
  40. package/dist/private/node/session/exchange.js +1 -1
  41. package/dist/private/node/session/exchange.js.map +1 -1
  42. package/dist/private/node/session/identity-token-validation.js +1 -1
  43. package/dist/private/node/session/identity-token-validation.js.map +1 -1
  44. package/dist/private/node/session/post-auth.js +10 -10
  45. package/dist/private/node/session/post-auth.js.map +1 -1
  46. package/dist/private/node/session/store.js +6 -6
  47. package/dist/private/node/session/store.js.map +1 -1
  48. package/dist/private/node/session/validate.js +2 -2
  49. package/dist/private/node/session/validate.js.map +1 -1
  50. package/dist/private/node/session.js +2 -2
  51. package/dist/private/node/session.js.map +1 -1
  52. package/dist/{typing → private/node}/simple-definitions.d.ts +0 -0
  53. package/dist/{typing → private/node}/simple-definitions.js +0 -0
  54. package/dist/private/node/simple-definitions.js.map +1 -0
  55. package/dist/private/node/ui/alert.d.ts +1 -1
  56. package/dist/private/node/ui/alert.js +2 -2
  57. package/dist/private/node/ui/alert.js.map +1 -1
  58. package/dist/private/node/ui/components/Alert.d.ts +5 -0
  59. package/dist/private/node/ui/components/Alert.js +9 -6
  60. package/dist/private/node/ui/components/Alert.js.map +1 -1
  61. package/dist/private/node/ui/components/Alert.test.js +30 -4
  62. package/dist/private/node/ui/components/Alert.test.js.map +1 -1
  63. package/dist/private/node/ui/components/AutocompletePrompt.d.ts +12 -0
  64. package/dist/private/node/ui/components/AutocompletePrompt.js +111 -0
  65. package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -0
  66. package/dist/private/node/ui/components/AutocompletePrompt.test.d.ts +1 -0
  67. package/dist/private/node/ui/components/AutocompletePrompt.test.js +473 -0
  68. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -0
  69. package/dist/private/node/ui/components/Banner.d.ts +0 -1
  70. package/dist/private/node/ui/components/Banner.js +4 -4
  71. package/dist/private/node/ui/components/Banner.js.map +1 -1
  72. package/dist/private/node/ui/components/Banner.test.js +10 -5
  73. package/dist/private/node/ui/components/Banner.test.js.map +1 -1
  74. package/dist/private/node/ui/components/FatalError.js +1 -1
  75. package/dist/private/node/ui/components/FatalError.js.map +1 -1
  76. package/dist/private/node/ui/components/FatalError.test.js +4 -8
  77. package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
  78. package/dist/private/node/ui/components/{Table.d.ts → Prompts/InfoTable.d.ts} +2 -2
  79. package/dist/private/node/ui/components/{Table.js → Prompts/InfoTable.js} +6 -6
  80. package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -0
  81. package/dist/private/node/ui/components/SelectInput.d.ts +9 -2
  82. package/dist/private/node/ui/components/SelectInput.js +96 -52
  83. package/dist/private/node/ui/components/SelectInput.js.map +1 -1
  84. package/dist/private/node/ui/components/SelectInput.test.js +140 -54
  85. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  86. package/dist/private/node/ui/components/SelectPrompt.d.ts +6 -4
  87. package/dist/private/node/ui/components/SelectPrompt.js +18 -11
  88. package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
  89. package/dist/private/node/ui/components/SelectPrompt.test.js +113 -23
  90. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  91. package/dist/private/node/ui/components/Table/Column.d.ts +5 -0
  92. package/dist/private/node/ui/components/Table/Column.js +2 -0
  93. package/dist/private/node/ui/components/Table/Column.js.map +1 -0
  94. package/dist/private/node/ui/components/Table/Row.d.ts +12 -0
  95. package/dist/private/node/ui/components/Table/Row.js +24 -0
  96. package/dist/private/node/ui/components/Table/Row.js.map +1 -0
  97. package/dist/private/node/ui/components/Table/ScalarDict.d.ts +5 -0
  98. package/dist/private/node/ui/components/Table/ScalarDict.js +2 -0
  99. package/dist/private/node/ui/components/Table/ScalarDict.js.map +1 -0
  100. package/dist/private/node/ui/components/Table/Table.d.ts +12 -0
  101. package/dist/private/node/ui/components/Table/Table.js +30 -0
  102. package/dist/private/node/ui/components/Table/Table.js.map +1 -0
  103. package/dist/private/node/ui/components/Table/Table.test.d.ts +1 -0
  104. package/dist/private/node/ui/components/Table/Table.test.js +41 -0
  105. package/dist/private/node/ui/components/Table/Table.test.js.map +1 -0
  106. package/dist/private/node/ui/components/Tasks.d.ts +6 -5
  107. package/dist/private/node/ui/components/Tasks.js +32 -11
  108. package/dist/private/node/ui/components/Tasks.js.map +1 -1
  109. package/dist/private/node/ui/components/Tasks.test.js +55 -9
  110. package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
  111. package/dist/private/node/ui/components/TextInput.d.ts +4 -1
  112. package/dist/private/node/ui/components/TextInput.js +22 -13
  113. package/dist/private/node/ui/components/TextInput.js.map +1 -1
  114. package/dist/private/node/ui/components/TextInput.test.js +47 -40
  115. package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
  116. package/dist/private/node/ui/components/TextPrompt.d.ts +3 -1
  117. package/dist/private/node/ui/components/TextPrompt.js +28 -15
  118. package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
  119. package/dist/private/node/ui/components/TextPrompt.test.js +71 -15
  120. package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
  121. package/dist/private/node/ui/components/TokenizedText.d.ts +3 -0
  122. package/dist/private/node/ui/components/TokenizedText.js +33 -1
  123. package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
  124. package/dist/private/node/ui/utilities.d.ts +2 -0
  125. package/dist/private/node/ui/utilities.js +6 -0
  126. package/dist/private/node/ui/utilities.js.map +1 -0
  127. package/dist/public/common/string.d.ts +11 -0
  128. package/dist/public/common/string.js +21 -0
  129. package/dist/public/common/string.js.map +1 -1
  130. package/dist/{typing → public/common/ts}/pick-by-prefix.d.ts +4 -3
  131. package/dist/{typing → public/common/ts}/pick-by-prefix.js +0 -0
  132. package/dist/public/common/ts/pick-by-prefix.js.map +1 -0
  133. package/dist/public/common/version.d.ts +1 -0
  134. package/dist/public/common/version.js +2 -0
  135. package/dist/public/common/version.js.map +1 -0
  136. package/dist/public/node/analytics.js +2 -2
  137. package/dist/public/node/analytics.js.map +1 -1
  138. package/dist/public/node/api/admin.d.ts +4 -1
  139. package/dist/public/node/api/admin.js +5 -4
  140. package/dist/public/node/api/admin.js.map +1 -1
  141. package/dist/public/node/api/http.d.ts +0 -0
  142. package/dist/public/node/api/http.js +2 -0
  143. package/dist/public/node/api/http.js.map +1 -0
  144. package/dist/public/node/api/oxygen.js +1 -1
  145. package/dist/public/node/api/oxygen.js.map +1 -1
  146. package/dist/public/node/archiver.js +2 -1
  147. package/dist/public/node/archiver.js.map +1 -1
  148. package/dist/public/node/cli.js +6 -6
  149. package/dist/public/node/cli.js.map +1 -1
  150. package/dist/public/node/dot-env.js +2 -2
  151. package/dist/public/node/dot-env.js.map +1 -1
  152. package/dist/public/node/environment/local.js +17 -17
  153. package/dist/public/node/environment/local.js.map +1 -1
  154. package/dist/public/node/environment/spin.js +6 -6
  155. package/dist/public/node/environment/spin.js.map +1 -1
  156. package/dist/public/node/error-handler.js +13 -10
  157. package/dist/public/node/error-handler.js.map +1 -1
  158. package/dist/public/node/framework.js +2 -2
  159. package/dist/public/node/framework.js.map +1 -1
  160. package/dist/public/node/fs.d.ts +241 -4
  161. package/dist/public/node/fs.js +366 -2
  162. package/dist/public/node/fs.js.map +1 -1
  163. package/dist/public/node/git.d.ts +90 -0
  164. package/dist/public/node/git.js +174 -0
  165. package/dist/public/node/git.js.map +1 -0
  166. package/dist/public/node/github.js +1 -1
  167. package/dist/public/node/github.js.map +1 -1
  168. package/dist/{http/fetch.d.ts → public/node/http.d.ts} +18 -7
  169. package/dist/{http/fetch.js → public/node/http.js} +21 -8
  170. package/dist/public/node/http.js.map +1 -0
  171. package/dist/public/node/liquid.js +9 -9
  172. package/dist/public/node/liquid.js.map +1 -1
  173. package/dist/public/node/node-package-manager.d.ts +20 -9
  174. package/dist/public/node/node-package-manager.js +19 -25
  175. package/dist/public/node/node-package-manager.js.map +1 -1
  176. package/dist/public/node/path.d.ts +22 -0
  177. package/dist/{path.js → public/node/path.js} +8 -20
  178. package/dist/public/node/path.js.map +1 -0
  179. package/dist/public/node/presets.js +5 -5
  180. package/dist/public/node/presets.js.map +1 -1
  181. package/dist/public/node/ruby.js +29 -33
  182. package/dist/public/node/ruby.js.map +1 -1
  183. package/dist/public/node/session.js +2 -2
  184. package/dist/public/node/session.js.map +1 -1
  185. package/dist/public/node/ui.d.ts +63 -9
  186. package/dist/public/node/ui.js +83 -8
  187. package/dist/public/node/ui.js.map +1 -1
  188. package/dist/public/node/vscode.js +8 -8
  189. package/dist/public/node/vscode.js.map +1 -1
  190. package/dist/secure-store.js +4 -4
  191. package/dist/secure-store.js.map +1 -1
  192. package/dist/store.d.ts +10 -10
  193. package/dist/store.js +21 -22
  194. package/dist/store.js.map +1 -1
  195. package/dist/testing/store.js +3 -3
  196. package/dist/testing/store.js.map +1 -1
  197. package/dist/testing/ui.d.ts +4 -1
  198. package/dist/testing/ui.js +24 -1
  199. package/dist/testing/ui.js.map +1 -1
  200. package/dist/tsconfig.tsbuildinfo +1 -1
  201. package/dist/ui/executor.d.ts +2 -14
  202. package/dist/ui/executor.js +38 -72
  203. package/dist/ui/executor.js.map +1 -1
  204. package/dist/ui.js +9 -26
  205. package/dist/ui.js.map +1 -1
  206. package/package.json +4 -6
  207. package/dist/constants.d.ts +0 -48
  208. package/dist/constants.js +0 -67
  209. package/dist/constants.js.map +0 -1
  210. package/dist/file.d.ts +0 -98
  211. package/dist/file.js +0 -216
  212. package/dist/file.js.map +0 -1
  213. package/dist/http/fetch.js.map +0 -1
  214. package/dist/http/formdata.d.ts +0 -3
  215. package/dist/http/formdata.js +0 -6
  216. package/dist/http/formdata.js.map +0 -1
  217. package/dist/http.d.ts +0 -26
  218. package/dist/http.js +0 -31
  219. package/dist/http.js.map +0 -1
  220. package/dist/npm.d.ts +0 -27
  221. package/dist/npm.js +0 -20
  222. package/dist/npm.js.map +0 -1
  223. package/dist/path.d.ts +0 -25
  224. package/dist/path.js.map +0 -1
  225. package/dist/private/node/ui/components/Table.js.map +0 -1
  226. package/dist/typing/deep-required.js.map +0 -1
  227. package/dist/typing/overloaded-parameters.js.map +0 -1
  228. package/dist/typing/pick-by-prefix.js.map +0 -1
  229. package/dist/typing/simple-definitions.js.map +0 -1
  230. package/dist/ui/inquirer/autocomplete.d.ts +0 -11
  231. package/dist/ui/inquirer/autocomplete.js +0 -110
  232. package/dist/ui/inquirer/autocomplete.js.map +0 -1
  233. package/dist/ui/inquirer/input.d.ts +0 -16
  234. package/dist/ui/inquirer/input.js +0 -45
  235. package/dist/ui/inquirer/input.js.map +0 -1
  236. package/dist/ui/inquirer/password.d.ts +0 -7
  237. package/dist/ui/inquirer/password.js +0 -8
  238. package/dist/ui/inquirer/password.js.map +0 -1
  239. package/dist/ui/inquirer/select.d.ts +0 -14
  240. package/dist/ui/inquirer/select.js +0 -26
  241. package/dist/ui/inquirer/select.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { isTruthy, isSet } from '../../../private/node/environment/utilities.js';
2
- import constants from '../../../constants.js';
3
- import { exists as fileExists } from '../../../file.js';
2
+ import { environmentVariables, pathConstants } from '../../../private/node/constants.js';
3
+ import { fileExists } from '../fs.js';
4
4
  import { exec } from '../system.js';
5
5
  import { isSpin } from '../environment/spin.js';
6
6
  import isInteractive from 'is-interactive';
@@ -29,7 +29,7 @@ export function homeDirectory() {
29
29
  * @returns True if SHOPIFY_ENV is development.
30
30
  */
31
31
  export function isDevelopment(env = process.env) {
32
- return env[constants.environmentVariables.env] === 'development';
32
+ return env[environmentVariables.env] === 'development';
33
33
  }
34
34
  /**
35
35
  * Returns true if the CLI is running in verbose mode.
@@ -38,7 +38,7 @@ export function isDevelopment(env = process.env) {
38
38
  * @returns True if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed.
39
39
  */
40
40
  export function isVerbose(env = process.env) {
41
- return isTruthy(env[constants.environmentVariables.verbose]) || process.argv.includes('--verbose');
41
+ return isTruthy(env[environmentVariables.verbose]) || process.argv.includes('--verbose');
42
42
  }
43
43
  /**
44
44
  * Returns true if the environment in which the CLI is running is either
@@ -48,10 +48,10 @@ export function isVerbose(env = process.env) {
48
48
  * @returns True if the CLI is used in a Shopify environment.
49
49
  */
50
50
  export async function isShopify(env = process.env) {
51
- if (Object.prototype.hasOwnProperty.call(env, constants.environmentVariables.runAsUser)) {
52
- return !isTruthy(env[constants.environmentVariables.runAsUser]);
51
+ if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {
52
+ return !isTruthy(env[environmentVariables.runAsUser]);
53
53
  }
54
- const devInstalled = await fileExists(constants.paths.executables.dev);
54
+ const devInstalled = await fileExists(pathConstants.executables.dev);
55
55
  return devInstalled || isSpin(env);
56
56
  }
57
57
  /**
@@ -63,7 +63,7 @@ export async function isShopify(env = process.env) {
63
63
  * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.
64
64
  */
65
65
  export function isUnitTest(env = process.env) {
66
- return isTruthy(env[constants.environmentVariables.unitTest]);
66
+ return isTruthy(env[environmentVariables.unitTest]);
67
67
  }
68
68
  /**
69
69
  * Returns true if reporting analytics is enabled.
@@ -72,7 +72,7 @@ export function isUnitTest(env = process.env) {
72
72
  * @returns True unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.
73
73
  */
74
74
  export function analyticsDisabled(env = process.env) {
75
- return isTruthy(env[constants.environmentVariables.noAnalytics]) || isDevelopment(env);
75
+ return isTruthy(env[environmentVariables.noAnalytics]) || isDevelopment(env);
76
76
  }
77
77
  /**
78
78
  * Returns true if reporting analytics should always happen, regardless of DEBUG mode etc.
@@ -81,7 +81,7 @@ export function analyticsDisabled(env = process.env) {
81
81
  * @returns True if SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS is truthy.
82
82
  */
83
83
  export function alwaysLogAnalytics(env = process.env) {
84
- return isTruthy(env[constants.environmentVariables.alwaysLogAnalytics]);
84
+ return isTruthy(env[environmentVariables.alwaysLogAnalytics]);
85
85
  }
86
86
  /**
87
87
  * Returns true if the CLI User is 1P.
@@ -90,7 +90,7 @@ export function alwaysLogAnalytics(env = process.env) {
90
90
  * @returns True if SHOPIFY_CLI_1P is truthy.
91
91
  */
92
92
  export function firstPartyDev(env = process.env) {
93
- return isTruthy(env[constants.environmentVariables.firstPartyDev]);
93
+ return isTruthy(env[environmentVariables.firstPartyDev]);
94
94
  }
95
95
  /**
96
96
  * Returns true if the CLI should use device auth.
@@ -99,7 +99,7 @@ export function firstPartyDev(env = process.env) {
99
99
  * @returns True if SHOPIFY_CLI_DEVICE_AUTH is truthy or the CLI is run from a cloud environment.
100
100
  */
101
101
  export function useDeviceAuth(env = process.env) {
102
- return isTruthy(env[constants.environmentVariables.deviceAuth]) || isCloudEnvironment(env);
102
+ return isTruthy(env[environmentVariables.deviceAuth]) || isCloudEnvironment(env);
103
103
  }
104
104
  /**
105
105
  * Returns true if the CLI should use theme bundling.
@@ -108,7 +108,7 @@ export function useDeviceAuth(env = process.env) {
108
108
  * @returns True if SHOPIFY_CLI_THEME_BUNDLING is truthy.
109
109
  */
110
110
  export function useThemeBundling(env = process.env) {
111
- return isTruthy(env[constants.environmentVariables.themeBundling]);
111
+ return isTruthy(env[environmentVariables.themeBundling]);
112
112
  }
113
113
  /**
114
114
  * Return gitpodURL if we are running in gitpod.
@@ -118,7 +118,7 @@ export function useThemeBundling(env = process.env) {
118
118
  * @returns The gitpod URL.
119
119
  */
120
120
  export function gitpodURL(env = process.env) {
121
- return env[constants.environmentVariables.gitpod];
121
+ return env[environmentVariables.gitpod];
122
122
  }
123
123
  /**
124
124
  * Return codespaceURL if we are running in codespaces.
@@ -128,7 +128,7 @@ export function gitpodURL(env = process.env) {
128
128
  * @returns The codespace URL.
129
129
  */
130
130
  export function codespaceURL(env = process.env) {
131
- return env[constants.environmentVariables.codespaceName];
131
+ return env[environmentVariables.codespaceName];
132
132
  }
133
133
  /**
134
134
  * Checks if the CLI is run from a cloud environment.
@@ -147,10 +147,10 @@ export function isCloudEnvironment(env = process.env) {
147
147
  * @returns Cloud platform information.
148
148
  */
149
149
  export function cloudEnvironment(env = process.env) {
150
- if (isSet(env[constants.environmentVariables.codespaces])) {
150
+ if (isSet(env[environmentVariables.codespaces])) {
151
151
  return { platform: 'codespaces', editor: true };
152
152
  }
153
- if (isSet(env[constants.environmentVariables.gitpod])) {
153
+ if (isSet(env[environmentVariables.gitpod])) {
154
154
  return { platform: 'gitpod', editor: true };
155
155
  }
156
156
  if (isSpin(env)) {
@@ -1 +1 @@
1
- {"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../src/public/node/environment/local.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy, isSet} from '../../../private/node/environment/utilities.js'\nimport constants from '../../../constants.js'\nimport {exists as fileExists} from '../../../file.js'\nimport {exec} from '../system.js'\nimport {isSpin} from '../environment/spin.js'\nimport isInteractive from 'is-interactive'\nimport macaddress from 'macaddress'\nimport {homedir} from 'os'\n\n/**\n * It returns true if the terminal is interactive.\n *\n * @returns True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n *\n * @returns The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_ENV is development.\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[constants.environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed.\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present) or a cloud environment (spin).\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, constants.environmentVariables.runAsUser)) {\n return !isTruthy(env[constants.environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(constants.paths.executables.dev)\n return devInstalled || isSpin(env)\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/**\n * Returns true if reporting analytics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS is truthy.\n */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.alwaysLogAnalytics])\n}\n\n/**\n * Returns true if the CLI User is 1P.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_1P is truthy.\n */\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.firstPartyDev])\n}\n\n/**\n * Returns true if the CLI should use device auth.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_DEVICE_AUTH is truthy or the CLI is run from a cloud environment.\n */\nexport function useDeviceAuth(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.deviceAuth]) || isCloudEnvironment(env)\n}\n\n/**\n * Returns true if the CLI should use theme bundling.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_THEME_BUNDLING is truthy.\n */\nexport function useThemeBundling(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.themeBundling])\n}\n\n/**\n * Return gitpodURL if we are running in gitpod.\n * Https://www.gitpod.io/docs/environment-variables#default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The gitpod URL.\n */\nexport function gitpodURL(env = process.env): string | undefined {\n return env[constants.environmentVariables.gitpod]\n}\n\n/**\n * Return codespaceURL if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace URL.\n */\nexport function codespaceURL(env = process.env): string | undefined {\n return env[constants.environmentVariables.codespaceName]\n}\n\n/**\n * Checks if the CLI is run from a cloud environment.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns True in case the CLI is run from a cloud environment.\n */\nexport function isCloudEnvironment(env: NodeJS.ProcessEnv = process.env): boolean {\n return cloudEnvironment(env).platform !== 'localhost'\n}\n\n/**\n * Returns the cloud environment platform name and if the platform support online IDE in case the CLI is run from one of\n * them. Platform name 'localhost' is returned otherwise.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns Cloud platform information.\n */\nexport function cloudEnvironment(env: NodeJS.ProcessEnv = process.env): {\n platform: 'spin' | 'codespaces' | 'gitpod' | 'localhost'\n editor: boolean\n} {\n if (isSet(env[constants.environmentVariables.codespaces])) {\n return {platform: 'codespaces', editor: true}\n }\n if (isSet(env[constants.environmentVariables.gitpod])) {\n return {platform: 'gitpod', editor: true}\n }\n if (isSpin(env)) {\n return {platform: 'spin', editor: false}\n }\n return {platform: 'localhost', editor: false}\n}\n\n/**\n * Returns whether the environment has Git available.\n *\n * @returns A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The CI platform info.\n */\nexport function ciPlatform(env = process.env): {isCI: true; name: string} | {isCI: false; name?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n }\n\n return {\n isCI: true,\n name,\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Returns the first mac address found.\n *\n * @returns Mac address.\n */\nexport function macAddress(): Promise<string> {\n return macaddress.one()\n}\n"]}
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../src/public/node/environment/local.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy, isSet} from '../../../private/node/environment/utilities.js'\nimport {environmentVariables, pathConstants} from '../../../private/node/constants.js'\nimport {fileExists} from '../fs.js'\nimport {exec} from '../system.js'\nimport {isSpin} from '../environment/spin.js'\nimport isInteractive from 'is-interactive'\nimport macaddress from 'macaddress'\nimport {homedir} from 'os'\n\n/**\n * It returns true if the terminal is interactive.\n *\n * @returns True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n *\n * @returns The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_ENV is development.\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed.\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present) or a cloud environment (spin).\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {\n return !isTruthy(env[environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(pathConstants.executables.dev)\n return devInstalled || isSpin(env)\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/**\n * Returns true if reporting analytics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS is truthy.\n */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[environmentVariables.alwaysLogAnalytics])\n}\n\n/**\n * Returns true if the CLI User is 1P.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_1P is truthy.\n */\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[environmentVariables.firstPartyDev])\n}\n\n/**\n * Returns true if the CLI should use device auth.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_DEVICE_AUTH is truthy or the CLI is run from a cloud environment.\n */\nexport function useDeviceAuth(env = process.env): boolean {\n return isTruthy(env[environmentVariables.deviceAuth]) || isCloudEnvironment(env)\n}\n\n/**\n * Returns true if the CLI should use theme bundling.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_THEME_BUNDLING is truthy.\n */\nexport function useThemeBundling(env = process.env): boolean {\n return isTruthy(env[environmentVariables.themeBundling])\n}\n\n/**\n * Return gitpodURL if we are running in gitpod.\n * Https://www.gitpod.io/docs/environment-variables#default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The gitpod URL.\n */\nexport function gitpodURL(env = process.env): string | undefined {\n return env[environmentVariables.gitpod]\n}\n\n/**\n * Return codespaceURL if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace URL.\n */\nexport function codespaceURL(env = process.env): string | undefined {\n return env[environmentVariables.codespaceName]\n}\n\n/**\n * Checks if the CLI is run from a cloud environment.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns True in case the CLI is run from a cloud environment.\n */\nexport function isCloudEnvironment(env: NodeJS.ProcessEnv = process.env): boolean {\n return cloudEnvironment(env).platform !== 'localhost'\n}\n\n/**\n * Returns the cloud environment platform name and if the platform support online IDE in case the CLI is run from one of\n * them. Platform name 'localhost' is returned otherwise.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns Cloud platform information.\n */\nexport function cloudEnvironment(env: NodeJS.ProcessEnv = process.env): {\n platform: 'spin' | 'codespaces' | 'gitpod' | 'localhost'\n editor: boolean\n} {\n if (isSet(env[environmentVariables.codespaces])) {\n return {platform: 'codespaces', editor: true}\n }\n if (isSet(env[environmentVariables.gitpod])) {\n return {platform: 'gitpod', editor: true}\n }\n if (isSpin(env)) {\n return {platform: 'spin', editor: false}\n }\n return {platform: 'localhost', editor: false}\n}\n\n/**\n * Returns whether the environment has Git available.\n *\n * @returns A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The CI platform info.\n */\nexport function ciPlatform(env = process.env): {isCI: true; name: string} | {isCI: false; name?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n }\n\n return {\n isCI: true,\n name,\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Returns the first mac address found.\n *\n * @returns Mac address.\n */\nexport function macAddress(): Promise<string> {\n return macaddress.one()\n}\n"]}
@@ -1,8 +1,8 @@
1
+ import { fileExists, readFileSync } from '../fs.js';
1
2
  import { isTruthy } from '../../../private/node/environment/utilities.js';
2
- import constants from '../../../constants.js';
3
+ import { environmentVariables } from '../../../private/node/constants.js';
3
4
  import { captureOutput } from '../system.js';
4
5
  import { content, token } from '../../../output.js';
5
- import { exists, readSync } from '../../../file.js';
6
6
  import { getCachedSpinFqdn, setCachedSpinFqdn } from '../../../private/node/environment/spin-cache.js';
7
7
  import { Abort } from '../../../error.js';
8
8
  import { Environment, serviceEnvironment } from '../../../private/node/environment/service.js';
@@ -30,8 +30,8 @@ export async function spinFqdn(env = process.env) {
30
30
  let spinFqdn = getCachedSpinFqdn();
31
31
  if (spinFqdn)
32
32
  return spinFqdn;
33
- if (await exists(spinFqdnFilePath)) {
34
- spinFqdn = await readSync(spinFqdnFilePath).toString();
33
+ if (await fileExists(spinFqdnFilePath)) {
34
+ spinFqdn = await readFileSync(spinFqdnFilePath).toString();
35
35
  }
36
36
  else {
37
37
  const spinInstance = await instance(env);
@@ -69,7 +69,7 @@ export async function show(spinInstance, env = process.env) {
69
69
  * @returns True if the CLI is running in a Spin environment.
70
70
  */
71
71
  export function isSpin(env = process.env) {
72
- return isTruthy(env[constants.environmentVariables.spin]);
72
+ return isTruthy(env[environmentVariables.spin]);
73
73
  }
74
74
  /**
75
75
  * Returns the value of the SPIN_INSTANCE environment variable.
@@ -78,7 +78,7 @@ export function isSpin(env = process.env) {
78
78
  * @returns The value of the SPIN_INSTANCE environment variable.
79
79
  */
80
80
  export function instance(env = process.env) {
81
- return env[constants.environmentVariables.spinInstance];
81
+ return env[environmentVariables.spinInstance];
82
82
  }
83
83
  /**
84
84
  * Returns true if the CLI is running in a Spin environment.
@@ -1 +1 @@
1
- {"version":3,"file":"spin.js","sourceRoot":"","sources":["../../../../src/public/node/environment/spin.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from '../../../private/node/environment/utilities.js'\nimport constants from '../../../constants.js'\nimport {captureOutput} from '../system.js'\nimport {content, token} from '../../../output.js'\nimport {exists, readSync} from '../../../file.js'\nimport {getCachedSpinFqdn, setCachedSpinFqdn} from '../../../private/node/environment/spin-cache.js'\nimport {Abort} from '../../../error.js'\nimport {Environment, serviceEnvironment} from '../../../private/node/environment/service.js'\n\nconst SpinInstanceNotFoundMessages = (spinInstance: string | undefined, error: string) => {\n const errorMessage = content`${token.genericShellCommand(\n `spin`,\n )} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:\n${error}\n `\n let nextSteps: string | undefined\n if (spinInstance) {\n nextSteps = `Make sure ${spinInstance} is the instance name and not a fully qualified domain name`\n }\n return {errorMessage, nextSteps}\n}\n\nconst spinFqdnFilePath = '/etc/spin/machine/fqdn'\n\n/**\n * When ran in a Spin environment, it returns the fqdn of the instance.\n *\n * Will cache the value of the Spin FQDN during the execution of the CLI.\n * To avoid multiple calls to `readSync` or `show`.\n *\n * @param env - Environment variables.\n * @returns Fqdn of the Spin environment.\n */\nexport async function spinFqdn(env = process.env): Promise<string> {\n let spinFqdn = getCachedSpinFqdn()\n if (spinFqdn) return spinFqdn\n\n if (await exists(spinFqdnFilePath)) {\n spinFqdn = await readSync(spinFqdnFilePath).toString()\n } else {\n const spinInstance = await instance(env)\n const showResponse = await show(spinInstance, env)\n\n spinFqdn = showResponse.fqdn\n }\n setCachedSpinFqdn(spinFqdn)\n return spinFqdn\n}\n\n/**\n * Runs \"spin show\" and returns the JSON-parsed output.\n *\n * @param spinInstance - When it's undefined, we'll fetch the latest one.\n * @param env - Environment variables.\n * @returns The JSON-parsed output of the Spin CLI.\n * @throws Any error raised from the underlying Spin CLI.\n */\nexport async function show(spinInstance: string | undefined, env = process.env): Promise<{fqdn: string}> {\n const latest = spinInstance === undefined\n const args = latest ? ['show', '--latest', '--json'] : ['show', '--json']\n const output = await captureOutput('spin', args, {env})\n const json = JSON.parse(output)\n if (json.error) {\n const {errorMessage, nextSteps} = SpinInstanceNotFoundMessages(spinInstance, json.error)\n throw new Abort(errorMessage, nextSteps)\n } else {\n return json\n }\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n *\n * @param env - Environment variables.\n * @returns True if the CLI is running in a Spin environment.\n */\nexport function isSpin(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.spin])\n}\n\n/**\n * Returns the value of the SPIN_INSTANCE environment variable.\n *\n * @param env - Environment variables.\n * @returns The value of the SPIN_INSTANCE environment variable.\n */\nexport function instance(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinInstance]\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n *\n * @param env - Environment variables.\n * @returns True if the CLI is running in a Spin environment.\n */\nexport function isSpinEnvironment(env = process.env): boolean {\n return serviceEnvironment(env) === Environment.Spin\n}\n"]}
1
+ {"version":3,"file":"spin.js","sourceRoot":"","sources":["../../../../src/public/node/environment/spin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,MAAM,UAAU,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,gDAAgD,CAAA;AACvE,OAAO,EAAC,oBAAoB,EAAC,MAAM,oCAAoC,CAAA;AACvE,OAAO,EAAC,aAAa,EAAC,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,iDAAiD,CAAA;AACpG,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,8CAA8C,CAAA;AAE5F,MAAM,4BAA4B,GAAG,CAAC,YAAgC,EAAE,KAAa,EAAE,EAAE;IACvF,MAAM,YAAY,GAAG,OAAO,CAAA,GAAG,KAAK,CAAC,mBAAmB,CACtD,MAAM,CACP;EACD,KAAK;GACJ,CAAA;IACD,IAAI,SAA6B,CAAA;IACjC,IAAI,YAAY,EAAE;QAChB,SAAS,GAAG,aAAa,YAAY,6DAA6D,CAAA;KACnG;IACD,OAAO,EAAC,YAAY,EAAE,SAAS,EAAC,CAAA;AAClC,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,wBAAwB,CAAA;AAEjD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC9C,IAAI,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IAClC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAE7B,IAAI,MAAM,UAAU,CAAC,gBAAgB,CAAC,EAAE;QACtC,QAAQ,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAA;KAC3D;SAAM;QACL,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;QAElD,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAA;KAC7B;IACD,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC3B,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,YAAgC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG;IAC5E,MAAM,MAAM,GAAG,YAAY,KAAK,SAAS,CAAA;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACzE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,EAAC,GAAG,EAAC,CAAC,CAAA;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC/B,IAAI,IAAI,CAAC,KAAK,EAAE;QACd,MAAM,EAAC,YAAY,EAAE,SAAS,EAAC,GAAG,4BAA4B,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QACxF,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;KACzC;SAAM;QACL,OAAO,IAAI,CAAA;KACZ;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACtC,OAAO,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACxC,OAAO,GAAG,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACjD,OAAO,kBAAkB,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,IAAI,CAAA;AACrD,CAAC","sourcesContent":["import {fileExists, readFileSync} from '../fs.js'\nimport {isTruthy} from '../../../private/node/environment/utilities.js'\nimport {environmentVariables} from '../../../private/node/constants.js'\nimport {captureOutput} from '../system.js'\nimport {content, token} from '../../../output.js'\nimport {getCachedSpinFqdn, setCachedSpinFqdn} from '../../../private/node/environment/spin-cache.js'\nimport {Abort} from '../../../error.js'\nimport {Environment, serviceEnvironment} from '../../../private/node/environment/service.js'\n\nconst SpinInstanceNotFoundMessages = (spinInstance: string | undefined, error: string) => {\n const errorMessage = content`${token.genericShellCommand(\n `spin`,\n )} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:\n${error}\n `\n let nextSteps: string | undefined\n if (spinInstance) {\n nextSteps = `Make sure ${spinInstance} is the instance name and not a fully qualified domain name`\n }\n return {errorMessage, nextSteps}\n}\n\nconst spinFqdnFilePath = '/etc/spin/machine/fqdn'\n\n/**\n * When ran in a Spin environment, it returns the fqdn of the instance.\n *\n * Will cache the value of the Spin FQDN during the execution of the CLI.\n * To avoid multiple calls to `readSync` or `show`.\n *\n * @param env - Environment variables.\n * @returns Fqdn of the Spin environment.\n */\nexport async function spinFqdn(env = process.env): Promise<string> {\n let spinFqdn = getCachedSpinFqdn()\n if (spinFqdn) return spinFqdn\n\n if (await fileExists(spinFqdnFilePath)) {\n spinFqdn = await readFileSync(spinFqdnFilePath).toString()\n } else {\n const spinInstance = await instance(env)\n const showResponse = await show(spinInstance, env)\n\n spinFqdn = showResponse.fqdn\n }\n setCachedSpinFqdn(spinFqdn)\n return spinFqdn\n}\n\n/**\n * Runs \"spin show\" and returns the JSON-parsed output.\n *\n * @param spinInstance - When it's undefined, we'll fetch the latest one.\n * @param env - Environment variables.\n * @returns The JSON-parsed output of the Spin CLI.\n * @throws Any error raised from the underlying Spin CLI.\n */\nexport async function show(spinInstance: string | undefined, env = process.env): Promise<{fqdn: string}> {\n const latest = spinInstance === undefined\n const args = latest ? ['show', '--latest', '--json'] : ['show', '--json']\n const output = await captureOutput('spin', args, {env})\n const json = JSON.parse(output)\n if (json.error) {\n const {errorMessage, nextSteps} = SpinInstanceNotFoundMessages(spinInstance, json.error)\n throw new Abort(errorMessage, nextSteps)\n } else {\n return json\n }\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n *\n * @param env - Environment variables.\n * @returns True if the CLI is running in a Spin environment.\n */\nexport function isSpin(env = process.env): boolean {\n return isTruthy(env[environmentVariables.spin])\n}\n\n/**\n * Returns the value of the SPIN_INSTANCE environment variable.\n *\n * @param env - Environment variables.\n * @returns The value of the SPIN_INSTANCE environment variable.\n */\nexport function instance(env = process.env): string | undefined {\n return env[environmentVariables.spinInstance]\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n *\n * @param env - Environment variables.\n * @returns True if the CLI is running in a Spin environment.\n */\nexport function isSpinEnvironment(env = process.env): boolean {\n return serviceEnvironment(env) === Environment.Spin\n}\n"]}
@@ -1,11 +1,12 @@
1
1
  import { reportAnalyticsEvent } from './analytics.js';
2
+ import * as path from './path.js';
2
3
  import { getEnvironmentData } from '../../private/node/analytics.js';
3
4
  import { AbortSilent, CancelExecution, mapper as errorMapper, shouldReport as shouldReportError, handler, cleanSingleStackTracePath, } from '../../error.js';
4
5
  import { debug, info } from '../../output.js';
5
- import * as path from '../../path.js';
6
6
  import * as metadata from '../../metadata.js';
7
7
  import { fanoutHooks } from '../../plugins.js';
8
- import constants, { bugsnagApiKey } from '../../constants.js';
8
+ import { bugsnagApiKey } from '../../private/node/constants.js';
9
+ import { CLI_KIT_VERSION } from '../common/version.js';
9
10
  import { settings } from '@oclif/core';
10
11
  import StackTracey from 'stacktracey';
11
12
  import Bugsnag from '@bugsnag/js';
@@ -78,7 +79,7 @@ export async function sendErrorToBugsnag(error) {
78
79
  .join('\n');
79
80
  reportableError.stack = `Error: ${reportableError.message}\n${formattedStacktrace}`;
80
81
  if (report) {
81
- await initializeBugsnag();
82
+ initializeBugsnag();
82
83
  await new Promise((resolve, reject) => {
83
84
  Bugsnag.notify(reportableError, undefined, (error, event) => {
84
85
  if (error) {
@@ -99,11 +100,13 @@ export async function sendErrorToBugsnag(error) {
99
100
  * This gives us very consistent paths for errors generated by the CLI.
100
101
  */
101
102
  export function cleanStackFrameFilePath({ currentFilePath, projectRoot, pluginLocations, }) {
102
- const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath);
103
+ const fullLocation = path.isAbsolutePath(currentFilePath)
104
+ ? currentFilePath
105
+ : path.joinPath(projectRoot, currentFilePath);
103
106
  const matchingPluginPath = pluginLocations.filter(({ pluginPath }) => fullLocation.indexOf(pluginPath) === 0)[0];
104
107
  if (matchingPluginPath !== undefined) {
105
108
  // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )
106
- return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation));
109
+ return path.joinPath(matchingPluginPath.name, path.relativePath(matchingPluginPath.pluginPath, fullLocation));
107
110
  }
108
111
  // strip prefix up to node_modules folder, so we can normalize error reporting
109
112
  return currentFilePath.replace(/.*node_modules\//, '');
@@ -116,12 +119,12 @@ export async function registerCleanBugsnagErrorsFromWithinPlugins(config) {
116
119
  // Bugsnag have their own plug-ins that use this private field
117
120
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
121
  const bugsnagConfigProjectRoot = Bugsnag?._client?._config?.projectRoot ?? process.cwd();
119
- const projectRoot = path.normalize(bugsnagConfigProjectRoot);
122
+ const projectRoot = path.normalizePath(bugsnagConfigProjectRoot);
120
123
  const pluginLocations = await Promise.all(config.plugins.map(async (plugin) => {
121
124
  const followSymlinks = await realpath(plugin.root);
122
- return { name: plugin.name, pluginPath: path.normalize(followSymlinks) };
125
+ return { name: plugin.name, pluginPath: path.normalizePath(followSymlinks) };
123
126
  }));
124
- await initializeBugsnag();
127
+ initializeBugsnag();
125
128
  Bugsnag.addOnError(async (event) => {
126
129
  event.errors.forEach((error) => {
127
130
  error.stacktrace.forEach((stackFrame) => {
@@ -182,7 +185,7 @@ export async function addBugsnagMetadata(event, config) {
182
185
  event.addMetadata(section, values);
183
186
  });
184
187
  }
185
- async function initializeBugsnag() {
188
+ function initializeBugsnag() {
186
189
  if (Bugsnag.isStarted()) {
187
190
  return;
188
191
  }
@@ -190,7 +193,7 @@ async function initializeBugsnag() {
190
193
  appType: 'node',
191
194
  apiKey: bugsnagApiKey,
192
195
  logger: null,
193
- appVersion: await constants.versions.cliKit(),
196
+ appVersion: CLI_KIT_VERSION,
194
197
  autoTrackSessions: false,
195
198
  autoDetectErrors: false,
196
199
  });
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/public/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {reportAnalyticsEvent} from './analytics.js'\nimport {getEnvironmentData} from '../../private/node/analytics.js'\nimport {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../../error.js'\nimport {debug, info} from '../../output.js'\nimport * as path from '../../path.js'\nimport * as metadata from '../../metadata.js'\nimport {fanoutHooks} from '../../plugins.js'\nimport constants, {bugsnagApiKey} from '../../constants.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(\n error: (CancelExecution | AbortSilent) & {exitCode?: number | undefined},\n config?: Interfaces.Config,\n): void\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): Promise<void>\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): unknown {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportAnalyticsEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await initializeBugsnag()\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path is within a node_modules folder, remove prefix up\n * to and including the node_modules folder.\n *\n * This gives us very consistent paths for errors generated by the CLI.\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n\n // strip prefix up to node_modules folder, so we can normalize error reporting\n return currentFilePath.replace(/.*node_modules\\//, '')\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config): Promise<void> {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n await initializeBugsnag()\n Bugsnag.addOnError(async (event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport async function addBugsnagMetadata(event: Event, config: Interfaces.Config): Promise<void> {\n const publicData = metadata.getAllPublic()\n const {commandStartOptions} = metadata.getAllSensitive()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = await getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n\nasync function initializeBugsnag() {\n if (Bugsnag.isStarted()) {\n return\n }\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: await constants.versions.cliKit(),\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n}\n"]}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/public/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {reportAnalyticsEvent} from './analytics.js'\nimport * as path from './path.js'\nimport {getEnvironmentData} from '../../private/node/analytics.js'\nimport {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../../error.js'\nimport {debug, info} from '../../output.js'\nimport * as metadata from '../../metadata.js'\nimport {fanoutHooks} from '../../plugins.js'\nimport {bugsnagApiKey} from '../../private/node/constants.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(\n error: (CancelExecution | AbortSilent) & {exitCode?: number | undefined},\n config?: Interfaces.Config,\n): void\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): Promise<void>\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): unknown {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportAnalyticsEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n initializeBugsnag()\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path is within a node_modules folder, remove prefix up\n * to and including the node_modules folder.\n *\n * This gives us very consistent paths for errors generated by the CLI.\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolutePath(currentFilePath)\n ? currentFilePath\n : path.joinPath(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.joinPath(matchingPluginPath.name, path.relativePath(matchingPluginPath.pluginPath, fullLocation))\n }\n\n // strip prefix up to node_modules folder, so we can normalize error reporting\n return currentFilePath.replace(/.*node_modules\\//, '')\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config): Promise<void> {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalizePath(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalizePath(followSymlinks)}\n }),\n )\n initializeBugsnag()\n Bugsnag.addOnError(async (event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport async function addBugsnagMetadata(event: Event, config: Interfaces.Config): Promise<void> {\n const publicData = metadata.getAllPublic()\n const {commandStartOptions} = metadata.getAllSensitive()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = await getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n\nfunction initializeBugsnag() {\n if (Bugsnag.isStarted()) {\n return\n }\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: CLI_KIT_VERSION,\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { join as pathJoin } from '../../path.js';
1
+ import { joinPath } from './path.js';
2
2
  import { existsSync, readFileSync } from 'fs';
3
3
  const frameworks = [
4
4
  {
@@ -124,7 +124,7 @@ function loadFwConfigFile(rootPath, fwConfigFileName, fwConfigFiles = {}) {
124
124
  if (fwConfigFiles[fwConfigFileName]) {
125
125
  return fwConfigFiles;
126
126
  }
127
- const fwConfigFilePath = pathJoin(rootPath, fwConfigFileName);
127
+ const fwConfigFilePath = joinPath(rootPath, fwConfigFileName);
128
128
  if (!existsSync(fwConfigFilePath)) {
129
129
  return fwConfigFiles;
130
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"framework.js","sourceRoot":"","sources":["../../../src/public/node/framework.ts"],"names":[],"mappings":"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","sourcesContent":["import {join as pathJoin} from '../../path.js'\nimport {existsSync, readFileSync} from 'fs'\n\ninterface FrameworkDetectionPattern {\n /**\n * @example A file path\n * ```\n * \"package.json\"\n * ```\n */\n path: string\n /**\n * @example A matcher\n * ```\n * \"\\\"(dev)?(d|D)ependencies\\\":\\\\s*{[^}]*\\\"next\\\":\\\\s*\\\".+?\\\"[^}]*}\"\n * ```\n */\n matchContent?: string\n}\n\ninterface Framework {\n /**\n * Name of the framework\n * @example \"nextjs\"\n */\n name: string\n\n /**\n * Detectors used to find out the framework\n */\n detectors: {\n /**\n * Collection of detectors that must be matched for the framework\n * to be detected.\n */\n every?: FrameworkDetectionPattern[]\n /**\n * Collection of detectors where one match triggers the framework\n * to be detected.\n */\n some?: FrameworkDetectionPattern[]\n }\n}\n\nconst frameworks: Framework[] = [\n {\n name: 'remix',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"@remix-run\\\\/.*\":\\\\s*\".+?\"[^}]*}',\n },\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"react\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'nextjs',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"next\":\\\\s*\".+?\"[^}]*}',\n },\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"react\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'express',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"express\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'rails',\n detectors: {\n every: [\n {\n path: 'Gemfile',\n matchContent: 'gem \"rails\"',\n },\n ],\n },\n },\n {\n name: 'flask',\n detectors: {\n every: [\n {\n path: 'Pipfile',\n matchContent: 'flask',\n },\n ],\n },\n },\n {\n name: 'django',\n detectors: {\n every: [\n {\n path: 'Pipfile',\n matchContent: 'django',\n },\n ],\n },\n },\n {\n name: 'laravel',\n detectors: {\n every: [\n {\n path: 'composer.json',\n matchContent: '\"require\":\\\\s*{[^}]*\"laravel/framework\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'symfony',\n detectors: {\n every: [\n {\n path: 'composer.json',\n matchContent: '\"require\":\\\\s*{[^}]*\"symfony\\\\/.*\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n]\n\n/**\n * Tries to identify the using of a framework analyzing the existence and/or content of different files inside a\n * specific directory.\n *\n * @param rootDirectory - Directory from which the files required for each framework are searched\n * @returns The name of the framework used or 'unknown' otherwise\n */\nexport async function resolveFramework(rootDirectory: string): Promise<string> {\n const fwConfigFiles: {[key: string]: string | undefined} = {}\n\n const matchedFramework = frameworks.find(\n (framework) =>\n (!framework.detectors?.some ||\n framework.detectors?.some?.reduce(\n (_previousDetectorsMatch: boolean, detector) =>\n matchDetector(detector, loadFwConfigFile(rootDirectory, detector.path, fwConfigFiles)),\n false,\n )) &&\n (!framework.detectors?.every ||\n framework.detectors?.every?.reduce(\n (previousDetectorsMatch: boolean, detector) =>\n previousDetectorsMatch\n ? matchDetector(detector, loadFwConfigFile(rootDirectory, detector.path, fwConfigFiles))\n : false,\n true,\n )),\n )\n\n return matchedFramework ? matchedFramework.name : 'unknown'\n}\n\nfunction matchDetector(detector: FrameworkDetectionPattern, fwConfigFiles: {[key: string]: string | undefined} = {}) {\n if (!fwConfigFiles[detector.path]) return false\n\n return !detector.matchContent || new RegExp(detector.matchContent).test(fwConfigFiles[detector.path]!)\n}\n\nfunction loadFwConfigFile(\n rootPath: string,\n fwConfigFileName: string,\n fwConfigFiles: {[key: string]: string | undefined} = {},\n) {\n if (fwConfigFiles[fwConfigFileName]) {\n return fwConfigFiles\n }\n\n const fwConfigFilePath = pathJoin(rootPath, fwConfigFileName)\n if (!existsSync(fwConfigFilePath)) {\n return fwConfigFiles\n }\n\n const rawContent = readFileSync(fwConfigFilePath, {encoding: 'utf8'})\n\n fwConfigFiles[fwConfigFileName] = rawContent\n return fwConfigFiles\n}\n"]}
1
+ {"version":3,"file":"framework.js","sourceRoot":"","sources":["../../../src/public/node/framework.ts"],"names":[],"mappings":"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","sourcesContent":["import {joinPath} from './path.js'\nimport {existsSync, readFileSync} from 'fs'\n\ninterface FrameworkDetectionPattern {\n /**\n * @example A file path\n * ```\n * \"package.json\"\n * ```\n */\n path: string\n /**\n * @example A matcher\n * ```\n * \"\\\"(dev)?(d|D)ependencies\\\":\\\\s*{[^}]*\\\"next\\\":\\\\s*\\\".+?\\\"[^}]*}\"\n * ```\n */\n matchContent?: string\n}\n\ninterface Framework {\n /**\n * Name of the framework\n * @example \"nextjs\"\n */\n name: string\n\n /**\n * Detectors used to find out the framework\n */\n detectors: {\n /**\n * Collection of detectors that must be matched for the framework\n * to be detected.\n */\n every?: FrameworkDetectionPattern[]\n /**\n * Collection of detectors where one match triggers the framework\n * to be detected.\n */\n some?: FrameworkDetectionPattern[]\n }\n}\n\nconst frameworks: Framework[] = [\n {\n name: 'remix',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"@remix-run\\\\/.*\":\\\\s*\".+?\"[^}]*}',\n },\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"react\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'nextjs',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"next\":\\\\s*\".+?\"[^}]*}',\n },\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"react\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'express',\n detectors: {\n every: [\n {\n path: 'package.json',\n matchContent: '\"(dev)?(d|D)ependencies\":\\\\s*{[^}]*\"express\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'rails',\n detectors: {\n every: [\n {\n path: 'Gemfile',\n matchContent: 'gem \"rails\"',\n },\n ],\n },\n },\n {\n name: 'flask',\n detectors: {\n every: [\n {\n path: 'Pipfile',\n matchContent: 'flask',\n },\n ],\n },\n },\n {\n name: 'django',\n detectors: {\n every: [\n {\n path: 'Pipfile',\n matchContent: 'django',\n },\n ],\n },\n },\n {\n name: 'laravel',\n detectors: {\n every: [\n {\n path: 'composer.json',\n matchContent: '\"require\":\\\\s*{[^}]*\"laravel/framework\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n {\n name: 'symfony',\n detectors: {\n every: [\n {\n path: 'composer.json',\n matchContent: '\"require\":\\\\s*{[^}]*\"symfony\\\\/.*\":\\\\s*\".+?\"[^}]*}',\n },\n ],\n },\n },\n]\n\n/**\n * Tries to identify the using of a framework analyzing the existence and/or content of different files inside a\n * specific directory.\n *\n * @param rootDirectory - Directory from which the files required for each framework are searched\n * @returns The name of the framework used or 'unknown' otherwise\n */\nexport async function resolveFramework(rootDirectory: string): Promise<string> {\n const fwConfigFiles: {[key: string]: string | undefined} = {}\n\n const matchedFramework = frameworks.find(\n (framework) =>\n (!framework.detectors?.some ||\n framework.detectors?.some?.reduce(\n (_previousDetectorsMatch: boolean, detector) =>\n matchDetector(detector, loadFwConfigFile(rootDirectory, detector.path, fwConfigFiles)),\n false,\n )) &&\n (!framework.detectors?.every ||\n framework.detectors?.every?.reduce(\n (previousDetectorsMatch: boolean, detector) =>\n previousDetectorsMatch\n ? matchDetector(detector, loadFwConfigFile(rootDirectory, detector.path, fwConfigFiles))\n : false,\n true,\n )),\n )\n\n return matchedFramework ? matchedFramework.name : 'unknown'\n}\n\nfunction matchDetector(detector: FrameworkDetectionPattern, fwConfigFiles: {[key: string]: string | undefined} = {}) {\n if (!fwConfigFiles[detector.path]) return false\n\n return !detector.matchContent || new RegExp(detector.matchContent).test(fwConfigFiles[detector.path]!)\n}\n\nfunction loadFwConfigFile(\n rootPath: string,\n fwConfigFileName: string,\n fwConfigFiles: {[key: string]: string | undefined} = {},\n) {\n if (fwConfigFiles[fwConfigFileName]) {\n return fwConfigFiles\n }\n\n const fwConfigFilePath = joinPath(rootPath, fwConfigFileName)\n if (!existsSync(fwConfigFilePath)) {\n return fwConfigFiles\n }\n\n const rawContent = readFileSync(fwConfigFilePath, {encoding: 'utf8'})\n\n fwConfigFiles[fwConfigFileName] = rawContent\n return fwConfigFiles\n}\n"]}