@shopify/oxygen-cli 1.4.0 → 1.6.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.
- package/README.md +2 -0
- package/dist/commands/oxygen/deploy.d.ts +9 -9
- package/dist/commands/oxygen/deploy.js +58 -43
- package/dist/deploy/build-cancel.d.ts +9 -2
- package/dist/deploy/build-cancel.js +4 -3
- package/dist/deploy/build-cancel.test.js +21 -4
- package/dist/deploy/build-initiate.d.ts +9 -2
- package/dist/deploy/build-initiate.js +4 -3
- package/dist/deploy/build-initiate.test.js +19 -8
- package/dist/deploy/build-project.d.ts +7 -2
- package/dist/deploy/build-project.js +34 -19
- package/dist/deploy/build-project.test.js +14 -8
- package/dist/deploy/deployment-cancel.d.ts +9 -2
- package/dist/deploy/deployment-cancel.js +4 -3
- package/dist/deploy/deployment-cancel.test.js +19 -16
- package/dist/deploy/deployment-complete.d.ts +2 -2
- package/dist/deploy/deployment-initiate.d.ts +10 -4
- package/dist/deploy/deployment-initiate.js +4 -3
- package/dist/deploy/deployment-initiate.test.js +26 -10
- package/dist/deploy/get-upload-files.d.ts +2 -2
- package/dist/deploy/health-check.d.ts +12 -0
- package/dist/deploy/health-check.js +44 -0
- package/dist/deploy/health-check.test.d.ts +2 -0
- package/dist/deploy/health-check.test.js +92 -0
- package/dist/deploy/index.d.ts +10 -3
- package/dist/deploy/index.js +54 -26
- package/dist/deploy/metadata.d.ts +4 -3
- package/dist/deploy/metadata.js +3 -3
- package/dist/deploy/metadata.test.js +4 -4
- package/dist/deploy/types.d.ts +17 -2
- package/dist/deploy/types.js +3 -1
- package/dist/deploy/upload-files.d.ts +9 -2
- package/dist/deploy/upload-files.js +7 -4
- package/dist/deploy/upload-files.test.js +37 -18
- package/dist/utils/test-helper.d.ts +2 -2
- package/dist/utils/test-helper.js +3 -0
- package/dist/utils/utils.d.ts +3 -3
- package/dist/utils/utils.js +1 -5
- package/oclif.manifest.json +50 -33
- package/package.json +8 -8
@@ -3,7 +3,7 @@ import { fetch } from '@shopify/cli-kit/node/http';
|
|
3
3
|
import { vi, describe, beforeEach, it, expect } from 'vitest';
|
4
4
|
import { Response } from 'node-fetch';
|
5
5
|
import { createTestConfig } from '../utils/test-helper.js';
|
6
|
-
import { deployDefaults } from '../utils/utils.js';
|
6
|
+
import { stderrLogger, deployDefaults } from '../utils/utils.js';
|
7
7
|
import { uploadFiles } from './upload-files.js';
|
8
8
|
|
9
9
|
class NamedReadable extends Readable {
|
@@ -29,22 +29,16 @@ vi.mock("@shopify/cli-kit/node/fs", () => {
|
|
29
29
|
})
|
30
30
|
};
|
31
31
|
});
|
32
|
-
vi.mock("fs", () => {
|
33
|
-
return {
|
34
|
-
createReadStream: vi.fn(() => {
|
35
|
-
const readable = new NamedReadable();
|
36
|
-
readable.push("dummy");
|
37
|
-
readable.emit("end");
|
38
|
-
return readable;
|
39
|
-
})
|
40
|
-
};
|
41
|
-
});
|
42
32
|
const testConfig = createTestConfig("/tmp/deploymentRoot");
|
43
33
|
describe("UploadFiles", () => {
|
44
34
|
beforeEach(() => {
|
45
35
|
vi.mocked(fetch).mockReset();
|
46
36
|
});
|
47
37
|
it("Performs a form upload", async () => {
|
38
|
+
const hooks = {
|
39
|
+
onUploadFilesStart: vi.fn(),
|
40
|
+
onUploadFilesComplete: vi.fn()
|
41
|
+
};
|
48
42
|
const response = new Response();
|
49
43
|
vi.mocked(fetch).mockResolvedValueOnce(response);
|
50
44
|
const testWorkerUpload = [
|
@@ -56,7 +50,12 @@ describe("UploadFiles", () => {
|
|
56
50
|
parameters: [{ name: "someName", value: "someValue" }]
|
57
51
|
}
|
58
52
|
];
|
59
|
-
await uploadFiles(
|
53
|
+
await uploadFiles({
|
54
|
+
config: testConfig,
|
55
|
+
targets: testWorkerUpload,
|
56
|
+
logger: stderrLogger,
|
57
|
+
hooks
|
58
|
+
});
|
60
59
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(1);
|
61
60
|
expect(vi.mocked(fetch)).toHaveBeenCalledWith(
|
62
61
|
"https://storage.googleapis.com/the-bucket/",
|
@@ -73,6 +72,8 @@ describe("UploadFiles", () => {
|
|
73
72
|
})
|
74
73
|
})
|
75
74
|
);
|
75
|
+
expect(hooks.onUploadFilesStart).toBeCalled();
|
76
|
+
expect(hooks.onUploadFilesComplete).toBeCalled();
|
76
77
|
});
|
77
78
|
it("Retries a failed form upload until the max upload attempts then throws", async () => {
|
78
79
|
vi.mocked(fetch).mockRejectedValue(new Error("some error"));
|
@@ -85,9 +86,13 @@ describe("UploadFiles", () => {
|
|
85
86
|
parameters: [{ name: "someName", value: "someValue" }]
|
86
87
|
}
|
87
88
|
];
|
88
|
-
await expect(
|
89
|
-
|
90
|
-
|
89
|
+
await expect(
|
90
|
+
uploadFiles({
|
91
|
+
config: testConfig,
|
92
|
+
targets: testWorkerUpload,
|
93
|
+
logger: stderrLogger
|
94
|
+
})
|
95
|
+
).rejects.toThrow("Failed to upload file index.js");
|
91
96
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(
|
92
97
|
Number(deployDefaults.maxUploadAttempts) + 1
|
93
98
|
);
|
@@ -108,7 +113,11 @@ describe("UploadFiles", () => {
|
|
108
113
|
parameters: null
|
109
114
|
}
|
110
115
|
];
|
111
|
-
await uploadFiles(
|
116
|
+
await uploadFiles({
|
117
|
+
config: testConfig,
|
118
|
+
targets: testWorkerUpload,
|
119
|
+
logger: stderrLogger
|
120
|
+
});
|
112
121
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(2);
|
113
122
|
const secondCall = vi.mocked(fetch).mock.calls[1];
|
114
123
|
expect(secondCall[0]).toBe("https://upload-it-here.com/");
|
@@ -145,7 +154,11 @@ describe("UploadFiles", () => {
|
|
145
154
|
parameters: null
|
146
155
|
}
|
147
156
|
];
|
148
|
-
await uploadFiles(
|
157
|
+
await uploadFiles({
|
158
|
+
config: testConfig,
|
159
|
+
targets: testWorkerUpload,
|
160
|
+
logger: stderrLogger
|
161
|
+
});
|
149
162
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(4);
|
150
163
|
const statusCall = vi.mocked(fetch).mock.calls[2];
|
151
164
|
expect(statusCall[0]).toBe("https://upload-it-here.com/");
|
@@ -183,7 +196,13 @@ describe("UploadFiles", () => {
|
|
183
196
|
parameters: null
|
184
197
|
}
|
185
198
|
];
|
186
|
-
await expect(
|
199
|
+
await expect(
|
200
|
+
uploadFiles({
|
201
|
+
config: testConfig,
|
202
|
+
targets: testWorkerUpload,
|
203
|
+
logger: stderrLogger
|
204
|
+
})
|
205
|
+
).rejects.toThrow(
|
187
206
|
`Failed to upload file index.js after ${deployDefaults.maxResumabeUploadAttempts} attempts`
|
188
207
|
);
|
189
208
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig } from '../deploy/types.js';
|
2
2
|
|
3
3
|
declare const testToken: {
|
4
4
|
accessToken: string;
|
@@ -9,6 +9,6 @@ declare const testToken: {
|
|
9
9
|
namespace: string;
|
10
10
|
namespaceId: string;
|
11
11
|
};
|
12
|
-
declare function createTestConfig(rootFolder: string):
|
12
|
+
declare function createTestConfig(rootFolder: string): DeploymentConfig;
|
13
13
|
|
14
14
|
export { createTestConfig, testToken };
|
@@ -13,13 +13,16 @@ function createTestConfig(rootFolder) {
|
|
13
13
|
return {
|
14
14
|
assetsDir: "/assets/",
|
15
15
|
buildCommand: String(deployDefaults.buildCommandDefault),
|
16
|
+
buildOutput: true,
|
16
17
|
deploymentToken: testToken,
|
17
18
|
environmentTag: "environment",
|
18
19
|
deploymentUrl: "https://localhost:3000",
|
20
|
+
healthCheckMaxDuration: 300,
|
19
21
|
metadata: {},
|
20
22
|
rootPath: rootFolder,
|
21
23
|
publicDeployment: false,
|
22
24
|
skipBuild: false,
|
25
|
+
skipHealthCheck: false,
|
23
26
|
workerDir: "/worker/",
|
24
27
|
workerOnly: false
|
25
28
|
};
|
package/dist/utils/utils.d.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig, ClientError, DeploymentToken } from '../deploy/types.js';
|
2
2
|
|
3
3
|
declare const deployDefaults: {
|
4
4
|
[key: string]: string | number;
|
5
5
|
};
|
6
6
|
declare function errorHandler(error: any): void;
|
7
|
-
declare function getBuildCommandFromLockFile(config:
|
7
|
+
declare function getBuildCommandFromLockFile(config: DeploymentConfig): string;
|
8
8
|
declare enum Header {
|
9
9
|
OxygenNamespaceHandle = "X-Oxygen-Namespace-Handle"
|
10
10
|
}
|
@@ -13,7 +13,7 @@ declare function stderrLogger(log: string): void;
|
|
13
13
|
declare const maxLabelLength = 90;
|
14
14
|
declare function parseToken(inputToken: string): DeploymentToken;
|
15
15
|
interface VerifyConfigParams {
|
16
|
-
config:
|
16
|
+
config: DeploymentConfig;
|
17
17
|
performedBuild?: boolean;
|
18
18
|
}
|
19
19
|
declare function verifyConfig({ config, performedBuild, }: VerifyConfigParams): Promise<void>;
|
package/dist/utils/utils.js
CHANGED
@@ -6,6 +6,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
6
6
|
const deployDefaults = {
|
7
7
|
assetsDirDefault: "dist/client/",
|
8
8
|
buildCommandDefault: "yarn build",
|
9
|
+
healthCheckMaxDurationDefault: 180,
|
9
10
|
maxUploadAttempts: 3,
|
10
11
|
maxResumabeUploadAttempts: 9,
|
11
12
|
workerDirDefault: "dist/worker/"
|
@@ -72,11 +73,6 @@ function stderrLogger(log) {
|
|
72
73
|
}
|
73
74
|
const maxLabelLength = 90;
|
74
75
|
function parseToken(inputToken) {
|
75
|
-
if (!inputToken) {
|
76
|
-
throw new Error(
|
77
|
-
"No deployment token provided. Use the --token flag to set a deployment token."
|
78
|
-
);
|
79
|
-
}
|
80
76
|
try {
|
81
77
|
const decodedToken = Buffer.from(inputToken, "base64").toString("utf-8");
|
82
78
|
const rawToken = JSON.parse(decodedToken);
|
package/oclif.manifest.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "1.
|
2
|
+
"version": "1.6.0",
|
3
3
|
"commands": {
|
4
4
|
"oxygen:deploy": {
|
5
5
|
"id": "oxygen:deploy",
|
@@ -11,22 +11,23 @@
|
|
11
11
|
"hidden": false,
|
12
12
|
"aliases": [],
|
13
13
|
"flags": {
|
14
|
-
"
|
15
|
-
"name": "
|
14
|
+
"assetsFolder": {
|
15
|
+
"name": "assetsFolder",
|
16
16
|
"type": "option",
|
17
|
-
"char": "
|
18
|
-
"description": "
|
17
|
+
"char": "a",
|
18
|
+
"description": "Assets folder",
|
19
19
|
"required": false,
|
20
|
-
"multiple": false
|
20
|
+
"multiple": false,
|
21
|
+
"default": "dist/client/"
|
21
22
|
},
|
22
|
-
"
|
23
|
-
"name": "
|
23
|
+
"buildCommand": {
|
24
|
+
"name": "buildCommand",
|
24
25
|
"type": "option",
|
25
|
-
"char": "
|
26
|
-
"description": "
|
26
|
+
"char": "b",
|
27
|
+
"description": "Build command",
|
27
28
|
"required": false,
|
28
29
|
"multiple": false,
|
29
|
-
"default": "
|
30
|
+
"default": "yarn build"
|
30
31
|
},
|
31
32
|
"environmentTag": {
|
32
33
|
"name": "environmentTag",
|
@@ -36,29 +37,28 @@
|
|
36
37
|
"required": false,
|
37
38
|
"multiple": false
|
38
39
|
},
|
39
|
-
"
|
40
|
-
"name": "
|
40
|
+
"healthCheckMaxDuration": {
|
41
|
+
"name": "healthCheckMaxDuration",
|
41
42
|
"type": "option",
|
42
|
-
"char": "
|
43
|
-
"description": "
|
43
|
+
"char": "d",
|
44
|
+
"description": "the maximum duration (in seconds) that the health check is allowed to run before it is considered failed.",
|
44
45
|
"required": false,
|
45
46
|
"multiple": false,
|
46
|
-
"default":
|
47
|
+
"default": 180
|
47
48
|
},
|
48
|
-
"
|
49
|
-
"name": "
|
49
|
+
"path": {
|
50
|
+
"name": "path",
|
50
51
|
"type": "option",
|
51
|
-
"char": "
|
52
|
-
"description": "
|
52
|
+
"char": "p",
|
53
|
+
"description": "Root path",
|
53
54
|
"required": false,
|
54
55
|
"multiple": false,
|
55
|
-
"default": "
|
56
|
+
"default": "./"
|
56
57
|
},
|
57
|
-
"
|
58
|
-
"name": "
|
58
|
+
"publicDeployment": {
|
59
|
+
"name": "publicDeployment",
|
59
60
|
"type": "boolean",
|
60
|
-
"
|
61
|
-
"description": "Worker only deployment",
|
61
|
+
"description": "Marks a preview deployment as publicly accessible.",
|
62
62
|
"required": false,
|
63
63
|
"allowNo": false
|
64
64
|
},
|
@@ -70,19 +70,36 @@
|
|
70
70
|
"required": false,
|
71
71
|
"allowNo": false
|
72
72
|
},
|
73
|
-
"
|
74
|
-
"name": "
|
73
|
+
"skipHealthCheck": {
|
74
|
+
"name": "skipHealthCheck",
|
75
|
+
"type": "boolean",
|
76
|
+
"char": "h",
|
77
|
+
"description": "Skip running deployment health check",
|
78
|
+
"required": false,
|
79
|
+
"allowNo": false
|
80
|
+
},
|
81
|
+
"token": {
|
82
|
+
"name": "token",
|
75
83
|
"type": "option",
|
76
|
-
"char": "
|
77
|
-
"description": "
|
84
|
+
"char": "t",
|
85
|
+
"description": "Oxygen deployment token",
|
86
|
+
"required": true,
|
87
|
+
"multiple": false
|
88
|
+
},
|
89
|
+
"workerFolder": {
|
90
|
+
"name": "workerFolder",
|
91
|
+
"type": "option",
|
92
|
+
"char": "w",
|
93
|
+
"description": "Worker folder",
|
78
94
|
"required": false,
|
79
95
|
"multiple": false,
|
80
|
-
"default": "
|
96
|
+
"default": "dist/worker/"
|
81
97
|
},
|
82
|
-
"
|
83
|
-
"name": "
|
98
|
+
"workerOnly": {
|
99
|
+
"name": "workerOnly",
|
84
100
|
"type": "boolean",
|
85
|
-
"
|
101
|
+
"char": "o",
|
102
|
+
"description": "Worker only deployment",
|
86
103
|
"required": false,
|
87
104
|
"allowNo": false
|
88
105
|
},
|
package/package.json
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
6
6
|
},
|
7
7
|
"license": "MIT",
|
8
|
-
"version": "1.
|
8
|
+
"version": "1.6.0",
|
9
9
|
"type": "module",
|
10
10
|
"scripts": {
|
11
11
|
"build": "tsup --clean --config ./tsup.config.ts && oclif manifest",
|
@@ -31,8 +31,8 @@
|
|
31
31
|
"/oclif.manifest.json"
|
32
32
|
],
|
33
33
|
"dependencies": {
|
34
|
-
"@oclif/core": "2.
|
35
|
-
"@shopify/cli-kit": "^3.
|
34
|
+
"@oclif/core": "2.9.4",
|
35
|
+
"@shopify/cli-kit": "^3.47.5",
|
36
36
|
"async": "^3.2.4"
|
37
37
|
},
|
38
38
|
"devDependencies": {
|
@@ -40,15 +40,15 @@
|
|
40
40
|
"@shopify/eslint-plugin": "^42.1.0",
|
41
41
|
"@shopify/prettier-config": "^1.1.2",
|
42
42
|
"@types/async": "^3.2.18",
|
43
|
-
"@types/node": "^20.
|
43
|
+
"@types/node": "^20.4.2",
|
44
44
|
"@types/prettier": "^2.7.3",
|
45
|
-
"eslint": "^8.
|
45
|
+
"eslint": "^8.45.0",
|
46
46
|
"node-fetch": "^3.3.1",
|
47
47
|
"oclif": "^3",
|
48
|
-
"tsup": "^
|
48
|
+
"tsup": "^7.1.0",
|
49
49
|
"typescript": "^5.1.3",
|
50
|
-
"vite": "^4.
|
51
|
-
"vitest": "^0.
|
50
|
+
"vite": "^4.4.4",
|
51
|
+
"vitest": "^0.33.0"
|
52
52
|
},
|
53
53
|
"prettier": "@shopify/prettier-config",
|
54
54
|
"oclif": {
|