@shopify/oxygen-cli 1.0.2
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 +91 -0
- package/dist/commands/oxygen/deploy.d.ts +26 -0
- package/dist/commands/oxygen/deploy.js +121 -0
- package/dist/deploy/build-cancel.d.ts +6 -0
- package/dist/deploy/build-cancel.js +36 -0
- package/dist/deploy/build-cancel.test.d.ts +2 -0
- package/dist/deploy/build-cancel.test.js +73 -0
- package/dist/deploy/build-initiate.d.ts +6 -0
- package/dist/deploy/build-initiate.js +38 -0
- package/dist/deploy/build-initiate.test.d.ts +2 -0
- package/dist/deploy/build-initiate.test.js +81 -0
- package/dist/deploy/build-project.d.ts +5 -0
- package/dist/deploy/build-project.js +32 -0
- package/dist/deploy/build-project.test.d.ts +2 -0
- package/dist/deploy/build-project.test.js +53 -0
- package/dist/deploy/deployment-cancel.d.ts +6 -0
- package/dist/deploy/deployment-cancel.js +36 -0
- package/dist/deploy/deployment-cancel.test.d.ts +2 -0
- package/dist/deploy/deployment-cancel.test.js +78 -0
- package/dist/deploy/deployment-complete.d.ts +6 -0
- package/dist/deploy/deployment-complete.js +33 -0
- package/dist/deploy/deployment-complete.test.d.ts +2 -0
- package/dist/deploy/deployment-complete.test.js +77 -0
- package/dist/deploy/deployment-initiate.d.ts +17 -0
- package/dist/deploy/deployment-initiate.js +40 -0
- package/dist/deploy/deployment-initiate.test.d.ts +2 -0
- package/dist/deploy/deployment-initiate.test.js +136 -0
- package/dist/deploy/get-upload-files.d.ts +5 -0
- package/dist/deploy/get-upload-files.js +65 -0
- package/dist/deploy/get-upload-files.test.d.ts +2 -0
- package/dist/deploy/get-upload-files.test.js +56 -0
- package/dist/deploy/graphql/build-cancel.d.ts +14 -0
- package/dist/deploy/graphql/build-cancel.js +14 -0
- package/dist/deploy/graphql/build-initiate.d.ts +15 -0
- package/dist/deploy/graphql/build-initiate.js +15 -0
- package/dist/deploy/graphql/deployment-cancel.d.ts +14 -0
- package/dist/deploy/graphql/deployment-cancel.js +14 -0
- package/dist/deploy/graphql/deployment-complete.d.ts +17 -0
- package/dist/deploy/graphql/deployment-complete.js +16 -0
- package/dist/deploy/graphql/deployment-initiate.d.ts +28 -0
- package/dist/deploy/graphql/deployment-initiate.js +25 -0
- package/dist/deploy/index.d.ts +5 -0
- package/dist/deploy/index.js +74 -0
- package/dist/deploy/metadata.d.ts +11 -0
- package/dist/deploy/metadata.js +65 -0
- package/dist/deploy/metadata.test.d.ts +2 -0
- package/dist/deploy/metadata.test.js +131 -0
- package/dist/deploy/types.d.ts +52 -0
- package/dist/deploy/types.js +7 -0
- package/dist/deploy/upload-files.d.ts +6 -0
- package/dist/deploy/upload-files.js +156 -0
- package/dist/deploy/upload-files.test.d.ts +2 -0
- package/dist/deploy/upload-files.test.js +194 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/oxygen-cli.d.ts +1 -0
- package/dist/oxygen-cli.js +5 -0
- package/dist/utils/test-helper.d.ts +14 -0
- package/dist/utils/test-helper.js +27 -0
- package/dist/utils/utils.d.ts +20 -0
- package/dist/utils/utils.js +126 -0
- package/dist/utils/utils.test.d.ts +2 -0
- package/dist/utils/utils.test.js +154 -0
- package/oclif.manifest.json +108 -0
- package/package.json +68 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
2
|
+
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
|
+
import { vi, describe, test, expect } from 'vitest';
|
4
|
+
import { createTestConfig } from '../utils/test-helper.js';
|
5
|
+
import { Header } from '../utils/utils.js';
|
6
|
+
import { deploymentCancel } from './deployment-cancel.js';
|
7
|
+
|
8
|
+
vi.mock("@shopify/cli-kit/node/api/graphql");
|
9
|
+
vi.mock("@shopify/cli-kit/node/output");
|
10
|
+
const testConfig = createTestConfig("/tmp/deploymentRoot");
|
11
|
+
describe("DeploymentComplete", () => {
|
12
|
+
test("should cancel a deployment", async () => {
|
13
|
+
const response = {
|
14
|
+
deploymentCancel: {
|
15
|
+
deployment: {
|
16
|
+
id: "deployment-1"
|
17
|
+
},
|
18
|
+
userErrors: []
|
19
|
+
}
|
20
|
+
};
|
21
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
22
|
+
const completeResponse = await deploymentCancel(
|
23
|
+
testConfig,
|
24
|
+
"deployment-1",
|
25
|
+
"some reason"
|
26
|
+
);
|
27
|
+
expect(completeResponse).toEqual(response.deploymentCancel);
|
28
|
+
expect(graphqlRequest).toHaveBeenCalledWith({
|
29
|
+
query: expect.any(String),
|
30
|
+
api: "Oxygen",
|
31
|
+
url: `${testConfig.deploymentUrl}/api/v2/admin/graphql`,
|
32
|
+
token: testConfig.deploymentToken.accessToken,
|
33
|
+
variables: {
|
34
|
+
deploymentId: "deployment-1",
|
35
|
+
reason: "some reason"
|
36
|
+
},
|
37
|
+
addedHeaders: {
|
38
|
+
[Header.OxygenNamespaceHandle]: `${testConfig.deploymentToken.namespace}`
|
39
|
+
}
|
40
|
+
});
|
41
|
+
});
|
42
|
+
test("should throw AbortError when deploymentComplete fails with error", async () => {
|
43
|
+
const response = {
|
44
|
+
deploymentCancel: {
|
45
|
+
userErrors: [
|
46
|
+
{
|
47
|
+
message: "Cannot cancel deployment."
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
51
|
+
};
|
52
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
53
|
+
await expect(
|
54
|
+
deploymentCancel(testConfig, "deployment-1", "some reason")
|
55
|
+
).rejects.toThrow(
|
56
|
+
new AbortError(
|
57
|
+
`Failed to cancel deployment: ${response.deploymentCancel.userErrors[0]?.message}`
|
58
|
+
)
|
59
|
+
);
|
60
|
+
});
|
61
|
+
test("should throw AbortError when unauthorized", async () => {
|
62
|
+
const error = {
|
63
|
+
statusCode: 401
|
64
|
+
};
|
65
|
+
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
66
|
+
try {
|
67
|
+
await expect(
|
68
|
+
deploymentCancel(testConfig, "deployment-1", "some reason")
|
69
|
+
).rejects.toThrow(
|
70
|
+
new AbortError(
|
71
|
+
"You are not authorized to perform this action. Please check your deployment token."
|
72
|
+
)
|
73
|
+
);
|
74
|
+
} catch (err) {
|
75
|
+
expect(error).toBeInstanceOf(AbortError);
|
76
|
+
}
|
77
|
+
});
|
78
|
+
});
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { DeploymentCompleteResponse } from './graphql/deployment-complete.js';
|
2
|
+
import { DeployConfig } from './types.js';
|
3
|
+
|
4
|
+
declare function deploymentComplete(config: DeployConfig, deploymentId: string): Promise<DeploymentCompleteResponse>;
|
5
|
+
|
6
|
+
export { deploymentComplete };
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
4
|
+
import { DeploymentCompleteQuery } from './graphql/deployment-complete.js';
|
5
|
+
|
6
|
+
async function deploymentComplete(config, deploymentId) {
|
7
|
+
const variables = {
|
8
|
+
deploymentId
|
9
|
+
};
|
10
|
+
try {
|
11
|
+
const response = await graphqlRequest({
|
12
|
+
query: DeploymentCompleteQuery,
|
13
|
+
api: "Oxygen",
|
14
|
+
url: `${config.deploymentUrl}/api/v2/admin/graphql`,
|
15
|
+
token: config.deploymentToken.accessToken,
|
16
|
+
variables,
|
17
|
+
addedHeaders: {
|
18
|
+
[Header.OxygenNamespaceHandle]: config.deploymentToken.namespace
|
19
|
+
}
|
20
|
+
});
|
21
|
+
if (response.deploymentComplete.userErrors.length >= 1) {
|
22
|
+
throw new AbortError(
|
23
|
+
`Failed to complete deployment: ${response.deploymentComplete.userErrors[0]?.message}`
|
24
|
+
);
|
25
|
+
}
|
26
|
+
return response.deploymentComplete;
|
27
|
+
} catch (error) {
|
28
|
+
errorHandler(error);
|
29
|
+
throw error;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
export { deploymentComplete };
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
2
|
+
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
|
+
import { vi, describe, test, expect } from 'vitest';
|
4
|
+
import { createTestConfig } from '../utils/test-helper.js';
|
5
|
+
import { Header } from '../utils/utils.js';
|
6
|
+
import { deploymentComplete } from './deployment-complete.js';
|
7
|
+
|
8
|
+
vi.mock("@shopify/cli-kit/node/api/graphql");
|
9
|
+
const testConfig = createTestConfig("/tmp/deploymentRoot");
|
10
|
+
describe("DeploymentComplete", () => {
|
11
|
+
test("should complete a deployment", async () => {
|
12
|
+
const response = {
|
13
|
+
deploymentComplete: {
|
14
|
+
deployment: {
|
15
|
+
id: "deployment-1",
|
16
|
+
status: "pending",
|
17
|
+
url: "https://www.go-here.com"
|
18
|
+
},
|
19
|
+
userErrors: []
|
20
|
+
}
|
21
|
+
};
|
22
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
23
|
+
const completeResponse = await deploymentComplete(
|
24
|
+
testConfig,
|
25
|
+
"deployment-1"
|
26
|
+
);
|
27
|
+
expect(completeResponse).toEqual(response.deploymentComplete);
|
28
|
+
expect(graphqlRequest).toHaveBeenCalledWith({
|
29
|
+
query: expect.any(String),
|
30
|
+
api: "Oxygen",
|
31
|
+
url: `${testConfig.deploymentUrl}/api/v2/admin/graphql`,
|
32
|
+
token: testConfig.deploymentToken.accessToken,
|
33
|
+
variables: {
|
34
|
+
deploymentId: "deployment-1"
|
35
|
+
},
|
36
|
+
addedHeaders: {
|
37
|
+
[Header.OxygenNamespaceHandle]: `${testConfig.deploymentToken.namespace}`
|
38
|
+
}
|
39
|
+
});
|
40
|
+
});
|
41
|
+
test("should throw AbortError when deploymentComplete fails with error", async () => {
|
42
|
+
const response = {
|
43
|
+
deploymentComplete: {
|
44
|
+
userErrors: [
|
45
|
+
{
|
46
|
+
message: "Cannot complete deployment."
|
47
|
+
}
|
48
|
+
]
|
49
|
+
}
|
50
|
+
};
|
51
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
52
|
+
await expect(
|
53
|
+
deploymentComplete(testConfig, "deployment-1")
|
54
|
+
).rejects.toThrow(
|
55
|
+
new AbortError(
|
56
|
+
`Failed to complete deployment: ${response.deploymentComplete.userErrors[0]?.message}`
|
57
|
+
)
|
58
|
+
);
|
59
|
+
});
|
60
|
+
test("should throw AbortError when unauthorized", async () => {
|
61
|
+
const error = {
|
62
|
+
statusCode: 401
|
63
|
+
};
|
64
|
+
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
65
|
+
try {
|
66
|
+
await expect(
|
67
|
+
deploymentComplete(testConfig, "deployment-1")
|
68
|
+
).rejects.toThrow(
|
69
|
+
new AbortError(
|
70
|
+
"You are not authorized to perform this action. Please check your deployment token."
|
71
|
+
)
|
72
|
+
);
|
73
|
+
} catch (err) {
|
74
|
+
expect(error).toBeInstanceOf(AbortError);
|
75
|
+
}
|
76
|
+
});
|
77
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { DeployConfig, DeploymentManifestFile, EnvironmentInput } from './types.js';
|
2
|
+
import { DeploymentInitiateResponse } from './graphql/deployment-initiate.js';
|
3
|
+
|
4
|
+
type DeploymentInitiateInput = {
|
5
|
+
buildId: string;
|
6
|
+
environment?: never;
|
7
|
+
manifest: DeploymentManifestFile[];
|
8
|
+
labels?: string[];
|
9
|
+
} | {
|
10
|
+
environment?: EnvironmentInput;
|
11
|
+
buildId?: never;
|
12
|
+
manifest: DeploymentManifestFile[];
|
13
|
+
labels?: string[];
|
14
|
+
};
|
15
|
+
declare function deploymentInitiate(config: DeployConfig, input: DeploymentInitiateInput): Promise<DeploymentInitiateResponse>;
|
16
|
+
|
17
|
+
export { deploymentInitiate };
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
|
+
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
5
|
+
import { DeploymentInitiateQuery } from './graphql/deployment-initiate.js';
|
6
|
+
|
7
|
+
async function deploymentInitiate(config, input) {
|
8
|
+
const variables = {
|
9
|
+
buildId: input.buildId,
|
10
|
+
environment: input.environment,
|
11
|
+
files: input.manifest,
|
12
|
+
labels: input.labels
|
13
|
+
};
|
14
|
+
try {
|
15
|
+
const response = await graphqlRequest({
|
16
|
+
query: DeploymentInitiateQuery,
|
17
|
+
api: "Oxygen",
|
18
|
+
url: `${config.deploymentUrl}/api/v2/admin/graphql`,
|
19
|
+
token: config.deploymentToken.accessToken,
|
20
|
+
variables,
|
21
|
+
addedHeaders: {
|
22
|
+
[Header.OxygenNamespaceHandle]: config.deploymentToken.namespace
|
23
|
+
}
|
24
|
+
});
|
25
|
+
if (response.deploymentInitiate.userErrors.length >= 1) {
|
26
|
+
throw new AbortError(
|
27
|
+
`Failed to create deployment. ${response.deploymentInitiate.userErrors[0]?.message}`
|
28
|
+
);
|
29
|
+
}
|
30
|
+
outputCompleted(
|
31
|
+
`Deployment initiated, ${response.deploymentInitiate.deploymentTargets.length} files to upload.`
|
32
|
+
);
|
33
|
+
return response.deploymentInitiate;
|
34
|
+
} catch (error) {
|
35
|
+
errorHandler(error);
|
36
|
+
throw error;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
export { deploymentInitiate };
|
@@ -0,0 +1,136 @@
|
|
1
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
2
|
+
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
|
+
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
|
+
import { vi, describe, test, expect } from 'vitest';
|
5
|
+
import { createTestConfig } from '../utils/test-helper.js';
|
6
|
+
import { Header } from '../utils/utils.js';
|
7
|
+
import { deploymentInitiate } from './deployment-initiate.js';
|
8
|
+
|
9
|
+
vi.mock("@shopify/cli-kit/node/api/graphql");
|
10
|
+
vi.mock("@shopify/cli-kit/node/output");
|
11
|
+
const testConfig = createTestConfig("/tmp/deploymentRoot");
|
12
|
+
const testManifest = [
|
13
|
+
{
|
14
|
+
filePath: "index.js",
|
15
|
+
fileSize: 20,
|
16
|
+
mimeType: "application/javascript",
|
17
|
+
fileType: "WORKER",
|
18
|
+
fileHash: "b62d550d0cae0c4f15e0e16fc2492893"
|
19
|
+
}
|
20
|
+
];
|
21
|
+
const testResponse = {
|
22
|
+
deploymentInitiate: {
|
23
|
+
deployment: {
|
24
|
+
id: "gid://oxygen-hub/Deployment/1"
|
25
|
+
},
|
26
|
+
deploymentTargets: [
|
27
|
+
{
|
28
|
+
filePath: "index.js",
|
29
|
+
fileSize: 20,
|
30
|
+
uploadUrl: "https://storage.googleapis.com/dms-assets-test/",
|
31
|
+
fileType: "WORKER",
|
32
|
+
parameters: []
|
33
|
+
}
|
34
|
+
],
|
35
|
+
userErrors: []
|
36
|
+
}
|
37
|
+
};
|
38
|
+
describe("DeploymentInitiate", () => {
|
39
|
+
test("should initiate a deployment with a buildId", async () => {
|
40
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(testResponse);
|
41
|
+
const initiateResponse = await deploymentInitiate(testConfig, {
|
42
|
+
buildId: "build-1",
|
43
|
+
manifest: testManifest
|
44
|
+
});
|
45
|
+
expect(initiateResponse).toEqual(testResponse.deploymentInitiate);
|
46
|
+
expect(graphqlRequest).toHaveBeenCalledWith({
|
47
|
+
query: expect.any(String),
|
48
|
+
api: "Oxygen",
|
49
|
+
url: `${testConfig.deploymentUrl}/api/v2/admin/graphql`,
|
50
|
+
token: testConfig.deploymentToken.accessToken,
|
51
|
+
variables: {
|
52
|
+
buildId: "build-1",
|
53
|
+
environment: void 0,
|
54
|
+
files: testManifest
|
55
|
+
},
|
56
|
+
addedHeaders: {
|
57
|
+
[Header.OxygenNamespaceHandle]: `${testConfig.deploymentToken.namespace}`
|
58
|
+
}
|
59
|
+
});
|
60
|
+
expect(outputCompleted).toHaveBeenCalledWith(
|
61
|
+
`Deployment initiated, ${testManifest.length} files to upload.`
|
62
|
+
);
|
63
|
+
});
|
64
|
+
test("should initiate a deployment with an environmentName", async () => {
|
65
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(testResponse);
|
66
|
+
const initiateResponse = await deploymentInitiate(testConfig, {
|
67
|
+
buildId: void 0,
|
68
|
+
environment: { tag: "preview" },
|
69
|
+
manifest: testManifest
|
70
|
+
});
|
71
|
+
expect(initiateResponse).toEqual(testResponse.deploymentInitiate);
|
72
|
+
expect(graphqlRequest).toHaveBeenCalledWith({
|
73
|
+
query: expect.any(String),
|
74
|
+
api: "Oxygen",
|
75
|
+
url: `${testConfig.deploymentUrl}/api/v2/admin/graphql`,
|
76
|
+
token: testConfig.deploymentToken.accessToken,
|
77
|
+
variables: {
|
78
|
+
buildId: void 0,
|
79
|
+
environment: { tag: "preview" },
|
80
|
+
files: testManifest
|
81
|
+
},
|
82
|
+
addedHeaders: {
|
83
|
+
[Header.OxygenNamespaceHandle]: `${testConfig.deploymentToken.namespace}`
|
84
|
+
}
|
85
|
+
});
|
86
|
+
expect(outputCompleted).toHaveBeenCalledWith(
|
87
|
+
`Deployment initiated, ${testManifest.length} files to upload.`
|
88
|
+
);
|
89
|
+
});
|
90
|
+
test("should throw AbortError when deployment initiation fails due to user errors", async () => {
|
91
|
+
const response = {
|
92
|
+
deploymentInitiate: {
|
93
|
+
userErrors: [
|
94
|
+
{
|
95
|
+
message: "Error: cannot proceed with deployment."
|
96
|
+
}
|
97
|
+
]
|
98
|
+
}
|
99
|
+
};
|
100
|
+
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
101
|
+
const deploymentInitData = {
|
102
|
+
buildId: void 0,
|
103
|
+
environment: { tag: "preview" },
|
104
|
+
manifest: testManifest
|
105
|
+
};
|
106
|
+
await expect(
|
107
|
+
deploymentInitiate(testConfig, deploymentInitData)
|
108
|
+
).rejects.toThrow(
|
109
|
+
new AbortError(
|
110
|
+
`Failed to create deployment. ${response.deploymentInitiate.userErrors[0]?.message}`
|
111
|
+
)
|
112
|
+
);
|
113
|
+
});
|
114
|
+
test("should throw AbortError when unauthorized", async () => {
|
115
|
+
const error = {
|
116
|
+
statusCode: 401
|
117
|
+
};
|
118
|
+
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
119
|
+
try {
|
120
|
+
const deploymentInitData = {
|
121
|
+
buildId: void 0,
|
122
|
+
environment: { tag: "preview" },
|
123
|
+
manifest: testManifest
|
124
|
+
};
|
125
|
+
await expect(
|
126
|
+
deploymentInitiate(testConfig, deploymentInitData)
|
127
|
+
).rejects.toThrow(
|
128
|
+
new AbortError(
|
129
|
+
"You are not authorized to perform this action. Please check your deployment token."
|
130
|
+
)
|
131
|
+
);
|
132
|
+
} catch (err) {
|
133
|
+
expect(error).toBeInstanceOf(AbortError);
|
134
|
+
}
|
135
|
+
});
|
136
|
+
});
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { glob, fileSizeSync, readFileSync } from '@shopify/cli-kit/node/fs';
|
2
|
+
import { fileHash } from '@shopify/cli-kit/node/crypto';
|
3
|
+
import { joinPath, relativePath } from '@shopify/cli-kit/node/path';
|
4
|
+
import { lookupMimeType } from '@shopify/cli-kit/node/mimes';
|
5
|
+
import { FileType } from './types.js';
|
6
|
+
|
7
|
+
async function getUploadFiles(config) {
|
8
|
+
const workerPath = joinPath(config.rootPath, config.workerDir);
|
9
|
+
const workerFiles = await glob(`${workerPath}/**`);
|
10
|
+
let manifest = createManifestEntries({
|
11
|
+
files: workerFiles,
|
12
|
+
basePath: workerPath,
|
13
|
+
type: FileType.Worker,
|
14
|
+
filter: workerFileFilter
|
15
|
+
});
|
16
|
+
if (!config.workerOnly) {
|
17
|
+
const assetPath = joinPath(config.rootPath, config.assetsDir);
|
18
|
+
const assetFiles = await glob(`${assetPath}/**`);
|
19
|
+
manifest = [
|
20
|
+
...manifest,
|
21
|
+
...createManifestEntries({
|
22
|
+
files: assetFiles,
|
23
|
+
basePath: assetPath,
|
24
|
+
type: FileType.Asset
|
25
|
+
})
|
26
|
+
];
|
27
|
+
}
|
28
|
+
return manifest;
|
29
|
+
}
|
30
|
+
function createHash(file) {
|
31
|
+
const buff = readFileSync(file);
|
32
|
+
return fileHash(buff);
|
33
|
+
}
|
34
|
+
function createManifestEntries(params) {
|
35
|
+
const { files, basePath, type, filter } = params;
|
36
|
+
const manifest = [];
|
37
|
+
files.forEach((file) => {
|
38
|
+
const filePath = relativePath(basePath, file);
|
39
|
+
if (filter && !filter(filePath, type)) {
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
manifest.push({
|
43
|
+
filePath,
|
44
|
+
fileSize: fileSizeSync(file),
|
45
|
+
mimeType: lookupMimeType(file),
|
46
|
+
fileType: type,
|
47
|
+
fileHash: createHash(file)
|
48
|
+
});
|
49
|
+
});
|
50
|
+
return manifest;
|
51
|
+
}
|
52
|
+
function workerFileFilter(fileName, type) {
|
53
|
+
if (type === FileType.Asset) {
|
54
|
+
return true;
|
55
|
+
}
|
56
|
+
const allowedExtensions = [".js.map", ".mjs.map", ".map", ".js", ".mjs"];
|
57
|
+
const allowedFilenames = ["index"];
|
58
|
+
const regexString = `^(${allowedFilenames.join(
|
59
|
+
"|"
|
60
|
+
)})(${allowedExtensions.join("|")})$`;
|
61
|
+
const regex = new RegExp(regexString);
|
62
|
+
return regex.test(fileName);
|
63
|
+
}
|
64
|
+
|
65
|
+
export { getUploadFiles };
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { mkdir, appendFile, rmdir, touchFile } from '@shopify/cli-kit/node/fs';
|
2
|
+
import { beforeAll, afterAll, describe, test, expect } from 'vitest';
|
3
|
+
import { createTestConfig } from '../utils/test-helper.js';
|
4
|
+
import { FileType } from './types.js';
|
5
|
+
import { getUploadFiles } from './get-upload-files.js';
|
6
|
+
|
7
|
+
const randomString = Math.random().toString(36).substring(7);
|
8
|
+
const rootFolder = `/tmp/${randomString}`;
|
9
|
+
const testConfig = createTestConfig(rootFolder);
|
10
|
+
beforeAll(async () => {
|
11
|
+
await mkdir(rootFolder);
|
12
|
+
await mkdir(`${rootFolder}/worker`);
|
13
|
+
appendFile(`${rootFolder}/worker/index.js`, 'console.log("Hello World")');
|
14
|
+
await mkdir(`${rootFolder}/assets`);
|
15
|
+
appendFile(`${rootFolder}/assets/image.png`, "foo");
|
16
|
+
});
|
17
|
+
afterAll(async () => {
|
18
|
+
await rmdir(rootFolder, { force: true });
|
19
|
+
});
|
20
|
+
describe("GetUploadFiles", () => {
|
21
|
+
test("GetUploadFiles creates a manifest of files", async () => {
|
22
|
+
const manifest = await getUploadFiles(testConfig);
|
23
|
+
const expectedManifest = [
|
24
|
+
{
|
25
|
+
filePath: "index.js",
|
26
|
+
fileSize: 26,
|
27
|
+
mimeType: "application/javascript",
|
28
|
+
fileType: FileType.Worker,
|
29
|
+
fileHash: "87a53c8019cbd3358025a289a46b1d25"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
filePath: "image.png",
|
33
|
+
fileSize: 3,
|
34
|
+
mimeType: "image/png",
|
35
|
+
fileType: FileType.Asset,
|
36
|
+
fileHash: "acbd18db4cc2f85cedef654fccc4a4d8"
|
37
|
+
}
|
38
|
+
];
|
39
|
+
expect(manifest).toEqual(expectedManifest);
|
40
|
+
});
|
41
|
+
test("GetUploadFiles manifest does not included non-worker files", async () => {
|
42
|
+
await touchFile(`${rootFolder}/worker/image.jpg`);
|
43
|
+
await touchFile(`${rootFolder}/worker/worker.ts`);
|
44
|
+
await touchFile(`${rootFolder}/worker/index.js.map`);
|
45
|
+
const manifest = await getUploadFiles(testConfig);
|
46
|
+
const workerFileExist = (fileName) => {
|
47
|
+
return manifest.some(
|
48
|
+
(file) => file.filePath === fileName && file.fileType === FileType.Worker
|
49
|
+
);
|
50
|
+
};
|
51
|
+
expect(workerFileExist("image.jpg")).toBe(false);
|
52
|
+
expect(workerFileExist("worker.ts")).toBe(false);
|
53
|
+
expect(workerFileExist("index.js.map")).toBe(true);
|
54
|
+
expect(workerFileExist("index.js")).toBe(true);
|
55
|
+
});
|
56
|
+
});
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { OxygenError } from '../types.js';
|
2
|
+
|
3
|
+
declare const BuildCancelQuery = "\n mutation BuildCancel($buildId: ID!, $reason: String!) {\n buildCancel(id: $buildId, reason: $reason) {\n build {\n id\n }\n userErrors {\n message\n }\n }\n }\n";
|
4
|
+
interface BuildCancelQueryData {
|
5
|
+
buildCancel: BuildCancelResponse;
|
6
|
+
}
|
7
|
+
interface BuildCancelResponse {
|
8
|
+
build: {
|
9
|
+
id: string;
|
10
|
+
};
|
11
|
+
userErrors: OxygenError[];
|
12
|
+
}
|
13
|
+
|
14
|
+
export { BuildCancelQuery, BuildCancelQueryData, BuildCancelResponse };
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { OxygenError } from '../types.js';
|
2
|
+
|
3
|
+
declare const BuildInitiateQuery = "\n mutation BuildInitiate($environment: EnvironmentSelectorInput, $labels: [String!]) {\n buildInitiate(environment: $environment, labels: $labels) {\n build {\n id\n assetPath\n }\n userErrors {\n message\n }\n }\n }\n";
|
4
|
+
interface BuildInitiateQueryData {
|
5
|
+
buildInitiate: BuildInitiateResponse;
|
6
|
+
}
|
7
|
+
interface BuildInitiateResponse {
|
8
|
+
build: {
|
9
|
+
id: string;
|
10
|
+
assetPath: string;
|
11
|
+
};
|
12
|
+
userErrors: OxygenError[];
|
13
|
+
}
|
14
|
+
|
15
|
+
export { BuildInitiateQuery, BuildInitiateQueryData, BuildInitiateResponse };
|
@@ -0,0 +1,15 @@
|
|
1
|
+
const BuildInitiateQuery = `
|
2
|
+
mutation BuildInitiate($environment: EnvironmentSelectorInput, $labels: [String!]) {
|
3
|
+
buildInitiate(environment: $environment, labels: $labels) {
|
4
|
+
build {
|
5
|
+
id
|
6
|
+
assetPath
|
7
|
+
}
|
8
|
+
userErrors {
|
9
|
+
message
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
`;
|
14
|
+
|
15
|
+
export { BuildInitiateQuery };
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { OxygenError } from '../types.js';
|
2
|
+
|
3
|
+
declare const DeploymentCancelQuery = "\nmutation DeploymentCancel($deploymentId: ID!, $reason: DeploymentCancellationReason!) {\n deploymentCancel(id: $deploymentId, reason: $reason) {\n deployment {\n id\n }\n userErrors {\n message\n }\n }\n}\n";
|
4
|
+
interface DeploymentCancelQueryData {
|
5
|
+
deploymentCancel: DeploymentCancelResponse;
|
6
|
+
}
|
7
|
+
interface DeploymentCancelResponse {
|
8
|
+
deployment: {
|
9
|
+
id: string;
|
10
|
+
};
|
11
|
+
userErrors: OxygenError[];
|
12
|
+
}
|
13
|
+
|
14
|
+
export { DeploymentCancelQuery, DeploymentCancelQueryData, DeploymentCancelResponse };
|
@@ -0,0 +1,14 @@
|
|
1
|
+
const DeploymentCancelQuery = `
|
2
|
+
mutation DeploymentCancel($deploymentId: ID!, $reason: DeploymentCancellationReason!) {
|
3
|
+
deploymentCancel(id: $deploymentId, reason: $reason) {
|
4
|
+
deployment {
|
5
|
+
id
|
6
|
+
}
|
7
|
+
userErrors {
|
8
|
+
message
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
`;
|
13
|
+
|
14
|
+
export { DeploymentCancelQuery };
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { OxygenError } from '../types.js';
|
2
|
+
|
3
|
+
declare const DeploymentCompleteQuery = "\n mutation DeploymentComplete($deploymentId: ID!) {\n deploymentComplete(id: $deploymentId) {\n deployment {\n id\n status\n url\n }\n userErrors {\n message\n }\n }\n }\n";
|
4
|
+
interface DeploymentCompleteQueryData {
|
5
|
+
deploymentComplete: DeploymentCompleteResponse;
|
6
|
+
}
|
7
|
+
interface DeploymentCompleteResponse {
|
8
|
+
deployment: Deployment;
|
9
|
+
userErrors: OxygenError[];
|
10
|
+
}
|
11
|
+
interface Deployment {
|
12
|
+
id: string;
|
13
|
+
status: string;
|
14
|
+
url: string;
|
15
|
+
}
|
16
|
+
|
17
|
+
export { DeploymentCompleteQuery, DeploymentCompleteQueryData, DeploymentCompleteResponse };
|
@@ -0,0 +1,16 @@
|
|
1
|
+
const DeploymentCompleteQuery = `
|
2
|
+
mutation DeploymentComplete($deploymentId: ID!) {
|
3
|
+
deploymentComplete(id: $deploymentId) {
|
4
|
+
deployment {
|
5
|
+
id
|
6
|
+
status
|
7
|
+
url
|
8
|
+
}
|
9
|
+
userErrors {
|
10
|
+
message
|
11
|
+
}
|
12
|
+
}
|
13
|
+
}
|
14
|
+
`;
|
15
|
+
|
16
|
+
export { DeploymentCompleteQuery };
|