@shopify/cli-kit 3.47.5 → 3.48.1

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 (154) hide show
  1. package/assets/cli-ruby/lib/project_types/extension/messages/messages.rb +18 -1
  2. package/assets/cli-ruby/lib/shopify_cli/constants.rb +1 -0
  3. package/assets/cli-ruby/lib/shopify_cli/environment.rb +7 -0
  4. package/assets/cli-ruby/lib/shopify_cli/theme/extension/dev_server.rb +8 -2
  5. package/dist/private/node/api/graphql.js +8 -1
  6. package/dist/private/node/api/graphql.js.map +1 -1
  7. package/dist/private/node/api/headers.js +1 -1
  8. package/dist/private/node/api/headers.js.map +1 -1
  9. package/dist/private/node/api/urls.d.ts +6 -0
  10. package/dist/private/node/api/urls.js +16 -0
  11. package/dist/private/node/api/urls.js.map +1 -0
  12. package/dist/private/node/api.js +2 -1
  13. package/dist/private/node/api.js.map +1 -1
  14. package/dist/private/node/ui/alert.js +3 -1
  15. package/dist/private/node/ui/alert.js.map +1 -1
  16. package/dist/private/node/ui/components/Alert.d.ts +1 -1
  17. package/dist/private/node/ui/components/Alert.js.map +1 -1
  18. package/dist/private/node/ui/components/AutocompletePrompt.d.ts +7 -2
  19. package/dist/private/node/ui/components/AutocompletePrompt.js +28 -91
  20. package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
  21. package/dist/private/node/ui/components/AutocompletePrompt.test.js +317 -257
  22. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
  23. package/dist/private/node/ui/components/ConcurrentOutput.d.ts +1 -0
  24. package/dist/private/node/ui/components/ConcurrentOutput.js +59 -32
  25. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  26. package/dist/private/node/ui/components/ConcurrentOutput.test.js +62 -22
  27. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
  28. package/dist/private/node/ui/components/DangerousConfirmationPrompt.d.ts +12 -0
  29. package/dist/private/node/ui/components/DangerousConfirmationPrompt.js +77 -0
  30. package/dist/private/node/ui/components/DangerousConfirmationPrompt.js.map +1 -0
  31. package/dist/private/node/ui/components/DangerousConfirmationPrompt.test.js +101 -0
  32. package/dist/private/node/ui/components/DangerousConfirmationPrompt.test.js.map +1 -0
  33. package/dist/private/node/ui/components/List.d.ts +1 -0
  34. package/dist/private/node/ui/components/List.js +2 -2
  35. package/dist/private/node/ui/components/List.js.map +1 -1
  36. package/dist/private/node/ui/components/{GitDiff.d.ts → Prompts/GitDiff.d.ts} +4 -2
  37. package/dist/private/node/ui/components/{GitDiff.js → Prompts/GitDiff.js} +3 -2
  38. package/dist/private/node/ui/components/Prompts/GitDiff.js.map +1 -0
  39. package/dist/private/node/ui/components/Prompts/GitDiff.test.d.ts +1 -0
  40. package/dist/private/node/ui/components/{GitDiff.test.js → Prompts/GitDiff.test.js} +50 -28
  41. package/dist/private/node/ui/components/Prompts/GitDiff.test.js.map +1 -0
  42. package/dist/private/node/ui/components/Prompts/InfoMessage.d.ts +14 -0
  43. package/dist/private/node/ui/components/Prompts/InfoMessage.js +11 -0
  44. package/dist/private/node/ui/components/Prompts/InfoMessage.js.map +1 -0
  45. package/dist/private/node/ui/components/Prompts/InfoMessage.test.d.ts +1 -0
  46. package/dist/private/node/ui/components/Prompts/InfoMessage.test.js +21 -0
  47. package/dist/private/node/ui/components/Prompts/InfoMessage.test.js.map +1 -0
  48. package/dist/private/node/ui/components/Prompts/InfoTable.d.ts +1 -0
  49. package/dist/private/node/ui/components/Prompts/InfoTable.js +11 -7
  50. package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -1
  51. package/dist/private/node/ui/components/Prompts/InfoTable.test.js +6 -4
  52. package/dist/private/node/ui/components/Prompts/InfoTable.test.js.map +1 -1
  53. package/dist/private/node/ui/components/Prompts/PromptLayout.d.ts +21 -0
  54. package/dist/private/node/ui/components/Prompts/PromptLayout.js +73 -0
  55. package/dist/private/node/ui/components/Prompts/PromptLayout.js.map +1 -0
  56. package/dist/private/node/ui/components/Prompts/PromptLayout.test.d.ts +1 -0
  57. package/dist/private/node/ui/components/Prompts/PromptLayout.test.js +129 -0
  58. package/dist/private/node/ui/components/Prompts/PromptLayout.test.js.map +1 -0
  59. package/dist/private/node/ui/components/Scrollbar.d.ts +10 -0
  60. package/dist/private/node/ui/components/Scrollbar.js +44 -0
  61. package/dist/private/node/ui/components/Scrollbar.js.map +1 -0
  62. package/dist/private/node/ui/components/Scrollbar.test.d.ts +1 -0
  63. package/dist/private/node/ui/components/Scrollbar.test.js +96 -0
  64. package/dist/private/node/ui/components/Scrollbar.test.js.map +1 -0
  65. package/dist/private/node/ui/components/SelectInput.d.ts +3 -6
  66. package/dist/private/node/ui/components/SelectInput.js +57 -41
  67. package/dist/private/node/ui/components/SelectInput.js.map +1 -1
  68. package/dist/private/node/ui/components/SelectInput.test.js +120 -192
  69. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  70. package/dist/private/node/ui/components/SelectPrompt.d.ts +7 -6
  71. package/dist/private/node/ui/components/SelectPrompt.js +11 -68
  72. package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
  73. package/dist/private/node/ui/components/SelectPrompt.test.js +135 -65
  74. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  75. package/dist/private/node/ui/components/Table/Row.js +2 -1
  76. package/dist/private/node/ui/components/Table/Row.js.map +1 -1
  77. package/dist/private/node/ui/components/Table/Table.js +2 -1
  78. package/dist/private/node/ui/components/Table/Table.js.map +1 -1
  79. package/dist/private/node/ui/components/Tasks.js +1 -8
  80. package/dist/private/node/ui/components/Tasks.js.map +1 -1
  81. package/dist/private/node/ui/components/TextInput.d.ts +1 -0
  82. package/dist/private/node/ui/components/TextInput.js +10 -4
  83. package/dist/private/node/ui/components/TextInput.js.map +1 -1
  84. package/dist/private/node/ui/components/TextInput.test.js +27 -18
  85. package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
  86. package/dist/private/node/ui/components/TextPrompt.d.ts +2 -3
  87. package/dist/private/node/ui/components/TextPrompt.js +18 -16
  88. package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
  89. package/dist/private/node/ui/components/TextPrompt.test.js +25 -11
  90. package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
  91. package/dist/private/node/ui/hooks/use-prompt.d.ts +18 -0
  92. package/dist/private/node/ui/hooks/use-prompt.js +20 -0
  93. package/dist/private/node/ui/hooks/use-prompt.js.map +1 -0
  94. package/dist/private/node/ui/hooks/use-select-state.d.ts +4 -4
  95. package/dist/private/node/ui/hooks/use-select-state.js +9 -9
  96. package/dist/private/node/ui/hooks/use-select-state.js.map +1 -1
  97. package/dist/public/common/object.d.ts +16 -0
  98. package/dist/public/common/object.js +26 -0
  99. package/dist/public/common/object.js.map +1 -1
  100. package/dist/public/common/string.d.ts +16 -0
  101. package/dist/public/common/string.js +30 -0
  102. package/dist/public/common/string.js.map +1 -1
  103. package/dist/public/common/version.d.ts +1 -1
  104. package/dist/public/common/version.js +1 -1
  105. package/dist/public/common/version.js.map +1 -1
  106. package/dist/public/node/analytics.js +3 -1
  107. package/dist/public/node/analytics.js.map +1 -1
  108. package/dist/public/node/api/partners.js +11 -2
  109. package/dist/public/node/api/partners.js.map +1 -1
  110. package/dist/public/node/base-command.d.ts +1 -0
  111. package/dist/public/node/base-command.js +21 -1
  112. package/dist/public/node/base-command.js.map +1 -1
  113. package/dist/public/node/figures.d.ts +2 -0
  114. package/dist/public/node/figures.js +3 -0
  115. package/dist/public/node/figures.js.map +1 -0
  116. package/dist/public/node/http.js +5 -2
  117. package/dist/public/node/http.js.map +1 -1
  118. package/dist/public/node/metadata.d.ts +2 -1
  119. package/dist/public/node/metadata.js +5 -2
  120. package/dist/public/node/metadata.js.map +1 -1
  121. package/dist/public/node/monorail.d.ts +22 -1
  122. package/dist/public/node/monorail.js +1 -1
  123. package/dist/public/node/monorail.js.map +1 -1
  124. package/dist/public/node/node-package-manager.d.ts +2 -0
  125. package/dist/public/node/node-package-manager.js +5 -2
  126. package/dist/public/node/node-package-manager.js.map +1 -1
  127. package/dist/public/node/output.d.ts +1 -1
  128. package/dist/public/node/output.js +1 -1
  129. package/dist/public/node/output.js.map +1 -1
  130. package/dist/public/node/ruby.d.ts +1 -0
  131. package/dist/public/node/ruby.js +1 -0
  132. package/dist/public/node/ruby.js.map +1 -1
  133. package/dist/public/node/system.js +2 -2
  134. package/dist/public/node/system.js.map +1 -1
  135. package/dist/public/node/themes/models/theme.d.ts +2 -1
  136. package/dist/public/node/themes/models/theme.js +2 -1
  137. package/dist/public/node/themes/models/theme.js.map +1 -1
  138. package/dist/public/node/themes/theme-urls.d.ts +1 -0
  139. package/dist/public/node/themes/theme-urls.js +4 -0
  140. package/dist/public/node/themes/theme-urls.js.map +1 -1
  141. package/dist/public/node/themes/themes-api.d.ts +9 -1
  142. package/dist/public/node/themes/themes-api.js +14 -3
  143. package/dist/public/node/themes/themes-api.js.map +1 -1
  144. package/dist/public/node/toml.d.ts +3 -2
  145. package/dist/public/node/toml.js +5 -2
  146. package/dist/public/node/toml.js.map +1 -1
  147. package/dist/public/node/ui.d.ts +82 -27
  148. package/dist/public/node/ui.js +97 -32
  149. package/dist/public/node/ui.js.map +1 -1
  150. package/dist/tsconfig.tsbuildinfo +1 -1
  151. package/package.json +15 -14
  152. package/dist/private/node/ui/components/GitDiff.js.map +0 -1
  153. package/dist/private/node/ui/components/GitDiff.test.js.map +0 -1
  154. /package/dist/private/node/ui/components/{GitDiff.test.d.ts → DangerousConfirmationPrompt.test.d.ts} +0 -0
@@ -1,10 +1,11 @@
1
1
  export const DEVELOPMENT_THEME_ROLE = 'development';
2
2
  export class Theme {
3
- constructor(id, name, _role, createdAtRuntime = false) {
3
+ constructor(id, name, _role, createdAtRuntime = false, processing = false) {
4
4
  this.id = id;
5
5
  this.name = name;
6
6
  this._role = _role;
7
7
  this.createdAtRuntime = createdAtRuntime;
8
+ this.processing = processing;
8
9
  }
9
10
  get role() {
10
11
  if (this._role === 'main') {
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../../../src/public/node/themes/models/theme.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CAAA;AAEnD,MAAM,OAAO,KAAK;IAChB,YAAmB,EAAU,EAAS,IAAY,EAAU,KAAa,EAAS,mBAAmB,KAAK;QAAvF,OAAE,GAAF,EAAE,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAQ;QAAU,UAAK,GAAL,KAAK,CAAQ;QAAS,qBAAgB,GAAhB,gBAAgB,CAAQ;IAAG,CAAC;IAE9G,IAAI,IAAI;QACN,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE;YACzB,OAAO,MAAM,CAAA;SACd;aAAM;YACL,OAAO,IAAI,CAAC,KAAK,CAAA;SAClB;IACH,CAAC;IAED,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,KAAK,KAAK,MAAM,EAAE;YACpB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAA;SACpB;aAAM;YACL,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;SACnB;IACH,CAAC;IAED,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAA;IAC7C,CAAC;CACF","sourcesContent":["export const DEVELOPMENT_THEME_ROLE = 'development'\n\nexport class Theme {\n constructor(public id: number, public name: string, private _role: string, public createdAtRuntime = false) {}\n\n get role(): string {\n if (this._role === 'main') {\n return 'live'\n } else {\n return this._role\n }\n }\n\n set role(_role: string) {\n if (_role === 'live') {\n this._role = 'main'\n } else {\n this._role = _role\n }\n }\n\n get hasDevelopmentRole(): boolean {\n return this.role === DEVELOPMENT_THEME_ROLE\n }\n}\n"]}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../../../src/public/node/themes/models/theme.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CAAA;AAEnD,MAAM,OAAO,KAAK;IAChB,YACS,EAAU,EACV,IAAY,EACX,KAAa,EACd,mBAAmB,KAAK,EACxB,aAAa,KAAK;QAJlB,OAAE,GAAF,EAAE,CAAQ;QACV,SAAI,GAAJ,IAAI,CAAQ;QACX,UAAK,GAAL,KAAK,CAAQ;QACd,qBAAgB,GAAhB,gBAAgB,CAAQ;QACxB,eAAU,GAAV,UAAU,CAAQ;IACxB,CAAC;IAEJ,IAAI,IAAI;QACN,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE;YACzB,OAAO,MAAM,CAAA;SACd;aAAM;YACL,OAAO,IAAI,CAAC,KAAK,CAAA;SAClB;IACH,CAAC;IAED,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,KAAK,KAAK,MAAM,EAAE;YACpB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAA;SACpB;aAAM;YACL,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;SACnB;IACH,CAAC;IAED,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAA;IAC7C,CAAC;CACF","sourcesContent":["export const DEVELOPMENT_THEME_ROLE = 'development'\n\nexport class Theme {\n constructor(\n public id: number,\n public name: string,\n private _role: string,\n public createdAtRuntime = false,\n public processing = false,\n ) {}\n\n get role(): string {\n if (this._role === 'main') {\n return 'live'\n } else {\n return this._role\n }\n }\n\n set role(_role: string) {\n if (_role === 'live') {\n this._role = 'main'\n } else {\n this._role = _role\n }\n }\n\n get hasDevelopmentRole(): boolean {\n return this.role === DEVELOPMENT_THEME_ROLE\n }\n}\n"]}
@@ -2,4 +2,5 @@ import { Theme } from '@shopify/cli-kit/node/themes/models/theme';
2
2
  import { AdminSession } from '@shopify/cli-kit/node/session';
3
3
  export declare function themePreviewUrl(theme: Theme, session: AdminSession): string;
4
4
  export declare function themeEditorUrl(theme: Theme, session: AdminSession): string;
5
+ export declare function codeEditorUrl(theme: Theme, session: AdminSession): string;
5
6
  export declare function storeAdminUrl(session: AdminSession): string;
@@ -9,6 +9,10 @@ export function themeEditorUrl(theme, session) {
9
9
  const store = session.storeFqdn;
10
10
  return `https://${store}/admin/themes/${theme.id}/editor`;
11
11
  }
12
+ export function codeEditorUrl(theme, session) {
13
+ const store = session.storeFqdn;
14
+ return `https://${store}/admin/themes/${theme.id}`;
15
+ }
12
16
  export function storeAdminUrl(session) {
13
17
  const store = session.storeFqdn;
14
18
  return `https://${store}/admin`;
@@ -1 +1 @@
1
- {"version":3,"file":"theme-urls.js","sourceRoot":"","sources":["../../../../src/public/node/themes/theme-urls.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,OAAqB;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;QACzB,OAAO,WAAW,KAAK,EAAE,CAAA;KAC1B;IAED,OAAO,WAAW,KAAK,qBAAqB,KAAK,CAAC,EAAE,EAAE,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,OAAqB;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,OAAO,WAAW,KAAK,iBAAiB,KAAK,CAAC,EAAE,SAAS,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAqB;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,OAAO,WAAW,KAAK,QAAQ,CAAA;AACjC,CAAC","sourcesContent":["import {Theme} from '@shopify/cli-kit/node/themes/models/theme'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\n\nexport function themePreviewUrl(theme: Theme, session: AdminSession) {\n const store = session.storeFqdn\n if (theme.role === 'live') {\n return `https://${store}`\n }\n\n return `https://${store}?preview_theme_id=${theme.id}`\n}\n\nexport function themeEditorUrl(theme: Theme, session: AdminSession) {\n const store = session.storeFqdn\n return `https://${store}/admin/themes/${theme.id}/editor`\n}\n\nexport function storeAdminUrl(session: AdminSession) {\n const store = session.storeFqdn\n return `https://${store}/admin`\n}\n"]}
1
+ {"version":3,"file":"theme-urls.js","sourceRoot":"","sources":["../../../../src/public/node/themes/theme-urls.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,OAAqB;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;QACzB,OAAO,WAAW,KAAK,EAAE,CAAA;KAC1B;IAED,OAAO,WAAW,KAAK,qBAAqB,KAAK,CAAC,EAAE,EAAE,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,OAAqB;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,OAAO,WAAW,KAAK,iBAAiB,KAAK,CAAC,EAAE,SAAS,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,OAAqB;IAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,OAAO,WAAW,KAAK,iBAAiB,KAAK,CAAC,EAAE,EAAE,CAAA;AACpD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAqB;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,OAAO,WAAW,KAAK,QAAQ,CAAA;AACjC,CAAC","sourcesContent":["import {Theme} from '@shopify/cli-kit/node/themes/models/theme'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\n\nexport function themePreviewUrl(theme: Theme, session: AdminSession) {\n const store = session.storeFqdn\n if (theme.role === 'live') {\n return `https://${store}`\n }\n\n return `https://${store}?preview_theme_id=${theme.id}`\n}\n\nexport function themeEditorUrl(theme: Theme, session: AdminSession) {\n const store = session.storeFqdn\n return `https://${store}/admin/themes/${theme.id}/editor`\n}\n\nexport function codeEditorUrl(theme: Theme, session: AdminSession) {\n const store = session.storeFqdn\n return `https://${store}/admin/themes/${theme.id}`\n}\n\nexport function storeAdminUrl(session: AdminSession) {\n const store = session.storeFqdn\n return `https://${store}/admin`\n}\n"]}
@@ -1,9 +1,17 @@
1
1
  import { Theme } from './models/theme.js';
2
2
  import { AdminSession } from '@shopify/cli-kit/node/session';
3
- export type ThemeParams = Partial<Pick<Theme, 'name' | 'role'>>;
3
+ export type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing'>>;
4
4
  export declare function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined>;
5
5
  export declare function fetchThemes(session: AdminSession): Promise<Theme[]>;
6
6
  export declare function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined>;
7
+ interface UpgradeThemeOptions {
8
+ fromTheme: number;
9
+ toTheme: number;
10
+ script?: string;
11
+ session: AdminSession;
12
+ }
13
+ export declare function upgradeTheme(upgradeOptions: UpgradeThemeOptions): Promise<Theme | undefined>;
7
14
  export declare function updateTheme(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined>;
8
15
  export declare function publishTheme(id: number, session: AdminSession): Promise<Theme | undefined>;
9
16
  export declare function deleteTheme(id: number, session: AdminSession): Promise<Theme | undefined>;
17
+ export {};
@@ -6,17 +6,23 @@ import { retry } from '../../../private/node/themes/themes-api/retry.js';
6
6
  import { restRequest } from '@shopify/cli-kit/node/api/admin';
7
7
  import { AbortError } from '@shopify/cli-kit/node/error';
8
8
  export async function fetchTheme(id, session) {
9
- const response = await request('GET', `/themes/${id}`, session, undefined, { fields: 'id' });
9
+ const response = await request('GET', `/themes/${id}`, session, undefined, { fields: 'id,processing' });
10
10
  return buildTheme(response.json.theme);
11
11
  }
12
12
  export async function fetchThemes(session) {
13
- const response = await request('GET', '/themes', session, undefined, { fields: 'id,name,role' });
13
+ const response = await request('GET', '/themes', session, undefined, { fields: 'id,name,role,processing' });
14
14
  return buildThemes(response);
15
15
  }
16
16
  export async function createTheme(params, session) {
17
17
  const response = await request('POST', '/themes', session, { theme: { ...params } });
18
18
  return buildTheme({ ...response.json.theme, createdAtRuntime: true });
19
19
  }
20
+ export async function upgradeTheme(upgradeOptions) {
21
+ const { fromTheme, toTheme, session, script } = upgradeOptions;
22
+ const params = { from_theme: fromTheme, to_theme: toTheme, ...(script && { script }) };
23
+ const response = await request('POST', `/themes`, session, params);
24
+ return buildTheme(response.json.theme);
25
+ }
20
26
  export async function updateTheme(id, params, session) {
21
27
  const response = await request('PUT', `/themes/${id}`, session, { theme: { id, ...params } });
22
28
  return buildTheme(response.json.theme);
@@ -47,6 +53,8 @@ async function request(method, path, session, params, searchParams = {}) {
47
53
  return handleForbiddenError(session);
48
54
  case status === 401:
49
55
  throw new AbortError(`[${status}] API request unauthorized error`);
56
+ case status === 422:
57
+ throw new AbortError(`[${status}] API request unprocessable content: ${errors(response)}`);
50
58
  case status >= 400 && status <= 499:
51
59
  throw new AbortError(`[${status}] API request client error`);
52
60
  case status >= 500 && status <= 599:
@@ -68,7 +76,7 @@ function buildTheme(themeJson) {
68
76
  if (!themeJson?.id) {
69
77
  return undefined;
70
78
  }
71
- return new Theme(themeJson.id, themeJson.name, themeJson.role, themeJson.createdAtRuntime);
79
+ return new Theme(themeJson.id, themeJson.name, themeJson.role, themeJson.createdAtRuntime, themeJson.processing);
72
80
  }
73
81
  function handleForbiddenError(session) {
74
82
  const store = session.storeFqdn;
@@ -82,4 +90,7 @@ function handleForbiddenError(session) {
82
90
  'Shopify CLI. Logging in to the Shopify admin directly connects the development ' +
83
91
  'store with your Shopify login.');
84
92
  }
93
+ function errors(response) {
94
+ return JSON.stringify(response.json?.errors);
95
+ }
85
96
  //# sourceMappingURL=themes-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"themes-api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/themes-api.ts"],"names":[],"mappings":"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","sourcesContent":["import {storeAdminUrl} from './theme-urls.js'\nimport {Theme} from './models/theme.js'\nimport * as throttler from '../../../private/node/themes/themes-api/throttler.js'\nimport {apiCallLimit, retryAfter} from '../../../private/node/themes/themes-api/headers.js'\nimport {retry} from '../../../private/node/themes/themes-api/retry.js'\nimport {restRequest, RestResponse} from '@shopify/cli-kit/node/api/admin'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\nimport {AbortError} from '@shopify/cli-kit/node/error'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role'>>\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('GET', `/themes/${id}`, session, undefined, {fields: 'id'})\n return buildTheme(response.json.theme)\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const response = await request('GET', '/themes', session, undefined, {fields: 'id,name,role'})\n return buildThemes(response)\n}\n\nexport async function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('POST', '/themes', session, {theme: {...params}})\n return buildTheme({...response.json.theme, createdAtRuntime: true})\n}\n\nexport async function updateTheme(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('PUT', `/themes/${id}`, session, {theme: {id, ...params}})\n return buildTheme(response.json.theme)\n}\n\nexport async function publishTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n return updateTheme(id, {role: 'main'}, session)\n}\n\nexport async function deleteTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('DELETE', `/themes/${id}`, session)\n return buildTheme(response.json.theme)\n}\n\nasync function request<T>(\n method: string,\n path: string,\n session: AdminSession,\n params?: T,\n searchParams: {[name: string]: string} = {},\n): Promise<RestResponse> {\n const response = await throttler.throttle(() => restRequest(method, path, session, params, searchParams))\n\n const status = response.status\n const callLimit = apiCallLimit(response)\n\n throttler.updateApiCallLimit(callLimit)\n\n switch (true) {\n case status >= 200 && status <= 399:\n // Returns the successful reponse\n return response\n case status === 404:\n // Defer the decision when a resource is not found\n return response\n case status === 429:\n // Retry following the \"retry-after\" header\n return retry(() => request(method, path, session, params, searchParams), retryAfter(response))\n case status === 403:\n return handleForbiddenError(session)\n case status === 401:\n throw new AbortError(`[${status}] API request unauthorized error`)\n case status >= 400 && status <= 499:\n throw new AbortError(`[${status}] API request client error`)\n case status >= 500 && status <= 599:\n throw new AbortError(`[${status}] API request server error`)\n default:\n throw new AbortError(`[${status}] API request unexpected error`)\n }\n}\n\nfunction buildThemes(response: RestResponse): Theme[] {\n const themes = response.json?.themes\n\n if (themes?.length > 0) {\n return themes.map(buildTheme)\n }\n\n return []\n}\n\n// Using `any` to avoid introducing extra DTO layers.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction buildTheme(themeJson: any): Theme | undefined {\n if (!themeJson?.id) {\n return undefined\n }\n\n return new Theme(themeJson.id, themeJson.name, themeJson.role, themeJson.createdAtRuntime)\n}\n\nfunction handleForbiddenError(session: AdminSession): never {\n const store = session.storeFqdn\n const adminUrl = storeAdminUrl(session)\n\n throw new AbortError(\n `You are not authorized to edit themes on \"${store}\".`,\n \"You can't use Shopify CLI with development stores if you only have Partner staff \" +\n 'member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n `store URL at least once (for example, using \"${adminUrl}\") before you log in using ` +\n 'Shopify CLI. Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.',\n )\n}\n"]}
1
+ {"version":3,"file":"themes-api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/themes-api.ts"],"names":[],"mappings":"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","sourcesContent":["import {storeAdminUrl} from './theme-urls.js'\nimport {Theme} from './models/theme.js'\nimport * as throttler from '../../../private/node/themes/themes-api/throttler.js'\nimport {apiCallLimit, retryAfter} from '../../../private/node/themes/themes-api/headers.js'\nimport {retry} from '../../../private/node/themes/themes-api/retry.js'\nimport {restRequest, RestResponse} from '@shopify/cli-kit/node/api/admin'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\nimport {AbortError} from '@shopify/cli-kit/node/error'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing'>>\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('GET', `/themes/${id}`, session, undefined, {fields: 'id,processing'})\n return buildTheme(response.json.theme)\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const response = await request('GET', '/themes', session, undefined, {fields: 'id,name,role,processing'})\n return buildThemes(response)\n}\n\nexport async function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('POST', '/themes', session, {theme: {...params}})\n return buildTheme({...response.json.theme, createdAtRuntime: true})\n}\n\ninterface UpgradeThemeOptions {\n fromTheme: number\n toTheme: number\n script?: string\n session: AdminSession\n}\n\nexport async function upgradeTheme(upgradeOptions: UpgradeThemeOptions): Promise<Theme | undefined> {\n const {fromTheme, toTheme, session, script} = upgradeOptions\n const params = {from_theme: fromTheme, to_theme: toTheme, ...(script && {script})}\n const response = await request('POST', `/themes`, session, params)\n return buildTheme(response.json.theme)\n}\n\nexport async function updateTheme(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('PUT', `/themes/${id}`, session, {theme: {id, ...params}})\n return buildTheme(response.json.theme)\n}\n\nexport async function publishTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n return updateTheme(id, {role: 'main'}, session)\n}\n\nexport async function deleteTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('DELETE', `/themes/${id}`, session)\n return buildTheme(response.json.theme)\n}\n\nasync function request<T>(\n method: string,\n path: string,\n session: AdminSession,\n params?: T,\n searchParams: {[name: string]: string} = {},\n): Promise<RestResponse> {\n const response = await throttler.throttle(() => restRequest(method, path, session, params, searchParams))\n\n const status = response.status\n const callLimit = apiCallLimit(response)\n\n throttler.updateApiCallLimit(callLimit)\n\n switch (true) {\n case status >= 200 && status <= 399:\n // Returns the successful reponse\n return response\n case status === 404:\n // Defer the decision when a resource is not found\n return response\n case status === 429:\n // Retry following the \"retry-after\" header\n return retry(() => request(method, path, session, params, searchParams), retryAfter(response))\n case status === 403:\n return handleForbiddenError(session)\n case status === 401:\n throw new AbortError(`[${status}] API request unauthorized error`)\n case status === 422:\n throw new AbortError(`[${status}] API request unprocessable content: ${errors(response)}`)\n case status >= 400 && status <= 499:\n throw new AbortError(`[${status}] API request client error`)\n case status >= 500 && status <= 599:\n throw new AbortError(`[${status}] API request server error`)\n default:\n throw new AbortError(`[${status}] API request unexpected error`)\n }\n}\n\nfunction buildThemes(response: RestResponse): Theme[] {\n const themes = response.json?.themes\n\n if (themes?.length > 0) {\n return themes.map(buildTheme)\n }\n\n return []\n}\n\n// Using `any` to avoid introducing extra DTO layers.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction buildTheme(themeJson: any): Theme | undefined {\n if (!themeJson?.id) {\n return undefined\n }\n\n return new Theme(themeJson.id, themeJson.name, themeJson.role, themeJson.createdAtRuntime, themeJson.processing)\n}\n\nfunction handleForbiddenError(session: AdminSession): never {\n const store = session.storeFqdn\n const adminUrl = storeAdminUrl(session)\n\n throw new AbortError(\n `You are not authorized to edit themes on \"${store}\".`,\n \"You can't use Shopify CLI with development stores if you only have Partner staff \" +\n 'member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n `store URL at least once (for example, using \"${adminUrl}\") before you log in using ` +\n 'Shopify CLI. Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.',\n )\n}\n\nfunction errors(response: RestResponse) {\n return JSON.stringify(response.json?.errors)\n}\n"]}
@@ -1,4 +1,5 @@
1
- import * as toml from '@iarna/toml';
1
+ import { JsonMap } from '../../private/common/json.js';
2
+ export type JsonMapType = JsonMap;
2
3
  /**
3
4
  * Given a TOML string, it returns a JSON object.
4
5
  *
@@ -12,4 +13,4 @@ export declare function decodeToml(input: string): object;
12
13
  * @param content - JSON object.
13
14
  * @returns TOML string.
14
15
  */
15
- export declare function encodeToml(content: toml.JsonMap): string;
16
+ export declare function encodeToml(content: JsonMap | object): string;
@@ -6,7 +6,8 @@ import * as toml from '@iarna/toml';
6
6
  * @returns JSON object.
7
7
  */
8
8
  export function decodeToml(input) {
9
- return toml.parse(input);
9
+ const normalizedInput = input.replace(/\r\n$/g, '\n');
10
+ return toml.parse(normalizedInput);
10
11
  }
11
12
  /**
12
13
  * Given a JSON object, it returns a TOML string.
@@ -15,6 +16,8 @@ export function decodeToml(input) {
15
16
  * @returns TOML string.
16
17
  */
17
18
  export function encodeToml(content) {
18
- return toml.stringify(content);
19
+ // our JsonMap type is fine with nulls/undefined, but the typing for TOML library isn't.
20
+ const tomlSafeContent = content;
21
+ return toml.stringify(tomlSafeContent);
19
22
  }
20
23
  //# sourceMappingURL=toml.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toml.js","sourceRoot":"","sources":["../../../src/public/node/toml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAqB;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC","sourcesContent":["import * as toml from '@iarna/toml'\n\n/**\n * Given a TOML string, it returns a JSON object.\n *\n * @param input - TOML string.\n * @returns JSON object.\n */\nexport function decodeToml(input: string): object {\n return toml.parse(input)\n}\n\n/**\n * Given a JSON object, it returns a TOML string.\n *\n * @param content - JSON object.\n * @returns TOML string.\n */\nexport function encodeToml(content: toml.JsonMap): string {\n return toml.stringify(content)\n}\n"]}
1
+ {"version":3,"file":"toml.js","sourceRoot":"","sources":["../../../src/public/node/toml.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AAInC;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAyB;IAClD,wFAAwF;IACxF,MAAM,eAAe,GAAG,OAAuB,CAAA;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;AACxC,CAAC","sourcesContent":["import {JsonMap} from '../../private/common/json.js'\nimport * as toml from '@iarna/toml'\n\nexport type JsonMapType = JsonMap\n\n/**\n * Given a TOML string, it returns a JSON object.\n *\n * @param input - TOML string.\n * @returns JSON object.\n */\nexport function decodeToml(input: string): object {\n const normalizedInput = input.replace(/\\r\\n$/g, '\\n')\n return toml.parse(normalizedInput)\n}\n\n/**\n * Given a JSON object, it returns a TOML string.\n *\n * @param content - JSON object.\n * @returns TOML string.\n */\nexport function encodeToml(content: JsonMap | object): string {\n // our JsonMap type is fine with nulls/undefined, but the typing for TOML library isn't.\n const tomlSafeContent = content as toml.JsonMap\n return toml.stringify(tomlSafeContent)\n}\n"]}
@@ -6,11 +6,13 @@ import { CustomSection } from '../../private/node/ui/components/Alert.js';
6
6
  import ScalarDict from '../../private/node/ui/components/Table/ScalarDict.js';
7
7
  import { TableColumn, TableProps } from '../../private/node/ui/components/Table/Table.js';
8
8
  import { InlineToken, LinkToken, ListToken, TokenItem } from '../../private/node/ui/components/TokenizedText.js';
9
+ import { DangerousConfirmationPromptProps } from '../../private/node/ui/components/DangerousConfirmationPrompt.js';
9
10
  import { SelectPromptProps } from '../../private/node/ui/components/SelectPrompt.js';
10
11
  import { Task } from '../../private/node/ui/components/Tasks.js';
11
12
  import { TextPromptProps } from '../../private/node/ui/components/TextPrompt.js';
12
13
  import { AutocompletePromptProps } from '../../private/node/ui/components/AutocompletePrompt.js';
13
14
  import { InfoTableSection } from '../../private/node/ui/components/Prompts/InfoTable.js';
15
+ import { InfoMessageProps } from '../../private/node/ui/components/Prompts/InfoMessage.js';
14
16
  import { Key as InkKey, RenderOptions } from 'ink';
15
17
  type PartialBy<T, TKey extends keyof T> = Omit<T, TKey> & Partial<Pick<T, TKey>>;
16
18
  export interface RenderConcurrentOptions extends PartialBy<ConcurrentOutputProps, 'abortSignal'> {
@@ -19,12 +21,12 @@ export interface RenderConcurrentOptions extends PartialBy<ConcurrentOutputProps
19
21
  /**
20
22
  * Renders output from concurrent processes to the terminal with {@link ConcurrentOutput}.
21
23
  * @example
22
- * 0000-00-00 00:00:00 │ backend │ first backend message
23
- * 0000-00-00 00:00:00 │ backend │ second backend message
24
- * 0000-00-00 00:00:00 │ backend │ third backend message
25
- * 0000-00-00 00:00:00 │ frontend │ first frontend message
26
- * 0000-00-00 00:00:00 │ frontend │ second frontend message
27
- * 0000-00-00 00:00:00 │ frontend │ third frontend message
24
+ * 00:00:00 │ backend │ first backend message
25
+ * 00:00:00 │ backend │ second backend message
26
+ * 00:00:00 │ backend │ third backend message
27
+ * 00:00:00 │ frontend │ first frontend message
28
+ * 00:00:00 │ frontend │ second frontend message
29
+ * 00:00:00 │ frontend │ third frontend message
28
30
  *
29
31
  * › Press p │ preview in your browser
30
32
  * › Press q │ quit.
@@ -132,6 +134,20 @@ export declare function renderSuccess(options: RenderAlertOptions): string | und
132
134
  *
133
135
  */
134
136
  export declare function renderWarning(options: RenderAlertOptions): string | undefined;
137
+ /**
138
+ * Renders an error banner to the console.
139
+ * @example
140
+ * ╭─ error ──────────────────────────────────────────────────╮
141
+ * │ │
142
+ * │ Version couldn't be released. │
143
+ * │ │
144
+ * │ This version needs to be submitted for review and │
145
+ * │ approved by Shopify before it can be released. │
146
+ * │ │
147
+ * ╰──────────────────────────────────────────────────────────╯
148
+ *
149
+ */
150
+ export declare function renderError(options: RenderAlertOptions): string | undefined;
135
151
  interface RenderFatalErrorOptions {
136
152
  renderOptions?: RenderOptions;
137
153
  }
@@ -185,32 +201,34 @@ export interface RenderSelectPromptOptions<T> extends Omit<SelectPromptProps<T>,
185
201
  * @example
186
202
  * ? Associate your project with the org Castile Ventures?
187
203
  *
188
- * Add: • new-ext
189
- *
190
- * Remove: • integrated-demand-ext
191
- * • order-discount
204
+ *Add
205
+ * ┃ • new-ext
206
+ *
207
+ * ┃ Remove
208
+ * ┃ • integrated-demand-ext
209
+ * ┃ • order-discount
192
210
  *
193
211
  * Automations
194
- * > (a) fifth
195
- * (2) sixth
212
+ * > fifth
213
+ * sixth
196
214
  *
197
215
  * Merchant Admin
198
- * (3) eighth
199
- * (4) ninth
216
+ * eighth
217
+ * ninth
200
218
  *
201
219
  * Other
202
- * (f) first
203
- * (s) second
204
- * (7) third (limit reached)
205
- * (8) fourth
206
- * (9) seventh
207
- * (10) tenth
220
+ * first
221
+ * second
222
+ * third (limit reached)
223
+ * fourth
224
+ * seventh
225
+ * tenth
208
226
  *
209
- * Press ↑↓ arrows to select, enter to confirm
227
+ * Press ↑↓ arrows to select, enter to confirm.
210
228
  *
211
229
  */
212
230
  export declare function renderSelectPrompt<T>({ renderOptions, isConfirmationPrompt, ...props }: RenderSelectPromptOptions<T>): Promise<T>;
213
- export interface RenderConfirmationPromptOptions extends Pick<SelectPromptProps<boolean>, 'message' | 'infoTable' | 'gitDiff' | 'abortSignal'> {
231
+ export interface RenderConfirmationPromptOptions extends Pick<SelectPromptProps<boolean>, 'message' | 'infoTable' | 'infoMessage' | 'gitDiff' | 'abortSignal'> {
214
232
  confirmationMessage?: string;
215
233
  cancellationMessage?: string;
216
234
  renderOptions?: RenderOptions;
@@ -221,16 +239,21 @@ export interface RenderConfirmationPromptOptions extends Pick<SelectPromptProps<
221
239
  * @example
222
240
  * ? Delete the following themes from the store?
223
241
  *
224
- * first theme (#1)
225
- * • second theme (#2)
242
+ * ┃ Info message title
243
+ *
244
+ * ┃ Info message body
245
+ * ┃
246
+ * ┃ • first theme (#1)
247
+ * ┃ • second theme (#2)
226
248
  *
227
249
  * > (y) Yes, confirm changes
228
250
  * (n) Cancel
229
251
  *
230
- * Press ↑↓ arrows to select, enter or a shortcut to confirm
252
+ * Press ↑↓ arrows to select, enter or a shortcut to
253
+ * confirm.
231
254
  *
232
255
  */
233
- export declare function renderConfirmationPrompt({ message, infoTable, gitDiff, confirmationMessage, cancellationMessage, renderOptions, defaultValue, abortSignal, }: RenderConfirmationPromptOptions): Promise<boolean>;
256
+ export declare function renderConfirmationPrompt({ message, infoTable, gitDiff, confirmationMessage, cancellationMessage, renderOptions, defaultValue, abortSignal, infoMessage, }: RenderConfirmationPromptOptions): Promise<boolean>;
234
257
  export interface RenderAutocompleteOptions<T> extends PartialBy<Omit<AutocompletePromptProps<T>, 'onSubmit'>, 'search'> {
235
258
  renderOptions?: RenderOptions;
236
259
  }
@@ -239,6 +262,10 @@ export interface RenderAutocompleteOptions<T> extends PartialBy<Omit<Autocomplet
239
262
  * @example
240
263
  * ? Select a template: Type to search...
241
264
  *
265
+ * ┃ Info message title
266
+ * ┃
267
+ * ┃ Info message body
268
+ *
242
269
  * > first
243
270
  * second
244
271
  * third
@@ -265,7 +292,7 @@ export interface RenderAutocompleteOptions<T> extends PartialBy<Omit<Autocomplet
265
292
  * twenty-fourth
266
293
  * twenty-fifth
267
294
  *
268
- * Press ↑↓ arrows to select, enter to confirm
295
+ * Press ↑↓ arrows to select, enter to confirm.
269
296
  *
270
297
  */
271
298
  export declare function renderAutocompletePrompt<T>({ renderOptions, ...props }: RenderAutocompleteOptions<T>): Promise<T>;
@@ -304,6 +331,33 @@ export interface RenderTextPromptOptions extends Omit<TextPromptProps, 'onSubmit
304
331
  *
305
332
  */
306
333
  export declare function renderTextPrompt({ renderOptions, ...props }: RenderTextPromptOptions): Promise<string>;
334
+ export interface RenderDangerousConfirmationPromptOptions extends Omit<DangerousConfirmationPromptProps, 'onSubmit'> {
335
+ renderOptions?: RenderOptions;
336
+ }
337
+ /**
338
+ * Renders a dangerous confirmation prompt to the console, forcing the user to
339
+ * type a confirmation string to proceed.
340
+ * @example
341
+ * ? Release a new version of nightly-app-2023-06-19?
342
+ *
343
+ * ┃ Includes:
344
+ * ┃ + web-px (new)
345
+ * ┃ + sub-ui-ext
346
+ * ┃ + theme-app-ext
347
+ * ┃ + paymentify (from Partner Dashboard)
348
+ * ┃
349
+ * ┃ Removes:
350
+ * ┃ - prod-discount-fun
351
+ * ┃
352
+ * ┃ This can permanently delete app user data.
353
+ *
354
+ * Type nightly-app-2023-06-19 to confirm, or press Escape
355
+ * to cancel.
356
+ * > █
357
+ * ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
358
+ *
359
+ */
360
+ export declare function renderDangerousConfirmationPrompt({ renderOptions, ...props }: RenderDangerousConfirmationPromptOptions): Promise<boolean>;
307
361
  interface RenderTextOptions {
308
362
  text: string;
309
363
  logLevel?: LogLevel;
@@ -319,4 +373,5 @@ export declare function renderText({ text, logLevel, logger }: RenderTextOptions
319
373
  /** Waits for any key to be pressed except Ctrl+C which will terminate the process. */
320
374
  export declare const keypress: () => Promise<unknown>;
321
375
  export type Key = InkKey;
376
+ export type InfoMessage = InfoMessageProps['message'];
322
377
  export { Task, TokenItem, InlineToken, LinkToken, TableColumn, InfoTableSection, ListToken };
@@ -10,6 +10,7 @@ import { alert } from '../../private/node/ui/alert.js';
10
10
  import { FatalError } from '../../private/node/ui/components/FatalError.js';
11
11
  import { Table } from '../../private/node/ui/components/Table/Table.js';
12
12
  import { tokenItemToString, } from '../../private/node/ui/components/TokenizedText.js';
13
+ import { DangerousConfirmationPrompt, } from '../../private/node/ui/components/DangerousConfirmationPrompt.js';
13
14
  import { SelectPrompt } from '../../private/node/ui/components/SelectPrompt.js';
14
15
  import { Tasks } from '../../private/node/ui/components/Tasks.js';
15
16
  import { TextPrompt } from '../../private/node/ui/components/TextPrompt.js';
@@ -19,12 +20,12 @@ import React from 'react';
19
20
  /**
20
21
  * Renders output from concurrent processes to the terminal with {@link ConcurrentOutput}.
21
22
  * @example
22
- * 0000-00-00 00:00:00 │ backend │ first backend message
23
- * 0000-00-00 00:00:00 │ backend │ second backend message
24
- * 0000-00-00 00:00:00 │ backend │ third backend message
25
- * 0000-00-00 00:00:00 │ frontend │ first frontend message
26
- * 0000-00-00 00:00:00 │ frontend │ second frontend message
27
- * 0000-00-00 00:00:00 │ frontend │ third frontend message
23
+ * 00:00:00 │ backend │ first backend message
24
+ * 00:00:00 │ backend │ second backend message
25
+ * 00:00:00 │ backend │ third backend message
26
+ * 00:00:00 │ frontend │ first frontend message
27
+ * 00:00:00 │ frontend │ second frontend message
28
+ * 00:00:00 │ frontend │ third frontend message
28
29
  *
29
30
  * › Press p │ preview in your browser
30
31
  * › Press q │ quit.
@@ -149,6 +150,22 @@ export function renderSuccess(options) {
149
150
  export function renderWarning(options) {
150
151
  return alert({ ...options, type: 'warning' });
151
152
  }
153
+ /**
154
+ * Renders an error banner to the console.
155
+ * @example
156
+ * ╭─ error ──────────────────────────────────────────────────╮
157
+ * │ │
158
+ * │ Version couldn't be released. │
159
+ * │ │
160
+ * │ This version needs to be submitted for review and │
161
+ * │ approved by Shopify before it can be released. │
162
+ * │ │
163
+ * ╰──────────────────────────────────────────────────────────╯
164
+ *
165
+ */
166
+ export function renderError(options) {
167
+ return alert({ ...options, type: 'error' });
168
+ }
152
169
  /**
153
170
  * Renders a Fatal error to the console inside a banner.
154
171
  * @example Basic
@@ -202,28 +219,30 @@ export function renderFatalError(error, { renderOptions } = {}) {
202
219
  * @example
203
220
  * ? Associate your project with the org Castile Ventures?
204
221
  *
205
- * Add: • new-ext
206
- *
207
- * Remove: • integrated-demand-ext
208
- * • order-discount
222
+ *Add
223
+ * ┃ • new-ext
224
+ *
225
+ * ┃ Remove
226
+ * ┃ • integrated-demand-ext
227
+ * ┃ • order-discount
209
228
  *
210
229
  * Automations
211
- * > (a) fifth
212
- * (2) sixth
230
+ * > fifth
231
+ * sixth
213
232
  *
214
233
  * Merchant Admin
215
- * (3) eighth
216
- * (4) ninth
234
+ * eighth
235
+ * ninth
217
236
  *
218
237
  * Other
219
- * (f) first
220
- * (s) second
221
- * (7) third (limit reached)
222
- * (8) fourth
223
- * (9) seventh
224
- * (10) tenth
238
+ * first
239
+ * second
240
+ * third (limit reached)
241
+ * fourth
242
+ * seventh
243
+ * tenth
225
244
  *
226
- * Press ↑↓ arrows to select, enter to confirm
245
+ * Press ↑↓ arrows to select, enter to confirm.
227
246
  *
228
247
  */
229
248
  export async function renderSelectPrompt({ renderOptions, isConfirmationPrompt, ...props }) {
@@ -246,16 +265,21 @@ export async function renderSelectPrompt({ renderOptions, isConfirmationPrompt,
246
265
  * @example
247
266
  * ? Delete the following themes from the store?
248
267
  *
249
- * first theme (#1)
250
- * • second theme (#2)
268
+ * ┃ Info message title
269
+ *
270
+ * ┃ Info message body
271
+ * ┃
272
+ * ┃ • first theme (#1)
273
+ * ┃ • second theme (#2)
251
274
  *
252
275
  * > (y) Yes, confirm changes
253
276
  * (n) Cancel
254
277
  *
255
- * Press ↑↓ arrows to select, enter or a shortcut to confirm
278
+ * Press ↑↓ arrows to select, enter or a shortcut to
279
+ * confirm.
256
280
  *
257
281
  */
258
- export async function renderConfirmationPrompt({ message, infoTable, gitDiff, confirmationMessage = 'Yes, confirm', cancellationMessage = 'No, cancel', renderOptions, defaultValue = true, abortSignal, }) {
282
+ export async function renderConfirmationPrompt({ message, infoTable, gitDiff, confirmationMessage = 'Yes, confirm', cancellationMessage = 'No, cancel', renderOptions, defaultValue = true, abortSignal, infoMessage, }) {
259
283
  // eslint-disable-next-line prefer-rest-params
260
284
  recordUIEvent({ type: 'confirmationPrompt', properties: arguments[0] });
261
285
  const choices = [
@@ -275,11 +299,11 @@ export async function renderConfirmationPrompt({ message, infoTable, gitDiff, co
275
299
  message,
276
300
  infoTable,
277
301
  gitDiff,
278
- submitWithShortcuts: true,
279
302
  renderOptions,
280
303
  defaultValue,
281
304
  isConfirmationPrompt: true,
282
305
  abortSignal,
306
+ infoMessage,
283
307
  });
284
308
  }
285
309
  /**
@@ -287,6 +311,10 @@ export async function renderConfirmationPrompt({ message, infoTable, gitDiff, co
287
311
  * @example
288
312
  * ? Select a template: Type to search...
289
313
  *
314
+ * ┃ Info message title
315
+ * ┃
316
+ * ┃ Info message body
317
+ *
290
318
  * > first
291
319
  * second
292
320
  * third
@@ -313,7 +341,7 @@ export async function renderConfirmationPrompt({ message, infoTable, gitDiff, co
313
341
  * twenty-fourth
314
342
  * twenty-fifth
315
343
  *
316
- * Press ↑↓ arrows to select, enter to confirm
344
+ * Press ↑↓ arrows to select, enter to confirm.
317
345
  *
318
346
  */
319
347
  export async function renderAutocompletePrompt({ renderOptions, ...props }) {
@@ -322,8 +350,11 @@ export async function renderAutocompletePrompt({ renderOptions, ...props }) {
322
350
  recordUIEvent({ type: 'autocompletePrompt', properties: arguments[0] });
323
351
  const newProps = {
324
352
  search(term) {
353
+ const lowerTerm = term.toLowerCase();
325
354
  return Promise.resolve({
326
- data: props.choices.filter((item) => item.label.toLowerCase().includes(term.toLowerCase())),
355
+ data: props.choices.filter((item) => {
356
+ return (item.label.toLowerCase().includes(lowerTerm) || (item.group && item.group.toLowerCase().includes(lowerTerm)));
357
+ }),
327
358
  });
328
359
  },
329
360
  ...props,
@@ -372,10 +403,7 @@ export async function renderTasks(tasks, { renderOptions } = {}) {
372
403
  });
373
404
  // eslint-disable-next-line max-params
374
405
  return new Promise((resolve, reject) => {
375
- render(React.createElement(Tasks, { tasks: tasks, onComplete: resolve }), {
376
- ...renderOptions,
377
- exitOnCtrlC: false,
378
- })
406
+ render(React.createElement(Tasks, { tasks: tasks, onComplete: resolve }), renderOptions)
379
407
  .then(() => resetRecordedSleep())
380
408
  .catch(reject);
381
409
  });
@@ -402,6 +430,43 @@ export async function renderTextPrompt({ renderOptions, ...props }) {
402
430
  .finally(resetRecordedSleep);
403
431
  });
404
432
  }
433
+ /**
434
+ * Renders a dangerous confirmation prompt to the console, forcing the user to
435
+ * type a confirmation string to proceed.
436
+ * @example
437
+ * ? Release a new version of nightly-app-2023-06-19?
438
+ *
439
+ * ┃ Includes:
440
+ * ┃ + web-px (new)
441
+ * ┃ + sub-ui-ext
442
+ * ┃ + theme-app-ext
443
+ * ┃ + paymentify (from Partner Dashboard)
444
+ * ┃
445
+ * ┃ Removes:
446
+ * ┃ - prod-discount-fun
447
+ * ┃
448
+ * ┃ This can permanently delete app user data.
449
+ *
450
+ * Type nightly-app-2023-06-19 to confirm, or press Escape
451
+ * to cancel.
452
+ * > █
453
+ * ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
454
+ *
455
+ */
456
+ export async function renderDangerousConfirmationPrompt({ renderOptions, ...props }) {
457
+ throwInNonTTY({ message: props.message, stdin: renderOptions?.stdin });
458
+ // eslint-disable-next-line prefer-rest-params
459
+ recordUIEvent({ type: 'dangerousConfirmationPrompt', properties: arguments[0] });
460
+ // eslint-disable-next-line max-params
461
+ return new Promise((resolve, reject) => {
462
+ render(React.createElement(DangerousConfirmationPrompt, { ...props, onSubmit: (value) => resolve(value) }), {
463
+ ...renderOptions,
464
+ exitOnCtrlC: false,
465
+ })
466
+ .catch(reject)
467
+ .finally(resetRecordedSleep);
468
+ });
469
+ }
405
470
  /** Renders a text string to the console.
406
471
  * Using this function makes sure that correct spacing is applied among the various components.
407
472
  * @example