@squiz/component-cli-lib 1.39.1-alpha.24 → 1.39.1-alpha.25
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/.env.example +1 -0
- package/.npm/_logs/{2023-06-29T01_54_23_207Z-debug-0.log → 2023-06-29T05_18_12_005Z-debug-0.log} +14 -14
- package/lib/index.js +200 -176
- package/lib/index.js.map +4 -4
- package/lib/integration-tests/helper.d.ts +5 -1
- package/lib/integration-tests/upload-and-render-page.integration.spec.d.ts +1 -0
- package/package.json +9 -9
- package/src/integration-tests/__components__/test-page-render/main.js +3 -0
- package/src/integration-tests/__components__/test-page-render/manifest.json +27 -0
- package/src/integration-tests/helper.ts +60 -39
- package/src/integration-tests/upload-and-render-page.integration.spec.ts +151 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -3,6 +3,7 @@ import { ContentApi } from '@squiz/component-web-api-lib';
|
|
|
3
3
|
interface Config {
|
|
4
4
|
managementServiceUrl: string;
|
|
5
5
|
renderServiceUrl: string;
|
|
6
|
+
pageRenderServiceUrl: string;
|
|
6
7
|
contentServiceUrl: string;
|
|
7
8
|
tenantId: string;
|
|
8
9
|
jobServiceUrl: string;
|
|
@@ -11,15 +12,16 @@ interface Config {
|
|
|
11
12
|
}
|
|
12
13
|
declare const configObj: Config;
|
|
13
14
|
export default configObj;
|
|
14
|
-
export declare const authToken: string;
|
|
15
15
|
export declare const managementService: import("axios").AxiosInstance;
|
|
16
16
|
export declare const managementServiceRoot: import("axios").AxiosInstance;
|
|
17
17
|
export declare const renderService: import("axios").AxiosInstance;
|
|
18
18
|
export declare const contentService: import("axios").AxiosInstance;
|
|
19
|
+
export declare const pageRenderService: import("axios").AxiosInstance;
|
|
19
20
|
export declare const jobService: import("axios").AxiosInstance;
|
|
20
21
|
export declare const ci_buildVersion: string;
|
|
21
22
|
export declare const ci_buildBranch: string;
|
|
22
23
|
export declare function getTestComponents(): Promise<import("@squiz/component-lib").ManifestV1[]>;
|
|
24
|
+
export declare function getTestComponent(componentFolderName: string): Promise<import("@squiz/component-lib").ManifestV1[]>;
|
|
23
25
|
export declare function getTestJobs(): Promise<import("@squiz/component-lib").ManifestV1[]>;
|
|
24
26
|
export declare function createFile(filePath: string, sizeInMB: number): Promise<void>;
|
|
25
27
|
export declare function removeFile(filePath: string): void;
|
|
@@ -27,7 +29,9 @@ export declare function deleteComponentSet(webPath: string): Promise<void>;
|
|
|
27
29
|
export declare function addComponentSet(componentSet: ComponentSetWebModelForCreate): Promise<void>;
|
|
28
30
|
export declare function addContentItem(contentItem: ContentApi.ContentItemWebModel): Promise<void>;
|
|
29
31
|
export declare function deleteContentItem(contentItemId: string): Promise<void>;
|
|
32
|
+
export declare function deleteContentSchema(contentSchemaName: string): Promise<void>;
|
|
30
33
|
export declare function deleteComponent(manifest: Manifest): Promise<void>;
|
|
31
34
|
export declare function deleteComponents(manifests: Manifest[]): Promise<void>;
|
|
35
|
+
export declare function uploadTestComponent(componentFolderPath: string, tempFolderPath: string): Promise<void>;
|
|
32
36
|
export declare function deleteJob(manifest: Manifest): Promise<void>;
|
|
33
37
|
export declare function deleteJobs(manifests: Manifest[]): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiz/component-cli-lib",
|
|
3
|
-
"version": "1.39.1-alpha.
|
|
3
|
+
"version": "1.39.1-alpha.25",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@squiz/component-lib": "1.39.1-alpha.
|
|
17
|
-
"@squiz/component-web-api-lib": "1.39.1-alpha.
|
|
18
|
-
"@squiz/dx-common-lib": "1.39.1-alpha.
|
|
19
|
-
"@squiz/dx-json-schema-lib": "1.39.1-alpha.
|
|
20
|
-
"@squiz/dx-logger-lib": "1.39.1-alpha.
|
|
21
|
-
"@squiz/virus-scanner-lib": "1.39.1-alpha.
|
|
16
|
+
"@squiz/component-lib": "1.39.1-alpha.25",
|
|
17
|
+
"@squiz/component-web-api-lib": "1.39.1-alpha.25",
|
|
18
|
+
"@squiz/dx-common-lib": "1.39.1-alpha.25",
|
|
19
|
+
"@squiz/dx-json-schema-lib": "1.39.1-alpha.25",
|
|
20
|
+
"@squiz/dx-logger-lib": "1.39.1-alpha.25",
|
|
21
|
+
"@squiz/virus-scanner-lib": "1.39.1-alpha.25",
|
|
22
22
|
"@types/cli-color": "2.0.2",
|
|
23
23
|
"@types/express": "4.17.17",
|
|
24
24
|
"@types/jest": "28.1.8",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"typescript": "4.9.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@squiz/render-runtime-lib": "1.39.1-alpha.
|
|
35
|
+
"@squiz/render-runtime-lib": "1.39.1-alpha.25",
|
|
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": "d73ef9c2a7228c9218e55562eeb87040c2454643"
|
|
43
43
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://localhost:3000/schemas/v1.json#",
|
|
3
|
+
"name": "test-page-render",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"mainFunction": "main",
|
|
6
|
+
"displayName": "some-display-name",
|
|
7
|
+
"namespace": "unit-test-components",
|
|
8
|
+
"description": "some-description",
|
|
9
|
+
"functions": [
|
|
10
|
+
{
|
|
11
|
+
"name": "main",
|
|
12
|
+
"entry": "main.js",
|
|
13
|
+
"input": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"text ": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"required": []
|
|
21
|
+
},
|
|
22
|
+
"output": {
|
|
23
|
+
"responseType": "html"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -9,12 +9,15 @@ 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 { uploadComponentFolder } from '../upload-component-folder';
|
|
13
|
+
import { buildDevelopmentJwt, DxpServiceId } from '@squiz/dxp-auth-lib';
|
|
12
14
|
|
|
13
15
|
config();
|
|
14
16
|
|
|
15
17
|
interface Config {
|
|
16
18
|
managementServiceUrl: string;
|
|
17
19
|
renderServiceUrl: string;
|
|
20
|
+
pageRenderServiceUrl: string;
|
|
18
21
|
contentServiceUrl: string;
|
|
19
22
|
tenantId: string;
|
|
20
23
|
jobServiceUrl: string;
|
|
@@ -24,6 +27,7 @@ interface Config {
|
|
|
24
27
|
|
|
25
28
|
const configObj: Config = {
|
|
26
29
|
managementServiceUrl: parseEnvVarForVar('COMPONENT_MANAGEMENT_SERVICE_URL').replace(/\/+$/, ''),
|
|
30
|
+
pageRenderServiceUrl: parseEnvVarForVar('PAGE_RENDER_SERVICE_URL').replace(/\/+$/, ''),
|
|
27
31
|
renderServiceUrl: parseEnvVarForVar('COMPONENT_RENDER_SERVICE_URL').replace(/\/+$/, ''),
|
|
28
32
|
contentServiceUrl: parseEnvVarForVar('CONTENT_API_URL').replace(/\/+$/, ''),
|
|
29
33
|
tenantId: parseEnvVarForVar('TENANT_ID'),
|
|
@@ -42,46 +46,37 @@ if (!configObj.ci_buildBranch) {
|
|
|
42
46
|
|
|
43
47
|
export default configObj;
|
|
44
48
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
const authToken =
|
|
50
|
+
'Bearer ' +
|
|
51
|
+
buildDevelopmentJwt({
|
|
52
|
+
service: {
|
|
53
|
+
[DxpServiceId.contentStore]: {
|
|
54
|
+
privileges: [
|
|
55
|
+
'CONTENT_SCHEMA_READ',
|
|
56
|
+
'CONTENT_SCHEMA_WRITE',
|
|
57
|
+
'CONTENT_ITEM_READ',
|
|
58
|
+
'CONTENT_ITEM_WRITE',
|
|
59
|
+
'SETTINGS_READ',
|
|
60
|
+
'SETTINGS_WRITE',
|
|
61
|
+
'PAGE_CONTENTS_WRITE',
|
|
62
|
+
'PAGE_CONTENTS_READ',
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
[DxpServiceId.components]: {
|
|
66
|
+
privileges: [
|
|
67
|
+
'COMPONENT_READ',
|
|
68
|
+
'COMPONENT_WRITE',
|
|
69
|
+
'COMPONENT_DEPLOY',
|
|
70
|
+
'COMPONENT_SET_WRITE',
|
|
71
|
+
'COMPONENT_DELETE',
|
|
72
|
+
'COMPONENT_SET_WRITE',
|
|
73
|
+
'COMPONENT_SET_READ',
|
|
74
|
+
'COMPONENT_SET_ENVIRONMENT_READ',
|
|
75
|
+
'COMPONENT_SET_ENVIRONMENT_WRITE',
|
|
76
|
+
],
|
|
77
|
+
},
|
|
70
78
|
},
|
|
71
|
-
|
|
72
|
-
privileges: [
|
|
73
|
-
'CONTENT_SCHEMA_READ',
|
|
74
|
-
'CONTENT_SCHEMA_WRITE',
|
|
75
|
-
'CONTENT_ITEM_READ',
|
|
76
|
-
'CONTENT_ITEM_WRITE',
|
|
77
|
-
'SETTINGS_READ',
|
|
78
|
-
'SETTINGS_WRITE',
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const authToken = `Bearer xxx.${Buffer.from(JSON.stringify(validToken)).toString('base64')}.zzz`;
|
|
79
|
+
});
|
|
85
80
|
|
|
86
81
|
export const managementService = axios.create({
|
|
87
82
|
baseURL: configObj.managementServiceUrl + '/v1',
|
|
@@ -111,6 +106,13 @@ export const contentService = axios.create({
|
|
|
111
106
|
},
|
|
112
107
|
});
|
|
113
108
|
|
|
109
|
+
export const pageRenderService = axios.create({
|
|
110
|
+
baseURL: configObj.pageRenderServiceUrl,
|
|
111
|
+
headers: {
|
|
112
|
+
authorization: authToken,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
|
|
114
116
|
export const jobService = axios.create({
|
|
115
117
|
baseURL: configObj.jobServiceUrl,
|
|
116
118
|
headers: {
|
|
@@ -127,6 +129,12 @@ export async function getTestComponents() {
|
|
|
127
129
|
return await manifestService.listAllComponentManifests();
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
export async function getTestComponent(componentFolderName: string) {
|
|
133
|
+
const componentsDir = path.join(__dirname, '/__components__/', componentFolderName);
|
|
134
|
+
const manifestService = new ManifestServiceForDev(componentsDir, getLogger({ name: 'getTestComponents' }));
|
|
135
|
+
return await manifestService.listAllComponentManifests();
|
|
136
|
+
}
|
|
137
|
+
|
|
130
138
|
export async function getTestJobs() {
|
|
131
139
|
const jobsDir = path.join(__dirname, '/__jobs__/');
|
|
132
140
|
const manifestService = new ManifestServiceForDev(jobsDir, getLogger({ name: 'getTestJobs' }));
|
|
@@ -174,6 +182,14 @@ export async function deleteContentItem(contentItemId: string) {
|
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
184
|
|
|
185
|
+
export async function deleteContentSchema(contentSchemaName: string) {
|
|
186
|
+
try {
|
|
187
|
+
await contentService.delete(`/content-item/${contentSchemaName}`);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
//no ops
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
177
193
|
export async function deleteComponent(manifest: Manifest) {
|
|
178
194
|
try {
|
|
179
195
|
await managementService.delete(`/component/${manifest.getName()}`);
|
|
@@ -191,6 +207,11 @@ export async function deleteComponents(manifests: Manifest[]) {
|
|
|
191
207
|
await Promise.all(manifests.map((manifest) => deleteComponent(manifest)));
|
|
192
208
|
}
|
|
193
209
|
|
|
210
|
+
export async function uploadTestComponent(componentFolderPath: string, tempFolderPath: string): Promise<void> {
|
|
211
|
+
const componentPath = path.join(__dirname, componentFolderPath);
|
|
212
|
+
await uploadComponentFolder(managementServiceRoot, configObj.managementServiceUrl, componentPath, tempFolderPath);
|
|
213
|
+
}
|
|
214
|
+
|
|
194
215
|
export async function deleteJob(manifest: Manifest) {
|
|
195
216
|
try {
|
|
196
217
|
await jobService.delete(`/job/${manifest.getName()}/${manifest.getVersion()}`);
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ContentItemWebModeForSave,
|
|
3
|
+
ContentSchemaType,
|
|
4
|
+
ContentSchemaWebModelForCreate,
|
|
5
|
+
PageContentsWebModel,
|
|
6
|
+
} from '@squiz/component-web-api-lib/src/generated/ContentApi';
|
|
7
|
+
import { ComponentSetWebModelForCreate } from '@squiz/component-lib';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import {
|
|
10
|
+
addComponentSet,
|
|
11
|
+
contentService,
|
|
12
|
+
deleteComponentSet,
|
|
13
|
+
deleteComponents,
|
|
14
|
+
deleteContentItem,
|
|
15
|
+
deleteContentSchema,
|
|
16
|
+
getTestComponent,
|
|
17
|
+
pageRenderService,
|
|
18
|
+
uploadTestComponent,
|
|
19
|
+
} from './helper';
|
|
20
|
+
import fsp from 'fs/promises';
|
|
21
|
+
import { randomInt } from 'crypto';
|
|
22
|
+
|
|
23
|
+
const SCHEMA_NAME = 'test-schema-name' + randomInt(10000);
|
|
24
|
+
const CONTENT_ITEM_ID = 'test-content-id' + randomInt(10000);
|
|
25
|
+
const PAGE_CONTENT_ID = 'test-page-content-id' + randomInt(10000);
|
|
26
|
+
const COMPONENT_SET_WEB_PATH = 'local-development-only' + randomInt(10000);
|
|
27
|
+
const COMPONENT_NAME = 'test-page-render';
|
|
28
|
+
const COMPONENT_NAMESPACE = 'unit-test-components';
|
|
29
|
+
const COMPONENT_CONTENT_ID = 'component-content-id' + randomInt(10000);
|
|
30
|
+
const COMPONENT_CONTENT_SCHEMA_NAME = `${COMPONENT_NAMESPACE}/${COMPONENT_NAME}/1.0.0/main`;
|
|
31
|
+
|
|
32
|
+
const componentContentItem = {
|
|
33
|
+
id: COMPONENT_CONTENT_ID,
|
|
34
|
+
schemaName: COMPONENT_CONTENT_SCHEMA_NAME,
|
|
35
|
+
content: {
|
|
36
|
+
text: 'component-input-string',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// This schema emulates the layout input schema
|
|
41
|
+
const contentSchema: ContentSchemaWebModelForCreate = {
|
|
42
|
+
name: SCHEMA_NAME,
|
|
43
|
+
schema: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
nodes: {
|
|
47
|
+
type: 'FormattedText',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ['nodes'],
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
},
|
|
53
|
+
contentSchemaType: ContentSchemaType.Component,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// The content item with the formatted text
|
|
57
|
+
const contentItem: ContentItemWebModeForSave = {
|
|
58
|
+
id: CONTENT_ITEM_ID,
|
|
59
|
+
schemaName: SCHEMA_NAME,
|
|
60
|
+
content: {
|
|
61
|
+
nodes: [
|
|
62
|
+
{
|
|
63
|
+
type: 'tag',
|
|
64
|
+
tag: 'h1',
|
|
65
|
+
children: [
|
|
66
|
+
{
|
|
67
|
+
type: 'text',
|
|
68
|
+
value: 'Hello World!',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: 'component',
|
|
74
|
+
schemaName: `http://localhost:3000/d/${COMPONENT_NAMESPACE}/${COMPONENT_NAME}/1.0.0`,
|
|
75
|
+
componentSet: COMPONENT_SET_WEB_PATH,
|
|
76
|
+
content: {
|
|
77
|
+
contentItemId: COMPONENT_CONTENT_ID,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'tag',
|
|
82
|
+
tag: 'p',
|
|
83
|
+
children: [
|
|
84
|
+
{
|
|
85
|
+
type: 'text',
|
|
86
|
+
value: 'Bottom text',
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
// The page content item which references the content item
|
|
94
|
+
const pageContents: PageContentsWebModel = {
|
|
95
|
+
name: 'page-contents-test-1',
|
|
96
|
+
id: PAGE_CONTENT_ID,
|
|
97
|
+
layouts: [
|
|
98
|
+
{
|
|
99
|
+
schemaName: SCHEMA_NAME,
|
|
100
|
+
content: {
|
|
101
|
+
contentItemId: CONTENT_ITEM_ID,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
//The componentSet for the component in the content item
|
|
107
|
+
const testComponentSet: ComponentSetWebModelForCreate = {
|
|
108
|
+
webPath: COMPONENT_SET_WEB_PATH,
|
|
109
|
+
displayName: 'test-set',
|
|
110
|
+
description: 'test-set',
|
|
111
|
+
headers: {},
|
|
112
|
+
components: {},
|
|
113
|
+
componentVersionRules: {
|
|
114
|
+
[`${COMPONENT_NAMESPACE}/${COMPONENT_NAME}`]: {
|
|
115
|
+
renderableVersionPattern: '1.0.0',
|
|
116
|
+
editableVersions: [],
|
|
117
|
+
excludedVersions: [],
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
describe('PageRenderController- Integration', () => {
|
|
123
|
+
const testFilesDir = path.resolve(__dirname, 'test-files');
|
|
124
|
+
beforeAll(async () => {
|
|
125
|
+
await fsp.rm(testFilesDir, { force: true, recursive: true });
|
|
126
|
+
await fsp.mkdir(testFilesDir);
|
|
127
|
+
// Component Configuration
|
|
128
|
+
await uploadTestComponent('/__components__/test-page-render', testFilesDir);
|
|
129
|
+
await addComponentSet(testComponentSet);
|
|
130
|
+
// Post component items
|
|
131
|
+
await contentService.post('content-item', componentContentItem);
|
|
132
|
+
// Post items
|
|
133
|
+
await contentService.post('content-schema', contentSchema);
|
|
134
|
+
await contentService.post('content-item', contentItem);
|
|
135
|
+
await contentService.post('page-contents', pageContents);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
afterAll(async () => {
|
|
139
|
+
await deleteContentItem(contentItem.id!);
|
|
140
|
+
await deleteContentItem(componentContentItem.id!);
|
|
141
|
+
await deleteContentSchema(COMPONENT_CONTENT_SCHEMA_NAME);
|
|
142
|
+
await deleteContentSchema(contentSchema.name);
|
|
143
|
+
await deleteComponentSet(COMPONENT_SET_WEB_PATH);
|
|
144
|
+
await deleteComponents(await getTestComponent(COMPONENT_NAME));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should render a page', async () => {
|
|
148
|
+
const page = await pageRenderService.get(`p/${PAGE_CONTENT_ID}`);
|
|
149
|
+
expect(page.data).toEqual('<h1>Hello World!</h1><div>component-html</div><p>Bottom text</p>');
|
|
150
|
+
});
|
|
151
|
+
});
|