@squiz/component-cli-lib 1.21.1-alpha.7 → 1.22.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/.gitlab-ci.yml +3 -2
- package/.npm/_logs/2023-03-29T01_27_31_742Z-debug-0.log +37 -0
- package/build.js +2 -1
- package/lib/component-dev.d.ts +1 -1
- package/lib/index.js +113 -121
- package/lib/index.js.map +4 -4
- package/lib/integration-tests/helper.d.ts +3 -1
- package/package.json +10 -10
- package/src/component-dev.integration.spec.ts +1 -1
- package/src/component-dev.ts +4 -5
- package/src/integration-tests/__components__/cmp-no-api-key/main.js +25 -0
- package/src/integration-tests/__components__/cmp-no-api-key/manifest.json +41 -0
- package/src/integration-tests/__components__/cmp-property-order/main.js +6 -0
- package/src/integration-tests/__components__/cmp-property-order/manifest.json +60 -0
- package/src/integration-tests/__components__/matrix-asset-uri/manifest.json +1 -1
- package/src/integration-tests/helper.ts +20 -8
- package/src/integration-tests/upload-and-render-component.integration.spec.ts +132 -63
- package/src/upload-component-folder.ts +6 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/.npm/_logs/2023-03-08T00_08_24_902Z-debug-0.log +0 -39
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentSetWebModelForCreate } from '@squiz/component-lib';
|
|
1
|
+
import { ComponentSetWebModelForCreate, Manifest } from '@squiz/component-lib';
|
|
2
2
|
import { ContentApi } from '@squiz/component-web-api-lib';
|
|
3
3
|
interface Config {
|
|
4
4
|
managementServiceUrl: string;
|
|
@@ -23,3 +23,5 @@ export declare function deleteComponentSet(webPath: string): Promise<void>;
|
|
|
23
23
|
export declare function addComponentSet(componentSet: ComponentSetWebModelForCreate): Promise<void>;
|
|
24
24
|
export declare function addContentItem(contentItem: ContentApi.ContentItemWebModel): Promise<void>;
|
|
25
25
|
export declare function deleteContentItem(contentItemId: string): Promise<void>;
|
|
26
|
+
export declare function deleteComponent(manifest: Manifest): Promise<void>;
|
|
27
|
+
export declare function deleteComponents(manifests: Manifest[]): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiz/component-cli-lib",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@squiz/component-lib": "1.
|
|
17
|
-
"@squiz/component-web-api-lib": "1.
|
|
18
|
-
"@squiz/dx-common-lib": "1.
|
|
19
|
-
"@squiz/dx-json-schema-lib": "1.
|
|
20
|
-
"@squiz/dx-logger-lib": "1.
|
|
21
|
-
"@squiz/virus-scanner-lib": "1.
|
|
16
|
+
"@squiz/component-lib": "1.22.0",
|
|
17
|
+
"@squiz/component-web-api-lib": "1.22.0",
|
|
18
|
+
"@squiz/dx-common-lib": "1.22.0",
|
|
19
|
+
"@squiz/dx-json-schema-lib": "1.22.0",
|
|
20
|
+
"@squiz/dx-logger-lib": "1.22.0",
|
|
21
|
+
"@squiz/virus-scanner-lib": "1.22.0",
|
|
22
22
|
"@types/cli-color": "2.0.2",
|
|
23
23
|
"@types/express": "4.17.17",
|
|
24
24
|
"@types/jest": "28.1.8",
|
|
25
|
-
"@types/node": "
|
|
25
|
+
"@types/node": "18.15.2",
|
|
26
26
|
"@types/supertest": "2.0.12",
|
|
27
27
|
"dotenv": "16.0.3",
|
|
28
28
|
"jest": "29.4.1",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"typescript": "4.9.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@squiz/render-runtime-lib": "1.
|
|
35
|
+
"@squiz/render-runtime-lib": "1.22.0",
|
|
36
36
|
"archiver": "5.3.1",
|
|
37
37
|
"axios": "1.3.2",
|
|
38
38
|
"cli-color": "^2.0.2",
|
|
39
39
|
"open": "^8.4.0",
|
|
40
40
|
"supertest": "^6.2.3"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "c683f01b30c8b35cc23c5bd7426778a94467baec"
|
|
43
43
|
}
|
|
@@ -21,7 +21,7 @@ describe('component-dev', () => {
|
|
|
21
21
|
|
|
22
22
|
it('should fail validation when requesting a function with a missing entry file', async () => {
|
|
23
23
|
const response = await request.get(
|
|
24
|
-
'/r/unit-test-components/test-component/1.0.3/
|
|
24
|
+
'/r/unit-test-components/test-component/1.0.3/main?_componentSet=set&something=not-used',
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
expect(response.body).toEqual({
|
package/src/component-dev.ts
CHANGED
|
@@ -9,7 +9,6 @@ import path from 'path';
|
|
|
9
9
|
import { ComponentFunctionService, ComponentSetServiceForLocalDev, ManifestServiceForDev } from '@squiz/component-lib';
|
|
10
10
|
import open from 'open';
|
|
11
11
|
import { DevelopmentApiKeyService } from '@squiz/dx-common-lib';
|
|
12
|
-
import { JsonValidationService } from '@squiz/dx-json-schema-lib';
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* startDevelopmentRender starts a dev-mode render stack for any
|
|
@@ -37,14 +36,14 @@ export function startDevelopmentRender(
|
|
|
37
36
|
dataMountPoint,
|
|
38
37
|
shouldCacheResponses: false,
|
|
39
38
|
workerTimeout: 5_000,
|
|
40
|
-
|
|
39
|
+
minWorkers: 2,
|
|
40
|
+
maxWorkers: 2,
|
|
41
41
|
},
|
|
42
42
|
logger,
|
|
43
43
|
);
|
|
44
|
-
const
|
|
45
|
-
const componentFunctionService = new ComponentFunctionService(rootUrl, jsonValidationService);
|
|
44
|
+
const componentFunctionService = new ComponentFunctionService(rootUrl);
|
|
46
45
|
const componentSetService = new ComponentSetServiceForLocalDev(logger);
|
|
47
|
-
const manifestService = new ManifestServiceForDev(dataMountPoint, logger
|
|
46
|
+
const manifestService = new ManifestServiceForDev(dataMountPoint, logger);
|
|
48
47
|
const contentItemService = undefined;
|
|
49
48
|
const renderInputService = new RenderInputService(
|
|
50
49
|
componentSetService,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} input
|
|
3
|
+
* @param {ComponentInfo} info
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async function (input, info) {
|
|
6
|
+
function hasDxpApiKey(obj) {
|
|
7
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
8
|
+
if (obj.hasOwnProperty('dxpApiKey')) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
for (const prop in obj) {
|
|
12
|
+
if (hasDxpApiKey(obj[prop])) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (hasDxpApiKey(input) || hasDxpApiKey(info)) {
|
|
21
|
+
return 'true';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return 'false';
|
|
25
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://localhost:3000/schemas/v1.json#",
|
|
3
|
+
|
|
4
|
+
"name": "cmp-no-api-key",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"mainFunction": "main",
|
|
7
|
+
"displayName": "some-display-name",
|
|
8
|
+
"namespace": "smoke-test-components",
|
|
9
|
+
"description": "some-description",
|
|
10
|
+
"functions": [
|
|
11
|
+
{
|
|
12
|
+
"name": "main",
|
|
13
|
+
"entry": "main.js",
|
|
14
|
+
"input": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"text": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"format": "multi-line"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["text"]
|
|
23
|
+
},
|
|
24
|
+
"output": { "responseType": "html" }
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"previews": {
|
|
28
|
+
"test-preview": {
|
|
29
|
+
"functionData": {
|
|
30
|
+
"main": {
|
|
31
|
+
"inputData": {
|
|
32
|
+
"type": "inline",
|
|
33
|
+
"value": {
|
|
34
|
+
"text": "this is a test"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://localhost:3000/schemas/v1.json#",
|
|
3
|
+
|
|
4
|
+
"name": "cmp-property-order",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"mainFunction": "main",
|
|
7
|
+
"displayName": "some-display-name",
|
|
8
|
+
"namespace": "smoke-test-components",
|
|
9
|
+
"description": "some-description",
|
|
10
|
+
"functions": [
|
|
11
|
+
{
|
|
12
|
+
"name": "main",
|
|
13
|
+
"entry": "main.js",
|
|
14
|
+
"input": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"input1": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"333": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"input333": {
|
|
24
|
+
"type": "string"
|
|
25
|
+
},
|
|
26
|
+
"\"": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"~": {
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"": {
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
"$": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"111": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"input22": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
},
|
|
44
|
+
"222": {
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
"*": {
|
|
48
|
+
"type": "string"
|
|
49
|
+
},
|
|
50
|
+
"null": {
|
|
51
|
+
"type": "null",
|
|
52
|
+
"default": null
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"required": []
|
|
56
|
+
},
|
|
57
|
+
"output": { "responseType": "html" }
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
1
|
+
import axios, { AxiosError } from 'axios';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
4
|
import fsp from 'fs/promises';
|
|
5
5
|
import { randomBytes } from 'crypto';
|
|
6
|
-
import { ComponentSetWebModelForCreate, ManifestServiceForDev } from '@squiz/component-lib';
|
|
6
|
+
import { ComponentSetWebModelForCreate, Manifest, ManifestServiceForDev } from '@squiz/component-lib';
|
|
7
7
|
import { parseEnvVarForVar } from '@squiz/dx-common-lib';
|
|
8
8
|
import { ContentApi } from '@squiz/component-web-api-lib';
|
|
9
9
|
import { config } from 'dotenv';
|
|
10
10
|
import { execSync } from 'child_process';
|
|
11
11
|
import { getLogger } from '@squiz/dx-logger-lib';
|
|
12
|
-
import { JsonValidationService } from '@squiz/dx-json-schema-lib';
|
|
13
12
|
|
|
14
13
|
config();
|
|
15
14
|
|
|
@@ -112,11 +111,7 @@ export const ci_buildBranch = configObj.ci_buildBranch;
|
|
|
112
111
|
|
|
113
112
|
export async function getTestComponents() {
|
|
114
113
|
const componentsDir = path.join(__dirname, '/__components__/');
|
|
115
|
-
const manifestService = new ManifestServiceForDev(
|
|
116
|
-
componentsDir,
|
|
117
|
-
getLogger({ name: 'getTestComponents' }),
|
|
118
|
-
new JsonValidationService(),
|
|
119
|
-
);
|
|
114
|
+
const manifestService = new ManifestServiceForDev(componentsDir, getLogger({ name: 'getTestComponents' }));
|
|
120
115
|
return await manifestService.listAllComponentManifests();
|
|
121
116
|
}
|
|
122
117
|
export async function createFile(filePath: string, sizeInMB: number) {
|
|
@@ -159,3 +154,20 @@ export async function deleteContentItem(contentItemId: string) {
|
|
|
159
154
|
//no ops
|
|
160
155
|
}
|
|
161
156
|
}
|
|
157
|
+
|
|
158
|
+
export async function deleteComponent(manifest: Manifest) {
|
|
159
|
+
try {
|
|
160
|
+
await managementService.delete(`/component/${manifest.getName()}`);
|
|
161
|
+
await contentService.delete(
|
|
162
|
+
`/content-schema/${manifest.getName()}/${manifest.getVersion()}/${manifest.getComponentFunctionByName().name}`,
|
|
163
|
+
);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if ((error as AxiosError).response?.status !== 404) {
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export async function deleteComponents(manifests: Manifest[]) {
|
|
172
|
+
await Promise.all(manifests.map((manifest) => deleteComponent(manifest)));
|
|
173
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { uploadComponentFolder } from '../index';
|
|
2
2
|
import configObj, {
|
|
3
|
-
renderService,
|
|
4
3
|
managementService,
|
|
4
|
+
renderService,
|
|
5
5
|
getTestComponents,
|
|
6
6
|
createFile,
|
|
7
|
+
deleteComponents,
|
|
7
8
|
removeFile,
|
|
8
9
|
addComponentSet,
|
|
9
10
|
deleteComponentSet,
|
|
10
11
|
addContentItem,
|
|
11
12
|
deleteContentItem,
|
|
12
13
|
managementServiceRoot,
|
|
13
|
-
contentService,
|
|
14
14
|
} from './helper';
|
|
15
15
|
|
|
16
16
|
import path from 'path';
|
|
@@ -19,7 +19,6 @@ import { logger } from '../upload-component-folder';
|
|
|
19
19
|
import { ComponentSetWebModelForCreate } from '@squiz/component-lib';
|
|
20
20
|
import fsp from 'fs/promises';
|
|
21
21
|
import { randomUUID } from 'crypto';
|
|
22
|
-
import { AxiosError } from 'axios';
|
|
23
22
|
|
|
24
23
|
const webPath = 'set-' + randomUUID();
|
|
25
24
|
const contentItemId = randomUUID();
|
|
@@ -36,18 +35,8 @@ describe('uploading a component', () => {
|
|
|
36
35
|
// clean up the component added by the test
|
|
37
36
|
await deleteComponentSet(webPath);
|
|
38
37
|
await deleteContentItem(contentItemId);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
await managementService.delete(`/component/${manifest.getName()}`).catch(() => null);
|
|
42
|
-
await contentService
|
|
43
|
-
.delete(
|
|
44
|
-
`/content-schema/${manifest.getName()}/${manifest.getVersion()}/${
|
|
45
|
-
manifest.getComponentFunctionByName().name
|
|
46
|
-
}`,
|
|
47
|
-
)
|
|
48
|
-
.catch(() => null);
|
|
49
|
-
}
|
|
50
|
-
// clean up the test componnet files
|
|
38
|
+
await deleteComponents(await getTestComponents());
|
|
39
|
+
// clean up the test component files
|
|
51
40
|
await fsp.rm(testFilesDir, { force: true, recursive: true });
|
|
52
41
|
logger.silent = false;
|
|
53
42
|
});
|
|
@@ -102,22 +91,9 @@ describe('uploading a component', () => {
|
|
|
102
91
|
|
|
103
92
|
describe('Deploy a basic component having a input with multiline format', () => {
|
|
104
93
|
beforeAll(async () => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
for (const manifest of await getTestComponents()) {
|
|
109
|
-
await managementService.delete(`/component/${manifest.getName()}`);
|
|
110
|
-
await contentService.delete(
|
|
111
|
-
`/content-schema/${manifest.getName()}/${manifest.getVersion()}/${
|
|
112
|
-
manifest.getComponentFunctionByName().name
|
|
113
|
-
}`,
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
} catch (error: unknown) {
|
|
117
|
-
if ((error as AxiosError).response?.status !== 404) {
|
|
118
|
-
throw error;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
94
|
+
await deleteComponentSet(webPath);
|
|
95
|
+
await deleteContentItem(contentItemId);
|
|
96
|
+
await deleteComponents(await getTestComponents());
|
|
121
97
|
});
|
|
122
98
|
|
|
123
99
|
it('Should upload the component and return a valid url to preview', async () => {
|
|
@@ -160,26 +136,27 @@ describe('uploading a component', () => {
|
|
|
160
136
|
expect(response.status).toEqual(200);
|
|
161
137
|
expect(response.data).toEqual(`<div>Input: from-content-item-service</div>`);
|
|
162
138
|
});
|
|
139
|
+
|
|
140
|
+
it('Should return relevant error if upload fails at the server', async () => {
|
|
141
|
+
// delete the previously uploaded component
|
|
142
|
+
await managementService.delete(`/component/smoke-test-components/cmp-format-string`);
|
|
143
|
+
|
|
144
|
+
// trying uploading the component again should fail at the server
|
|
145
|
+
// due to content item schema already exist matching the component name/version
|
|
146
|
+
const componentPath = path.join(__dirname, '/__components__/cmp-format-string');
|
|
147
|
+
await expect(
|
|
148
|
+
uploadComponentFolder(managementServiceRoot, configObj.managementServiceUrl, componentPath, testFilesDir),
|
|
149
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
150
|
+
`"Unexpected response code 500. Error occurred when creating content schema: Content schema smoke-test-components/cmp-format-string/1.0.0/main already exists"`,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
163
153
|
});
|
|
164
154
|
|
|
165
155
|
describe('Deploy a basic component with input format matrix-asset-uri', () => {
|
|
166
156
|
beforeAll(async () => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
for (const manifest of await getTestComponents()) {
|
|
171
|
-
await managementService.delete(`/component/${manifest.getName()}`);
|
|
172
|
-
await contentService.delete(
|
|
173
|
-
`/content-schema/${manifest.getName()}/${manifest.getVersion()}/${
|
|
174
|
-
manifest.getComponentFunctionByName().name
|
|
175
|
-
}`,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
} catch (error) {
|
|
179
|
-
if ((error as AxiosError).response?.status !== 404) {
|
|
180
|
-
throw error;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
157
|
+
await deleteComponentSet(webPath);
|
|
158
|
+
await deleteContentItem(contentItemId);
|
|
159
|
+
await deleteComponents(await getTestComponents());
|
|
183
160
|
});
|
|
184
161
|
it('Should upload the component and return a valid url to preview', async () => {
|
|
185
162
|
const componentPath = path.join(__dirname, '/__components__/matrix-asset-uri');
|
|
@@ -231,22 +208,9 @@ describe('uploading a component', () => {
|
|
|
231
208
|
const componentPath = path.join(__dirname, '/__components__/cmp-static-file-test');
|
|
232
209
|
|
|
233
210
|
beforeAll(async () => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
for (const manifest of await getTestComponents()) {
|
|
238
|
-
await managementService.delete(`/component/${manifest.getName()}`);
|
|
239
|
-
await contentService.delete(
|
|
240
|
-
`/content-schema/${manifest.getName()}/${manifest.getVersion()}/${
|
|
241
|
-
manifest.getComponentFunctionByName().name
|
|
242
|
-
}`,
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
} catch (error) {
|
|
246
|
-
if ((error as AxiosError).response?.status !== 404) {
|
|
247
|
-
throw error;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
211
|
+
await deleteComponentSet(webPath);
|
|
212
|
+
await deleteContentItem(contentItemId);
|
|
213
|
+
await deleteComponents(await getTestComponents());
|
|
250
214
|
});
|
|
251
215
|
|
|
252
216
|
it('Should upload the component and return a valid url to preview', async () => {
|
|
@@ -351,4 +315,109 @@ describe('uploading a component', () => {
|
|
|
351
315
|
);
|
|
352
316
|
});
|
|
353
317
|
});
|
|
318
|
+
|
|
319
|
+
describe('Deploy a basic component using and not expose the x-api-key', () => {
|
|
320
|
+
// component to deploy for this test
|
|
321
|
+
const componentPath = path.join(__dirname, '/__components__/cmp-no-api-key');
|
|
322
|
+
|
|
323
|
+
beforeAll(async () => {
|
|
324
|
+
await deleteComponentSet(webPath);
|
|
325
|
+
await deleteContentItem(contentItemId);
|
|
326
|
+
await deleteComponents(await getTestComponents());
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it('Should upload the component and return a valid url', async () => {
|
|
330
|
+
await uploadComponentFolder(
|
|
331
|
+
managementServiceRoot,
|
|
332
|
+
configObj.managementServiceUrl,
|
|
333
|
+
componentPath,
|
|
334
|
+
|
|
335
|
+
testFilesDir,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
const uploadedComponent =
|
|
339
|
+
'<a href="/r/smoke-test-components/cmp-no-api-key/1.0.0?_previewKey=test-preview">1.0.0</a>';
|
|
340
|
+
const get = await supertest(configObj.renderServiceUrl).get('/');
|
|
341
|
+
expect(get.status).toEqual(200);
|
|
342
|
+
expect((get as any)?.res?.text).toContain(uploadedComponent);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('Should render component', async () => {
|
|
346
|
+
const componentSet: ComponentSetWebModelForCreate = {
|
|
347
|
+
webPath,
|
|
348
|
+
displayName: 'some-display-name',
|
|
349
|
+
description: 'Set description',
|
|
350
|
+
headers: {},
|
|
351
|
+
environmentVariables: {},
|
|
352
|
+
components: {},
|
|
353
|
+
componentVersionRules: {
|
|
354
|
+
'smoke-test-components/cmp-no-api-key': {
|
|
355
|
+
renderableVersionPattern: '1.0.0',
|
|
356
|
+
editableVersions: [],
|
|
357
|
+
excludedVersions: [],
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
await addComponentSet(componentSet);
|
|
363
|
+
|
|
364
|
+
const response = await renderService.get(
|
|
365
|
+
`/r/smoke-test-components/cmp-no-api-key/1.0.0/?_componentSet=${webPath}&text=hello`,
|
|
366
|
+
{ headers: { 'x-api-key': 'this is key' } },
|
|
367
|
+
);
|
|
368
|
+
expect(response.status).toEqual(200);
|
|
369
|
+
expect(response.data).toEqual(false);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
describe('Deploy component with properties defined in a specific order', () => {
|
|
374
|
+
// component to deploy for this test
|
|
375
|
+
const componentPath = path.join(__dirname, '/__components__/cmp-property-order');
|
|
376
|
+
|
|
377
|
+
beforeAll(async () => {
|
|
378
|
+
await deleteComponentSet(webPath);
|
|
379
|
+
await deleteContentItem(contentItemId);
|
|
380
|
+
await deleteComponents(await getTestComponents());
|
|
381
|
+
|
|
382
|
+
await uploadComponentFolder(managementServiceRoot, configObj.managementServiceUrl, componentPath, testFilesDir);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('Should preserve input field order when uploading schema to content store', async () => {
|
|
386
|
+
const response = await supertest(configObj.contentServiceUrl).get(
|
|
387
|
+
'/content-schema/smoke-test-components/cmp-property-order/1.0.0/main',
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
// Relates to DEVX-891, property order is preserved so that we can reliably draw a UI from it.
|
|
391
|
+
//
|
|
392
|
+
// The sequence here is important and should follow the rules defined here:
|
|
393
|
+
// * https://tc39.es/ecma262/#sec-ordinaryownpropertykeys
|
|
394
|
+
// * https://stackoverflow.com/a/38218582
|
|
395
|
+
//
|
|
396
|
+
// Per EMCA-262 numeric keys appear first in ascending order but all other keys should appear
|
|
397
|
+
// in the order they were originally defined, they should not be affected by them being stored in
|
|
398
|
+
// a JSONB DB column or anything else.
|
|
399
|
+
//
|
|
400
|
+
// Asserting on the encoded contents of the response to avoid any decoding in the test having
|
|
401
|
+
// a potential influence on the outcome.
|
|
402
|
+
const expectedProperties =
|
|
403
|
+
'"111":{"type":"string"},' +
|
|
404
|
+
'"222":{"type":"string"},' +
|
|
405
|
+
'"333":{"type":"string"},' +
|
|
406
|
+
'"input1":{"type":"string"},' +
|
|
407
|
+
'"input333":{"type":"string"},' +
|
|
408
|
+
'"\\"":{"type":"string"},' +
|
|
409
|
+
'"~":{"type":"string"},' +
|
|
410
|
+
'"":{"type":"string"},' +
|
|
411
|
+
'"$":{"type":"string"},' +
|
|
412
|
+
'"input22":{"type":"string"},' +
|
|
413
|
+
'"*":{"type":"string"},' +
|
|
414
|
+
'"null":{"type":"null","default":null}';
|
|
415
|
+
|
|
416
|
+
expect(response.status).toEqual(200);
|
|
417
|
+
expect(response.text).toEqual(
|
|
418
|
+
`{"name":"smoke-test-components/cmp-property-order/1.0.0/main",` +
|
|
419
|
+
`"schema":{"type":"object","properties":{${expectedProperties}},"required":[]},"contentSchemaType":"component"}`,
|
|
420
|
+
);
|
|
421
|
+
});
|
|
422
|
+
});
|
|
354
423
|
});
|
|
@@ -7,7 +7,6 @@ import path from 'path';
|
|
|
7
7
|
import { AxiosResponse, AxiosError, AxiosInstance } from 'axios';
|
|
8
8
|
import color from 'cli-color';
|
|
9
9
|
import { getLogger, Logger } from '@squiz/dx-logger-lib';
|
|
10
|
-
import { JsonValidationService } from '@squiz/dx-json-schema-lib';
|
|
11
10
|
|
|
12
11
|
export const logger: Logger = getLogger({ name: 'upload-component', format: 'human' });
|
|
13
12
|
|
|
@@ -44,7 +43,8 @@ export async function uploadComponentFolder(
|
|
|
44
43
|
logger.info(`deployment id: ${initialUpload.id} status: ${color.green('success')}`);
|
|
45
44
|
logger.info(`uploaded location: ${result.accessLink}`);
|
|
46
45
|
} else {
|
|
47
|
-
|
|
46
|
+
const message = result?.message ?? 'unknown';
|
|
47
|
+
logger.error(`failed due an unexpected reason: ${message}`);
|
|
48
48
|
}
|
|
49
49
|
} catch (e) {
|
|
50
50
|
await fsp.rm(tmpDir, { force: true, recursive: true });
|
|
@@ -54,7 +54,7 @@ export async function uploadComponentFolder(
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
async function preUploadChecks(apiClient: AxiosInstance, managementURL: string, folderPath: string) {
|
|
57
|
-
const service = new ManifestServiceForDev(folderPath, logger
|
|
57
|
+
const service = new ManifestServiceForDev(folderPath, logger);
|
|
58
58
|
const manifestPath = path.join(folderPath, `manifest.json`);
|
|
59
59
|
|
|
60
60
|
const result = await service.readManifest(manifestPath);
|
|
@@ -136,10 +136,11 @@ function handleError(error: any): Error {
|
|
|
136
136
|
const newError = new Error(errorMessage || 'An error has occurred');
|
|
137
137
|
|
|
138
138
|
if (isAxiosError(error)) {
|
|
139
|
+
const errorCode = response.status ?? 'unknown';
|
|
139
140
|
if (response?.data?.message) {
|
|
140
|
-
newError.message =
|
|
141
|
+
newError.message = `Unexpected response code ${errorCode}. ${response.data.message}`.trim();
|
|
141
142
|
} else {
|
|
142
|
-
newError.message =
|
|
143
|
+
newError.message = `${errorMessage} (code: ${errorCode})`;
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|