@squiz/component-cli-lib 1.39.1-alpha.24 → 1.39.1-alpha.26

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.
@@ -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>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/component-cli-lib",
3
- "version": "1.39.1-alpha.24",
3
+ "version": "1.39.1-alpha.26",
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.24",
17
- "@squiz/component-web-api-lib": "1.39.1-alpha.24",
18
- "@squiz/dx-common-lib": "1.39.1-alpha.24",
19
- "@squiz/dx-json-schema-lib": "1.39.1-alpha.24",
20
- "@squiz/dx-logger-lib": "1.39.1-alpha.24",
21
- "@squiz/virus-scanner-lib": "1.39.1-alpha.24",
16
+ "@squiz/component-lib": "1.39.1-alpha.26",
17
+ "@squiz/component-web-api-lib": "1.39.1-alpha.26",
18
+ "@squiz/dx-common-lib": "1.39.1-alpha.26",
19
+ "@squiz/dx-json-schema-lib": "1.39.1-alpha.26",
20
+ "@squiz/dx-logger-lib": "1.39.1-alpha.26",
21
+ "@squiz/virus-scanner-lib": "1.39.1-alpha.26",
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.24",
35
+ "@squiz/render-runtime-lib": "1.39.1-alpha.26",
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": "8e4a8fcb0500763656aff431e30309f206cc8223"
42
+ "gitHead": "bdd4622954e79f527bbccd49667379d4f0b0bd8e"
43
43
  }
@@ -0,0 +1,3 @@
1
+ module.exports = async function (input, info) {
2
+ return `<div>component-html</div>`;
3
+ };
@@ -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 DXP_COMPONENTS_SERVICE_NAME = 'dxpComponents';
46
- const DXP_CONTENT_STORE_SERVICE_NAME = 'dxpContentStore';
47
-
48
- const validToken = {
49
- organisationId: 'aa',
50
- permission: '',
51
- tenant: configObj.tenantId,
52
- tenantId: 'zz',
53
- userId: 'zz',
54
-
55
- service: {
56
- [DXP_COMPONENTS_SERVICE_NAME]: {
57
- privileges: [
58
- 'COMPONENT_DEPLOY',
59
- 'COMPONENT_DELETE',
60
- 'COMPONENT_READ',
61
- 'COMPONENT_SET_RULES_READ',
62
- 'COMPONENT_SET_RULES_WRITE',
63
-
64
- 'COMPONENT_SET_READ',
65
- 'COMPONENT_SET_WRITE',
66
-
67
- 'COMPONENT_SET_ENVIRONMENT_READ',
68
- 'COMPONENT_SET_ENVIRONMENT_WRITE',
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
- [DXP_CONTENT_STORE_SERVICE_NAME]: {
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
+ });