@squiz/component-cli-lib 1.2.1-alpha.99 → 1.2.3
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/.gitlab-ci.yml +42 -27
- package/CHANGELOG.md +88 -0
- package/jest.config.ts +3 -0
- package/jest.integration.config.ts +4 -0
- package/lib/component-dev-folder-structures.spec.d.ts +1 -0
- package/lib/component-dev-folder-structures.spec.js +58 -0
- package/lib/component-dev-folder-structures.spec.js.map +1 -0
- package/lib/component-dev.d.ts +4 -1
- package/lib/component-dev.js +24 -18
- package/lib/component-dev.js.map +1 -1
- package/lib/component-dev.spec.js +28 -65
- package/lib/component-dev.spec.js.map +1 -1
- package/lib/integration-tests/__components__/big-package/manifest.json +5 -2
- package/lib/integration-tests/__components__/cmp-static-file-test/manifest.json +8 -5
- package/lib/integration-tests/__components__/invalid-manifest/manifest.json +5 -2
- package/lib/integration-tests/helper.d.ts +6 -0
- package/lib/integration-tests/helper.js +31 -6
- package/lib/integration-tests/helper.js.map +1 -1
- package/lib/integration-tests/service-deployment.spec.js +36 -1
- package/lib/integration-tests/service-deployment.spec.js.map +1 -1
- package/lib/integration-tests/upload-and-render-component.spec.js +38 -17
- package/lib/integration-tests/upload-and-render-component.spec.js.map +1 -1
- package/lib/upload-component-folder.d.ts +1 -1
- package/lib/upload-component-folder.js +10 -6
- package/lib/upload-component-folder.js.map +1 -1
- package/package.json +10 -10
- package/src/component-dev-folder-structures.spec.ts +69 -0
- package/src/component-dev.spec.ts +31 -83
- package/src/component-dev.ts +40 -18
- package/src/integration-tests/__components__/big-package/manifest.json +5 -2
- package/src/integration-tests/__components__/cmp-static-file-test/manifest.json +8 -6
- package/src/integration-tests/__components__/invalid-manifest/manifest.json +5 -2
- package/src/integration-tests/helper.ts +28 -1
- package/src/integration-tests/service-deployment.spec.ts +51 -2
- package/src/integration-tests/upload-and-render-component.spec.ts +78 -17
- package/src/upload-component-folder.ts +16 -7
- package/tsconfig.tsbuildinfo +1 -1
package/src/component-dev.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
ComponentPreviewService,
|
|
3
|
+
ComponentRunnerServiceWithWorkers,
|
|
4
|
+
setupRenderRuntimeServer,
|
|
5
|
+
} from '@squiz/render-runtime-lib';
|
|
6
|
+
import { getLogger, LoggerOptions } from '@squiz/dx-logger-lib';
|
|
3
7
|
import path from 'path';
|
|
8
|
+
import { ComponentFunctionService, ComponentSetServiceForLocalDev, ManifestServiceForDev } from '@squiz/component-lib';
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* startDevelopmentRender starts a dev-mode render stack for any
|
|
@@ -11,24 +16,41 @@ import path from 'path';
|
|
|
11
16
|
* @param {object} options - Additional configuration for the dev stack
|
|
12
17
|
* @returns a function to stop the render stack
|
|
13
18
|
*/
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
export function startDevelopmentRender(
|
|
20
|
+
componentPath: string,
|
|
21
|
+
options: { port: number; previewFile?: string; loggingFormat?: LoggerOptions['format'] },
|
|
22
|
+
) {
|
|
23
|
+
const logger = getLogger({ name: 'component-dev', format: options.loggingFormat || 'human' });
|
|
24
|
+
const rootUrl = `http://localhost:${options.port}`;
|
|
25
|
+
const dataMountPoint = path.resolve(process.cwd(), componentPath);
|
|
26
|
+
|
|
27
|
+
const componentRunnerService = new ComponentRunnerServiceWithWorkers(
|
|
28
|
+
{
|
|
29
|
+
dataMountPoint,
|
|
30
|
+
shouldCacheResponses: false,
|
|
31
|
+
workerTimeout: 5_000,
|
|
22
32
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
logger,
|
|
34
|
+
);
|
|
35
|
+
const webServer = setupRenderRuntimeServer(
|
|
36
|
+
{
|
|
37
|
+
logger,
|
|
38
|
+
componentRunnerService,
|
|
39
|
+
componentSetService: new ComponentSetServiceForLocalDev(logger),
|
|
40
|
+
componentFunctionService: new ComponentFunctionService(rootUrl),
|
|
41
|
+
componentPreviewService: new ComponentPreviewService(options.previewFile),
|
|
42
|
+
manifestService: new ManifestServiceForDev(dataMountPoint, logger),
|
|
30
43
|
},
|
|
44
|
+
{ rootUrl },
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const server = webServer.listen(options.port, () => {
|
|
48
|
+
logger.info(`Component development webserver started on port ${options.port}`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
server.on('close', async () => {
|
|
52
|
+
await componentRunnerService.stop();
|
|
31
53
|
});
|
|
32
54
|
|
|
33
|
-
return
|
|
55
|
+
return server;
|
|
34
56
|
}
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
"name": "big-package",
|
|
5
5
|
"version": "1.0.2",
|
|
6
|
-
"
|
|
6
|
+
"mainFunction": "render-json",
|
|
7
|
+
"namespace": "smoke-test-components",
|
|
8
|
+
"displayName": "some-displayName",
|
|
9
|
+
"description": "some-description",
|
|
7
10
|
"functions": [
|
|
8
11
|
{
|
|
9
12
|
"name": "render-json",
|
|
@@ -18,7 +21,7 @@
|
|
|
18
21
|
"required": ["something"]
|
|
19
22
|
},
|
|
20
23
|
"output": {
|
|
21
|
-
"
|
|
24
|
+
"responseType": "json",
|
|
22
25
|
"definition": {
|
|
23
26
|
"properties": {
|
|
24
27
|
"my-prop": {
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
"name": "cmp-static-file-test",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"
|
|
7
|
-
|
|
6
|
+
"mainFunction": "main",
|
|
7
|
+
"namespace": "smoke-test-components",
|
|
8
|
+
"displayName": "some-displayName",
|
|
9
|
+
"description": "some-description",
|
|
8
10
|
"functions": [
|
|
9
11
|
{
|
|
10
12
|
"entry": "main.js",
|
|
@@ -19,9 +21,9 @@
|
|
|
19
21
|
"required": ["something"]
|
|
20
22
|
},
|
|
21
23
|
"output": {
|
|
22
|
-
"
|
|
24
|
+
"responseType": "html",
|
|
23
25
|
|
|
24
|
-
"
|
|
26
|
+
"staticFiles": [
|
|
25
27
|
{
|
|
26
28
|
"location": "header",
|
|
27
29
|
"file": {
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
}
|
|
35
37
|
],
|
|
36
38
|
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
+
"staticFiles": {
|
|
40
|
+
"locationRoot": "public"
|
|
39
41
|
}
|
|
40
42
|
}
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
"name": "invalid-manifes@t",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"
|
|
6
|
+
"mainFunction": "main",
|
|
7
|
+
"namespace": "smoke-test-components",
|
|
8
|
+
"displayName": "some-displayName",
|
|
9
|
+
"description": "some-description",
|
|
7
10
|
|
|
8
11
|
"functions": [
|
|
9
12
|
{
|
|
@@ -19,7 +22,7 @@
|
|
|
19
22
|
"required": ["something"]
|
|
20
23
|
},
|
|
21
24
|
"output": {
|
|
22
|
-
"
|
|
25
|
+
"responseType": "html"
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
]
|
|
@@ -4,7 +4,8 @@ import path from 'path';
|
|
|
4
4
|
|
|
5
5
|
import fsp from 'fs/promises';
|
|
6
6
|
import { randomBytes } from 'crypto';
|
|
7
|
-
import {
|
|
7
|
+
import { ComponentSetWebModel } from '@squiz/component-lib';
|
|
8
|
+
import { parseEnvVarForVar } from '@squiz/dx-common-lib';
|
|
8
9
|
import { config } from 'dotenv';
|
|
9
10
|
|
|
10
11
|
config();
|
|
@@ -12,6 +13,7 @@ config();
|
|
|
12
13
|
interface Config {
|
|
13
14
|
managementServiceUrl: string;
|
|
14
15
|
renderServiceUrl: string;
|
|
16
|
+
contentServiceUrl: string;
|
|
15
17
|
ci_buildVersion: string;
|
|
16
18
|
ci_buildBranch: string;
|
|
17
19
|
}
|
|
@@ -19,6 +21,7 @@ interface Config {
|
|
|
19
21
|
const configObj: Config = {
|
|
20
22
|
managementServiceUrl: parseEnvVarForVar('COMPONENT_MANAGEMENT_SERVICE_URL').replace(/\/+$/, ''),
|
|
21
23
|
renderServiceUrl: parseEnvVarForVar('COMPONENT_RENDER_SERVICE_URL').replace(/\/+$/, ''),
|
|
24
|
+
contentServiceUrl: parseEnvVarForVar('CONTENT_API_URL').replace(/\/+$/, ''),
|
|
22
25
|
ci_buildVersion: parseEnvVarForVar('CI_COMMIT_SHORT_SHA'),
|
|
23
26
|
ci_buildBranch: parseEnvVarForVar('CI_COMMIT_REF_NAME'),
|
|
24
27
|
};
|
|
@@ -26,6 +29,10 @@ const configObj: Config = {
|
|
|
26
29
|
export default configObj;
|
|
27
30
|
|
|
28
31
|
export const managementService = axios.create({
|
|
32
|
+
baseURL: configObj.managementServiceUrl + '/v1',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const managementServiceRoot = axios.create({
|
|
29
36
|
baseURL: configObj.managementServiceUrl,
|
|
30
37
|
});
|
|
31
38
|
|
|
@@ -33,6 +40,10 @@ export const renderService = axios.create({
|
|
|
33
40
|
baseURL: configObj.renderServiceUrl,
|
|
34
41
|
});
|
|
35
42
|
|
|
43
|
+
export const contentService = axios.create({
|
|
44
|
+
baseURL: configObj.contentServiceUrl,
|
|
45
|
+
});
|
|
46
|
+
|
|
36
47
|
export const ci_buildVersion = configObj.ci_buildVersion;
|
|
37
48
|
export const ci_buildBranch = configObj.ci_buildBranch;
|
|
38
49
|
|
|
@@ -56,3 +67,19 @@ export async function createFile(filePath: string, sizeInMB: number) {
|
|
|
56
67
|
export function removeFile(filePath: string) {
|
|
57
68
|
fsp.unlink(filePath);
|
|
58
69
|
}
|
|
70
|
+
|
|
71
|
+
export async function deleteComponentSet(webPath: string) {
|
|
72
|
+
try {
|
|
73
|
+
await managementService.delete(`/component-set/${webPath}`);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// no ops
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function addComponentSet(componentSet: ComponentSetWebModel) {
|
|
80
|
+
try {
|
|
81
|
+
await managementService.post(`/component-set`, componentSet);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
//no ops
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
renderService,
|
|
3
|
+
managementService,
|
|
4
|
+
contentService,
|
|
5
|
+
managementServiceRoot,
|
|
6
|
+
ci_buildVersion,
|
|
7
|
+
ci_buildBranch,
|
|
8
|
+
} from './helper';
|
|
2
9
|
|
|
3
10
|
interface HealthInfo {
|
|
4
11
|
status: string;
|
|
@@ -8,14 +15,56 @@ interface HealthInfo {
|
|
|
8
15
|
|
|
9
16
|
describe('Verify latest services deployments', () => {
|
|
10
17
|
it('Should have latest Management API service', async () => {
|
|
11
|
-
const response: HealthInfo = (await
|
|
18
|
+
const response: HealthInfo = (await managementServiceRoot.get('/health')).data;
|
|
12
19
|
expect(response.buildVersion).toBe(ci_buildVersion);
|
|
13
20
|
expect(response.buildBranch).toBe(ci_buildBranch);
|
|
14
21
|
});
|
|
15
22
|
|
|
23
|
+
it('Should return 200 for Management API docs', async () => {
|
|
24
|
+
const req = await managementService.get('/docs');
|
|
25
|
+
expect(req.status).toBe(200);
|
|
26
|
+
expect(req.headers['content-type']).toEqual('text/html; charset=utf-8');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('Should return 200 for Management API docs.json', async () => {
|
|
30
|
+
const req = await managementService.get('/docs.json');
|
|
31
|
+
expect(req.status).toBe(200);
|
|
32
|
+
expect(req.headers['content-type']).toEqual('application/json; charset=UTF-8');
|
|
33
|
+
});
|
|
34
|
+
|
|
16
35
|
it('Should have latest Render Runtime service', async () => {
|
|
17
36
|
const response: HealthInfo = (await renderService.get('/health')).data;
|
|
18
37
|
expect(response.buildVersion).toBe(ci_buildVersion);
|
|
19
38
|
expect(response.buildBranch).toBe(ci_buildBranch);
|
|
20
39
|
});
|
|
40
|
+
|
|
41
|
+
it('Should return 200 for Render Runtime API docs', async () => {
|
|
42
|
+
const req = await renderService.get('/docs');
|
|
43
|
+
expect(req.status).toBe(200);
|
|
44
|
+
expect(req.headers['content-type']).toEqual('text/html; charset=utf-8');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('Should return 200 for Render Runtime API docs.json', async () => {
|
|
48
|
+
const req = await renderService.get('/docs.json');
|
|
49
|
+
expect(req.status).toBe(200);
|
|
50
|
+
expect(req.headers['content-type']).toEqual('application/json; charset=UTF-8');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('Should have latest Content API service', async () => {
|
|
54
|
+
const response: HealthInfo = (await contentService.get('/health')).data;
|
|
55
|
+
expect(response.buildVersion).toBe(ci_buildVersion);
|
|
56
|
+
expect(response.buildBranch).toBe(ci_buildBranch);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('Should return 200 for Content API docs', async () => {
|
|
60
|
+
const req = await contentService.get('/docs');
|
|
61
|
+
expect(req.status).toBe(200);
|
|
62
|
+
expect(req.headers['content-type']).toEqual('text/html; charset=utf-8');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('Should return 200 for Content API docs.json', async () => {
|
|
66
|
+
const req = await contentService.get('/docs.json');
|
|
67
|
+
expect(req.status).toBe(200);
|
|
68
|
+
expect(req.headers['content-type']).toEqual('application/json; charset=UTF-8');
|
|
69
|
+
});
|
|
21
70
|
});
|
|
@@ -1,24 +1,46 @@
|
|
|
1
1
|
import { uploadComponentFolder } from '../index';
|
|
2
|
-
import configObj, {
|
|
2
|
+
import configObj, {
|
|
3
|
+
renderService,
|
|
4
|
+
managementService,
|
|
5
|
+
getTestComponents,
|
|
6
|
+
createFile,
|
|
7
|
+
removeFile,
|
|
8
|
+
addComponentSet,
|
|
9
|
+
deleteComponentSet,
|
|
10
|
+
} from './helper';
|
|
3
11
|
import color from 'cli-color';
|
|
4
12
|
import path from 'path';
|
|
5
13
|
import supertest from 'supertest';
|
|
6
14
|
import { logger } from '../upload-component-folder';
|
|
15
|
+
import { ComponentSetWebModel } from '@squiz/component-lib';
|
|
16
|
+
import fsp from 'fs/promises';
|
|
7
17
|
|
|
8
18
|
const mockConsoleError = jest.fn();
|
|
9
19
|
const mockConsoleLog = jest.fn();
|
|
10
20
|
|
|
11
21
|
const orgConsoleError = console.error;
|
|
22
|
+
const webPath = 'set';
|
|
23
|
+
const testFilesDir = path.resolve(__dirname, 'test-files');
|
|
24
|
+
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
await fsp.rm(testFilesDir, { force: true, recursive: true });
|
|
27
|
+
await fsp.mkdir(testFilesDir);
|
|
28
|
+
});
|
|
12
29
|
|
|
13
30
|
afterAll(async () => {
|
|
14
31
|
// clean up the component added by the test
|
|
32
|
+
await deleteComponentSet(webPath);
|
|
33
|
+
|
|
15
34
|
for (const componentName of getTestComponents()) {
|
|
16
35
|
try {
|
|
17
|
-
await managementService.delete(`/component/${componentName}`);
|
|
36
|
+
await managementService.delete(`/component/smoke-test-components/${componentName}`);
|
|
18
37
|
} catch {
|
|
19
38
|
// no op
|
|
20
39
|
}
|
|
21
40
|
}
|
|
41
|
+
|
|
42
|
+
// clean up the test componnet files
|
|
43
|
+
await fsp.rm(testFilesDir, { force: true, recursive: true });
|
|
22
44
|
});
|
|
23
45
|
|
|
24
46
|
describe('Test isolated test cases', () => {
|
|
@@ -30,16 +52,26 @@ describe('Test isolated test cases', () => {
|
|
|
30
52
|
it('Should fail uploading a component without manifest.json', async () => {
|
|
31
53
|
mockConsoleError.mockClear();
|
|
32
54
|
const componentPath = path.join(__dirname, '/__components__/invalid-upload');
|
|
33
|
-
await uploadComponentFolder(
|
|
55
|
+
await uploadComponentFolder(
|
|
56
|
+
componentPath,
|
|
57
|
+
configObj.managementServiceUrl + '/v1',
|
|
58
|
+
configObj.renderServiceUrl,
|
|
59
|
+
testFilesDir,
|
|
60
|
+
);
|
|
34
61
|
expect(mockConsoleError.mock.calls[0][0]).toEqual(color.red('manifest could not be found'));
|
|
35
62
|
});
|
|
36
63
|
|
|
37
64
|
it('Should fail uploading a component that has invalid manifest.json', async () => {
|
|
38
65
|
mockConsoleError.mockClear();
|
|
39
66
|
const componentPath = path.join(__dirname, '/__components__/invalid-manifest');
|
|
40
|
-
await uploadComponentFolder(
|
|
67
|
+
await uploadComponentFolder(
|
|
68
|
+
componentPath,
|
|
69
|
+
configObj.managementServiceUrl + '/v1',
|
|
70
|
+
configObj.renderServiceUrl,
|
|
71
|
+
testFilesDir,
|
|
72
|
+
);
|
|
41
73
|
expect(mockConsoleError.mock.calls[0][0]).toEqual(
|
|
42
|
-
color.red('/name
|
|
74
|
+
color.red('failed validation: /name pattern must match pattern "^[a-zA-Z0-9_\\-]+$"'),
|
|
43
75
|
);
|
|
44
76
|
});
|
|
45
77
|
|
|
@@ -48,7 +80,12 @@ describe('Test isolated test cases', () => {
|
|
|
48
80
|
const componentPath = path.join(__dirname, '/__components__/big-package');
|
|
49
81
|
const filePath = `${componentPath}/105mb-file`;
|
|
50
82
|
await createFile(filePath, 105); // Higher limit has been used because compression reduces the size if you use closer to 100MB
|
|
51
|
-
await uploadComponentFolder(
|
|
83
|
+
await uploadComponentFolder(
|
|
84
|
+
componentPath,
|
|
85
|
+
configObj.managementServiceUrl + '/v1',
|
|
86
|
+
configObj.renderServiceUrl,
|
|
87
|
+
testFilesDir,
|
|
88
|
+
);
|
|
52
89
|
expect(mockConsoleError.mock.calls[0][0]).toEqual(
|
|
53
90
|
color.red(['File size exceeds the maximum limit of 100MB'].join('')),
|
|
54
91
|
);
|
|
@@ -61,6 +98,7 @@ describe('Deploy basic component having a static file', () => {
|
|
|
61
98
|
const componentPath = path.join(__dirname, '/__components__/cmp-static-file-test');
|
|
62
99
|
|
|
63
100
|
beforeAll(async () => {
|
|
101
|
+
await deleteComponentSet(webPath);
|
|
64
102
|
for (const componentName of getTestComponents()) {
|
|
65
103
|
try {
|
|
66
104
|
await managementService.delete(`/component/${componentName}`);
|
|
@@ -80,33 +118,56 @@ describe('Deploy basic component having a static file', () => {
|
|
|
80
118
|
});
|
|
81
119
|
|
|
82
120
|
it('Should upload the component and return a valid url to preview', async () => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
121
|
+
await uploadComponentFolder(
|
|
122
|
+
componentPath,
|
|
123
|
+
configObj.managementServiceUrl + '/v1',
|
|
124
|
+
configObj.renderServiceUrl,
|
|
125
|
+
testFilesDir,
|
|
126
|
+
);
|
|
89
127
|
|
|
128
|
+
const uploadedComponent = '<a href="/r/set/smoke-test-components/cmp-static-file-test/1.0.0">1.0.0</a>';
|
|
129
|
+
const get = await supertest(configObj.renderServiceUrl).get('/');
|
|
90
130
|
expect(get.status).toEqual(200);
|
|
91
131
|
expect((get as any)?.res?.text).toContain(uploadedComponent);
|
|
92
132
|
});
|
|
93
133
|
|
|
94
134
|
it('Should fail upload the component with same version', async () => {
|
|
95
135
|
mockConsoleError.mockClear();
|
|
96
|
-
await uploadComponentFolder(
|
|
136
|
+
await uploadComponentFolder(
|
|
137
|
+
componentPath,
|
|
138
|
+
configObj.managementServiceUrl + '/v1',
|
|
139
|
+
configObj.renderServiceUrl,
|
|
140
|
+
testFilesDir,
|
|
141
|
+
);
|
|
97
142
|
expect(mockConsoleError.mock.calls[0][0]).toEqual(
|
|
98
|
-
color.red('Cannot upload component version, cmp-static-file-test 1.0.0 already exists'),
|
|
143
|
+
color.red('Cannot upload component version, smoke-test-components/cmp-static-file-test 1.0.0 already exists'),
|
|
99
144
|
);
|
|
100
145
|
});
|
|
101
146
|
|
|
102
147
|
it('Should render component', async () => {
|
|
103
|
-
const
|
|
148
|
+
const componentSet: ComponentSetWebModel = {
|
|
149
|
+
webPath,
|
|
150
|
+
displayName: 'Set',
|
|
151
|
+
description: 'Set description',
|
|
152
|
+
headers: {},
|
|
153
|
+
environmentVariables: {},
|
|
154
|
+
components: {
|
|
155
|
+
'smoke-test-components/cmp-static-file-test': [{ environmentVariables: {}, version: '1.0.0' }],
|
|
156
|
+
},
|
|
157
|
+
componentVersionRules: {},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
await addComponentSet(componentSet);
|
|
161
|
+
|
|
162
|
+
const response = await renderService.get(
|
|
163
|
+
'/r/set/smoke-test-components/cmp-static-file-test/1.0.0/?something=hello',
|
|
164
|
+
);
|
|
104
165
|
expect(response.status).toEqual(200);
|
|
105
166
|
expect(response.data).toEqual(
|
|
106
167
|
[
|
|
107
168
|
'<div>Input: hello</div>',
|
|
108
|
-
'<div>cmp-static-file-test 1.0.0 ',
|
|
109
|
-
`${configObj.renderServiceUrl}/s/cmp-static-file-test/1.0.0/birthday-cake.png</div>`,
|
|
169
|
+
'<div>smoke-test-components/cmp-static-file-test 1.0.0 ',
|
|
170
|
+
`${configObj.renderServiceUrl}/s/smoke-test-components/cmp-static-file-test/1.0.0/birthday-cake.png</div>`,
|
|
110
171
|
].join(''),
|
|
111
172
|
);
|
|
112
173
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ScanStatus, uploadFile } from '@squiz/virus-scanner-lib';
|
|
2
|
-
|
|
3
|
-
import {
|
|
2
|
+
|
|
3
|
+
import { zipDirectory } from '@squiz/dx-common-lib';
|
|
4
|
+
import { Manifest, ManifestServiceForDev } from '@squiz/component-lib';
|
|
4
5
|
import fsp from 'fs/promises';
|
|
5
6
|
import path from 'path';
|
|
6
7
|
import axios, { AxiosResponse, AxiosError, AxiosInstance } from 'axios';
|
|
@@ -13,8 +14,9 @@ export async function uploadComponentFolder(
|
|
|
13
14
|
folderPath: string,
|
|
14
15
|
componentServiceManagementUrl: string,
|
|
15
16
|
componentRenderServiceUrl: string,
|
|
17
|
+
baseTempDir: string = '',
|
|
16
18
|
): Promise<void> {
|
|
17
|
-
const tmpDir =
|
|
19
|
+
const tmpDir = await fsp.mkdtemp(path.resolve(baseTempDir, 'cmp-upload'));
|
|
18
20
|
|
|
19
21
|
try {
|
|
20
22
|
const axiosInstance = axios.create({
|
|
@@ -58,19 +60,26 @@ export async function uploadComponentFolder(
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
async function preUploadChecks(folderPath: string, renderService: string) {
|
|
61
|
-
const
|
|
63
|
+
const service = new ManifestServiceForDev(folderPath, logger);
|
|
64
|
+
const manifestPath = path.join(folderPath, `manifest.json`);
|
|
65
|
+
|
|
66
|
+
const result = await service.readManifest(manifestPath);
|
|
67
|
+
await service.assertManifestIsValid(manifestPath, result.getModel());
|
|
68
|
+
|
|
62
69
|
if (await checkIfVersionExists(result, renderService)) {
|
|
63
|
-
throw new Error(`Cannot upload component version, ${result.
|
|
70
|
+
throw new Error(`Cannot upload component version, ${result.getName()} ${result.getVersion()} already exists`);
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
|
|
67
|
-
async function checkIfVersionExists(inputManifest:
|
|
74
|
+
async function checkIfVersionExists(inputManifest: Manifest, renderService: string) {
|
|
68
75
|
const axiosInstance = axios.create({
|
|
69
76
|
baseURL: renderService,
|
|
70
77
|
});
|
|
71
78
|
|
|
72
79
|
try {
|
|
73
|
-
const response = await axiosInstance.get(
|
|
80
|
+
const response = await axiosInstance.get(
|
|
81
|
+
`d/${inputManifest.getName()}/${inputManifest.getVersion()}/manifest.json`,
|
|
82
|
+
);
|
|
74
83
|
if (response.status === 200) {
|
|
75
84
|
return true;
|
|
76
85
|
}
|