@shopify/cli-hydrogen 5.4.0 → 5.4.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.
@@ -3,11 +3,13 @@ import Command from '@shopify/cli-kit/node/base-command';
3
3
  import colors from '@shopify/cli-kit/node/colors';
4
4
  import { outputWarn, outputInfo, outputContent } from '@shopify/cli-kit/node/output';
5
5
  import { AbortError } from '@shopify/cli-kit/node/error';
6
+ import { getLatestGitCommit } from '@shopify/cli-kit/node/git';
6
7
  import { resolvePath } from '@shopify/cli-kit/node/path';
7
- import { renderFatalError, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
8
+ import { renderFatalError, renderSelectPrompt, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
9
+ import { ciPlatform } from '@shopify/cli-kit/node/context/local';
8
10
  import { parseToken, createDeploy } from '@shopify/oxygen-cli/deploy';
9
- import { commonFlags } from '../../lib/flags.js';
10
- import { getOxygenDeploymentToken } from '../../lib/get-oxygen-token.js';
11
+ import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
12
+ import { getOxygenDeploymentData } from '../../lib/get-oxygen-deployment-data.js';
11
13
  import { runBuild } from './build.js';
12
14
 
13
15
  const deploymentLogger = (message, level = "info") => {
@@ -17,25 +19,36 @@ const deploymentLogger = (message, level = "info") => {
17
19
  };
18
20
  class Deploy extends Command {
19
21
  static flags = {
22
+ "env-branch": Flags.string({
23
+ char: "e",
24
+ description: "Environment branch (tag) for environment to deploy to",
25
+ required: false
26
+ }),
20
27
  path: commonFlags.path,
21
28
  shop: commonFlags.shop,
22
- publicDeployment: Flags.boolean({
29
+ "public-deployment": Flags.boolean({
23
30
  env: "SHOPIFY_HYDROGEN_FLAG_PUBLIC_DEPLOYMENT",
24
31
  description: "Marks a preview deployment as publicly accessible.",
25
32
  required: false,
26
33
  default: false
27
34
  }),
28
- metadataUrl: Flags.string({
35
+ token: Flags.string({
36
+ char: "t",
37
+ description: "Oxygen deployment token",
38
+ env: "SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN",
39
+ required: false
40
+ }),
41
+ "metadata-url": Flags.string({
29
42
  description: "URL that links to the deployment. Will be saved and displayed in the Shopify admin",
30
43
  required: false,
31
44
  env: "SHOPIFY_HYDROGEN_FLAG_METADATA_URL"
32
45
  }),
33
- metadataUser: Flags.string({
46
+ "metadata-user": Flags.string({
34
47
  description: "User that initiated the deployment. Will be saved and displayed in the Shopify admin",
35
48
  required: false,
36
49
  env: "SHOPIFY_HYDROGEN_FLAG_METADATA_USER"
37
50
  }),
38
- metadataVersion: Flags.string({
51
+ "metadata-version": Flags.string({
39
52
  description: "A version identifier for the deployment. Will be saved and displayed in the Shopify admin",
40
53
  required: false,
41
54
  env: "SHOPIFY_HYDROGEN_FLAG_METADATA_VERSION"
@@ -44,24 +57,26 @@ class Deploy extends Command {
44
57
  static hidden = true;
45
58
  async run() {
46
59
  const { flags } = await this.parse(Deploy);
47
- const actualPath = flags.path ? resolvePath(flags.path) : process.cwd();
48
- await oxygenDeploy({
49
- path: actualPath,
50
- shop: flags.shop,
51
- publicDeployment: flags.publicDeployment,
52
- metadataUrl: flags.metadataUrl,
53
- metadataUser: flags.metadataUser,
54
- metadataVersion: flags.metadataVersion
55
- }).catch((error) => {
60
+ const deploymentOptions = this.flagsToOxygenDeploymentOptions(flags);
61
+ await oxygenDeploy(deploymentOptions).catch((error) => {
56
62
  renderFatalError(error);
57
63
  process.exit(1);
58
64
  }).finally(() => {
59
65
  process.exit(0);
60
66
  });
61
67
  }
68
+ flagsToOxygenDeploymentOptions(flags) {
69
+ const camelFlags = flagsToCamelObject(flags);
70
+ return {
71
+ ...camelFlags,
72
+ environmentTag: flags["env-branch"],
73
+ path: flags.path ? resolvePath(flags.path) : process.cwd()
74
+ };
75
+ }
62
76
  }
63
77
  async function oxygenDeploy(options) {
64
78
  const {
79
+ environmentTag,
65
80
  path,
66
81
  shop,
67
82
  publicDeployment,
@@ -69,25 +84,69 @@ async function oxygenDeploy(options) {
69
84
  metadataUser,
70
85
  metadataVersion
71
86
  } = options;
72
- const token = await getOxygenDeploymentToken({
73
- root: path,
74
- flagShop: shop
75
- });
87
+ const ci = ciPlatform();
88
+ let token = options.token;
89
+ let branch;
90
+ let deploymentData;
91
+ let deploymentEnvironmentTag = void 0;
92
+ let gitCommit;
93
+ try {
94
+ gitCommit = await getLatestGitCommit(path);
95
+ branch = (/HEAD -> ([^,]*)/.exec(gitCommit.refs) || [])[1];
96
+ } catch (error) {
97
+ outputWarn("Could not retrieve Git history.");
98
+ branch = void 0;
99
+ }
100
+ if (!ci.isCI) {
101
+ deploymentData = await getOxygenDeploymentData({
102
+ root: path,
103
+ flagShop: shop
104
+ });
105
+ if (!deploymentData) {
106
+ return;
107
+ }
108
+ token = token || deploymentData.oxygenDeploymentToken;
109
+ }
76
110
  if (!token) {
77
- throw new AbortError("Could not obtain Oxygen deployment token");
111
+ const errMessage = ci.isCI ? [
112
+ "No deployment token provided. Use the ",
113
+ { command: "--token" },
114
+ " flag to provide a token."
115
+ ] : `Could not obtain an Oxygen deployment token, please try again or contact Shopify support.`;
116
+ throw new AbortError(errMessage);
117
+ }
118
+ if (!ci.isCI && !environmentTag && deploymentData?.environments) {
119
+ if (deploymentData.environments.length > 1) {
120
+ const choices = [
121
+ ...deploymentData.environments.map(({ name, branch: branch2 }) => ({
122
+ label: name,
123
+ value: branch2
124
+ }))
125
+ ];
126
+ deploymentEnvironmentTag = await renderSelectPrompt({
127
+ message: "Select an environment to deploy to",
128
+ choices,
129
+ defaultValue: branch
130
+ });
131
+ } else {
132
+ outputInfo(
133
+ `Using current checked out branch ${branch} as environment tag`
134
+ );
135
+ }
78
136
  }
79
137
  const config = {
80
138
  assetsDir: "dist/client",
81
139
  deploymentUrl: "https://oxygen.shopifyapps.com",
82
140
  deploymentToken: parseToken(token),
83
- healthCheckMaxDuration: 180,
141
+ environmentTag: environmentTag || deploymentEnvironmentTag || branch,
142
+ verificationMaxDuration: 180,
84
143
  metadata: {
85
144
  ...metadataUrl ? { url: metadataUrl } : {},
86
145
  ...metadataUser ? { user: metadataUser } : {},
87
146
  ...metadataVersion ? { version: metadataVersion } : {}
88
147
  },
89
148
  publicDeployment,
90
- skipHealthCheck: false,
149
+ skipVerification: false,
91
150
  rootPath: path,
92
151
  skipBuild: false,
93
152
  workerOnly: false,
@@ -120,10 +179,10 @@ async function oxygenDeploy(options) {
120
179
  useCodegen: false
121
180
  });
122
181
  },
123
- onHealthCheckComplete: () => resolveHealthCheck(),
182
+ onVerificationComplete: () => resolveHealthCheck(),
124
183
  onUploadFilesStart: () => uploadStart(),
125
184
  onUploadFilesComplete: () => resolveUpload(),
126
- onHealthCheckError: (error) => {
185
+ onVerificationError: (error) => {
127
186
  deployError = new AbortError(
128
187
  error.message,
129
188
  "Please verify the deployment status in the Shopify Admin and retry deploying if necessary."
@@ -146,7 +205,7 @@ async function oxygenDeploy(options) {
146
205
  task: async () => await uploadPromise
147
206
  },
148
207
  {
149
- title: "Performing health check",
208
+ title: "Verifying deployment",
150
209
  task: async () => await healthCheckPromise
151
210
  }
152
211
  ]);
@@ -1,13 +1,14 @@
1
- import { vi, describe, beforeEach, afterEach, it, expect } from 'vitest';
1
+ import { vi, describe, expect, beforeEach, afterEach, it } from 'vitest';
2
2
  import { login } from '../../lib/auth.js';
3
3
  import { getStorefronts } from '../../lib/graphql/admin/link-storefront.js';
4
4
  import { AbortError } from '@shopify/cli-kit/node/error';
5
5
  import { renderSelectPrompt, renderSuccess, renderFatalError } from '@shopify/cli-kit/node/ui';
6
+ import { getLatestGitCommit } from '@shopify/cli-kit/node/git';
6
7
  import { oxygenDeploy, deploymentLogger } from './deploy.js';
7
- import { getOxygenDeploymentToken } from '../../lib/get-oxygen-token.js';
8
+ import { getOxygenDeploymentData } from '../../lib/get-oxygen-deployment-data.js';
8
9
  import { createDeploy, parseToken } from '@shopify/oxygen-cli/deploy';
9
10
 
10
- vi.mock("../../lib/get-oxygen-token.js");
11
+ vi.mock("../../lib/get-oxygen-deployment-data.js");
11
12
  vi.mock("@shopify/oxygen-cli/deploy");
12
13
  vi.mock("../../lib/auth.js");
13
14
  vi.mock("../../lib/shopify-config.js");
@@ -19,6 +20,8 @@ vi.mock("@shopify/cli-kit/node/output", async () => {
19
20
  return {
20
21
  outputContent: () => ({ value: "" }),
21
22
  outputInfo: () => {
23
+ },
24
+ outputWarn: () => {
22
25
  }
23
26
  };
24
27
  });
@@ -30,6 +33,16 @@ vi.mock("@shopify/cli-kit/node/ui", async () => {
30
33
  renderTasks: vi.fn()
31
34
  };
32
35
  });
36
+ vi.mock("@shopify/cli-kit/node/git", async () => {
37
+ return {
38
+ getLatestGitCommit: vi.fn()
39
+ };
40
+ });
41
+ vi.mock("@shopify/cli-kit/node/context/local", async () => {
42
+ return {
43
+ ciPlatform: () => ({ isCI: false })
44
+ };
45
+ });
33
46
  describe("deploy", () => {
34
47
  const ADMIN_SESSION = {
35
48
  token: "abc123",
@@ -66,6 +79,31 @@ describe("deploy", () => {
66
79
  namespace: "some-namespace",
67
80
  namespaceId: "1"
68
81
  };
82
+ const expectedConfig = {
83
+ assetsDir: "dist/client",
84
+ deploymentUrl: "https://oxygen.shopifyapps.com",
85
+ deploymentToken: mockToken,
86
+ verificationMaxDuration: 180,
87
+ metadata: {
88
+ url: deployParams.metadataUrl,
89
+ user: deployParams.metadataUser,
90
+ version: deployParams.metadataVersion
91
+ },
92
+ publicDeployment: deployParams.publicDeployment,
93
+ skipVerification: false,
94
+ rootPath: deployParams.path,
95
+ skipBuild: false,
96
+ workerOnly: false,
97
+ workerDir: "dist/worker"
98
+ };
99
+ const expectedHooks = {
100
+ buildFunction: expect.any(Function),
101
+ onVerificationComplete: expect.any(Function),
102
+ onUploadFilesStart: expect.any(Function),
103
+ onUploadFilesComplete: expect.any(Function),
104
+ onVerificationError: expect.any(Function),
105
+ onUploadFilesError: expect.any(Function)
106
+ };
69
107
  beforeEach(async () => {
70
108
  process.exit = vi.fn();
71
109
  vi.mocked(login).mockResolvedValue({
@@ -83,54 +121,68 @@ describe("deploy", () => {
83
121
  vi.mocked(createDeploy).mockResolvedValue(
84
122
  "https://a-lovely-deployment.com"
85
123
  );
86
- vi.mocked(getOxygenDeploymentToken).mockResolvedValue("some-encoded-token");
124
+ vi.mocked(getOxygenDeploymentData).mockResolvedValue({
125
+ oxygenDeploymentToken: "some-encoded-token",
126
+ environments: []
127
+ });
87
128
  vi.mocked(parseToken).mockReturnValue(mockToken);
88
129
  });
89
130
  afterEach(() => {
90
131
  vi.resetAllMocks();
91
132
  process.exit = originalExit;
92
133
  });
93
- it("calls getOxygenDeploymentToken with the correct parameters", async () => {
134
+ it("calls getOxygenDeploymentData with the correct parameters", async () => {
94
135
  await oxygenDeploy(deployParams);
95
- expect(getOxygenDeploymentToken).toHaveBeenCalledWith({
136
+ expect(getOxygenDeploymentData).toHaveBeenCalledWith({
96
137
  root: "./",
97
138
  flagShop: "snowdevil.myshopify.com"
98
139
  });
99
- expect(getOxygenDeploymentToken).toHaveBeenCalledTimes(1);
140
+ expect(getOxygenDeploymentData).toHaveBeenCalledTimes(1);
100
141
  });
101
142
  it("calls createDeploy with the correct parameters", async () => {
102
143
  await oxygenDeploy(deployParams);
103
- const expectedConfig = {
104
- assetsDir: "dist/client",
105
- deploymentUrl: "https://oxygen.shopifyapps.com",
106
- deploymentToken: mockToken,
107
- healthCheckMaxDuration: 180,
108
- metadata: {
109
- url: deployParams.metadataUrl,
110
- user: deployParams.metadataUser,
111
- version: deployParams.metadataVersion
112
- },
113
- publicDeployment: deployParams.publicDeployment,
114
- skipHealthCheck: false,
115
- rootPath: deployParams.path,
116
- skipBuild: false,
117
- workerOnly: false,
118
- workerDir: "dist/worker"
119
- };
120
144
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
121
145
  config: expectedConfig,
122
- hooks: {
123
- buildFunction: expect.any(Function),
124
- onHealthCheckComplete: expect.any(Function),
125
- onUploadFilesStart: expect.any(Function),
126
- onUploadFilesComplete: expect.any(Function),
127
- onHealthCheckError: expect.any(Function),
128
- onUploadFilesError: expect.any(Function)
129
- },
146
+ hooks: expectedHooks,
147
+ logger: deploymentLogger
148
+ });
149
+ expect(vi.mocked(renderSuccess)).toHaveBeenCalled;
150
+ });
151
+ it("calls createDeploy with the checked out branch name", async () => {
152
+ vi.mocked(getLatestGitCommit).mockResolvedValue({
153
+ hash: "123",
154
+ message: "test commit",
155
+ date: "2021-01-01",
156
+ author_name: "test author",
157
+ author_email: "test@author.com",
158
+ body: "test body",
159
+ refs: "HEAD -> main"
160
+ });
161
+ await oxygenDeploy(deployParams);
162
+ expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
163
+ config: { ...expectedConfig, environmentTag: "main" },
164
+ hooks: expectedHooks,
130
165
  logger: deploymentLogger
131
166
  });
132
167
  expect(vi.mocked(renderSuccess)).toHaveBeenCalled;
133
168
  });
169
+ it("calls renderSelectPrompt when there are multiple environments", async () => {
170
+ vi.mocked(getOxygenDeploymentData).mockResolvedValue({
171
+ oxygenDeploymentToken: "some-encoded-token",
172
+ environments: [
173
+ { name: "production", branch: "main" },
174
+ { name: "preview", branch: "staging" }
175
+ ]
176
+ });
177
+ await oxygenDeploy(deployParams);
178
+ expect(vi.mocked(renderSelectPrompt)).toHaveBeenCalledWith({
179
+ message: "Select an environment to deploy to",
180
+ choices: [
181
+ { label: "production", value: "main" },
182
+ { label: "preview", value: "staging" }
183
+ ]
184
+ });
185
+ });
134
186
  it("handles error during uploadFiles", async () => {
135
187
  const mockRenderFatalError = vi.fn();
136
188
  vi.mocked(renderFatalError).mockImplementation(mockRenderFatalError);
@@ -156,14 +208,14 @@ describe("deploy", () => {
156
208
  }
157
209
  }
158
210
  });
159
- it("handles error during health check", async () => {
211
+ it("handles error during deployment verification", async () => {
160
212
  const mockRenderFatalError = vi.fn();
161
213
  vi.mocked(renderFatalError).mockImplementation(mockRenderFatalError);
162
214
  const error = new Error("Cloudflare is down!");
163
215
  vi.mocked(createDeploy).mockImplementation((options) => {
164
216
  options.hooks?.onUploadFilesStart?.();
165
217
  options.hooks?.onUploadFilesComplete?.();
166
- options.hooks?.onHealthCheckError?.(error);
218
+ options.hooks?.onVerificationError?.(error);
167
219
  return new Promise((_resolve, reject) => {
168
220
  reject(error);
169
221
  });
@@ -15,9 +15,9 @@
15
15
  "dependencies": {
16
16
  "@remix-run/react": "1.19.1",
17
17
  "@shopify/cli": "3.49.2",
18
- "@shopify/cli-hydrogen": "^5.4.0",
18
+ "@shopify/cli-hydrogen": "^5.4.1",
19
19
  "@shopify/hydrogen": "^2023.7.9",
20
- "@shopify/remix-oxygen": "^1.1.4",
20
+ "@shopify/remix-oxygen": "^1.1.5",
21
21
  "graphql": "^16.6.0",
22
22
  "graphql-tag": "^2.12.6",
23
23
  "isbot": "^3.6.6",
@@ -4,9 +4,9 @@ import { linkStorefront } from '../commands/hydrogen/link.js';
4
4
  import { login } from './auth.js';
5
5
  import { getCliCommand } from './shell.js';
6
6
  import { renderMissingLink, renderMissingStorefront } from './render-errors.js';
7
- import { getOxygenToken } from './graphql/admin/oxygen-token.js';
7
+ import { getOxygenData } from './graphql/admin/get-oxygen-data.js';
8
8
 
9
- async function getOxygenDeploymentToken({
9
+ async function getOxygenDeploymentData({
10
10
  root
11
11
  }) {
12
12
  const [{ session, config }, cliCommand] = await Promise.all([
@@ -28,7 +28,7 @@ async function getOxygenDeploymentToken({
28
28
  if (!config.storefront) {
29
29
  return;
30
30
  }
31
- const { storefront } = await getOxygenToken(session, config.storefront.id);
31
+ const { storefront } = await getOxygenData(session, config.storefront.id);
32
32
  if (!storefront) {
33
33
  renderMissingStorefront({
34
34
  session,
@@ -41,7 +41,7 @@ async function getOxygenDeploymentToken({
41
41
  outputWarn(`Could not retrieve a deployment token.`);
42
42
  return;
43
43
  }
44
- return storefront.oxygenDeploymentToken;
44
+ return storefront;
45
45
  }
46
46
 
47
- export { getOxygenDeploymentToken };
47
+ export { getOxygenDeploymentData };
@@ -1,11 +1,11 @@
1
1
  import { vi, describe, beforeEach, afterEach, it, expect } from 'vitest';
2
2
  import { renderConfirmationPrompt } from '@shopify/cli-kit/node/ui';
3
- import { getOxygenDeploymentToken } from './get-oxygen-token.js';
3
+ import { getOxygenDeploymentData } from './get-oxygen-deployment-data.js';
4
4
  import { login } from './auth.js';
5
5
  import { getConfig } from './shopify-config.js';
6
6
  import { renderMissingLink, renderMissingStorefront } from './render-errors.js';
7
7
  import { linkStorefront } from '../commands/hydrogen/link.js';
8
- import { getOxygenToken } from './graphql/admin/oxygen-token.js';
8
+ import { getOxygenData } from './graphql/admin/get-oxygen-data.js';
9
9
 
10
10
  vi.mock("@shopify/cli-kit/node/ui", async () => {
11
11
  const original = await vi.importActual("@shopify/cli-kit/node/ui");
@@ -19,9 +19,19 @@ vi.mock("./admin-session.js");
19
19
  vi.mock("./shopify-config.js");
20
20
  vi.mock("./render-errors.js");
21
21
  vi.mock("../commands/hydrogen/link.js");
22
- vi.mock("./graphql/admin/oxygen-token.js");
23
- describe("getOxygenDeploymentToken", () => {
22
+ vi.mock("./graphql/admin/get-oxygen-data.js");
23
+ describe("getOxygenDeploymentData", () => {
24
24
  const OXYGEN_DEPLOYMENT_TOKEN = "a-lovely-token";
25
+ const environments = [
26
+ {
27
+ name: "production",
28
+ branch: "main"
29
+ },
30
+ {
31
+ name: "preview",
32
+ branch: "staging"
33
+ }
34
+ ];
25
35
  beforeEach(() => {
26
36
  vi.mocked(login).mockResolvedValue({
27
37
  session: {
@@ -41,16 +51,20 @@ describe("getOxygenDeploymentToken", () => {
41
51
  vi.mocked(getConfig).mockResolvedValue({
42
52
  storefront: { id: "storefront-id", title: "Existing Link" }
43
53
  });
44
- vi.mocked(getOxygenToken).mockResolvedValue({
45
- storefront: { oxygenDeploymentToken: OXYGEN_DEPLOYMENT_TOKEN }
54
+ vi.mocked(getOxygenData).mockResolvedValue({
55
+ storefront: {
56
+ oxygenDeploymentToken: OXYGEN_DEPLOYMENT_TOKEN,
57
+ environments
58
+ }
46
59
  });
47
60
  });
48
61
  afterEach(() => {
49
62
  vi.resetAllMocks();
50
63
  });
51
- it("returns the oxygen deployment token", async () => {
52
- const token = await getOxygenDeploymentToken({ root: "test-root" });
53
- expect(token).toBe(OXYGEN_DEPLOYMENT_TOKEN);
64
+ it("returns the oxygen deployment token and environments", async () => {
65
+ const data = await getOxygenDeploymentData({ root: "test-root" });
66
+ expect(data?.oxygenDeploymentToken).toBe(OXYGEN_DEPLOYMENT_TOKEN);
67
+ expect(data?.environments).toEqual(environments);
54
68
  });
55
69
  describe("when there is no linked storefront", () => {
56
70
  beforeEach(() => {
@@ -69,36 +83,36 @@ describe("getOxygenDeploymentToken", () => {
69
83
  });
70
84
  it("calls renderMissingLink and prompts the user to create a link", async () => {
71
85
  vi.mocked(renderConfirmationPrompt).mockResolvedValue(true);
72
- await getOxygenDeploymentToken({ root: "test-root" });
86
+ await getOxygenDeploymentData({ root: "test-root" });
73
87
  expect(renderMissingLink).toHaveBeenCalled();
74
88
  expect(renderConfirmationPrompt).toHaveBeenCalled();
75
89
  expect(linkStorefront).toHaveBeenCalled();
76
90
  });
77
91
  it("returns nothing if the user does not create a new link", async () => {
78
92
  vi.mocked(renderConfirmationPrompt).mockResolvedValue(false);
79
- const token = await getOxygenDeploymentToken({ root: "test-root" });
93
+ const token = await getOxygenDeploymentData({ root: "test-root" });
80
94
  expect(token).toEqual(void 0);
81
95
  });
82
96
  });
83
97
  describe("when there is no matching storefront in the shop", () => {
84
98
  beforeEach(() => {
85
- vi.mocked(getOxygenToken).mockResolvedValue({ storefront: null });
99
+ vi.mocked(getOxygenData).mockResolvedValue({ storefront: null });
86
100
  });
87
101
  it("calls renderMissingStorefront and returns nothing", async () => {
88
- const token = await getOxygenDeploymentToken({ root: "test-root" });
102
+ const token = await getOxygenDeploymentData({ root: "test-root" });
89
103
  expect(renderMissingStorefront).toHaveBeenCalled();
90
104
  expect(token).toEqual(void 0);
91
105
  });
92
106
  });
93
107
  describe("when the storefront does not have an oxygen deployment token", () => {
94
108
  beforeEach(() => {
95
- vi.mocked(getOxygenToken).mockResolvedValue({
96
- storefront: { oxygenDeploymentToken: "" }
109
+ vi.mocked(getOxygenData).mockResolvedValue({
110
+ storefront: { oxygenDeploymentToken: "", environments: [] }
97
111
  });
98
112
  });
99
113
  it("returns nothing", async () => {
100
- const token = await getOxygenDeploymentToken({ root: "test-root" });
101
- expect(token).toEqual(void 0);
114
+ const data = await getOxygenDeploymentData({ root: "test-root" });
115
+ expect(data).toEqual(void 0);
102
116
  });
103
117
  });
104
118
  });
@@ -1,15 +1,19 @@
1
1
  import { adminRequest } from './client.js';
2
2
 
3
- const GetDeploymentTokenQuery = `#graphql
3
+ const GetDeploymentDataQuery = `#graphql
4
4
  query GetDeploymentToken($id: ID!) {
5
5
  hydrogenStorefront(id: $id) {
6
6
  oxygenDeploymentToken
7
+ environments {
8
+ name
9
+ branch
10
+ }
7
11
  }
8
12
  }
9
13
  `;
10
- async function getOxygenToken(adminSession, storefrontId) {
14
+ async function getOxygenData(adminSession, storefrontId) {
11
15
  const { hydrogenStorefront } = await adminRequest(
12
- GetDeploymentTokenQuery,
16
+ GetDeploymentDataQuery,
13
17
  adminSession,
14
18
  {
15
19
  id: storefrontId
@@ -18,4 +22,4 @@ async function getOxygenToken(adminSession, storefrontId) {
18
22
  return { storefront: hydrogenStorefront };
19
23
  }
20
24
 
21
- export { GetDeploymentTokenQuery, getOxygenToken };
25
+ export { GetDeploymentDataQuery, getOxygenData };
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.4.0",
2
+ "version": "5.4.1",
3
3
  "commands": {
4
4
  "hydrogen:build": {
5
5
  "id": "hydrogen:build",
@@ -153,6 +153,14 @@
153
153
  "hidden": true,
154
154
  "aliases": [],
155
155
  "flags": {
156
+ "env-branch": {
157
+ "name": "env-branch",
158
+ "type": "option",
159
+ "char": "e",
160
+ "description": "Environment branch (tag) for environment to deploy to",
161
+ "required": false,
162
+ "multiple": false
163
+ },
156
164
  "path": {
157
165
  "name": "path",
158
166
  "type": "option",
@@ -166,29 +174,37 @@
166
174
  "description": "Shop URL. It can be the shop prefix (janes-apparel) or the full myshopify.com URL (janes-apparel.myshopify.com, https://janes-apparel.myshopify.com).",
167
175
  "multiple": false
168
176
  },
169
- "publicDeployment": {
170
- "name": "publicDeployment",
177
+ "public-deployment": {
178
+ "name": "public-deployment",
171
179
  "type": "boolean",
172
180
  "description": "Marks a preview deployment as publicly accessible.",
173
181
  "required": false,
174
182
  "allowNo": false
175
183
  },
176
- "metadataUrl": {
177
- "name": "metadataUrl",
184
+ "token": {
185
+ "name": "token",
186
+ "type": "option",
187
+ "char": "t",
188
+ "description": "Oxygen deployment token",
189
+ "required": false,
190
+ "multiple": false
191
+ },
192
+ "metadata-url": {
193
+ "name": "metadata-url",
178
194
  "type": "option",
179
195
  "description": "URL that links to the deployment. Will be saved and displayed in the Shopify admin",
180
196
  "required": false,
181
197
  "multiple": false
182
198
  },
183
- "metadataUser": {
184
- "name": "metadataUser",
199
+ "metadata-user": {
200
+ "name": "metadata-user",
185
201
  "type": "option",
186
202
  "description": "User that initiated the deployment. Will be saved and displayed in the Shopify admin",
187
203
  "required": false,
188
204
  "multiple": false
189
205
  },
190
- "metadataVersion": {
191
- "name": "metadataVersion",
206
+ "metadata-version": {
207
+ "name": "metadata-version",
192
208
  "type": "option",
193
209
  "description": "A version identifier for the deployment. Will be saved and displayed in the Shopify admin",
194
210
  "required": false,
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
- "version": "5.4.0",
7
+ "version": "5.4.1",
8
8
  "license": "MIT",
9
9
  "type": "module",
10
10
  "scripts": {
@@ -38,7 +38,7 @@
38
38
  "@shopify/cli-kit": "3.49.2",
39
39
  "@shopify/hydrogen-codegen": "^0.0.2",
40
40
  "@shopify/mini-oxygen": "^2.2.1",
41
- "@shopify/oxygen-cli": "^1.12.0",
41
+ "@shopify/oxygen-cli": "^2.0.0",
42
42
  "ansi-escapes": "^6.2.0",
43
43
  "diff": "^5.1.0",
44
44
  "fs-extra": "^11.1.0",
@@ -57,7 +57,7 @@
57
57
  "@remix-run/dev": "1.19.1",
58
58
  "@remix-run/react": "1.19.1",
59
59
  "@shopify/hydrogen-react": "^2023.7.4",
60
- "@shopify/remix-oxygen": "^1.1.4"
60
+ "@shopify/remix-oxygen": "^1.1.5"
61
61
  },
62
62
  "peerDependenciesMeta": {
63
63
  "@remix-run/dev": {