@shopify/cli-kit 3.43.0 → 3.44.1-pre.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 (140) hide show
  1. package/README.md +15 -7
  2. package/assets/cli-ruby/Gemfile +6 -3
  3. package/assets/cli-ruby/lib/project_types/extension/commands/serve.rb +10 -0
  4. package/assets/cli-ruby/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +1 -1
  5. package/assets/cli-ruby/lib/project_types/theme/cli.rb +1 -0
  6. package/assets/cli-ruby/lib/project_types/theme/commands/common/root_helper.rb +3 -2
  7. package/assets/cli-ruby/lib/project_types/theme/commands/console.rb +15 -0
  8. package/assets/cli-ruby/lib/project_types/theme/commands/push.rb +1 -0
  9. package/assets/cli-ruby/lib/project_types/theme/messages/messages.rb +4 -2
  10. package/assets/cli-ruby/lib/shopify_cli/constants.rb +1 -0
  11. package/assets/cli-ruby/lib/shopify_cli/environment.rb +4 -0
  12. package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/hot_reload/script_injector.rb +1 -1
  13. package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/hot_reload.rb +9 -2
  14. package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/proxy.rb +13 -12
  15. package/assets/cli-ruby/lib/shopify_cli/theme/dev_server.rb +2 -2
  16. package/assets/cli-ruby/lib/shopify_cli/theme/extension/dev_server.rb +7 -4
  17. package/assets/cli-ruby/lib/shopify_cli/theme/extension/host_theme.rb +19 -14
  18. package/assets/cli-ruby/lib/shopify_cli/theme/repl/api.rb +107 -0
  19. package/assets/cli-ruby/lib/shopify_cli/theme/repl/auth_dev_server.rb +80 -0
  20. package/assets/cli-ruby/lib/shopify_cli/theme/repl/auth_middleware.rb +73 -0
  21. package/assets/cli-ruby/lib/shopify_cli/theme/repl/resources/success.html +79 -0
  22. package/assets/cli-ruby/lib/shopify_cli/theme/repl/resources/template.liquid +15 -0
  23. package/assets/cli-ruby/lib/shopify_cli/theme/repl.rb +145 -0
  24. package/assets/cli-ruby/lib/shopify_cli/theme/syncer/standard_reporter.rb +2 -2
  25. package/assets/cli-ruby/lib/shopify_cli/theme/syncer.rb +1 -1
  26. package/assets/cli-ruby/lib/shopify_cli/theme/theme.rb +6 -6
  27. package/dist/private/node/analytics.d.ts +2 -2
  28. package/dist/private/node/analytics.js.map +1 -1
  29. package/dist/private/node/api/graphql.js +9 -16
  30. package/dist/private/node/api/graphql.js.map +1 -1
  31. package/dist/private/node/api/headers.js +8 -5
  32. package/dist/private/node/api/headers.js.map +1 -1
  33. package/dist/private/node/api.d.ts +9 -0
  34. package/dist/private/node/api.js +19 -0
  35. package/dist/private/node/api.js.map +1 -1
  36. package/dist/private/node/colors.js.map +1 -0
  37. package/dist/private/node/conf-store.d.ts +24 -5
  38. package/dist/private/node/conf-store.js +21 -3
  39. package/dist/private/node/conf-store.js.map +1 -1
  40. package/dist/private/node/constants.d.ts +2 -0
  41. package/dist/private/node/constants.js +2 -0
  42. package/dist/private/node/constants.js.map +1 -1
  43. package/dist/private/node/content-tokens.js +1 -1
  44. package/dist/private/node/content-tokens.js.map +1 -1
  45. package/dist/private/node/semver.js.map +1 -0
  46. package/dist/private/node/session/identity-token-validation.d.ts +1 -1
  47. package/dist/private/node/session/identity-token-validation.js +45 -20
  48. package/dist/private/node/session/identity-token-validation.js.map +1 -1
  49. package/dist/private/node/session/store.js +3 -46
  50. package/dist/private/node/session/store.js.map +1 -1
  51. package/dist/private/node/session.js +13 -10
  52. package/dist/private/node/session.js.map +1 -1
  53. package/dist/private/node/themes/generate-theme-name.js.map +1 -0
  54. package/dist/private/node/themes/replace-invalid-characters.js.map +1 -0
  55. package/dist/private/node/themes/themes-api/headers.js.map +1 -0
  56. package/dist/private/node/themes/themes-api/retry.js.map +1 -0
  57. package/dist/private/node/themes/themes-api/throttler.js.map +1 -0
  58. package/dist/private/node/ui/components/ConcurrentOutput.d.ts +0 -1
  59. package/dist/private/node/ui/components/ConcurrentOutput.js +0 -1
  60. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  61. package/dist/public/common/string.d.ts +16 -4
  62. package/dist/public/common/string.js +25 -4
  63. package/dist/public/common/string.js.map +1 -1
  64. package/dist/public/common/ts/deep-required.d.ts +0 -1
  65. package/dist/public/common/ts/deep-required.js.map +1 -1
  66. package/dist/public/common/ts/pick-by-prefix.d.ts +0 -1
  67. package/dist/public/common/ts/pick-by-prefix.js.map +1 -1
  68. package/dist/public/common/version.d.ts +1 -1
  69. package/dist/public/common/version.js +1 -1
  70. package/dist/public/common/version.js.map +1 -1
  71. package/dist/public/node/base-command.d.ts +8 -5
  72. package/dist/public/node/base-command.js +1 -1
  73. package/dist/public/node/base-command.js.map +1 -1
  74. package/dist/public/node/cli.d.ts +1 -1
  75. package/dist/public/node/cli.js +0 -1
  76. package/dist/public/node/cli.js.map +1 -1
  77. package/dist/public/node/context/spin.d.ts +14 -0
  78. package/dist/public/node/context/spin.js +19 -0
  79. package/dist/public/node/context/spin.js.map +1 -1
  80. package/dist/public/node/environment.d.ts +12 -0
  81. package/dist/public/node/environment.js +14 -0
  82. package/dist/public/node/environment.js.map +1 -0
  83. package/dist/public/node/fs.d.ts +8 -12
  84. package/dist/public/node/fs.js +11 -35
  85. package/dist/public/node/fs.js.map +1 -1
  86. package/dist/public/node/http.js +5 -10
  87. package/dist/public/node/http.js.map +1 -1
  88. package/dist/public/node/local-storage.d.ts +37 -0
  89. package/dist/public/node/local-storage.js +44 -0
  90. package/dist/public/node/local-storage.js.map +1 -0
  91. package/dist/public/node/node-package-manager.js +1 -1
  92. package/dist/public/node/node-package-manager.js.map +1 -1
  93. package/dist/public/node/output.d.ts +0 -1
  94. package/dist/public/node/output.js +1 -2
  95. package/dist/public/node/output.js.map +1 -1
  96. package/dist/public/node/path.d.ts +58 -2
  97. package/dist/public/node/path.js +75 -3
  98. package/dist/public/node/path.js.map +1 -1
  99. package/dist/public/node/ruby.d.ts +2 -1
  100. package/dist/public/node/ruby.js +85 -31
  101. package/dist/public/node/ruby.js.map +1 -1
  102. package/dist/public/node/themes/conf.d.ts +12 -0
  103. package/dist/public/node/themes/conf.js +24 -0
  104. package/dist/public/node/themes/conf.js.map +1 -0
  105. package/dist/public/node/themes/theme-manager.js +1 -1
  106. package/dist/public/node/themes/theme-manager.js.map +1 -1
  107. package/dist/public/node/themes/themes-api.js +3 -3
  108. package/dist/public/node/themes/themes-api.js.map +1 -1
  109. package/dist/tsconfig.tsbuildinfo +1 -1
  110. package/package.json +9 -8
  111. package/dist/private/node/secure-store.d.ts +0 -19
  112. package/dist/private/node/secure-store.js +0 -63
  113. package/dist/private/node/secure-store.js.map +0 -1
  114. package/dist/public/node/colors.js.map +0 -1
  115. package/dist/public/node/conf.d.ts +0 -2
  116. package/dist/public/node/conf.js +0 -3
  117. package/dist/public/node/conf.js.map +0 -1
  118. package/dist/public/node/semver.js.map +0 -1
  119. package/dist/public/node/themes/generate-theme-name.js.map +0 -1
  120. package/dist/public/node/themes/replace-invalid-characters.js.map +0 -1
  121. package/dist/public/node/themes/themes-api/headers.js.map +0 -1
  122. package/dist/public/node/themes/themes-api/retry.js.map +0 -1
  123. package/dist/public/node/themes/themes-api/throttler.js.map +0 -1
  124. package/dist/store/schema.d.ts +0 -3
  125. package/dist/store/schema.js +0 -27
  126. package/dist/store/schema.js.map +0 -1
  127. /package/dist/{public → private}/node/colors.d.ts +0 -0
  128. /package/dist/{public → private}/node/colors.js +0 -0
  129. /package/dist/{public → private}/node/semver.d.ts +0 -0
  130. /package/dist/{public → private}/node/semver.js +0 -0
  131. /package/dist/{public → private}/node/themes/generate-theme-name.d.ts +0 -0
  132. /package/dist/{public → private}/node/themes/generate-theme-name.js +0 -0
  133. /package/dist/{public → private}/node/themes/replace-invalid-characters.d.ts +0 -0
  134. /package/dist/{public → private}/node/themes/replace-invalid-characters.js +0 -0
  135. /package/dist/{public → private}/node/themes/themes-api/headers.d.ts +0 -0
  136. /package/dist/{public → private}/node/themes/themes-api/headers.js +0 -0
  137. /package/dist/{public → private}/node/themes/themes-api/retry.d.ts +0 -0
  138. /package/dist/{public → private}/node/themes/themes-api/retry.js +0 -0
  139. /package/dist/{public → private}/node/themes/themes-api/throttler.d.ts +0 -0
  140. /package/dist/{public → private}/node/themes/themes-api/throttler.js +0 -0
@@ -0,0 +1,79 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Shopify CLI</title>
8
+ <style type="text/css">
9
+ html {
10
+ font-family: -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
11
+ text-size-adjust: 100%;
12
+ text-rendering: optimizeLegibility;
13
+ -webkit-font-smoothing: antialiased;
14
+ -moz-osx-font-smoothing: grayscale;
15
+ }
16
+
17
+ body {
18
+ font-size: 26px;
19
+ line-height: normal;
20
+ margin: 0;
21
+ padding: 0;
22
+ }
23
+
24
+ button, input, optgroup, select, textarea {
25
+ font-family: inherit;
26
+ }
27
+
28
+ h1 {
29
+ font-weight: 600;
30
+ font-size: 1em;
31
+ }
32
+
33
+ p {
34
+ font-weight: 400;
35
+ }
36
+
37
+ .body-success {
38
+ color: #F6F6F7;
39
+ }
40
+
41
+ .body-error {
42
+ color: #202223;
43
+ }
44
+
45
+ .app-success {
46
+ width: 100vw;
47
+ height: 100vh;
48
+ background-color: #054A49;
49
+ display: flex;
50
+ }
51
+
52
+ .app-error {
53
+ width: 100vw;
54
+ height: 100vh;
55
+ background-color: #F6F6F7;
56
+ display: flex;
57
+ }
58
+
59
+ .container {
60
+ display: flex;
61
+ flex-direction: column;
62
+ justify-content: center;
63
+ width: 100%;
64
+ height: 100%;
65
+ padding-left: 7.5em;
66
+ }
67
+ </style>
68
+ <link rel="icon" href="favicon.svg" sizes="any" type="image/svg+xml">
69
+ </head>
70
+
71
+ <body class="body-success">
72
+ <div class="app-success">
73
+ <div class="container">
74
+ <h1>You've successfully activated the Shopify Liquid session!</h1>
75
+ <p>You can close this tab and return to your terminal.</p>
76
+ </div>
77
+ </div>
78
+ </body>
79
+ </html>
@@ -0,0 +1,15 @@
1
+ {% schema %}
2
+ {
3
+ "name": "t:sections.announcement-bar.name",
4
+ "max_blocks": 12,
5
+ "blocks": [
6
+ {
7
+ "type": "announcement",
8
+ "name": "t:sections.announcement-bar.blocks.announcement.name"
9
+ }
10
+ ],
11
+ "default": {
12
+ "blocks": [{"type": "announcement"}]
13
+ }
14
+ }
15
+ {% endschema %}
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "readline"
4
+ require "json"
5
+ require "cgi"
6
+
7
+ require "shopify_cli/theme/dev_server"
8
+
9
+ require_relative "theme_admin_api"
10
+ require_relative "repl/api"
11
+ require_relative "repl/auth_dev_server"
12
+ require_relative "repl/auth_middleware"
13
+
14
+ module ShopifyCLI
15
+ module Theme
16
+ class Repl
17
+ attr_reader :ctx, :api, :storefront_digest, :secure_session_id
18
+
19
+ HOST = "localhost"
20
+ PORT = 9293
21
+
22
+ def initialize(ctx)
23
+ @ctx = ctx
24
+ @api = Api.new(ctx, self)
25
+ @session = []
26
+ end
27
+
28
+ def run
29
+ authenticate!
30
+
31
+ ctx.puts <<~MSG
32
+ Welcome to Shopify Liquid console
33
+ (press Ctrl + C to exit)
34
+
35
+ MSG
36
+
37
+ trap("INT") { raise ShopifyCLI::AbortSilent }
38
+ trap("TERM") { raise ShopifyCLI::AbortSilent }
39
+
40
+ loop do
41
+ input = Readline.readline("> ", true)
42
+ output = liquid_eval(input)
43
+
44
+ render(output)
45
+ rescue StandardError => error
46
+ ctx.puts("{{red:Shopify Liquid console error: #{error.message}}}")
47
+ ctx.debug(error.backtrace)
48
+ end
49
+ end
50
+
51
+ def authenticate(storefront_digest, secure_session_id)
52
+ @storefront_digest = storefront_digest
53
+ @secure_session_id = secure_session_id
54
+ end
55
+
56
+ private
57
+
58
+ def render(output)
59
+ output = output ? JSON.pretty_generate(output) : "nil"
60
+
61
+ ctx.puts("{{cyan:#{output}}}")
62
+ end
63
+
64
+ def url
65
+ "http://#{HOST}:#{PORT}"
66
+ end
67
+
68
+ def liquid_eval(liquid_snippet)
69
+ render_result(liquid_snippet) || render_context(liquid_snippet)
70
+ end
71
+
72
+ def render_result(liquid_snippet)
73
+ entry_str = as_rendered_json(liquid_snippet)
74
+ response = request(entry_str)
75
+
76
+ return nil unless success?(response)
77
+
78
+ json = json_from_response(response)
79
+ json.last["value"]
80
+ end
81
+
82
+ def render_context(liquid_snippet)
83
+ entry_str = as_context_json(liquid_snippet)
84
+ response = request(entry_str)
85
+
86
+ @session << JSON.parse(entry_str) if success?(response)
87
+
88
+ nil
89
+ end
90
+
91
+ def request(entry_str)
92
+ request_body = @session
93
+ .map(&:to_json)
94
+ .push(entry_str)
95
+ .join(",")
96
+
97
+ response = api.request("[#{request_body}]")
98
+
99
+ if unauthorized?(response) || forbidden?(response)
100
+ ctx.puts("{{red:Session expired.}}")
101
+ raise ShopifyCLI::AbortSilent
102
+ end
103
+
104
+ response
105
+ end
106
+
107
+ def success?(response)
108
+ response.code == "200"
109
+ end
110
+
111
+ def unauthorized?(response)
112
+ response.code == "401"
113
+ end
114
+
115
+ def forbidden?(response)
116
+ response.code == "403"
117
+ end
118
+
119
+ def json_from_response(response)
120
+ json_str = response.body.lines[1..-2].join.strip
121
+ JSON.parse(json_str)
122
+ end
123
+
124
+ def as_rendered_json(liquid_snippet)
125
+ as_json_str("render", "{{ #{liquid_snippet} | json }}")
126
+ end
127
+
128
+ def as_context_json(liquid_snippet)
129
+ as_json_str("context", "\"{% #{liquid_snippet} %}\"")
130
+ end
131
+
132
+ def as_json_str(type, value)
133
+ <<~JSON
134
+ { "type": "#{type}", "value": #{value} }
135
+ JSON
136
+ end
137
+
138
+ def authenticate!
139
+ # Currently, Shopify CLI can't bypass the store password, so the
140
+ # `AuthDevServer` gets the session to perform requests at the SFR.
141
+ ShopifyCLI::Theme::Repl::AuthDevServer.start(ctx, self, PORT)
142
+ end
143
+ end
144
+ end
145
+ end
@@ -5,7 +5,7 @@ module ShopifyCLI
5
5
  class Syncer
6
6
  ##
7
7
  # ShopifyCLI::Theme::Syncer::StdReporter allows disabling/enabling
8
- # messages reported in the standard output (ShopifyCLI::Context#puts).
8
+ # messages reported in the standard error output (ShopifyCLI::Context#puts).
9
9
  #
10
10
  class StandardReporter
11
11
  attr_reader :ctx
@@ -24,7 +24,7 @@ module ShopifyCLI
24
24
  end
25
25
 
26
26
  def report(message)
27
- ctx.puts(message) if @enabled
27
+ ctx.error(message) if @enabled
28
28
  end
29
29
  end
30
30
  end
@@ -33,7 +33,7 @@ module ShopifyCLI
33
33
  :union_merge, # - Union merges the local file content with the remote file content
34
34
  ]
35
35
 
36
- attr_reader :ctx, :theme, :checksums, :error_checksums, :api_client, :pending
36
+ attr_reader :ctx, :theme, :checksums, :error_checksums, :api_client, :pending, :standard_reporter
37
37
  attr_accessor :include_filter, :ignore_filter
38
38
 
39
39
  def_delegators :@error_reporter, :has_any_error?
@@ -156,12 +156,6 @@ module ShopifyCLI
156
156
  end
157
157
  end
158
158
 
159
- private
160
-
161
- def random_name
162
- ShopifyCLI::Helpers::Haikunator.haikunate(9999)
163
- end
164
-
165
159
  def find(ctx, root, &block)
166
160
  _status, body = fetch_themes(ctx)
167
161
 
@@ -172,6 +166,12 @@ module ShopifyCLI
172
166
  end
173
167
  end
174
168
 
169
+ private
170
+
171
+ def random_name
172
+ ShopifyCLI::Helpers::Haikunator.haikunate(9999)
173
+ end
174
+
175
175
  def allowed_attrs(attrs)
176
176
  attrs.slice("id", "name", "role").transform_keys(&:to_sym)
177
177
  end
@@ -1,11 +1,11 @@
1
1
  import BaseCommand from '../../public/node/base-command.js';
2
2
  import { CommandContent } from '../../public/node/hooks/prerun.js';
3
- import { Interfaces } from '@oclif/core';
3
+ import { Command, Interfaces } from '@oclif/core';
4
4
  interface StartOptions {
5
5
  commandContent: CommandContent;
6
6
  args: string[];
7
7
  currentTime?: number;
8
- commandClass?: Interfaces.Command.Class | typeof BaseCommand;
8
+ commandClass?: Command.Class | typeof BaseCommand;
9
9
  }
10
10
  export declare function startAnalytics({ commandContent, args, currentTime, commandClass, }: StartOptions): Promise<void>;
11
11
  interface EnvironmentData {
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAC,iBAAiB,EAAE,6BAA6B,EAAC,MAAM,2CAA2C,CAAA;AAG1G,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAC,eAAe,EAAC,MAAM,yBAAyB,CAAA;AAEvD,OAAO,EAAC,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAC,MAAM,qCAAqC,CAAA;AAC5F,OAAO,EAAC,GAAG,EAAC,MAAM,4BAA4B,CAAA;AAS9C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,cAAc,EACd,IAAI,EACJ,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,EAClC,YAAY,GACC;IACb,IAAI,YAAY,GAAW,cAAc,CAAC,OAAO,CAAA;IACjD,IAAI,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,EAAE;QAC/F,YAAY,GAAI,YAAmC,CAAC,qBAAqB,EAAE,IAAI,cAAc,CAAC,OAAO,CAAA;KACtG;IAED,MAAM,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;QACzC,mBAAmB,EAAE;YACnB,SAAS,EAAE,WAAW;YACtB,YAAY;YACZ,SAAS,EAAE,IAAI;SAChB;KACF,CAAC,CAAC,CAAA;IAEH,MAAM,QAAQ,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC,CAAC;QACtC,gBAAgB,EAAE,6BAA6B,EAAE;QACjD,kBAAkB,EAAE,cAAc,CAAC,KAAK;QACxC,aAAa,EAAE,cAAc,CAAC,KAAK;QACnC,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI;KAC3C,CAAC,CAAC,CAAA;AACL,CAAC;AAeD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAyB;IAChE,MAAM,UAAU,GAAG,UAAU,EAAE,CAAA;IAE/B,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IAC1C,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAA;IAErF,MAAM,EAAC,QAAQ,EAAE,IAAI,EAAC,GAAG,eAAe,EAAE,CAAA;IAE1C,OAAO;QACL,KAAK,EAAE,GAAG,QAAQ,IAAI,IAAI,EAAE;QAC5B,MAAM,EAAE,UAAU,CAAC,IAAI;QACvB,eAAe,EAAE,UAAU,CAAC,IAAI;QAChC,+BAA+B,EAAE,WAAW,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QAC7E,4BAA4B,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;QAC5D,SAAS,EAAE,MAAM,CAAC,KAAK;QACvB,WAAW,EAAE,gBAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;QAChF,aAAa,EAAE,UAAU,CAAC,MAAM,UAAU,EAAE,CAAC;QAC7C,SAAS,EAAE,gBAAgB,EAAE,CAAC,QAAQ;QACtC,mBAAmB,EAAE,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC;KACpD,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,MAAyB;IACzE,OAAO;QACL,wBAAwB,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;KACjE,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAyB;IAC/C,OAAO,MAAM,CAAC,OAAO;SAClB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;SAC5B,IAAI,EAAE;SACN,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;AACtD,CAAC","sourcesContent":["import {hashString} from '../../public/node/crypto.js'\nimport {getPackageManager, packageManagerUsedForCreating} from '../../public/node/node-package-manager.js'\nimport BaseCommand from '../../public/node/base-command.js'\nimport {CommandContent} from '../../public/node/hooks/prerun.js'\nimport * as metadata from '../../public/node/metadata.js'\nimport {platformAndArch} from '../../public/node/os.js'\nimport {Interfaces} from '@oclif/core'\nimport {ciPlatform, cloudEnvironment, macAddress} from '@shopify/cli-kit/node/context/local'\nimport {cwd} from '@shopify/cli-kit/node/path'\n\ninterface StartOptions {\n commandContent: CommandContent\n args: string[]\n currentTime?: number\n commandClass?: Interfaces.Command.Class | typeof BaseCommand\n}\n\nexport async function startAnalytics({\n commandContent,\n args,\n currentTime = new Date().getTime(),\n commandClass,\n}: StartOptions): Promise<void> {\n let startCommand: string = commandContent.command\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsNameOverride')) {\n startCommand = (commandClass as typeof BaseCommand).analyticsNameOverride() ?? commandContent.command\n }\n\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n startTime: currentTime,\n startCommand,\n startArgs: args,\n },\n }))\n\n await metadata.addPublicMetadata(() => ({\n cmd_all_launcher: packageManagerUsedForCreating(),\n cmd_all_alias_used: commandContent.alias,\n cmd_all_topic: commandContent.topic,\n cmd_all_plugin: commandClass?.plugin?.name,\n }))\n}\n\ninterface EnvironmentData {\n uname: string\n env_ci: boolean\n env_ci_platform?: string\n env_plugin_installed_any_custom: boolean\n env_plugin_installed_shopify: string\n env_shell: string\n env_web_ide: string | undefined\n env_device_id: string\n env_cloud: string\n env_package_manager: string\n}\n\nexport async function getEnvironmentData(config: Interfaces.Config): Promise<EnvironmentData> {\n const ciplatform = ciPlatform()\n\n const pluginNames = getPluginNames(config)\n const shopifyPlugins = pluginNames.filter((plugin) => plugin.startsWith('@shopify/'))\n\n const {platform, arch} = platformAndArch()\n\n return {\n uname: `${platform} ${arch}`,\n env_ci: ciplatform.isCI,\n env_ci_platform: ciplatform.name,\n env_plugin_installed_any_custom: pluginNames.length !== shopifyPlugins.length,\n env_plugin_installed_shopify: JSON.stringify(shopifyPlugins),\n env_shell: config.shell,\n env_web_ide: cloudEnvironment().editor ? cloudEnvironment().platform : undefined,\n env_device_id: hashString(await macAddress()),\n env_cloud: cloudEnvironment().platform,\n env_package_manager: await getPackageManager(cwd()),\n }\n}\n\nexport async function getSensitiveEnvironmentData(config: Interfaces.Config) {\n return {\n env_plugin_installed_all: JSON.stringify(getPluginNames(config)),\n }\n}\n\nfunction getPluginNames(config: Interfaces.Config) {\n return config.plugins\n .map((plugin) => plugin.name)\n .sort()\n .filter((plugin) => !plugin.startsWith('@oclif/'))\n}\n"]}
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import {hashString} from '../../public/node/crypto.js'\nimport {getPackageManager, packageManagerUsedForCreating} from '../../public/node/node-package-manager.js'\nimport BaseCommand from '../../public/node/base-command.js'\nimport {CommandContent} from '../../public/node/hooks/prerun.js'\nimport * as metadata from '../../public/node/metadata.js'\nimport {platformAndArch} from '../../public/node/os.js'\nimport {Command, Interfaces} from '@oclif/core'\nimport {ciPlatform, cloudEnvironment, macAddress} from '@shopify/cli-kit/node/context/local'\nimport {cwd} from '@shopify/cli-kit/node/path'\n\ninterface StartOptions {\n commandContent: CommandContent\n args: string[]\n currentTime?: number\n commandClass?: Command.Class | typeof BaseCommand\n}\n\nexport async function startAnalytics({\n commandContent,\n args,\n currentTime = new Date().getTime(),\n commandClass,\n}: StartOptions): Promise<void> {\n let startCommand: string = commandContent.command\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsNameOverride')) {\n startCommand = (commandClass as typeof BaseCommand).analyticsNameOverride() ?? commandContent.command\n }\n\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n startTime: currentTime,\n startCommand,\n startArgs: args,\n },\n }))\n\n await metadata.addPublicMetadata(() => ({\n cmd_all_launcher: packageManagerUsedForCreating(),\n cmd_all_alias_used: commandContent.alias,\n cmd_all_topic: commandContent.topic,\n cmd_all_plugin: commandClass?.plugin?.name,\n }))\n}\n\ninterface EnvironmentData {\n uname: string\n env_ci: boolean\n env_ci_platform?: string\n env_plugin_installed_any_custom: boolean\n env_plugin_installed_shopify: string\n env_shell: string\n env_web_ide: string | undefined\n env_device_id: string\n env_cloud: string\n env_package_manager: string\n}\n\nexport async function getEnvironmentData(config: Interfaces.Config): Promise<EnvironmentData> {\n const ciplatform = ciPlatform()\n\n const pluginNames = getPluginNames(config)\n const shopifyPlugins = pluginNames.filter((plugin) => plugin.startsWith('@shopify/'))\n\n const {platform, arch} = platformAndArch()\n\n return {\n uname: `${platform} ${arch}`,\n env_ci: ciplatform.isCI,\n env_ci_platform: ciplatform.name,\n env_plugin_installed_any_custom: pluginNames.length !== shopifyPlugins.length,\n env_plugin_installed_shopify: JSON.stringify(shopifyPlugins),\n env_shell: config.shell,\n env_web_ide: cloudEnvironment().editor ? cloudEnvironment().platform : undefined,\n env_device_id: hashString(await macAddress()),\n env_cloud: cloudEnvironment().platform,\n env_package_manager: await getPackageManager(cwd()),\n }\n}\n\nexport async function getSensitiveEnvironmentData(config: Interfaces.Config) {\n return {\n env_plugin_installed_all: JSON.stringify(getPluginNames(config)),\n }\n}\n\nfunction getPluginNames(config: Interfaces.Config) {\n return config.plugins\n .map((plugin) => plugin.name)\n .sort()\n .filter((plugin) => !plugin.startsWith('@oclif/'))\n}\n"]}
@@ -1,19 +1,16 @@
1
1
  import { buildHeaders, httpsAgent, RequestClientError, sanitizedHeadersOutput } from './headers.js';
2
2
  import { stringifyMessage, outputContent, outputToken, outputDebug } from '../../../public/node/output.js';
3
3
  import { AbortError } from '../../../public/node/error.js';
4
+ import { debugLogResponseInfo } from '../api.js';
4
5
  import { ClientError, GraphQLClient } from 'graphql-request';
5
- import { performance } from 'perf_hooks';
6
6
  export function graphqlRequest(query, api, url, token, variables, handleErrors = true) {
7
7
  const action = async () => {
8
8
  const headers = buildHeaders(token);
9
- debugLogRequest(api, query, variables, headers);
9
+ debugLogRequestInfo(api, query, variables, headers);
10
10
  const clientOptions = { agent: await httpsAgent(), headers };
11
11
  const client = new GraphQLClient(url, clientOptions);
12
- const t0 = performance.now();
13
- const response = await client.request(query, variables);
14
- const t1 = performance.now();
15
- outputDebug(`Request to ${url.toString()} completed in ${Math.round(t1 - t0)} ms`);
16
- return response;
12
+ const response = await debugLogResponseInfo({ request: client.rawRequest(query, variables), url });
13
+ return response.data;
17
14
  };
18
15
  if (handleErrors) {
19
16
  return handlingErrors(api, action);
@@ -22,15 +19,11 @@ export function graphqlRequest(query, api, url, token, variables, handleErrors =
22
19
  return action();
23
20
  }
24
21
  }
25
- function debugLogRequest(api, query, variables, headers = {}) {
26
- outputDebug(outputContent `
27
- Sending ${outputToken.json(api)} GraphQL request:
28
- ${outputToken.raw(query.toString())}
29
-
30
- With variables:
31
- ${variables ? JSON.stringify(variables, null, 2) : ''}
32
-
33
- And headers:
22
+ function debugLogRequestInfo(api, query, variables, headers = {}) {
23
+ outputDebug(outputContent `Sending ${outputToken.json(api)} GraphQL request:
24
+ ${outputToken.raw(query.toString().trim())}
25
+ ${variables ? `\nWith variables:\n${JSON.stringify(variables, null, 2)}\n` : ''}
26
+ With request headers:
34
27
  ${sanitizedHeadersOutput(headers)}
35
28
  `);
36
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {buildHeaders, httpsAgent, RequestClientError, sanitizedHeadersOutput} from './headers.js'\nimport {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js'\nimport {AbortError} from '../../../public/node/error.js'\nimport {ClientError, GraphQLClient, RequestDocument, Variables} from 'graphql-request'\nimport {performance} from 'perf_hooks'\n\nexport interface GraphQLVariables {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport function graphqlRequest<T>(\n query: RequestDocument,\n api: string,\n url: string,\n token: string,\n variables?: Variables,\n handleErrors = true,\n): Promise<T> {\n const action = async () => {\n const headers = buildHeaders(token)\n debugLogRequest(api, query, variables, headers)\n const clientOptions = {agent: await httpsAgent(), headers}\n const client = new GraphQLClient(url, clientOptions)\n const t0 = performance.now()\n const response = await client.request<T>(query, variables)\n const t1 = performance.now()\n outputDebug(`Request to ${url.toString()} completed in ${Math.round(t1 - t0)} ms`)\n return response\n }\n\n if (handleErrors) {\n return handlingErrors(api, action)\n } else {\n return action()\n }\n}\n\nfunction debugLogRequest<T>(\n api: string,\n query: RequestDocument,\n variables?: Variables,\n headers: {[key: string]: string} = {},\n) {\n outputDebug(outputContent`\nSending ${outputToken.json(api)} GraphQL request:\n${outputToken.raw(query.toString())}\n\nWith variables:\n${variables ? JSON.stringify(variables, null, 2) : ''}\n\nAnd headers:\n${sanitizedHeadersOutput(headers)}\n`)\n}\n\nasync function handlingErrors<T>(api: string, action: () => Promise<T>): Promise<T> {\n try {\n return await action()\n } catch (error) {\n if (error instanceof ClientError) {\n const errorMessage = stringifyMessage(outputContent`\n The ${outputToken.raw(\n api,\n )} GraphQL API responded unsuccessfully with the HTTP status ${`${error.response.status}`} and errors:\n\n ${outputToken.json(error.response.errors)}\n `)\n let mappedError: Error\n if (error.response.status < 500) {\n mappedError = new RequestClientError(errorMessage, error.response.status)\n } else {\n mappedError = new AbortError(errorMessage)\n }\n mappedError.stack = error.stack\n throw mappedError\n } else {\n throw error\n }\n }\n}\n"]}
1
+ {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,sBAAsB,EAAC,MAAM,cAAc,CAAA;AACjG,OAAO,EAAC,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,gCAAgC,CAAA;AACxG,OAAO,EAAC,UAAU,EAAC,MAAM,+BAA+B,CAAA;AACxD,OAAO,EAAC,oBAAoB,EAAC,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAC,WAAW,EAAE,aAAa,EAA6B,MAAM,iBAAiB,CAAA;AAOtF,MAAM,UAAU,cAAc,CAC5B,KAAsB,EACtB,GAAW,EACX,GAAW,EACX,KAAa,EACb,SAAqB,EACrB,YAAY,GAAG,IAAI;IAEnB,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QACnC,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QACnD,MAAM,aAAa,GAAG,EAAC,KAAK,EAAE,MAAM,UAAU,EAAE,EAAE,OAAO,EAAC,CAAA;QAC1D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;QACpD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAI,KAAe,EAAE,SAAS,CAAC,EAAE,GAAG,EAAC,CAAC,CAAA;QAC7G,OAAO,QAAQ,CAAC,IAAI,CAAA;IACtB,CAAC,CAAA;IAED,IAAI,YAAY,EAAE;QAChB,OAAO,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;KACnC;SAAM;QACL,OAAO,MAAM,EAAE,CAAA;KAChB;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,GAAW,EACX,KAAsB,EACtB,SAAqB,EACrB,UAAmC,EAAE;IAErC,WAAW,CAAC,aAAa,CAAA,WAAW,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;IACvD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;EAC1C,SAAS,CAAC,CAAC,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;EAE7E,sBAAsB,CAAC,OAAO,CAAC;CAChC,CAAC,CAAA;AACF,CAAC;AAED,KAAK,UAAU,cAAc,CAAI,GAAW,EAAE,MAAwB;IACpE,IAAI;QACF,OAAO,MAAM,MAAM,EAAE,CAAA;KACtB;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,WAAW,EAAE;YAChC,MAAM,YAAY,GAAG,gBAAgB,CAAC,aAAa,CAAA;QACjD,WAAW,CAAC,GAAG,CACnB,GAAG,CACJ,8DAA8D,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE;;IAEvF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;OACpC,CAAC,CAAA;YACF,IAAI,WAAkB,CAAA;YACtB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE;gBAC/B,WAAW,GAAG,IAAI,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;aAC1E;iBAAM;gBACL,WAAW,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAA;aAC3C;YACD,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;YAC/B,MAAM,WAAW,CAAA;SAClB;aAAM;YACL,MAAM,KAAK,CAAA;SACZ;KACF;AACH,CAAC","sourcesContent":["import {buildHeaders, httpsAgent, RequestClientError, sanitizedHeadersOutput} from './headers.js'\nimport {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js'\nimport {AbortError} from '../../../public/node/error.js'\nimport {debugLogResponseInfo} from '../api.js'\nimport {ClientError, GraphQLClient, RequestDocument, Variables} from 'graphql-request'\n\nexport interface GraphQLVariables {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport function graphqlRequest<T>(\n query: RequestDocument,\n api: string,\n url: string,\n token: string,\n variables?: Variables,\n handleErrors = true,\n): Promise<T> {\n const action = async () => {\n const headers = buildHeaders(token)\n debugLogRequestInfo(api, query, variables, headers)\n const clientOptions = {agent: await httpsAgent(), headers}\n const client = new GraphQLClient(url, clientOptions)\n const response = await debugLogResponseInfo({request: client.rawRequest<T>(query as string, variables), url})\n return response.data\n }\n\n if (handleErrors) {\n return handlingErrors(api, action)\n } else {\n return action()\n }\n}\n\nfunction debugLogRequestInfo<T>(\n api: string,\n query: RequestDocument,\n variables?: Variables,\n headers: {[key: string]: string} = {},\n) {\n outputDebug(outputContent`Sending ${outputToken.json(api)} GraphQL request:\n ${outputToken.raw(query.toString().trim())}\n${variables ? `\\nWith variables:\\n${JSON.stringify(variables, null, 2)}\\n` : ''}\nWith request headers:\n${sanitizedHeadersOutput(headers)}\n`)\n}\n\nasync function handlingErrors<T>(api: string, action: () => Promise<T>): Promise<T> {\n try {\n return await action()\n } catch (error) {\n if (error instanceof ClientError) {\n const errorMessage = stringifyMessage(outputContent`\n The ${outputToken.raw(\n api,\n )} GraphQL API responded unsuccessfully with the HTTP status ${`${error.response.status}`} and errors:\n\n ${outputToken.json(error.response.errors)}\n `)\n let mappedError: Error\n if (error.response.status < 500) {\n mappedError = new RequestClientError(errorMessage, error.response.status)\n } else {\n mappedError = new AbortError(errorMessage)\n }\n mappedError.stack = error.stack\n throw mappedError\n } else {\n throw error\n }\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import { CLI_KIT_VERSION } from '../../../public/common/version.js';
2
2
  import { firstPartyDev } from '../../../public/node/context/local.js';
3
- import { randomUUID } from '../../../public/node/crypto.js';
4
3
  import { Environment, serviceEnvironment } from '../context/service.js';
5
4
  import { ExtendableError } from '../../../public/node/error.js';
6
5
  import https from 'https';
@@ -33,16 +32,17 @@ export function buildHeaders(token) {
33
32
  const userAgent = `Shopify CLI; v=${CLI_KIT_VERSION}`;
34
33
  const headers = {
35
34
  'User-Agent': userAgent,
35
+ 'Keep-Alive': 'timeout=30',
36
36
  // 'Sec-CH-UA': secCHUA, This header requires the Git sha.
37
37
  'Sec-CH-UA-PLATFORM': process.platform,
38
- 'X-Request-Id': randomUUID(),
39
38
  'Content-Type': 'application/json',
40
39
  ...(firstPartyDev() && { 'X-Shopify-Cli-Employee': '1' }),
41
40
  };
42
41
  if (token) {
42
+ const authString = token.startsWith('shpat') ? token : `Bearer ${token}`;
43
43
  // eslint-disable-next-line dot-notation
44
- headers['authorization'] = `Bearer ${token}`;
45
- headers['X-Shopify-Access-Token'] = `Bearer ${token}`;
44
+ headers['authorization'] = authString;
45
+ headers['X-Shopify-Access-Token'] = authString;
46
46
  }
47
47
  return headers;
48
48
  }
@@ -53,7 +53,10 @@ export function buildHeaders(token) {
53
53
  * set to false
54
54
  */
55
55
  export async function httpsAgent() {
56
- return new https.Agent({ rejectUnauthorized: await shouldRejectUnauthorizedRequests() });
56
+ return new https.Agent({
57
+ rejectUnauthorized: await shouldRejectUnauthorizedRequests(),
58
+ keepAlive: true,
59
+ });
57
60
  }
58
61
  /**
59
62
  * Spin stores the CA certificate in the keychain and it should be used when sending HTTP
@@ -1 +1 @@
1
- {"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../../src/private/node/api/headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAC,aAAa,EAAC,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAA;AACzD,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IAErD,YAAmB,OAAe,EAAE,UAAkB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;IAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,SAAS,EAAE;YAC1F,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAE,CAAA;SACrC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,OAAO,MAAM,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAA;IAC7C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,SAAS,GAAG,kBAAkB,eAAe,EAAE,CAAA;IAErD,MAAM,OAAO,GAA+B;QAC1C,YAAY,EAAE,SAAS;QACvB,0DAA0D;QAC1D,oBAAoB,EAAE,OAAO,CAAC,QAAQ;QACtC,cAAc,EAAE,UAAU,EAAE;QAC5B,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAC,wBAAwB,EAAE,GAAG,EAAC,CAAC;KACxD,CAAA;IACD,IAAI,KAAK,EAAE;QACT,wCAAwC;QACxC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAA;QAC5C,OAAO,CAAC,wBAAwB,CAAC,GAAG,UAAU,KAAK,EAAE,CAAA;KACtD;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,EAAC,kBAAkB,EAAE,MAAM,gCAAgC,EAAE,EAAC,CAAC,CAAA;AACxF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,gCAAgC;IAC7C,OAAO,CAAC,MAAM,kBAAkB,EAAE,CAAC,KAAK,WAAW,CAAC,IAAI,CAAA;AAC1D,CAAC","sourcesContent":["import {CLI_KIT_VERSION} from '../../../public/common/version.js'\nimport {firstPartyDev} from '../../../public/node/context/local.js'\nimport {randomUUID} from '../../../public/node/crypto.js'\nimport {Environment, serviceEnvironment} from '../context/service.js'\nimport {ExtendableError} from '../../../public/node/error.js'\nimport https from 'https'\n\nexport class RequestClientError extends ExtendableError {\n statusCode: number\n public constructor(message: string, statusCode: number) {\n super(message)\n this.statusCode = statusCode\n }\n}\n\n/**\n * Removes the sensitive data from the headers and outputs them as a string.\n * @param headers - HTTP headers.\n * @returns A sanitized version of the headers as a string.\n */\nexport function sanitizedHeadersOutput(headers: {[key: string]: string}): string {\n const sanitized: {[key: string]: string} = {}\n const keywords = ['token', 'authorization']\n Object.keys(headers).forEach((header) => {\n if (keywords.find((keyword) => header.toLocaleLowerCase().includes(keyword)) === undefined) {\n sanitized[header] = headers[header]!\n }\n })\n return Object.keys(sanitized)\n .map((header) => {\n return ` - ${header}: ${sanitized[header]}`\n })\n .join('\\n')\n}\n\nexport function buildHeaders(token?: string): {[key: string]: string} {\n const userAgent = `Shopify CLI; v=${CLI_KIT_VERSION}`\n\n const headers: {[header: string]: string} = {\n 'User-Agent': userAgent,\n // 'Sec-CH-UA': secCHUA, This header requires the Git sha.\n 'Sec-CH-UA-PLATFORM': process.platform,\n 'X-Request-Id': randomUUID(),\n 'Content-Type': 'application/json',\n ...(firstPartyDev() && {'X-Shopify-Cli-Employee': '1'}),\n }\n if (token) {\n // eslint-disable-next-line dot-notation\n headers['authorization'] = `Bearer ${token}`\n headers['X-Shopify-Access-Token'] = `Bearer ${token}`\n }\n\n return headers\n}\n\n/**\n * This utility function returns the https.Agent to use for a given service. The agent\n * includes the right configuration based on the service's environment. For example,\n * if the service is running in a Spin environment, the attribute \"rejectUnauthorized\" is\n * set to false\n */\nexport async function httpsAgent() {\n return new https.Agent({rejectUnauthorized: await shouldRejectUnauthorizedRequests()})\n}\n\n/**\n * Spin stores the CA certificate in the keychain and it should be used when sending HTTP\n * requests to Spin instances. However, Node doesn't read certificates from the Keychain\n * by default, which leads to Shopifolks running into issues that they workaround by setting the\n * NODE_TLS_REJECT_UNAUTHORIZED=0 environment variable, which applies to all the HTTP\n * requests sent from the CLI (context: https://github.com/nodejs/node/issues/39657)\n * This utility function allows controlling the behavior in a per-service level by returning\n * the value of for the \"rejectUnauthorized\" attribute that's used in the https agent.\n *\n * @returns A promise that resolves with a boolean indicating whether\n * unauthorized requests should be rejected or not.\n */\nasync function shouldRejectUnauthorizedRequests(): Promise<boolean> {\n return (await serviceEnvironment()) !== Environment.Spin\n}\n"]}
1
+ {"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../../src/private/node/api/headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAC,aAAa,EAAC,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IAErD,YAAmB,OAAe,EAAE,UAAkB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;IAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,SAAS,EAAE;YAC1F,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAE,CAAA;SACrC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,OAAO,MAAM,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAA;IAC7C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,SAAS,GAAG,kBAAkB,eAAe,EAAE,CAAA;IAErD,MAAM,OAAO,GAA+B;QAC1C,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,YAAY;QAC1B,0DAA0D;QAC1D,oBAAoB,EAAE,OAAO,CAAC,QAAQ;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAC,wBAAwB,EAAE,GAAG,EAAC,CAAC;KACxD,CAAA;IACD,IAAI,KAAK,EAAE;QACT,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAA;QACxE,wCAAwC;QACxC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,CAAA;QACrC,OAAO,CAAC,wBAAwB,CAAC,GAAG,UAAU,CAAA;KAC/C;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;QACrB,kBAAkB,EAAE,MAAM,gCAAgC,EAAE;QAC5D,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,gCAAgC;IAC7C,OAAO,CAAC,MAAM,kBAAkB,EAAE,CAAC,KAAK,WAAW,CAAC,IAAI,CAAA;AAC1D,CAAC","sourcesContent":["import {CLI_KIT_VERSION} from '../../../public/common/version.js'\nimport {firstPartyDev} from '../../../public/node/context/local.js'\nimport {Environment, serviceEnvironment} from '../context/service.js'\nimport {ExtendableError} from '../../../public/node/error.js'\nimport https from 'https'\n\nexport class RequestClientError extends ExtendableError {\n statusCode: number\n public constructor(message: string, statusCode: number) {\n super(message)\n this.statusCode = statusCode\n }\n}\n\n/**\n * Removes the sensitive data from the headers and outputs them as a string.\n * @param headers - HTTP headers.\n * @returns A sanitized version of the headers as a string.\n */\nexport function sanitizedHeadersOutput(headers: {[key: string]: string}): string {\n const sanitized: {[key: string]: string} = {}\n const keywords = ['token', 'authorization']\n Object.keys(headers).forEach((header) => {\n if (keywords.find((keyword) => header.toLocaleLowerCase().includes(keyword)) === undefined) {\n sanitized[header] = headers[header]!\n }\n })\n return Object.keys(sanitized)\n .map((header) => {\n return ` - ${header}: ${sanitized[header]}`\n })\n .join('\\n')\n}\n\nexport function buildHeaders(token?: string): {[key: string]: string} {\n const userAgent = `Shopify CLI; v=${CLI_KIT_VERSION}`\n\n const headers: {[header: string]: string} = {\n 'User-Agent': userAgent,\n 'Keep-Alive': 'timeout=30',\n // 'Sec-CH-UA': secCHUA, This header requires the Git sha.\n 'Sec-CH-UA-PLATFORM': process.platform,\n 'Content-Type': 'application/json',\n ...(firstPartyDev() && {'X-Shopify-Cli-Employee': '1'}),\n }\n if (token) {\n const authString = token.startsWith('shpat') ? token : `Bearer ${token}`\n // eslint-disable-next-line dot-notation\n headers['authorization'] = authString\n headers['X-Shopify-Access-Token'] = authString\n }\n\n return headers\n}\n\n/**\n * This utility function returns the https.Agent to use for a given service. The agent\n * includes the right configuration based on the service's environment. For example,\n * if the service is running in a Spin environment, the attribute \"rejectUnauthorized\" is\n * set to false\n */\nexport async function httpsAgent(): Promise<https.Agent> {\n return new https.Agent({\n rejectUnauthorized: await shouldRejectUnauthorizedRequests(),\n keepAlive: true,\n })\n}\n\n/**\n * Spin stores the CA certificate in the keychain and it should be used when sending HTTP\n * requests to Spin instances. However, Node doesn't read certificates from the Keychain\n * by default, which leads to Shopifolks running into issues that they workaround by setting the\n * NODE_TLS_REJECT_UNAUTHORIZED=0 environment variable, which applies to all the HTTP\n * requests sent from the CLI (context: https://github.com/nodejs/node/issues/39657)\n * This utility function allows controlling the behavior in a per-service level by returning\n * the value of for the \"rejectUnauthorized\" attribute that's used in the https agent.\n *\n * @returns A promise that resolves with a boolean indicating whether\n * unauthorized requests should be rejected or not.\n */\nasync function shouldRejectUnauthorizedRequests(): Promise<boolean> {\n return (await serviceEnvironment()) !== Environment.Spin\n}\n"]}
@@ -1,2 +1,11 @@
1
1
  export type API = 'admin' | 'storefront-renderer' | 'partners';
2
2
  export declare const allAPIs: API[];
3
+ interface RequestOptions<T> {
4
+ request: Promise<T>;
5
+ url: string;
6
+ }
7
+ export declare function debugLogResponseInfo<T extends {
8
+ headers: Headers;
9
+ status: number;
10
+ }>({ request, url, }: RequestOptions<T>): Promise<T>;
11
+ export {};
@@ -1,2 +1,21 @@
1
+ import { sanitizedHeadersOutput } from './api/headers.js';
2
+ import { outputDebug } from '@shopify/cli-kit/node/output';
3
+ import { performance } from 'perf_hooks';
1
4
  export const allAPIs = ['admin', 'storefront-renderer', 'partners'];
5
+ const interestingResponseHeaders = new Set(['cache-control', 'content-type', 'etag', 'x-request-id']);
6
+ export async function debugLogResponseInfo({ request, url, }) {
7
+ const t0 = performance.now();
8
+ const response = await request;
9
+ const t1 = performance.now();
10
+ const responseHeaders = {};
11
+ response.headers.forEach((value, key) => {
12
+ if (interestingResponseHeaders.has(key))
13
+ responseHeaders[key] = value;
14
+ });
15
+ outputDebug(`Request to ${url} completed in ${Math.round(t1 - t0)} ms
16
+ With response headers:
17
+ ${sanitizedHeadersOutput(responseHeaders)}
18
+ `);
19
+ return response;
20
+ }
2
21
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAU,CAAC,OAAO,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAA","sourcesContent":["export type API = 'admin' | 'storefront-renderer' | 'partners'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners']\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAA;AAItC,MAAM,CAAC,MAAM,OAAO,GAAU,CAAC,OAAO,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAA;AAO1E,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;AAErG,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAA+C,EACvF,OAAO,EACP,GAAG,GACe;IAClB,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAA;IAC9B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;IAE5B,MAAM,eAAe,GAA4B,EAAE,CAAA;IACnD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtC,IAAI,0BAA0B,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,WAAW,CAAC,cAAc,GAAG,iBAAiB,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;;EAEjE,sBAAsB,CAAC,eAAe,CAAC;KACpC,CAAC,CAAA;IAEJ,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["import {sanitizedHeadersOutput} from './api/headers.js'\nimport {outputDebug} from '@shopify/cli-kit/node/output'\nimport {performance} from 'perf_hooks'\n\nexport type API = 'admin' | 'storefront-renderer' | 'partners'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners']\n\ninterface RequestOptions<T> {\n request: Promise<T>\n url: string\n}\n\nconst interestingResponseHeaders = new Set(['cache-control', 'content-type', 'etag', 'x-request-id'])\n\nexport async function debugLogResponseInfo<T extends {headers: Headers; status: number}>({\n request,\n url,\n}: RequestOptions<T>): Promise<T> {\n const t0 = performance.now()\n const response = await request\n const t1 = performance.now()\n\n const responseHeaders: {[key: string]: string} = {}\n response.headers.forEach((value, key) => {\n if (interestingResponseHeaders.has(key)) responseHeaders[key] = value\n })\n outputDebug(`Request to ${url} completed in ${Math.round(t1 - t0)} ms\nWith response headers:\n${sanitizedHeadersOutput(responseHeaders)}\n `)\n\n return response\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../src/private/node/colors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAC,KAAK,IAAI,OAAO,EAAC,CAAA","sourcesContent":["import chalk from 'chalk'\n\nexport {chalk as default}\n"]}
@@ -1,21 +1,40 @@
1
- import Conf, { Schema } from 'conf';
2
- export { Conf, Schema };
1
+ import { LocalStorage } from '../../public/node/local-storage.js';
2
+ interface CacheValue<T> {
3
+ value: T;
4
+ timestamp: number;
5
+ }
6
+ export type IntrospectionUrlKey = `identity-introspection-url-${string}`;
7
+ interface Cache {
8
+ [introspectionUrlKey: IntrospectionUrlKey]: CacheValue<string>;
9
+ }
3
10
  export interface ConfSchema {
4
11
  sessionStore: string;
12
+ cache?: Cache;
5
13
  }
6
14
  /**
7
15
  * Get session.
8
16
  *
9
17
  * @returns Session.
10
18
  */
11
- export declare function getSession(config?: Conf<ConfSchema>): string | undefined;
19
+ export declare function getSession(config?: LocalStorage<ConfSchema>): string | undefined;
12
20
  /**
13
21
  * Set session.
14
22
  *
15
23
  * @param session - Session.
16
24
  */
17
- export declare function setSession(session: string, config?: Conf<ConfSchema>): void;
25
+ export declare function setSession(session: string, config?: LocalStorage<ConfSchema>): void;
18
26
  /**
19
27
  * Remove session.
20
28
  */
21
- export declare function removeSession(config?: Conf<ConfSchema>): void;
29
+ export declare function removeSession(config?: LocalStorage<ConfSchema>): void;
30
+ type CacheValueForKey<TKey extends keyof Cache> = NonNullable<Cache[TKey]>['value'];
31
+ /**
32
+ * Fetch from cache, or run the provided function to get the value, and cache it
33
+ * before returning it.
34
+ * @param key - The key to use for the cache.
35
+ * @param fn - The function to run to get the value to cache, if a cache miss occurs.
36
+ * @param timeout - The maximum valid age of a cached value, in milliseconds. If the cached value is older than this, it will be refreshed.
37
+ * @returns The value from the cache or the result of the function.
38
+ */
39
+ export declare function cacheRetrieveOrRepopulate(key: keyof Cache, fn: () => Promise<CacheValueForKey<typeof key>>, timeout?: number, config?: LocalStorage<ConfSchema>): Promise<CacheValueForKey<typeof key>>;
40
+ export {};
@@ -1,6 +1,5 @@
1
+ import { LocalStorage } from '../../public/node/local-storage.js';
1
2
  import { outputContent, outputDebug } from '@shopify/cli-kit/node/output';
2
- import Conf from 'conf';
3
- export { Conf };
4
3
  let _instance;
5
4
  /**
6
5
  * CLIKIT Store.
@@ -9,7 +8,7 @@ let _instance;
9
8
  */
10
9
  function cliKitStore() {
11
10
  if (!_instance) {
12
- _instance = new Conf({ projectName: 'shopify-cli-kit' });
11
+ _instance = new LocalStorage({ projectName: 'shopify-cli-kit' });
13
12
  }
14
13
  return _instance;
15
14
  }
@@ -38,4 +37,23 @@ export function removeSession(config = cliKitStore()) {
38
37
  outputDebug(outputContent `Removing session store...`);
39
38
  config.delete('sessionStore');
40
39
  }
40
+ /**
41
+ * Fetch from cache, or run the provided function to get the value, and cache it
42
+ * before returning it.
43
+ * @param key - The key to use for the cache.
44
+ * @param fn - The function to run to get the value to cache, if a cache miss occurs.
45
+ * @param timeout - The maximum valid age of a cached value, in milliseconds. If the cached value is older than this, it will be refreshed.
46
+ * @returns The value from the cache or the result of the function.
47
+ */
48
+ export async function cacheRetrieveOrRepopulate(key, fn, timeout, config = cliKitStore()) {
49
+ const cache = config.get('cache') || {};
50
+ const cached = cache[key];
51
+ if (cached && (timeout === undefined || Date.now() - cached.timestamp < timeout)) {
52
+ return cached.value;
53
+ }
54
+ const value = await fn();
55
+ cache[key] = { value, timestamp: Date.now() };
56
+ config.set('cache', cache);
57
+ return value;
58
+ }
41
59
  //# sourceMappingURL=conf-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conf-store.js","sourceRoot":"","sources":["../../../src/private/node/conf-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,8BAA8B,CAAA;AACvE,OAAO,IAAc,MAAM,MAAM,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAS,CAAA;AAMrB,IAAI,SAAuC,CAAA;AAE3C;;;;GAIG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC,SAAS,EAAE;QACd,SAAS,GAAG,IAAI,IAAI,CAAa,EAAC,WAAW,EAAE,iBAAiB,EAAC,CAAC,CAAA;KACnE;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,SAA2B,WAAW,EAAE;IACjE,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,OAAO,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,SAA2B,WAAW,EAAE;IAClF,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,SAA2B,WAAW,EAAE;IACpE,WAAW,CAAC,aAAa,CAAA,2BAA2B,CAAC,CAAA;IACrD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;AAC/B,CAAC","sourcesContent":["import {outputContent, outputDebug} from '@shopify/cli-kit/node/output'\nimport Conf, {Schema} from 'conf'\n\nexport {Conf, Schema}\n\nexport interface ConfSchema {\n sessionStore: string\n}\n\nlet _instance: Conf<ConfSchema> | undefined\n\n/**\n * CLIKIT Store.\n *\n * @returns CLIKitStore.\n */\nfunction cliKitStore() {\n if (!_instance) {\n _instance = new Conf<ConfSchema>({projectName: 'shopify-cli-kit'})\n }\n return _instance\n}\n\n/**\n * Get session.\n *\n * @returns Session.\n */\nexport function getSession(config: Conf<ConfSchema> = cliKitStore()): string | undefined {\n outputDebug(outputContent`Getting session store...`)\n return config.get('sessionStore')\n}\n\n/**\n * Set session.\n *\n * @param session - Session.\n */\nexport function setSession(session: string, config: Conf<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Setting session store...`)\n config.set('sessionStore', session)\n}\n\n/**\n * Remove session.\n */\nexport function removeSession(config: Conf<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Removing session store...`)\n config.delete('sessionStore')\n}\n"]}
1
+ {"version":3,"file":"conf-store.js","sourceRoot":"","sources":["../../../src/private/node/conf-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAA;AAC/D,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,8BAA8B,CAAA;AAkBvE,IAAI,SAA+C,CAAA;AAEnD;;;;GAIG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC,SAAS,EAAE;QACd,SAAS,GAAG,IAAI,YAAY,CAAa,EAAC,WAAW,EAAE,iBAAiB,EAAC,CAAC,CAAA;KAC3E;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,SAAmC,WAAW,EAAE;IACzE,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,OAAO,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,SAAmC,WAAW,EAAE;IAC1F,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,SAAmC,WAAW,EAAE;IAC5E,WAAW,CAAC,aAAa,CAAA,2BAA2B,CAAC,CAAA;IACrD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;AAC/B,CAAC;AAGD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,GAAgB,EAChB,EAA+C,EAC/C,OAAgB,EAChB,MAAM,GAAG,WAAW,EAAE;IAEtB,MAAM,KAAK,GAAU,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IAEzB,IAAI,MAAM,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,EAAE;QAChF,OAAO,MAAM,CAAC,KAAK,CAAA;KACpB;IAED,MAAM,KAAK,GAAG,MAAM,EAAE,EAAE,CAAA;IACxB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAC,CAAA;IAC3C,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC1B,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import {LocalStorage} from '../../public/node/local-storage.js'\nimport {outputContent, outputDebug} from '@shopify/cli-kit/node/output'\n\ninterface CacheValue<T> {\n value: T\n timestamp: number\n}\n\nexport type IntrospectionUrlKey = `identity-introspection-url-${string}`\n\ninterface Cache {\n [introspectionUrlKey: IntrospectionUrlKey]: CacheValue<string>\n}\n\nexport interface ConfSchema {\n sessionStore: string\n cache?: Cache\n}\n\nlet _instance: LocalStorage<ConfSchema> | undefined\n\n/**\n * CLIKIT Store.\n *\n * @returns CLIKitStore.\n */\nfunction cliKitStore() {\n if (!_instance) {\n _instance = new LocalStorage<ConfSchema>({projectName: 'shopify-cli-kit'})\n }\n return _instance\n}\n\n/**\n * Get session.\n *\n * @returns Session.\n */\nexport function getSession(config: LocalStorage<ConfSchema> = cliKitStore()): string | undefined {\n outputDebug(outputContent`Getting session store...`)\n return config.get('sessionStore')\n}\n\n/**\n * Set session.\n *\n * @param session - Session.\n */\nexport function setSession(session: string, config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Setting session store...`)\n config.set('sessionStore', session)\n}\n\n/**\n * Remove session.\n */\nexport function removeSession(config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Removing session store...`)\n config.delete('sessionStore')\n}\n\ntype CacheValueForKey<TKey extends keyof Cache> = NonNullable<Cache[TKey]>['value']\n/**\n * Fetch from cache, or run the provided function to get the value, and cache it\n * before returning it.\n * @param key - The key to use for the cache.\n * @param fn - The function to run to get the value to cache, if a cache miss occurs.\n * @param timeout - The maximum valid age of a cached value, in milliseconds. If the cached value is older than this, it will be refreshed.\n * @returns The value from the cache or the result of the function.\n */\nexport async function cacheRetrieveOrRepopulate(\n key: keyof Cache,\n fn: () => Promise<CacheValueForKey<typeof key>>,\n timeout?: number,\n config = cliKitStore(),\n): Promise<CacheValueForKey<typeof key>> {\n const cache: Cache = config.get('cache') || {}\n const cached = cache[key]\n\n if (cached && (timeout === undefined || Date.now() - cached.timestamp < timeout)) {\n return cached.value\n }\n\n const value = await fn()\n cache[key] = {value, timestamp: Date.now()}\n config.set('cache', cache)\n return value\n}\n"]}
@@ -19,6 +19,8 @@ export declare const environmentVariables: {
19
19
  codespaces: string;
20
20
  gitpod: string;
21
21
  spin: string;
22
+ spinAppPort: string;
23
+ spinAppHost: string;
22
24
  };
23
25
  export declare const pathConstants: {
24
26
  executables: {