@shopify/cli-kit 4.9.5 → 5.0.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 (124) hide show
  1. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.d.ts +5 -0
  2. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js +22 -0
  3. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js.map +1 -1
  4. package/dist/private/node/api/graphql.d.ts +2 -1
  5. package/dist/private/node/api/graphql.js +12 -1
  6. package/dist/private/node/api/graphql.js.map +1 -1
  7. package/dist/private/node/api.d.ts +2 -0
  8. package/dist/private/node/api.js +49 -22
  9. package/dist/private/node/api.js.map +1 -1
  10. package/dist/private/node/command-json-schema.js +1 -0
  11. package/dist/private/node/command-json-schema.js.map +1 -1
  12. package/dist/private/node/constants.d.ts +1 -0
  13. package/dist/private/node/constants.js +1 -0
  14. package/dist/private/node/constants.js.map +1 -1
  15. package/dist/private/node/dev-instance-output.d.ts +47 -0
  16. package/dist/private/node/dev-instance-output.js +143 -0
  17. package/dist/private/node/dev-instance-output.js.map +1 -0
  18. package/dist/private/node/json-error.d.ts +1 -15
  19. package/dist/private/node/json-error.js +4 -98
  20. package/dist/private/node/json-error.js.map +1 -1
  21. package/dist/private/node/output-context.d.ts +8 -0
  22. package/dist/private/node/output-context.js +10 -0
  23. package/dist/private/node/output-context.js.map +1 -0
  24. package/dist/private/node/output.test.js +4 -4
  25. package/dist/private/node/output.test.js.map +1 -1
  26. package/dist/private/node/session/automation-token.d.ts +50 -0
  27. package/dist/private/node/session/automation-token.js +77 -0
  28. package/dist/private/node/session/automation-token.js.map +1 -0
  29. package/dist/private/node/session/exchange.d.ts +2 -1
  30. package/dist/private/node/session/exchange.js +5 -3
  31. package/dist/private/node/session/exchange.js.map +1 -1
  32. package/dist/private/node/session/permanent-store-domain.d.ts +21 -0
  33. package/dist/private/node/session/permanent-store-domain.js +72 -0
  34. package/dist/private/node/session/permanent-store-domain.js.map +1 -0
  35. package/dist/private/node/session.d.ts +3 -2
  36. package/dist/private/node/session.js +12 -3
  37. package/dist/private/node/session.js.map +1 -1
  38. package/dist/private/node/themes/trust-challenge.d.ts +31 -0
  39. package/dist/private/node/themes/trust-challenge.js +143 -0
  40. package/dist/private/node/themes/trust-challenge.js.map +1 -0
  41. package/dist/private/node/ui/alert.js +1 -1
  42. package/dist/private/node/ui/alert.js.map +1 -1
  43. package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -7
  44. package/dist/private/node/ui/components/ConcurrentOutput.js +4 -8
  45. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  46. package/dist/private/node/ui/components/LoadingBar.js +9 -15
  47. package/dist/private/node/ui/components/LoadingBar.js.map +1 -1
  48. package/dist/private/node/ui/components/LoadingBar.test.js +45 -107
  49. package/dist/private/node/ui/components/LoadingBar.test.js.map +1 -1
  50. package/dist/private/node/ui/components/LoadingIndicator.d.ts +7 -0
  51. package/dist/private/node/ui/components/LoadingIndicator.js +22 -0
  52. package/dist/private/node/ui/components/LoadingIndicator.js.map +1 -0
  53. package/dist/public/common/version.d.ts +1 -1
  54. package/dist/public/common/version.js +1 -1
  55. package/dist/public/common/version.js.map +1 -1
  56. package/dist/public/node/api/admin.js +13 -0
  57. package/dist/public/node/api/admin.js.map +1 -1
  58. package/dist/public/node/api/graphql.js +38 -7
  59. package/dist/public/node/api/graphql.js.map +1 -1
  60. package/dist/public/node/archiver.js +13 -6
  61. package/dist/public/node/archiver.js.map +1 -1
  62. package/dist/public/node/base-command.d.ts +6 -0
  63. package/dist/public/node/base-command.js +97 -16
  64. package/dist/public/node/base-command.js.map +1 -1
  65. package/dist/public/node/dev-instance.d.ts +138 -0
  66. package/dist/public/node/dev-instance.js +365 -0
  67. package/dist/public/node/dev-instance.js.map +1 -0
  68. package/dist/public/node/environment.d.ts +6 -3
  69. package/dist/public/node/environment.js +11 -4
  70. package/dist/public/node/environment.js.map +1 -1
  71. package/dist/public/node/error/index.js +2 -1
  72. package/dist/public/node/error/index.js.map +1 -1
  73. package/dist/public/node/error/schema.d.ts +24 -24
  74. package/dist/public/node/error/serialization.d.ts +8 -0
  75. package/dist/public/node/error/serialization.js +103 -0
  76. package/dist/public/node/error/serialization.js.map +1 -0
  77. package/dist/public/node/graphiql/server.js +18 -2
  78. package/dist/public/node/graphiql/server.js.map +1 -1
  79. package/dist/public/node/is-global.js +2 -1
  80. package/dist/public/node/is-global.js.map +1 -1
  81. package/dist/public/node/notifications-system.d.ts +6 -6
  82. package/dist/public/node/path.d.ts +19 -3
  83. package/dist/public/node/path.js +21 -3
  84. package/dist/public/node/path.js.map +1 -1
  85. package/dist/public/node/session.d.ts +36 -2
  86. package/dist/public/node/session.js +48 -4
  87. package/dist/public/node/session.js.map +1 -1
  88. package/dist/public/node/system.d.ts +4 -0
  89. package/dist/public/node/system.js +39 -9
  90. package/dist/public/node/system.js.map +1 -1
  91. package/dist/public/node/themes/api.d.ts +9 -0
  92. package/dist/public/node/themes/api.js +50 -22
  93. package/dist/public/node/themes/api.js.map +1 -1
  94. package/dist/public/node/themes/theme-manager.d.ts +8 -1
  95. package/dist/public/node/themes/theme-manager.js +1 -1
  96. package/dist/public/node/themes/theme-manager.js.map +1 -1
  97. package/dist/public/node/tree-kill.js +12 -2
  98. package/dist/public/node/tree-kill.js.map +1 -1
  99. package/dist/public/node/ui/components.d.ts +1 -0
  100. package/dist/public/node/ui/components.js +1 -0
  101. package/dist/public/node/ui/components.js.map +1 -1
  102. package/dist/public/node/ui.d.ts +24 -4
  103. package/dist/public/node/ui.js +41 -18
  104. package/dist/public/node/ui.js.map +1 -1
  105. package/dist/public/node/upgrade/output.d.ts +17 -0
  106. package/dist/public/node/upgrade/output.js +51 -0
  107. package/dist/public/node/upgrade/output.js.map +1 -0
  108. package/dist/public/node/upgrade/result.d.ts +8 -0
  109. package/dist/public/node/upgrade/result.js +21 -0
  110. package/dist/public/node/upgrade/result.js.map +1 -0
  111. package/dist/public/node/upgrade/types.d.ts +61 -0
  112. package/dist/public/node/upgrade/types.js +46 -0
  113. package/dist/public/node/upgrade/types.js.map +1 -0
  114. package/dist/public/node/upgrade.d.ts +8 -0
  115. package/dist/public/node/upgrade.js +57 -22
  116. package/dist/public/node/upgrade.js.map +1 -1
  117. package/dist/tsconfig.tsbuildinfo +1 -1
  118. package/package.json +3 -3
  119. package/dist/private/node/ui/components/TextAnimation.d.ts +0 -10
  120. package/dist/private/node/ui/components/TextAnimation.js +0 -56
  121. package/dist/private/node/ui/components/TextAnimation.js.map +0 -1
  122. package/dist/private/node/ui/components/TextAnimation.test.d.ts +0 -1
  123. package/dist/private/node/ui/components/TextAnimation.test.js +0 -73
  124. package/dist/private/node/ui/components/TextAnimation.test.js.map +0 -1
@@ -2,9 +2,14 @@ import * as Types from './types.js';
2
2
  import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
3
3
  export type MetafieldDefinitionsByOwnerTypeQueryVariables = Types.Exact<{
4
4
  ownerType: Types.MetafieldOwnerType;
5
+ after?: Types.InputMaybe<Types.Scalars['String']['input']>;
5
6
  }>;
6
7
  export type MetafieldDefinitionsByOwnerTypeQuery = {
7
8
  metafieldDefinitions: {
9
+ pageInfo: {
10
+ hasNextPage: boolean;
11
+ endCursor?: string | null;
12
+ };
8
13
  nodes: {
9
14
  key: string;
10
15
  name: string;
@@ -11,6 +11,11 @@ export const MetafieldDefinitionsByOwnerType = {
11
11
  variable: { kind: 'Variable', name: { kind: 'Name', value: 'ownerType' } },
12
12
  type: { kind: 'NonNullType', type: { kind: 'NamedType', name: { kind: 'Name', value: 'MetafieldOwnerType' } } },
13
13
  },
14
+ {
15
+ kind: 'VariableDefinition',
16
+ variable: { kind: 'Variable', name: { kind: 'Name', value: 'after' } },
17
+ type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } },
18
+ },
14
19
  ],
15
20
  selectionSet: {
16
21
  kind: 'SelectionSet',
@@ -25,10 +30,27 @@ export const MetafieldDefinitionsByOwnerType = {
25
30
  value: { kind: 'Variable', name: { kind: 'Name', value: 'ownerType' } },
26
31
  },
27
32
  { kind: 'Argument', name: { kind: 'Name', value: 'first' }, value: { kind: 'IntValue', value: '250' } },
33
+ {
34
+ kind: 'Argument',
35
+ name: { kind: 'Name', value: 'after' },
36
+ value: { kind: 'Variable', name: { kind: 'Name', value: 'after' } },
37
+ },
28
38
  ],
29
39
  selectionSet: {
30
40
  kind: 'SelectionSet',
31
41
  selections: [
42
+ {
43
+ kind: 'Field',
44
+ name: { kind: 'Name', value: 'pageInfo' },
45
+ selectionSet: {
46
+ kind: 'SelectionSet',
47
+ selections: [
48
+ { kind: 'Field', name: { kind: 'Name', value: 'hasNextPage' } },
49
+ { kind: 'Field', name: { kind: 'Name', value: 'endCursor' } },
50
+ { kind: 'Field', name: { kind: 'Name', value: '__typename' } },
51
+ ],
52
+ },
53
+ },
32
54
  {
33
55
  kind: 'Field',
34
56
  name: { kind: 'Name', value: 'nodes' },
@@ -1 +1 @@
1
- {"version":3,"file":"metafield_definitions_by_owner_type.js","sourceRoot":"","sources":["../../../../../../src/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions */\nimport * as Types from './types.js'\n\nimport {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core'\n\nexport type MetafieldDefinitionsByOwnerTypeQueryVariables = Types.Exact<{\n ownerType: Types.MetafieldOwnerType\n}>\n\nexport type MetafieldDefinitionsByOwnerTypeQuery = {\n metafieldDefinitions: {\n nodes: {\n key: string\n name: string\n namespace: string\n description?: string | null\n type: {category: string; name: string}\n }[]\n }\n}\n\nexport const MetafieldDefinitionsByOwnerType = {\n kind: 'Document',\n definitions: [\n {\n kind: 'OperationDefinition',\n operation: 'query',\n name: {kind: 'Name', value: 'metafieldDefinitionsByOwnerType'},\n variableDefinitions: [\n {\n kind: 'VariableDefinition',\n variable: {kind: 'Variable', name: {kind: 'Name', value: 'ownerType'}},\n type: {kind: 'NonNullType', type: {kind: 'NamedType', name: {kind: 'Name', value: 'MetafieldOwnerType'}}},\n },\n ],\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'metafieldDefinitions'},\n arguments: [\n {\n kind: 'Argument',\n name: {kind: 'Name', value: 'ownerType'},\n value: {kind: 'Variable', name: {kind: 'Name', value: 'ownerType'}},\n },\n {kind: 'Argument', name: {kind: 'Name', value: 'first'}, value: {kind: 'IntValue', value: '250'}},\n ],\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'nodes'},\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {kind: 'Field', name: {kind: 'Name', value: 'key'}},\n {kind: 'Field', name: {kind: 'Name', value: 'name'}},\n {kind: 'Field', name: {kind: 'Name', value: 'namespace'}},\n {kind: 'Field', name: {kind: 'Name', value: 'description'}},\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'type'},\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {kind: 'Field', name: {kind: 'Name', value: 'category'}},\n {kind: 'Field', name: {kind: 'Name', value: 'name'}},\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n ],\n },\n },\n ],\n} as unknown as DocumentNode<MetafieldDefinitionsByOwnerTypeQuery, MetafieldDefinitionsByOwnerTypeQueryVariables>\n"]}
1
+ {"version":3,"file":"metafield_definitions_by_owner_type.js","sourceRoot":"","sources":["../../../../../../src/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE;QACX;YACE,IAAI,EAAE,qBAAqB;YAC3B,SAAS,EAAE,OAAO;YAClB,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,iCAAiC,EAAC;YAC9D,mBAAmB,EAAE;gBACnB;oBACE,IAAI,EAAE,oBAAoB;oBAC1B,QAAQ,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC,EAAC;oBACtE,IAAI,EAAE,EAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,EAAC,EAAC,EAAC;iBAC1G;gBACD;oBACE,IAAI,EAAE,oBAAoB;oBAC1B,QAAQ,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAC,EAAC;oBAClE,IAAI,EAAE,EAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAC,EAAC;iBACjE;aACF;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACV;wBACE,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAC;wBACnD,SAAS,EAAE;4BACT;gCACE,IAAI,EAAE,UAAU;gCAChB,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC;gCACxC,KAAK,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC,EAAC;6BACpE;4BACD,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAC,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAC,EAAC;4BACjG;gCACE,IAAI,EAAE,UAAU;gCAChB,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAC;gCACpC,KAAK,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAC,EAAC;6BAChE;yBACF;wBACD,YAAY,EAAE;4BACZ,IAAI,EAAE,cAAc;4BACpB,UAAU,EAAE;gCACV;oCACE,IAAI,EAAE,OAAO;oCACb,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAC;oCACvC,YAAY,EAAE;wCACZ,IAAI,EAAE,cAAc;wCACpB,UAAU,EAAE;4CACV,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAC,EAAC;4CAC3D,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC,EAAC;4CACzD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAC,EAAC;yCAC3D;qCACF;iCACF;gCACD;oCACE,IAAI,EAAE,OAAO;oCACb,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAC;oCACpC,YAAY,EAAE;wCACZ,IAAI,EAAE,cAAc;wCACpB,UAAU,EAAE;4CACV,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAC,EAAC;4CACnD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAC,EAAC;4CACpD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC,EAAC;4CACzD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAC,EAAC;4CAC3D;gDACE,IAAI,EAAE,OAAO;gDACb,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAC;gDACnC,YAAY,EAAE;oDACZ,IAAI,EAAE,cAAc;oDACpB,UAAU,EAAE;wDACV,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAC,EAAC;wDACxD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAC,EAAC;wDACpD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAC,EAAC;qDAC3D;iDACF;6CACF;4CACD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAC,EAAC;yCAC3D;qCACF;iCACF;gCACD,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAC,EAAC;6BAC3D;yBACF;qBACF;iBACF;aACF;SACF;KACF;CAC8G,CAAA","sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-definitions */\nimport * as Types from './types.js'\n\nimport {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core'\n\nexport type MetafieldDefinitionsByOwnerTypeQueryVariables = Types.Exact<{\n ownerType: Types.MetafieldOwnerType\n after?: Types.InputMaybe<Types.Scalars['String']['input']>\n}>\n\nexport type MetafieldDefinitionsByOwnerTypeQuery = {\n metafieldDefinitions: {\n pageInfo: {hasNextPage: boolean; endCursor?: string | null}\n nodes: {\n key: string\n name: string\n namespace: string\n description?: string | null\n type: {category: string; name: string}\n }[]\n }\n}\n\nexport const MetafieldDefinitionsByOwnerType = {\n kind: 'Document',\n definitions: [\n {\n kind: 'OperationDefinition',\n operation: 'query',\n name: {kind: 'Name', value: 'metafieldDefinitionsByOwnerType'},\n variableDefinitions: [\n {\n kind: 'VariableDefinition',\n variable: {kind: 'Variable', name: {kind: 'Name', value: 'ownerType'}},\n type: {kind: 'NonNullType', type: {kind: 'NamedType', name: {kind: 'Name', value: 'MetafieldOwnerType'}}},\n },\n {\n kind: 'VariableDefinition',\n variable: {kind: 'Variable', name: {kind: 'Name', value: 'after'}},\n type: {kind: 'NamedType', name: {kind: 'Name', value: 'String'}},\n },\n ],\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'metafieldDefinitions'},\n arguments: [\n {\n kind: 'Argument',\n name: {kind: 'Name', value: 'ownerType'},\n value: {kind: 'Variable', name: {kind: 'Name', value: 'ownerType'}},\n },\n {kind: 'Argument', name: {kind: 'Name', value: 'first'}, value: {kind: 'IntValue', value: '250'}},\n {\n kind: 'Argument',\n name: {kind: 'Name', value: 'after'},\n value: {kind: 'Variable', name: {kind: 'Name', value: 'after'}},\n },\n ],\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'pageInfo'},\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {kind: 'Field', name: {kind: 'Name', value: 'hasNextPage'}},\n {kind: 'Field', name: {kind: 'Name', value: 'endCursor'}},\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'nodes'},\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {kind: 'Field', name: {kind: 'Name', value: 'key'}},\n {kind: 'Field', name: {kind: 'Name', value: 'name'}},\n {kind: 'Field', name: {kind: 'Name', value: 'namespace'}},\n {kind: 'Field', name: {kind: 'Name', value: 'description'}},\n {\n kind: 'Field',\n name: {kind: 'Name', value: 'type'},\n selectionSet: {\n kind: 'SelectionSet',\n selections: [\n {kind: 'Field', name: {kind: 'Name', value: 'category'}},\n {kind: 'Field', name: {kind: 'Name', value: 'name'}},\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n {kind: 'Field', name: {kind: 'Name', value: '__typename'}},\n ],\n },\n },\n ],\n },\n },\n ],\n} as unknown as DocumentNode<MetafieldDefinitionsByOwnerTypeQuery, MetafieldDefinitionsByOwnerTypeQueryVariables>\n"]}
@@ -1,4 +1,4 @@
1
- import { Variables } from 'graphql-request';
1
+ import { ClientError, Variables } from 'graphql-request';
2
2
  export declare function debugLogRequestInfo(api: string, query: string, url: string, variables?: Variables, headers?: Record<string, string>): void;
3
3
  export declare function sanitizeVariables(variables: Variables): string;
4
4
  /**
@@ -12,3 +12,4 @@ export declare function sanitizeVariables(variables: Variables): string;
12
12
  */
13
13
  export declare function extractGraphQLErrorMessages(errors: any[] | undefined): string | undefined;
14
14
  export declare function errorHandler(api: string): (error: unknown, requestId?: string) => unknown;
15
+ export declare function extractGraphQLErrors(error: unknown): NonNullable<ClientError['response']['errors']>;
@@ -13,7 +13,7 @@ to ${sanitizeURL(url)}`);
13
13
  }
14
14
  export function sanitizeVariables(variables) {
15
15
  const result = { ...variables };
16
- const sensitiveKeys = ['apiKey', 'serialized_script'];
16
+ const sensitiveKeys = ['apiKey', 'serialized_script', 'sharedSecret', 'shared_secret'];
17
17
  const sanitizedResult = sanitizeDeepVariables(result, sensitiveKeys);
18
18
  return JSON.stringify(sanitizedResult, null, 2);
19
19
  }
@@ -114,6 +114,10 @@ export function errorHandler(api) {
114
114
  else if (extractedMessages && status >= 500) {
115
115
  errorMessage = `The ${api} GraphQL API responded with HTTP status ${status}: ${extractedMessages}`;
116
116
  }
117
+ else if (error.response.errors === undefined) {
118
+ // A 401 from an API gateway, for example, has no GraphQL body to quote.
119
+ errorMessage = `The ${api} GraphQL API responded unsuccessfully with the HTTP status ${status}.`;
120
+ }
117
121
  else {
118
122
  errorMessage = stringifyMessage(outputContent `
119
123
  The ${outputToken.raw(api)} GraphQL API responded unsuccessfully with${status === 200 ? '' : ` the HTTP status ${status} and`} errors:
@@ -139,4 +143,11 @@ ${outputToken.json(error.response.errors)}
139
143
  }
140
144
  };
141
145
  }
146
+ export function extractGraphQLErrors(error) {
147
+ if (error instanceof ClientError)
148
+ return Array.isArray(error.response.errors) ? error.response.errors : [];
149
+ if (error instanceof GraphQLClientError)
150
+ return Array.isArray(error.errors) ? error.errors : [];
151
+ return [];
152
+ }
142
153
  //# sourceMappingURL=graphql.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {GraphQLClientError, sanitizedHeadersOutput} from './headers.js'\nimport {sanitizeURL} from './urls.js'\nimport {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js'\nimport {AbortError} from '../../../public/node/error.js'\n\nimport {ClientError, Variables} from 'graphql-request'\n\nexport function debugLogRequestInfo(\n api: string,\n query: string,\n url: string,\n variables?: Variables,\n headers: Record<string, string> = {},\n) {\n outputDebug(outputContent`Sending ${outputToken.json(api)} GraphQL request:\n ${outputToken.raw(query.toString().trim())}\n${variables ? `\\nWith variables:\\n${sanitizeVariables(variables)}\\n` : ''}\nWith request headers:\n${sanitizedHeadersOutput(headers)}\\n\nto ${sanitizeURL(url)}`)\n}\n\nexport function sanitizeVariables(variables: Variables): string {\n const result: Variables = {...variables}\n const sensitiveKeys = ['apiKey', 'serialized_script']\n\n const sanitizedResult = sanitizeDeepVariables(result, sensitiveKeys)\n\n return JSON.stringify(sanitizedResult, null, 2)\n}\n\nfunction sanitizeDeepVariables(value: unknown, sensitiveKeys: string[]): unknown {\n // Checking for JSON\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value)\n if (typeof parsed === 'object' && parsed !== null) {\n const sanitized = sanitizeDeepVariables(parsed, sensitiveKeys)\n return JSON.stringify(sanitized, null)\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return value\n }\n }\n\n if (typeof value !== 'object' || value === null) {\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => sanitizeDeepVariables(item, sensitiveKeys))\n }\n\n const result: Variables = {}\n\n for (const [key, val] of Object.entries(value)) {\n if (sensitiveKeys.includes(key) && typeof val === 'string') {\n result[key] = '*****'\n continue\n }\n\n result[key] = sanitizeDeepVariables(val, sensitiveKeys)\n }\n\n return result\n}\n\n/**\n * Extracts human-readable error messages from a GraphQL errors array.\n *\n * Some APIs (e.g. App Management) return structured errors nested inside\n * `extensions.app_errors.errors[].message`. When those are present, we extract\n * them so the CLI displays a clean message instead of a raw JSON dump.\n * Falls back to each error's top-level `message` field, and ultimately to\n * the full JSON representation if no messages can be extracted.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractGraphQLErrorMessages(errors: any[] | undefined): string | undefined {\n if (!errors || errors.length === 0) return undefined\n\n const messages: string[] = []\n\n for (const error of errors) {\n // Check for nested app_errors (App Management API pattern)\n const appErrors = error?.extensions?.app_errors?.errors\n if (Array.isArray(appErrors) && appErrors.length > 0) {\n const appMessages: string[] = []\n for (const appError of appErrors) {\n const friendlyMessage = friendlyAppErrorMessage(appError)\n if (friendlyMessage) {\n appMessages.push(friendlyMessage)\n } else if (typeof appError?.message === 'string') {\n appMessages.push(appError.message)\n }\n }\n // Fall back to top-level error message if no app_error messages were extracted\n if (appMessages.length > 0) {\n messages.push(...appMessages)\n } else if (typeof error?.message === 'string') {\n messages.push(error.message)\n }\n }\n // Fall back to top-level error message\n else if (typeof error?.message === 'string') {\n messages.push(error.message)\n }\n }\n\n return messages.length > 0 ? messages.join('\\n') : undefined\n}\n\n/**\n * Maps known app_errors categories to user-friendly messages.\n * Returns undefined if the error doesn't match a known pattern.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction friendlyAppErrorMessage(appError: any): string | undefined {\n if (appError?.category === 'access_denied') {\n return \"You don't have the necessary permissions to perform this action. Check that you're using the correct account or token.\"\n }\n return undefined\n}\n\nexport function errorHandler(api: string): (error: unknown, requestId?: string) => unknown {\n return (error: unknown, requestId?: string) => {\n if (error instanceof ClientError) {\n const {status} = error.response\n\n const extractedMessages = extractGraphQLErrorMessages(error.response.errors)\n\n let errorMessage: string\n if (extractedMessages && status < 500) {\n errorMessage = extractedMessages\n } else if (extractedMessages && status >= 500) {\n errorMessage = `The ${api} GraphQL API responded with HTTP status ${status}: ${extractedMessages}`\n } else {\n errorMessage = stringifyMessage(outputContent`\nThe ${outputToken.raw(api)} GraphQL API responded unsuccessfully with${\n status === 200 ? '' : ` the HTTP status ${status} and`\n } errors:\n\n${outputToken.json(error.response.errors)}\n `)\n }\n if (requestId) {\n errorMessage += `\\n\\nRequest ID: ${requestId}`\n }\n let mappedError: Error\n if (status < 500) {\n mappedError = new GraphQLClientError(errorMessage, status, error.response.errors)\n } else {\n mappedError = new AbortError(errorMessage)\n }\n mappedError.stack = error.stack\n return mappedError\n } else {\n return error\n }\n }\n}\n"]}
1
+ {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {GraphQLClientError, sanitizedHeadersOutput} from './headers.js'\nimport {sanitizeURL} from './urls.js'\nimport {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js'\nimport {AbortError} from '../../../public/node/error.js'\n\nimport {ClientError, Variables} from 'graphql-request'\n\nexport function debugLogRequestInfo(\n api: string,\n query: string,\n url: string,\n variables?: Variables,\n headers: Record<string, string> = {},\n) {\n outputDebug(outputContent`Sending ${outputToken.json(api)} GraphQL request:\n ${outputToken.raw(query.toString().trim())}\n${variables ? `\\nWith variables:\\n${sanitizeVariables(variables)}\\n` : ''}\nWith request headers:\n${sanitizedHeadersOutput(headers)}\\n\nto ${sanitizeURL(url)}`)\n}\n\nexport function sanitizeVariables(variables: Variables): string {\n const result: Variables = {...variables}\n const sensitiveKeys = ['apiKey', 'serialized_script', 'sharedSecret', 'shared_secret']\n\n const sanitizedResult = sanitizeDeepVariables(result, sensitiveKeys)\n\n return JSON.stringify(sanitizedResult, null, 2)\n}\n\nfunction sanitizeDeepVariables(value: unknown, sensitiveKeys: string[]): unknown {\n // Checking for JSON\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value)\n if (typeof parsed === 'object' && parsed !== null) {\n const sanitized = sanitizeDeepVariables(parsed, sensitiveKeys)\n return JSON.stringify(sanitized, null)\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return value\n }\n }\n\n if (typeof value !== 'object' || value === null) {\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => sanitizeDeepVariables(item, sensitiveKeys))\n }\n\n const result: Variables = {}\n\n for (const [key, val] of Object.entries(value)) {\n if (sensitiveKeys.includes(key) && typeof val === 'string') {\n result[key] = '*****'\n continue\n }\n\n result[key] = sanitizeDeepVariables(val, sensitiveKeys)\n }\n\n return result\n}\n\n/**\n * Extracts human-readable error messages from a GraphQL errors array.\n *\n * Some APIs (e.g. App Management) return structured errors nested inside\n * `extensions.app_errors.errors[].message`. When those are present, we extract\n * them so the CLI displays a clean message instead of a raw JSON dump.\n * Falls back to each error's top-level `message` field, and ultimately to\n * the full JSON representation if no messages can be extracted.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractGraphQLErrorMessages(errors: any[] | undefined): string | undefined {\n if (!errors || errors.length === 0) return undefined\n\n const messages: string[] = []\n\n for (const error of errors) {\n // Check for nested app_errors (App Management API pattern)\n const appErrors = error?.extensions?.app_errors?.errors\n if (Array.isArray(appErrors) && appErrors.length > 0) {\n const appMessages: string[] = []\n for (const appError of appErrors) {\n const friendlyMessage = friendlyAppErrorMessage(appError)\n if (friendlyMessage) {\n appMessages.push(friendlyMessage)\n } else if (typeof appError?.message === 'string') {\n appMessages.push(appError.message)\n }\n }\n // Fall back to top-level error message if no app_error messages were extracted\n if (appMessages.length > 0) {\n messages.push(...appMessages)\n } else if (typeof error?.message === 'string') {\n messages.push(error.message)\n }\n }\n // Fall back to top-level error message\n else if (typeof error?.message === 'string') {\n messages.push(error.message)\n }\n }\n\n return messages.length > 0 ? messages.join('\\n') : undefined\n}\n\n/**\n * Maps known app_errors categories to user-friendly messages.\n * Returns undefined if the error doesn't match a known pattern.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction friendlyAppErrorMessage(appError: any): string | undefined {\n if (appError?.category === 'access_denied') {\n return \"You don't have the necessary permissions to perform this action. Check that you're using the correct account or token.\"\n }\n return undefined\n}\n\nexport function errorHandler(api: string): (error: unknown, requestId?: string) => unknown {\n return (error: unknown, requestId?: string) => {\n if (error instanceof ClientError) {\n const {status} = error.response\n\n const extractedMessages = extractGraphQLErrorMessages(error.response.errors)\n\n let errorMessage: string\n if (extractedMessages && status < 500) {\n errorMessage = extractedMessages\n } else if (extractedMessages && status >= 500) {\n errorMessage = `The ${api} GraphQL API responded with HTTP status ${status}: ${extractedMessages}`\n } else if (error.response.errors === undefined) {\n // A 401 from an API gateway, for example, has no GraphQL body to quote.\n errorMessage = `The ${api} GraphQL API responded unsuccessfully with the HTTP status ${status}.`\n } else {\n errorMessage = stringifyMessage(outputContent`\nThe ${outputToken.raw(api)} GraphQL API responded unsuccessfully with${\n status === 200 ? '' : ` the HTTP status ${status} and`\n } errors:\n\n${outputToken.json(error.response.errors)}\n `)\n }\n if (requestId) {\n errorMessage += `\\n\\nRequest ID: ${requestId}`\n }\n let mappedError: Error\n if (status < 500) {\n mappedError = new GraphQLClientError(errorMessage, status, error.response.errors)\n } else {\n mappedError = new AbortError(errorMessage)\n }\n mappedError.stack = error.stack\n return mappedError\n } else {\n return error\n }\n }\n}\n\nexport function extractGraphQLErrors(error: unknown): NonNullable<ClientError['response']['errors']> {\n if (error instanceof ClientError) return Array.isArray(error.response.errors) ? error.response.errors : []\n if (error instanceof GraphQLClientError) return Array.isArray(error.errors) ? error.errors : []\n return []\n}\n"]}
@@ -60,6 +60,8 @@ export declare function simpleRequestWithDebugLog<T extends {
60
60
  * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.
61
61
  *
62
62
  * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.
63
+ * Without a valid header, rate-limit retries use exponential backoff with jitter, capped at 8 seconds per delay.
64
+ * No new rate-limit retry starts after 30 seconds. A server-requested delay beyond that budget is not shortened.
63
65
  *
64
66
  * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows
65
67
  * for a token refresh for instance.
@@ -1,14 +1,17 @@
1
1
  import { sanitizedHeadersOutput } from './api/headers.js';
2
2
  import { sanitizeURL } from './api/urls.js';
3
- import { hasRateLimitCode } from './analytics/graphql-error-codes.js';
3
+ import { graphQLErrorCodes, isRateLimitCode } from './analytics/graphql-error-codes.js';
4
4
  import { sleepWithBackoffUntil } from './sleep-with-backoff.js';
5
5
  import { outputDebug } from '../../public/node/output.js';
6
6
  import { recordRetry } from '../../public/node/analytics.js';
7
7
  import { ClientError } from 'graphql-request';
8
+ import { getOperationAST, GraphQLError, parse } from 'graphql';
8
9
  import { performance } from 'perf_hooks';
9
10
  export const allAPIs = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management'];
10
11
  const DEFAULT_RETRY_DELAY_MS = 1000;
11
12
  const DEFAULT_RETRY_LIMIT = 10;
13
+ const MAX_THROTTLE_RETRY_DELAY_MS = 8000;
14
+ const MAX_THROTTLE_RETRY_TIME_MS = 30_000;
12
15
  const interestingResponseHeaders = new Set([
13
16
  'cache-control',
14
17
  'content-type',
@@ -158,14 +161,6 @@ async function makeVerboseRequest(requestOptions) {
158
161
  }
159
162
  const sanitizedHeaders = sanitizedHeadersOutput(responseHeaders);
160
163
  if (isThrottled(err)) {
161
- let delayMs;
162
- try {
163
- delayMs = responseHeaders['retry-after'] ? Number.parseInt(responseHeaders['retry-after'], 10) : undefined;
164
- // eslint-disable-next-line no-catch-all/no-catch-all
165
- }
166
- catch {
167
- // ignore errors in extracting retry-after header
168
- }
169
164
  return {
170
165
  status: 'can-retry',
171
166
  clientError: err,
@@ -173,7 +168,7 @@ async function makeVerboseRequest(requestOptions) {
173
168
  sanitizedHeaders,
174
169
  sanitizedUrl,
175
170
  requestId: responseHeaders['x-request-id'],
176
- delayMs,
171
+ delayMs: retryAfterDelayMs(responseHeaders['retry-after']),
177
172
  };
178
173
  }
179
174
  else if (err.response.status === 401) {
@@ -216,15 +211,43 @@ async function makeVerboseRequest(requestOptions) {
216
211
  requestId: responseHeaders['x-request-id'],
217
212
  };
218
213
  }
219
- // Shopify GraphQL APIs signal rate limiting with `extensions.code` set to
220
- // `THROTTLED` (often on a 200 response) or `429` — the same codes that
221
- // crash-report suppression and analytics grouping already treat as rate
222
- // limiting via this shared helper.
214
+ // Partial mutation data can include a successful write. Read queries are safe to repeat.
223
215
  function isThrottled(error) {
224
- if (error.response.status === 429) {
225
- return true;
216
+ if (error.response.data != null && !isReadOnlyQuery(error.request.query))
217
+ return false;
218
+ const httpRateLimited = error.response.status === 429;
219
+ const errors = error.response.errors;
220
+ if (!Array.isArray(errors) || errors.length === 0)
221
+ return httpRateLimited;
222
+ return errors.every((entry) => {
223
+ const codes = graphQLErrorCodes([entry]);
224
+ return (codes.length > 0 || httpRateLimited) && codes.every(isRateLimitCode);
225
+ });
226
+ }
227
+ function isReadOnlyQuery(query) {
228
+ if (typeof query !== 'string')
229
+ return false;
230
+ try {
231
+ return getOperationAST(parse(query))?.operation === 'query';
232
+ }
233
+ catch (error) {
234
+ if (error instanceof GraphQLError)
235
+ return false;
236
+ throw error;
237
+ }
238
+ }
239
+ function retryAfterDelayMs(retryAfter) {
240
+ const value = retryAfter?.trim();
241
+ if (!value)
242
+ return undefined;
243
+ const seconds = Number(value);
244
+ if (!Number.isNaN(seconds)) {
245
+ return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1000 : undefined;
226
246
  }
227
- return hasRateLimitCode(error.response.errors);
247
+ // The asctime HTTP-date format omits a time zone but still uses UTC.
248
+ const isAsctimeDate = /^[A-Za-z]{3} [A-Za-z]{3} (?: \d|\d{2}) \d{2}:\d{2}:\d{2} \d{4}$/.test(value);
249
+ const retryAt = Date.parse(isAsctimeDate ? `${value} GMT` : value);
250
+ return Number.isNaN(retryAt) ? undefined : Math.max(0, retryAt - Date.now());
228
251
  }
229
252
  export async function simpleRequestWithDebugLog(requestOptions, errorHandler) {
230
253
  const result = await makeVerboseRequest(requestOptions);
@@ -274,6 +297,8 @@ ${result.sanitizedHeaders}
274
297
  * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.
275
298
  *
276
299
  * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.
300
+ * Without a valid header, rate-limit retries use exponential backoff with jitter, capped at 8 seconds per delay.
301
+ * No new rate-limit retry starts after 30 seconds. A server-requested delay beyond that budget is not shortened.
277
302
  *
278
303
  * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows
279
304
  * for a token refresh for instance.
@@ -293,6 +318,7 @@ export async function retryAwareRequest(requestOptions, errorHandler, retryOptio
293
318
  let retriesUsed = 0;
294
319
  const limitRetriesTo = retryOptions.limitRetriesTo ?? DEFAULT_RETRY_LIMIT;
295
320
  let result = await makeVerboseRequest(requestOptions);
321
+ const retryDeadline = performance.now() + MAX_THROTTLE_RETRY_TIME_MS;
296
322
  outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms
297
323
  With response headers:
298
324
  ${result.sanitizedHeaders}
@@ -323,8 +349,10 @@ ${result.sanitizedHeaders}
323
349
  else if (result.status === 'unauthorized') {
324
350
  throw result.clientError;
325
351
  }
326
- if (limitRetriesTo <= retriesUsed) {
327
- outputDebug(`${limitRetriesTo} retries exhausted for request to ${result.sanitizedUrl}`);
352
+ const maximumDelayMs = Math.min((retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS) * 2 ** retriesUsed, MAX_THROTTLE_RETRY_DELAY_MS);
353
+ const retryDelayMs = result.delayMs ?? Math.floor(maximumDelayMs * (0.5 + Math.random() / 2));
354
+ if (limitRetriesTo <= retriesUsed || retryDelayMs >= retryDeadline - performance.now()) {
355
+ outputDebug(`Rate-limit retry budget exhausted after ${retriesUsed} retries for request to ${result.sanitizedUrl}`);
328
356
  if (errorHandler) {
329
357
  throw errorHandler(result.clientError, result.requestId);
330
358
  }
@@ -337,13 +365,12 @@ ${result.sanitizedHeaders}
337
365
  if (requestOptions.recordCommandRetries) {
338
366
  recordRetry(requestOptions.url, `http-retry-${retriesUsed}:${result.status}:`);
339
367
  }
340
- // prefer to wait based on a header if given; the caller's preference if not; and a default if neither.
341
- const retryDelayMs = result.delayMs ?? retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS;
342
368
  outputDebug(`Scheduling retry request #${retriesUsed} to ${result.sanitizedUrl} in ${retryDelayMs} ms`);
369
+ const previousResult = result;
343
370
  // eslint-disable-next-line no-await-in-loop
344
371
  result = await new Promise((resolve) => {
345
372
  retryOptions.scheduleDelay(() => {
346
- resolve(makeVerboseRequest(requestOptions));
373
+ resolve(performance.now() < retryDeadline ? makeVerboseRequest(requestOptions) : previousResult);
347
374
  }, retryDelayMs);
348
375
  });
349
376
  }
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {sanitizedHeadersOutput} from './api/headers.js'\nimport {sanitizeURL} from './api/urls.js'\nimport {hasRateLimitCode} from './analytics/graphql-error-codes.js'\nimport {sleepWithBackoffUntil} from './sleep-with-backoff.js'\nimport {outputDebug} from '../../public/node/output.js'\nimport {recordRetry} from '../../public/node/analytics.js'\n\nimport {Headers} from 'form-data'\nimport {ClientError} from 'graphql-request'\n\nimport {performance} from 'perf_hooks'\n\nexport type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management']\n\nconst DEFAULT_RETRY_DELAY_MS = 1000\nconst DEFAULT_RETRY_LIMIT = 10\n\nexport type NetworkRetryBehaviour =\n | {\n useNetworkLevelRetry: true\n maxRetryTimeMs: number\n recordCommandRetries?: boolean\n }\n | {\n useNetworkLevelRetry: false\n recordCommandRetries?: boolean\n }\n\ntype RequestOptions<T> = {\n request: () => Promise<T>\n url: string\n} & NetworkRetryBehaviour\n\nconst interestingResponseHeaders = new Set([\n 'cache-control',\n 'content-type',\n 'etag',\n 'x-request-id',\n 'server-timing',\n 'retry-after',\n])\n\nfunction responseHeaderIsInteresting(header: string): boolean {\n return interestingResponseHeaders.has(header)\n}\n\ninterface CommonResponse {\n duration: number\n sanitizedHeaders: string\n sanitizedUrl: string\n requestId?: string\n}\n\ntype OkResponse<T> = CommonResponse & {status: 'ok'; response: T}\ntype ClientErrorResponse = CommonResponse & {status: 'client-error'; clientError: ClientError}\ntype UnknownErrorResponse = CommonResponse & {status: 'unknown-error'; error: unknown}\ntype CanRetryErrorResponse = CommonResponse & {\n status: 'can-retry'\n clientError: ClientError\n delayMs: number | undefined\n}\ntype UnauthorizedErrorResponse = CommonResponse & {\n status: 'unauthorized'\n clientError: ClientError\n delayMs: number | undefined\n}\n\ntype VerboseResponse<T> =\n | OkResponse<T>\n | ClientErrorResponse\n | UnknownErrorResponse\n | CanRetryErrorResponse\n | UnauthorizedErrorResponse\n\n/**\n * Checks if an error is a transient network error that is likely to recover with retries.\n *\n * Use this function for retry logic. Use isNetworkError for error classification.\n *\n * Examples of transient errors (worth retrying):\n * - Connection timeouts, resets, and aborts\n * - DNS failures (enotfound, getaddrinfo, eai_again) - can be temporary\n * - Socket disconnects and hang ups\n * - Premature connection closes\n */\nexport function isTransientNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n const transientErrorMessages = [\n 'socket hang up',\n 'econnreset',\n 'econnaborted',\n 'enotfound',\n 'enetunreach',\n 'network socket disconnected',\n 'etimedout',\n 'econnrefused',\n 'eai_again',\n 'epipe',\n 'the operation was aborted',\n 'timeout',\n 'premature close',\n 'getaddrinfo',\n ]\n const errorMessage = error.message.toLowerCase()\n const anyMatches = transientErrorMessages.some((issueMessage) => errorMessage.includes(issueMessage))\n const missingReason = /^request to .* failed, reason:\\s*$/.test(errorMessage)\n return anyMatches || missingReason\n }\n return false\n}\n\n/**\n * Checks if an error is any kind of network-related error (connection issues, timeouts, DNS failures,\n * TLS/certificate errors, etc.) rather than an application logic error.\n *\n * These errors should be reported as user-facing errors (AbortError) rather than bugs (BugError),\n * regardless of whether they are transient or permanent.\n *\n * Examples include:\n * - Transient: connection timeouts, socket hang ups, temporary DNS failures\n * - Permanent: certificate validation failures, misconfigured SSL\n */\nexport function isNetworkError(error: unknown): boolean {\n // First check if it's a transient network error\n if (isTransientNetworkError(error)) {\n return true\n }\n\n // Then check for permanent network errors (SSL/TLS/certificate issues)\n if (error instanceof Error) {\n const permanentNetworkErrorMessages = ['certificate', 'cert', 'tls', 'ssl', 'altnames']\n const errorMessage = error.message.toLowerCase()\n return permanentNetworkErrorMessages.some((issueMessage) => errorMessage.includes(issueMessage))\n }\n\n return false\n}\n\n/**\n * Lower-cased substrings that mean a request was aborted rather than failing on its own.\n * `node-fetch` says 'The user aborted a request.', undici says 'This operation was aborted', and\n * cli-kit's own request timeout says 'The operation was aborted'.\n */\nconst ABORTED_FETCH_MESSAGE_FRAGMENTS = ['the user aborted a request', 'operation was aborted'] as const\n\n/**\n * Checks if an error is an aborted request: a user cancelling the command, the host process\n * cancelling it, or one of the CLI's own request timeouts firing.\n *\n * Not used by the retry logic, because a user-cancelled request must not be retried.\n * `isTransientNetworkError` separately matches the CLI's own timeout message, so timeouts do\n * still retry.\n *\n * The `name` check matches the `AbortError` shape that fetch throws, not cli-kit's own\n * `AbortError`, which leaves `name` as 'Error'.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the request was aborted.\n */\nexport function isAbortedFetchError(error: unknown): boolean {\n if (!(error instanceof Error)) return false\n if (error.name === 'AbortError') return true\n const errorMessage = error.message.toLowerCase()\n return ABORTED_FETCH_MESSAGE_FRAGMENTS.some((fragment) => errorMessage.includes(fragment))\n}\n\nasync function runRequestWithNetworkLevelRetry<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<T> {\n if (!requestOptions.useNetworkLevelRetry) {\n return requestOptions.request()\n }\n\n let lastSeenError: unknown\n\n for await (const _delayMs of sleepWithBackoffUntil(requestOptions.maxRetryTimeMs)) {\n try {\n return await requestOptions.request()\n } catch (err) {\n lastSeenError = err\n if (!isTransientNetworkError(err)) {\n throw err\n }\n\n // Record command retries\n if (requestOptions.recordCommandRetries) {\n recordRetry(requestOptions.url, `network-retry:${(err as Error).message}`)\n }\n\n outputDebug(`Retrying request to ${requestOptions.url} due to network error ${err}`)\n }\n }\n throw lastSeenError\n}\n\nasync function makeVerboseRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<VerboseResponse<T>> {\n const t0 = performance.now()\n let duration = 0\n const responseHeaders: Record<string, string> = {}\n const sanitizedUrl = sanitizeURL(requestOptions.url)\n let response: T = {} as T\n try {\n response = await runRequestWithNetworkLevelRetry(requestOptions)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response.headers.forEach((value: any, key: any) => {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err) {\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n\n if (err instanceof ClientError) {\n if (err.response.headers) {\n for (const [key, value] of err.response.headers as Iterable<[string, string]>) {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n }\n }\n const sanitizedHeaders = sanitizedHeadersOutput(responseHeaders)\n\n if (isThrottled(err)) {\n let delayMs: number | undefined\n\n try {\n delayMs = responseHeaders['retry-after'] ? Number.parseInt(responseHeaders['retry-after'], 10) : undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // ignore errors in extracting retry-after header\n }\n return {\n status: 'can-retry',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs,\n }\n } else if (err.response.status === 401) {\n return {\n status: 'unauthorized',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs: 500,\n }\n }\n\n return {\n status: 'client-error',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n return {\n status: 'unknown-error',\n error: err,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n return {\n status: 'ok',\n response,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n}\n\n// Shopify GraphQL APIs signal rate limiting with `extensions.code` set to\n// `THROTTLED` (often on a 200 response) or `429` — the same codes that\n// crash-report suppression and analytics grouping already treat as rate\n// limiting via this shared helper.\nfunction isThrottled(error: ClientError): boolean {\n if (error.response.status === 429) {\n return true\n }\n return hasRateLimitCode(error.response.errors)\n}\n\nexport async function simpleRequestWithDebugLog<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n): Promise<T> {\n const result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n switch (result.status) {\n case 'ok': {\n return result.response\n }\n case 'client-error': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unknown-error': {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n }\n case 'can-retry': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unauthorized': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n }\n}\n\n/**\n * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.\n *\n * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.\n *\n * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows\n * for a token refresh for instance.\n *\n * If there's a network error, e.g. DNS fails to resolve, then API calls are automatically retried.\n *\n * @param request - A function that returns a promise of the response\n * @param url - The URL to request\n * @param errorHandler - A function that handles errors\n * @param unauthorizedHandler - A function that handles unauthorized errors\n * @param retryOptions - Options for the retry\n * @returns The response from the request\n */\nexport async function retryAwareRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n retryOptions: {\n limitRetriesTo?: number\n defaultDelayMs?: number\n scheduleDelay: (fn: () => void, delay: number) => void\n } = {\n scheduleDelay: setTimeout,\n },\n): Promise<T> {\n let retriesUsed = 0\n const limitRetriesTo = retryOptions.limitRetriesTo ?? DEFAULT_RETRY_LIMIT\n\n let result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n while (true) {\n if (result.status === 'ok') {\n if (retriesUsed > 0) {\n outputDebug(`Request to ${result.sanitizedUrl} succeeded after ${retriesUsed} retries`)\n }\n return result.response\n } else if (result.status === 'client-error') {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n } else if (result.status === 'unknown-error') {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n } else if (result.status === 'unauthorized') {\n throw result.clientError\n }\n\n if (limitRetriesTo <= retriesUsed) {\n outputDebug(`${limitRetriesTo} retries exhausted for request to ${result.sanitizedUrl}`)\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n retriesUsed += 1\n\n // Record command retries\n if (requestOptions.recordCommandRetries) {\n recordRetry(requestOptions.url, `http-retry-${retriesUsed}:${result.status}:`)\n }\n\n // prefer to wait based on a header if given; the caller's preference if not; and a default if neither.\n const retryDelayMs = result.delayMs ?? retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS\n outputDebug(`Scheduling retry request #${retriesUsed} to ${result.sanitizedUrl} in ${retryDelayMs} ms`)\n\n // eslint-disable-next-line no-await-in-loop\n result = await new Promise<VerboseResponse<T>>((resolve) => {\n retryOptions.scheduleDelay(() => {\n resolve(makeVerboseRequest(requestOptions))\n }, retryDelayMs)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {sanitizedHeadersOutput} from './api/headers.js'\nimport {sanitizeURL} from './api/urls.js'\nimport {graphQLErrorCodes, isRateLimitCode} from './analytics/graphql-error-codes.js'\nimport {sleepWithBackoffUntil} from './sleep-with-backoff.js'\nimport {outputDebug} from '../../public/node/output.js'\nimport {recordRetry} from '../../public/node/analytics.js'\n\nimport {Headers} from 'form-data'\nimport {ClientError} from 'graphql-request'\nimport {getOperationAST, GraphQLError, parse} from 'graphql'\n\nimport {performance} from 'perf_hooks'\n\nexport type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management']\n\nconst DEFAULT_RETRY_DELAY_MS = 1000\nconst DEFAULT_RETRY_LIMIT = 10\nconst MAX_THROTTLE_RETRY_DELAY_MS = 8000\nconst MAX_THROTTLE_RETRY_TIME_MS = 30_000\n\nexport type NetworkRetryBehaviour =\n | {\n useNetworkLevelRetry: true\n maxRetryTimeMs: number\n recordCommandRetries?: boolean\n }\n | {\n useNetworkLevelRetry: false\n recordCommandRetries?: boolean\n }\n\ntype RequestOptions<T> = {\n request: () => Promise<T>\n url: string\n} & NetworkRetryBehaviour\n\nconst interestingResponseHeaders = new Set([\n 'cache-control',\n 'content-type',\n 'etag',\n 'x-request-id',\n 'server-timing',\n 'retry-after',\n])\n\nfunction responseHeaderIsInteresting(header: string): boolean {\n return interestingResponseHeaders.has(header)\n}\n\ninterface CommonResponse {\n duration: number\n sanitizedHeaders: string\n sanitizedUrl: string\n requestId?: string\n}\n\ntype OkResponse<T> = CommonResponse & {status: 'ok'; response: T}\ntype ClientErrorResponse = CommonResponse & {status: 'client-error'; clientError: ClientError}\ntype UnknownErrorResponse = CommonResponse & {status: 'unknown-error'; error: unknown}\ntype CanRetryErrorResponse = CommonResponse & {\n status: 'can-retry'\n clientError: ClientError\n delayMs: number | undefined\n}\ntype UnauthorizedErrorResponse = CommonResponse & {\n status: 'unauthorized'\n clientError: ClientError\n delayMs: number | undefined\n}\n\ntype VerboseResponse<T> =\n | OkResponse<T>\n | ClientErrorResponse\n | UnknownErrorResponse\n | CanRetryErrorResponse\n | UnauthorizedErrorResponse\n\n/**\n * Checks if an error is a transient network error that is likely to recover with retries.\n *\n * Use this function for retry logic. Use isNetworkError for error classification.\n *\n * Examples of transient errors (worth retrying):\n * - Connection timeouts, resets, and aborts\n * - DNS failures (enotfound, getaddrinfo, eai_again) - can be temporary\n * - Socket disconnects and hang ups\n * - Premature connection closes\n */\nexport function isTransientNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n const transientErrorMessages = [\n 'socket hang up',\n 'econnreset',\n 'econnaborted',\n 'enotfound',\n 'enetunreach',\n 'network socket disconnected',\n 'etimedout',\n 'econnrefused',\n 'eai_again',\n 'epipe',\n 'the operation was aborted',\n 'timeout',\n 'premature close',\n 'getaddrinfo',\n ]\n const errorMessage = error.message.toLowerCase()\n const anyMatches = transientErrorMessages.some((issueMessage) => errorMessage.includes(issueMessage))\n const missingReason = /^request to .* failed, reason:\\s*$/.test(errorMessage)\n return anyMatches || missingReason\n }\n return false\n}\n\n/**\n * Checks if an error is any kind of network-related error (connection issues, timeouts, DNS failures,\n * TLS/certificate errors, etc.) rather than an application logic error.\n *\n * These errors should be reported as user-facing errors (AbortError) rather than bugs (BugError),\n * regardless of whether they are transient or permanent.\n *\n * Examples include:\n * - Transient: connection timeouts, socket hang ups, temporary DNS failures\n * - Permanent: certificate validation failures, misconfigured SSL\n */\nexport function isNetworkError(error: unknown): boolean {\n // First check if it's a transient network error\n if (isTransientNetworkError(error)) {\n return true\n }\n\n // Then check for permanent network errors (SSL/TLS/certificate issues)\n if (error instanceof Error) {\n const permanentNetworkErrorMessages = ['certificate', 'cert', 'tls', 'ssl', 'altnames']\n const errorMessage = error.message.toLowerCase()\n return permanentNetworkErrorMessages.some((issueMessage) => errorMessage.includes(issueMessage))\n }\n\n return false\n}\n\n/**\n * Lower-cased substrings that mean a request was aborted rather than failing on its own.\n * `node-fetch` says 'The user aborted a request.', undici says 'This operation was aborted', and\n * cli-kit's own request timeout says 'The operation was aborted'.\n */\nconst ABORTED_FETCH_MESSAGE_FRAGMENTS = ['the user aborted a request', 'operation was aborted'] as const\n\n/**\n * Checks if an error is an aborted request: a user cancelling the command, the host process\n * cancelling it, or one of the CLI's own request timeouts firing.\n *\n * Not used by the retry logic, because a user-cancelled request must not be retried.\n * `isTransientNetworkError` separately matches the CLI's own timeout message, so timeouts do\n * still retry.\n *\n * The `name` check matches the `AbortError` shape that fetch throws, not cli-kit's own\n * `AbortError`, which leaves `name` as 'Error'.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the request was aborted.\n */\nexport function isAbortedFetchError(error: unknown): boolean {\n if (!(error instanceof Error)) return false\n if (error.name === 'AbortError') return true\n const errorMessage = error.message.toLowerCase()\n return ABORTED_FETCH_MESSAGE_FRAGMENTS.some((fragment) => errorMessage.includes(fragment))\n}\n\nasync function runRequestWithNetworkLevelRetry<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<T> {\n if (!requestOptions.useNetworkLevelRetry) {\n return requestOptions.request()\n }\n\n let lastSeenError: unknown\n\n for await (const _delayMs of sleepWithBackoffUntil(requestOptions.maxRetryTimeMs)) {\n try {\n return await requestOptions.request()\n } catch (err) {\n lastSeenError = err\n if (!isTransientNetworkError(err)) {\n throw err\n }\n\n // Record command retries\n if (requestOptions.recordCommandRetries) {\n recordRetry(requestOptions.url, `network-retry:${(err as Error).message}`)\n }\n\n outputDebug(`Retrying request to ${requestOptions.url} due to network error ${err}`)\n }\n }\n throw lastSeenError\n}\n\nasync function makeVerboseRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<VerboseResponse<T>> {\n const t0 = performance.now()\n let duration = 0\n const responseHeaders: Record<string, string> = {}\n const sanitizedUrl = sanitizeURL(requestOptions.url)\n let response: T = {} as T\n try {\n response = await runRequestWithNetworkLevelRetry(requestOptions)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response.headers.forEach((value: any, key: any) => {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err) {\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n\n if (err instanceof ClientError) {\n if (err.response.headers) {\n for (const [key, value] of err.response.headers as Iterable<[string, string]>) {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n }\n }\n const sanitizedHeaders = sanitizedHeadersOutput(responseHeaders)\n\n if (isThrottled(err)) {\n return {\n status: 'can-retry',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs: retryAfterDelayMs(responseHeaders['retry-after']),\n }\n } else if (err.response.status === 401) {\n return {\n status: 'unauthorized',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs: 500,\n }\n }\n\n return {\n status: 'client-error',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n return {\n status: 'unknown-error',\n error: err,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n return {\n status: 'ok',\n response,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n}\n\n// Partial mutation data can include a successful write. Read queries are safe to repeat.\nfunction isThrottled(error: ClientError): boolean {\n if (error.response.data != null && !isReadOnlyQuery(error.request.query)) return false\n const httpRateLimited = error.response.status === 429\n const errors = error.response.errors\n if (!Array.isArray(errors) || errors.length === 0) return httpRateLimited\n return errors.every((entry) => {\n const codes = graphQLErrorCodes([entry])\n return (codes.length > 0 || httpRateLimited) && codes.every(isRateLimitCode)\n })\n}\n\nfunction isReadOnlyQuery(query: string | string[]): boolean {\n if (typeof query !== 'string') return false\n try {\n return getOperationAST(parse(query))?.operation === 'query'\n } catch (error) {\n if (error instanceof GraphQLError) return false\n throw error\n }\n}\n\nfunction retryAfterDelayMs(retryAfter: string | undefined): number | undefined {\n const value = retryAfter?.trim()\n if (!value) return undefined\n\n const seconds = Number(value)\n if (!Number.isNaN(seconds)) {\n return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1000 : undefined\n }\n\n // The asctime HTTP-date format omits a time zone but still uses UTC.\n const isAsctimeDate = /^[A-Za-z]{3} [A-Za-z]{3} (?: \\d|\\d{2}) \\d{2}:\\d{2}:\\d{2} \\d{4}$/.test(value)\n const retryAt = Date.parse(isAsctimeDate ? `${value} GMT` : value)\n return Number.isNaN(retryAt) ? undefined : Math.max(0, retryAt - Date.now())\n}\n\nexport async function simpleRequestWithDebugLog<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n): Promise<T> {\n const result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n switch (result.status) {\n case 'ok': {\n return result.response\n }\n case 'client-error': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unknown-error': {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n }\n case 'can-retry': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unauthorized': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n }\n}\n\n/**\n * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.\n *\n * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.\n * Without a valid header, rate-limit retries use exponential backoff with jitter, capped at 8 seconds per delay.\n * No new rate-limit retry starts after 30 seconds. A server-requested delay beyond that budget is not shortened.\n *\n * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows\n * for a token refresh for instance.\n *\n * If there's a network error, e.g. DNS fails to resolve, then API calls are automatically retried.\n *\n * @param request - A function that returns a promise of the response\n * @param url - The URL to request\n * @param errorHandler - A function that handles errors\n * @param unauthorizedHandler - A function that handles unauthorized errors\n * @param retryOptions - Options for the retry\n * @returns The response from the request\n */\nexport async function retryAwareRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n retryOptions: {\n limitRetriesTo?: number\n defaultDelayMs?: number\n scheduleDelay: (fn: () => void, delay: number) => void\n } = {\n scheduleDelay: setTimeout,\n },\n): Promise<T> {\n let retriesUsed = 0\n const limitRetriesTo = retryOptions.limitRetriesTo ?? DEFAULT_RETRY_LIMIT\n\n let result = await makeVerboseRequest(requestOptions)\n const retryDeadline = performance.now() + MAX_THROTTLE_RETRY_TIME_MS\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n while (true) {\n if (result.status === 'ok') {\n if (retriesUsed > 0) {\n outputDebug(`Request to ${result.sanitizedUrl} succeeded after ${retriesUsed} retries`)\n }\n return result.response\n } else if (result.status === 'client-error') {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n } else if (result.status === 'unknown-error') {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n } else if (result.status === 'unauthorized') {\n throw result.clientError\n }\n\n const maximumDelayMs = Math.min(\n (retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS) * 2 ** retriesUsed,\n MAX_THROTTLE_RETRY_DELAY_MS,\n )\n const retryDelayMs = result.delayMs ?? Math.floor(maximumDelayMs * (0.5 + Math.random() / 2))\n if (limitRetriesTo <= retriesUsed || retryDelayMs >= retryDeadline - performance.now()) {\n outputDebug(\n `Rate-limit retry budget exhausted after ${retriesUsed} retries for request to ${result.sanitizedUrl}`,\n )\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n retriesUsed += 1\n\n // Record command retries\n if (requestOptions.recordCommandRetries) {\n recordRetry(requestOptions.url, `http-retry-${retriesUsed}:${result.status}:`)\n }\n\n outputDebug(`Scheduling retry request #${retriesUsed} to ${result.sanitizedUrl} in ${retryDelayMs} ms`)\n\n const previousResult = result\n // eslint-disable-next-line no-await-in-loop\n result = await new Promise<VerboseResponse<T>>((resolve) => {\n retryOptions.scheduleDelay(() => {\n resolve(performance.now() < retryDeadline ? makeVerboseRequest(requestOptions) : previousResult)\n }, retryDelayMs)\n })\n }\n}\n"]}
@@ -27,6 +27,7 @@ export async function printCommandJsonSchema(config, argv, lazyCommandLoader) {
27
27
  name: 'CommandOutput',
28
28
  schema: zod.union([outputSchema.schema, jsonErrorOutputSchema.schema, commandEventOutputSchema.schema]),
29
29
  definitions: {
30
+ ...outputSchema.definitions,
30
31
  Result: outputSchema.schema,
31
32
  Error: jsonErrorOutputSchema.schema,
32
33
  Event: commandEventOutputSchema.schema,
@@ -1 +1 @@
1
- {"version":3,"file":"command-json-schema.js","sourceRoot":"","sources":["../../../src/private/node/command-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAC,wBAAwB,EAAC,MAAM,qCAAqC,CAAA;AAC5E,OAAO,EAAC,qBAAqB,EAAC,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAC,sBAAsB,EAAwB,MAAM,yCAAyC,CAAA;AACrG,OAAO,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAC,GAAG,EAAC,MAAM,6BAA6B,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAA;AAI9C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,IAAc,EACd,iBAAqC;IAErC,MAAM,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACxC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,sDAAsD,CAAC,CAAA;IAE3G,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IACtC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IAEhE,MAAM,YAAY,GAAG,CAAC,MAAM,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACtF,MAAM,YAAY,GAAI,YAA4E,CAAC,gBAAgB,CAAA;IACnH,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,UAAU,CAAC,oDAAoD,CAAC,CAAA;IAE7F,MAAM,aAAa,GAAG,sBAAsB,CAAC;QAC3C,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,qBAAqB,CAAC,MAAM,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACvG,WAAW,EAAE;YACX,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,KAAK,EAAE,qBAAqB,CAAC,MAAM;YACnC,KAAK,EAAE,wBAAwB,CAAC,MAAM;SACvC;KACF,CAAC,CAAA;IACF,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/D,MAAM,WAAW,EAAE,CAAA;AACrB,CAAC","sourcesContent":["import {AbortError} from '../../public/node/error.js'\nimport {commandEventOutputSchema} from '../../public/node/command-events.js'\nimport {jsonErrorOutputSchema} from '../../public/node/error/schema.js'\nimport {defineJsonOutputSchema, type JsonOutputSchema} from '../../public/node/json-output-schema.js'\nimport {flushStdout, outputResult} from '../../public/node/output.js'\nimport {zod} from '../../public/node/schema.js'\nimport {normalizeArgv} from '@oclif/core/help'\nimport type {LazyCommandLoader} from '../../public/node/custom-oclif-loader.js'\nimport type {Config} from '@oclif/core'\n\n/**\n * Loads a command's schema without running its lifecycle or Oclif hooks.\n *\n * @param config - The loaded CLI configuration.\n * @param argv - The CLI arguments, including the command name.\n * @param lazyCommandLoader - The optional loader for bundled commands.\n */\nexport async function printCommandJsonSchema(\n config: Config,\n argv: string[],\n lazyCommandLoader?: LazyCommandLoader,\n): Promise<void> {\n const [id] = normalizeArgv(config, argv)\n if (!id || id.startsWith('-')) throw new AbortError('Specify a command to inspect its JSON output schema.')\n\n const command = config.findCommand(id)\n if (!command) throw new AbortError(`Command \"${id}\" not found.`)\n\n const commandClass = (await lazyCommandLoader?.(command.id)) ?? (await command.load())\n const outputSchema = (commandClass as typeof commandClass & {jsonOutputSchema?: JsonOutputSchema}).jsonOutputSchema\n if (!outputSchema) throw new AbortError('This command does not define a JSON output schema.')\n\n const commandSchema = defineJsonOutputSchema({\n name: 'CommandOutput',\n schema: zod.union([outputSchema.schema, jsonErrorOutputSchema.schema, commandEventOutputSchema.schema]),\n definitions: {\n Result: outputSchema.schema,\n Error: jsonErrorOutputSchema.schema,\n Event: commandEventOutputSchema.schema,\n },\n })\n outputResult(JSON.stringify(commandSchema.jsonSchema, null, 2))\n await flushStdout()\n}\n"]}
1
+ {"version":3,"file":"command-json-schema.js","sourceRoot":"","sources":["../../../src/private/node/command-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAC,wBAAwB,EAAC,MAAM,qCAAqC,CAAA;AAC5E,OAAO,EAAC,qBAAqB,EAAC,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAC,sBAAsB,EAAwB,MAAM,yCAAyC,CAAA;AACrG,OAAO,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAC,GAAG,EAAC,MAAM,6BAA6B,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAA;AAI9C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,IAAc,EACd,iBAAqC;IAErC,MAAM,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACxC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,sDAAsD,CAAC,CAAA;IAE3G,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IACtC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IAEhE,MAAM,YAAY,GAAG,CAAC,MAAM,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACtF,MAAM,YAAY,GAAI,YAA4E,CAAC,gBAAgB,CAAA;IACnH,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,UAAU,CAAC,oDAAoD,CAAC,CAAA;IAE7F,MAAM,aAAa,GAAG,sBAAsB,CAAC;QAC3C,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,qBAAqB,CAAC,MAAM,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACvG,WAAW,EAAE;YACX,GAAG,YAAY,CAAC,WAAW;YAC3B,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,KAAK,EAAE,qBAAqB,CAAC,MAAM;YACnC,KAAK,EAAE,wBAAwB,CAAC,MAAM;SACvC;KACF,CAAC,CAAA;IACF,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/D,MAAM,WAAW,EAAE,CAAA;AACrB,CAAC","sourcesContent":["import {AbortError} from '../../public/node/error.js'\nimport {commandEventOutputSchema} from '../../public/node/command-events.js'\nimport {jsonErrorOutputSchema} from '../../public/node/error/schema.js'\nimport {defineJsonOutputSchema, type JsonOutputSchema} from '../../public/node/json-output-schema.js'\nimport {flushStdout, outputResult} from '../../public/node/output.js'\nimport {zod} from '../../public/node/schema.js'\nimport {normalizeArgv} from '@oclif/core/help'\nimport type {LazyCommandLoader} from '../../public/node/custom-oclif-loader.js'\nimport type {Config} from '@oclif/core'\n\n/**\n * Loads a command's schema without running its lifecycle or Oclif hooks.\n *\n * @param config - The loaded CLI configuration.\n * @param argv - The CLI arguments, including the command name.\n * @param lazyCommandLoader - The optional loader for bundled commands.\n */\nexport async function printCommandJsonSchema(\n config: Config,\n argv: string[],\n lazyCommandLoader?: LazyCommandLoader,\n): Promise<void> {\n const [id] = normalizeArgv(config, argv)\n if (!id || id.startsWith('-')) throw new AbortError('Specify a command to inspect its JSON output schema.')\n\n const command = config.findCommand(id)\n if (!command) throw new AbortError(`Command \"${id}\" not found.`)\n\n const commandClass = (await lazyCommandLoader?.(command.id)) ?? (await command.load())\n const outputSchema = (commandClass as typeof commandClass & {jsonOutputSchema?: JsonOutputSchema}).jsonOutputSchema\n if (!outputSchema) throw new AbortError('This command does not define a JSON output schema.')\n\n const commandSchema = defineJsonOutputSchema({\n name: 'CommandOutput',\n schema: zod.union([outputSchema.schema, jsonErrorOutputSchema.schema, commandEventOutputSchema.schema]),\n definitions: {\n ...outputSchema.definitions,\n Result: outputSchema.schema,\n Error: jsonErrorOutputSchema.schema,\n Event: commandEventOutputSchema.schema,\n },\n })\n outputResult(JSON.stringify(commandSchema.jsonSchema, null, 2))\n await flushStdout()\n}\n"]}
@@ -8,6 +8,7 @@ export declare const environmentVariables: {
8
8
  env: string;
9
9
  noAnalytics: string;
10
10
  optOutInstrumentation: string;
11
+ serviceAccountToken: string;
11
12
  appAutomationToken: string;
12
13
  partnersToken: string;
13
14
  runAsUser: string;
@@ -18,6 +18,7 @@ export const environmentVariables = {
18
18
  env: 'SHOPIFY_CLI_ENV',
19
19
  noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',
20
20
  optOutInstrumentation: 'OPT_OUT_INSTRUMENTATION',
21
+ serviceAccountToken: 'SHOPIFY_SERVICE_ACCOUNT_TOKEN',
21
22
  appAutomationToken: 'SHOPIFY_APP_AUTOMATION_TOKEN',
22
23
  partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',
23
24
  runAsUser: 'SHOPIFY_RUN_AS_USER',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/private/node/constants.ts"],"names":[],"mappings":"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","sourcesContent":["import {joinPath} from '../../public/node/path.js'\nimport envPaths from 'env-paths'\n\nconst identifier = 'shopify-cli'\n\nconst cacheFolder = () => {\n if (process.env.XDG_CACHE_HOME) return process.env.XDG_CACHE_HOME\n return envPaths(identifier).cache\n}\n\nexport const logsFolder = () => {\n return envPaths(identifier).log\n}\n\nexport const environmentVariables = {\n alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',\n alwaysLogMetrics: 'SHOPIFY_CLI_ALWAYS_LOG_METRICS',\n deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',\n doctor: 'SHOPIFY_CLI_DOCTOR',\n enableCliRedirect: 'SHOPIFY_CLI_ENABLE_CLI_REDIRECT',\n env: 'SHOPIFY_CLI_ENV',\n noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',\n optOutInstrumentation: 'OPT_OUT_INSTRUMENTATION',\n appAutomationToken: 'SHOPIFY_APP_AUTOMATION_TOKEN',\n partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',\n runAsUser: 'SHOPIFY_RUN_AS_USER',\n serviceEnv: 'SHOPIFY_SERVICE_ENV',\n skipCliRedirect: 'SHOPIFY_CLI_SKIP_CLI_REDIRECT',\n spinInstance: 'SPIN_INSTANCE',\n themeToken: 'SHOPIFY_CLI_THEME_TOKEN',\n unitTest: 'SHOPIFY_UNIT_TEST',\n verbose: 'SHOPIFY_FLAG_VERBOSE',\n // Variables to detect if the CLI is running in a cloud environment\n codespaces: 'CODESPACES',\n codespaceName: 'CODESPACE_NAME',\n codespacePortForwardingDomain: 'GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN',\n gitpod: 'GITPOD_WORKSPACE_URL',\n cloudShell: 'CLOUD_SHELL',\n spinAppPort: 'SERVER_PORT',\n spinAppHost: 'SPIN_APP_HOST',\n organization: 'SHOPIFY_CLI_ORGANIZATION',\n identityToken: 'SHOPIFY_CLI_IDENTITY_TOKEN',\n refreshToken: 'SHOPIFY_CLI_REFRESH_TOKEN',\n otelURL: 'SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT',\n themeKitAccessDomain: 'SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN',\n json: 'SHOPIFY_FLAG_JSON',\n skipNetworkLevelRetry: 'SHOPIFY_CLI_SKIP_NETWORK_LEVEL_RETRY',\n maxRequestTimeForNetworkCalls: 'SHOPIFY_CLI_MAX_REQUEST_TIME_FOR_NETWORK_CALLS',\n disableImportScanning: 'SHOPIFY_CLI_DISABLE_IMPORT_SCANNING',\n}\n\nexport const defaultThemeKitAccessDomain = 'theme-kit-access.shopifyapps.com'\n\nexport const systemEnvironmentVariables = {\n backendPort: 'BACKEND_PORT',\n}\n\nexport const pathConstants = {\n executables: {\n dev: '/opt/dev/bin/dev',\n },\n directories: {\n cache: {\n path: () => {\n return cacheFolder()\n },\n vendor: {\n path: () => {\n return joinPath(cacheFolder(), 'vendor')\n },\n binaries: () => {\n return joinPath(cacheFolder(), 'vendor', 'binaries')\n },\n },\n },\n },\n}\n\nexport const sessionConstants = {\n expirationTimeMarginInMinutes: 4,\n}\n\nexport const bugsnagApiKey = '9e1e6889176fd0c795d5c659225e0fae'\n\nexport const reportingRateLimit = {limit: 300, timeout: {days: 1}}\n\nexport const themeKitAccessDomain =\n process.env[environmentVariables.themeKitAccessDomain] ?? defaultThemeKitAccessDomain\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/private/node/constants.ts"],"names":[],"mappings":"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","sourcesContent":["import {joinPath} from '../../public/node/path.js'\nimport envPaths from 'env-paths'\n\nconst identifier = 'shopify-cli'\n\nconst cacheFolder = () => {\n if (process.env.XDG_CACHE_HOME) return process.env.XDG_CACHE_HOME\n return envPaths(identifier).cache\n}\n\nexport const logsFolder = () => {\n return envPaths(identifier).log\n}\n\nexport const environmentVariables = {\n alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',\n alwaysLogMetrics: 'SHOPIFY_CLI_ALWAYS_LOG_METRICS',\n deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',\n doctor: 'SHOPIFY_CLI_DOCTOR',\n enableCliRedirect: 'SHOPIFY_CLI_ENABLE_CLI_REDIRECT',\n env: 'SHOPIFY_CLI_ENV',\n noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',\n optOutInstrumentation: 'OPT_OUT_INSTRUMENTATION',\n serviceAccountToken: 'SHOPIFY_SERVICE_ACCOUNT_TOKEN',\n appAutomationToken: 'SHOPIFY_APP_AUTOMATION_TOKEN',\n partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',\n runAsUser: 'SHOPIFY_RUN_AS_USER',\n serviceEnv: 'SHOPIFY_SERVICE_ENV',\n skipCliRedirect: 'SHOPIFY_CLI_SKIP_CLI_REDIRECT',\n spinInstance: 'SPIN_INSTANCE',\n themeToken: 'SHOPIFY_CLI_THEME_TOKEN',\n unitTest: 'SHOPIFY_UNIT_TEST',\n verbose: 'SHOPIFY_FLAG_VERBOSE',\n // Variables to detect if the CLI is running in a cloud environment\n codespaces: 'CODESPACES',\n codespaceName: 'CODESPACE_NAME',\n codespacePortForwardingDomain: 'GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN',\n gitpod: 'GITPOD_WORKSPACE_URL',\n cloudShell: 'CLOUD_SHELL',\n spinAppPort: 'SERVER_PORT',\n spinAppHost: 'SPIN_APP_HOST',\n organization: 'SHOPIFY_CLI_ORGANIZATION',\n identityToken: 'SHOPIFY_CLI_IDENTITY_TOKEN',\n refreshToken: 'SHOPIFY_CLI_REFRESH_TOKEN',\n otelURL: 'SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT',\n themeKitAccessDomain: 'SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN',\n json: 'SHOPIFY_FLAG_JSON',\n skipNetworkLevelRetry: 'SHOPIFY_CLI_SKIP_NETWORK_LEVEL_RETRY',\n maxRequestTimeForNetworkCalls: 'SHOPIFY_CLI_MAX_REQUEST_TIME_FOR_NETWORK_CALLS',\n disableImportScanning: 'SHOPIFY_CLI_DISABLE_IMPORT_SCANNING',\n}\n\nexport const defaultThemeKitAccessDomain = 'theme-kit-access.shopifyapps.com'\n\nexport const systemEnvironmentVariables = {\n backendPort: 'BACKEND_PORT',\n}\n\nexport const pathConstants = {\n executables: {\n dev: '/opt/dev/bin/dev',\n },\n directories: {\n cache: {\n path: () => {\n return cacheFolder()\n },\n vendor: {\n path: () => {\n return joinPath(cacheFolder(), 'vendor')\n },\n binaries: () => {\n return joinPath(cacheFolder(), 'vendor', 'binaries')\n },\n },\n },\n },\n}\n\nexport const sessionConstants = {\n expirationTimeMarginInMinutes: 4,\n}\n\nexport const bugsnagApiKey = '9e1e6889176fd0c795d5c659225e0fae'\n\nexport const reportingRateLimit = {limit: 300, timeout: {days: 1}}\n\nexport const themeKitAccessDomain =\n process.env[environmentVariables.themeKitAccessDomain] ?? defaultThemeKitAccessDomain\n"]}
@@ -0,0 +1,47 @@
1
+ import { zod } from '../../public/node/schema.js';
2
+ import { Writable, type WritableOptions } from 'stream';
3
+ export declare const devInstanceLogOutputSchema: import("../../public/node/json-output-schema.js").JsonOutputSchema<zod.ZodObject<{
4
+ timestamp: zod.ZodString;
5
+ source: zod.ZodString;
6
+ level: zod.ZodOptional<zod.ZodEnum<["debug", "info", "warning", "error"]>>;
7
+ message: zod.ZodString;
8
+ }, "strict", zod.ZodTypeAny, {
9
+ source: string;
10
+ message: string;
11
+ timestamp: string;
12
+ level?: "info" | "error" | "debug" | "warning" | undefined;
13
+ }, {
14
+ source: string;
15
+ message: string;
16
+ timestamp: string;
17
+ level?: "info" | "error" | "debug" | "warning" | undefined;
18
+ }>>;
19
+ /** One line of a dev instance's JSON Lines log. */
20
+ export type DevInstanceLogEntry = zod.infer<typeof devInstanceLogOutputSchema.schema>;
21
+ interface DevInstanceOutputOptions {
22
+ logFile: string;
23
+ logOutput?: Writable;
24
+ isActive: () => boolean;
25
+ onError: (error: unknown) => void;
26
+ }
27
+ export declare function createDevInstanceOutput({ logFile, logOutput, isActive, onError }: DevInstanceOutputOptions): {
28
+ opened: Promise<any[]>;
29
+ log: (entry: Omit<DevInstanceLogEntry, "timestamp"> & {
30
+ timestamp?: string;
31
+ }) => Promise<void>;
32
+ tee: (target: Writable, { source, stringWritesAreMessages }: {
33
+ source: string;
34
+ stringWritesAreMessages?: boolean;
35
+ }) => DevInstanceOutput;
36
+ flush: () => Promise<PromiseSettledResult<void>[]>;
37
+ close: () => Promise<void>;
38
+ };
39
+ declare class DevInstanceOutput extends Writable {
40
+ private readonly contexts;
41
+ constructor(options: WritableOptions & {
42
+ write: NonNullable<WritableOptions['write']>;
43
+ });
44
+ write(chunk: string | Uint8Array, encoding?: BufferEncoding | ((error?: Error | null) => void), callback?: (error?: Error | null) => void): boolean;
45
+ end(chunk?: string | Uint8Array | null | (() => void), encoding?: BufferEncoding | (() => void), callback?: () => void): this;
46
+ }
47
+ export {};