Skip to content

Commit 3e67a7a

Browse files
committed
feat: 🚧 hosting and deployment implementation [CS-35319]
1 parent 60f9217 commit 3e67a7a

File tree

20 files changed

+950
-56
lines changed

20 files changed

+950
-56
lines changed

.github/workflows/unit-test.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
name: Unit Test & Reports
12
on:
23
pull_request:
34
push:
@@ -17,6 +18,10 @@ jobs:
1718
uses: dorny/test-reporter@v1
1819
if: success() || failure() # run this step even if previous step failed
1920
with:
20-
name: Mocha Tests # Name of the check run which will be created
21+
name: Mocha Unit test # Name of the check run which will be created
2122
path: report.json # Path to test results
22-
reporter: mocha-json # Format of test results
23+
reporter: mocha-json # Format of test results
24+
- name: Coverage report
25+
uses: lucassabreu/comment-coverage-clover@main
26+
with:
27+
file: coverage/clover.xml

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jspm_packages/
3939
mochawesome-report/
4040
coverage/
4141
test/utility/dataFiles/
42+
report.json
4243

4344
# TypeScript v1 declaration files
4445
typings/

lib/app/hosting/deployment.js

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import cloneDeep from 'lodash/cloneDeep'
2+
import ContentstackCollection from '../../contentstackCollection'
3+
import error from '../../core/contentstackError'
4+
5+
export function Deployment (http, data, params) {
6+
http.defaults.versioningStrategy = undefined
7+
8+
if (data && data.app_uid) {
9+
this.params = params || {}
10+
this.urlPath = `/manifests/${data.app_uid}/hosting/deployments`
11+
if (data.organization_uid) {
12+
this.params = {
13+
organization_uid: data.organization_uid
14+
}
15+
}
16+
if (data.data) {
17+
Object.assign(this, cloneDeep(data.data))
18+
if (this.organization_uid) {
19+
this.params = {
20+
organization_uid: this.organization_uid
21+
}
22+
}
23+
}
24+
if (this.uid) {
25+
this.urlPath = `/manifests/${data.app_uid}/hosting/deployments/${this.uid}`
26+
/**
27+
* @descriptionThe The GET deployment call is used to get all the details of an deployment of an app
28+
* @memberof Deployment
29+
* @func fetch
30+
* @returns {Promise<Deployment>}
31+
*
32+
* @example
33+
* import * as contentstack from '@contentstack/management'
34+
* const client = contentstack.client({ authtoken: 'TOKEN'})
35+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment('deployment_uid').fetch()
36+
* .then((data) => {})
37+
*/
38+
this.fetch = async () => {
39+
try {
40+
const headers = {
41+
headers: { ...cloneDeep(this.params) }
42+
}
43+
44+
const response = await http.get(`${this.urlPath}`, headers)
45+
if (response.data) {
46+
const content = response.data.data
47+
return new Deployment(http, { data: content, app_uid: data.app_uid }, this.params)
48+
} else {
49+
throw error(response)
50+
}
51+
} catch (err) {
52+
throw error(err)
53+
}
54+
}
55+
56+
/**
57+
* @descriptionThe The list deployment logs call is used to list logs of a deployment.
58+
* @memberof Deployment
59+
* @func logs
60+
* @returns {Promise<Response>}
61+
*
62+
* @example
63+
* import * as contentstack from '@contentstack/management'
64+
* const client = contentstack.client({ authtoken: 'TOKEN'})
65+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment('deployment_uid').logs()
66+
* .then((data) => {})
67+
*/
68+
this.logs = async () => {
69+
try {
70+
const headers = {
71+
headers: { ...cloneDeep(this.params) }
72+
}
73+
74+
const response = await http.get(`${this.urlPath}/logs`, headers)
75+
if (response.data) {
76+
return response.data.data
77+
} else {
78+
throw error(response)
79+
}
80+
} catch (err) {
81+
throw error(err)
82+
}
83+
}
84+
85+
/**
86+
* @descriptionThe The create signed download url call is used to get the download url of the deployment source code.
87+
* @memberof signedDownloadUrl
88+
* @func logs
89+
* @returns {Promise<Response>}
90+
*
91+
* @example
92+
* import * as contentstack from '@contentstack/management'
93+
* const client = contentstack.client({ authtoken: 'TOKEN'})
94+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment('deployment_uid').signedDownloadUrl()
95+
* .then((data) => {})
96+
*/
97+
this.signedDownloadUrl = async () => {
98+
try {
99+
const headers = {
100+
headers: { ...cloneDeep(this.params) }
101+
}
102+
103+
const response = await http.post(`${this.urlPath}/signedDownloadUrl`, {}, headers)
104+
if (response.data) {
105+
return response.data.data
106+
} else {
107+
throw error(response)
108+
}
109+
} catch (err) {
110+
throw error(err)
111+
}
112+
}
113+
} else {
114+
/**
115+
* @descriptionThe The create hosting deployments call is used to deploy the uploaded file in hosting
116+
* @memberof Deployment
117+
* @func create
118+
* @returns {Promise<Deployment>}
119+
*
120+
* @example
121+
* import * as contentstack from '@contentstack/management'
122+
* const client = contentstack.client({ authtoken: 'TOKEN'})
123+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment().create()
124+
* .then((data) => {})
125+
*/
126+
this.create = async ({ uploadUid, fileType, withAdvancedOptions }) => {
127+
try {
128+
const headers = {
129+
headers: { ...cloneDeep(this.params) }
130+
}
131+
if (withAdvancedOptions) {
132+
headers.params = {
133+
with_advanced_options: withAdvancedOptions
134+
}
135+
}
136+
const response = await http.post(`${this.urlPath}`, { upload_uid: uploadUid, file_type: fileType }, headers)
137+
if (response.data) {
138+
const content = response.data.data
139+
return new Deployment(http, { data: content, app_uid: data.app_uid }, this.params)
140+
} else {
141+
throw error(response)
142+
}
143+
} catch (err) {
144+
throw error(err)
145+
}
146+
}
147+
148+
/**
149+
* @descriptionThe The list deployments call is used to get all the available deployments made for an app.
150+
* @memberof Deployment
151+
* @func findAll
152+
* @returns {Promise<ContentstackCollection>}
153+
*
154+
* @example
155+
* import * as contentstack from '@contentstack/management'
156+
* const client = contentstack.client({ authtoken: 'TOKEN'})
157+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment().create()
158+
* .then((data) => {})
159+
*/
160+
this.findAll = async (param = {}) => {
161+
try {
162+
const headers = {
163+
headers: { ...cloneDeep(this.params) },
164+
params: { ...cloneDeep(param) }
165+
}
166+
167+
const response = await http.get(`${this.urlPath}`, headers)
168+
if (response.data) {
169+
const content = response.data
170+
const collection = new ContentstackCollection(response, http)
171+
collection.items = DeploymentCollection(http, content, data.app_uid, this.params)
172+
return collection
173+
} else {
174+
throw error(response)
175+
}
176+
} catch (err) {
177+
throw error(err)
178+
}
179+
}
180+
}
181+
}
182+
}
183+
184+
export function DeploymentCollection (http, data, appUid, param) {
185+
const obj = cloneDeep(data.data) || []
186+
return obj.map((content) => {
187+
return new Deployment(http, { data: content, app_uid: appUid }, param)
188+
})
189+
}

lib/app/hosting/index.js

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
11
import cloneDeep from 'lodash/cloneDeep'
22
import error from '../../core/contentstackError'
3+
import { Deployment } from './deployment'
34

45
export function Hosting (http, data, params) {
56
http.defaults.versioningStrategy = undefined
67

7-
this.params = params | {}
8-
if (data) {
8+
this.params = params || {}
9+
if (data && data.app_uid) {
910
this.urlPath = `/manifests/${data.app_uid}/hosting`
1011
if (data.organization_uid) {
1112
this.params = {
1213
organization_uid: data.organization_uid
1314
}
1415
}
15-
if (data.data) {
16-
Object.assign(this, cloneDeep(data.data))
17-
if (this.organization_uid) {
18-
this.params = {
19-
organization_uid: this.organization_uid
20-
}
21-
}
22-
}
2316

2417
/**
2518
* @description The get hosting call is used to fetch to know whether the hosting is enabled or not.
@@ -37,7 +30,7 @@ export function Hosting (http, data, params) {
3730
try {
3831
const headers = {
3932
headers: { ...cloneDeep(this.params) }
40-
} || {}
33+
}
4134

4235
const response = await http.get(this.urlPath, headers)
4336
if (response.data) {
@@ -53,7 +46,7 @@ export function Hosting (http, data, params) {
5346
/**
5447
* @description The toggle hosting call is used to enable the hosting of an app.
5548
* @memberof Hosting
56-
* @func updateOAuth
49+
* @func enable
5750
* @returns {Promise<Response>}
5851
*
5952
* @example
@@ -66,9 +59,9 @@ export function Hosting (http, data, params) {
6659
try {
6760
const headers = {
6861
headers: { ...cloneDeep(this.params) }
69-
} || {}
62+
}
7063

71-
const response = await http.put(`${this.urlPath}/enable`, {}, headers)
64+
const response = await http.patch(`${this.urlPath}/enable`, {}, headers)
7265
if (response.data) {
7366
return response.data
7467
} else {
@@ -95,9 +88,9 @@ export function Hosting (http, data, params) {
9588
try {
9689
const headers = {
9790
headers: { ...cloneDeep(this.params) }
98-
} || {}
91+
}
9992

100-
const response = await http.put(`${this.urlPath}/disable`, {}, headers)
93+
const response = await http.patch(`${this.urlPath}/disable`, {}, headers)
10194
if (response.data) {
10295
return response.data
10396
} else {
@@ -124,7 +117,7 @@ export function Hosting (http, data, params) {
124117
try {
125118
const headers = {
126119
headers: { ...cloneDeep(this.params) }
127-
} || {}
120+
}
128121

129122
const response = await http.post(`${this.urlPath}/signedUploadUrl`, { }, headers)
130123
if (response.data) {
@@ -136,5 +129,58 @@ export function Hosting (http, data, params) {
136129
throw error(err)
137130
}
138131
}
132+
133+
/**
134+
* @descriptionThe The GET latest live deployment call is used to get details of latest deployment of the source file.
135+
* @memberof Hosting
136+
* @func latestLiveDeployment
137+
* @returns {Promise<Deployment>}
138+
*
139+
* @example
140+
* import * as contentstack from '@contentstack/management'
141+
* const client = contentstack.client({ authtoken: 'TOKEN'})
142+
* client.organization('organization_uid').app('manifest_uid').hosting().latestLiveDeployment()
143+
* .then((data) => {})
144+
*/
145+
this.latestLiveDeployment = async () => {
146+
try {
147+
const headers = {
148+
headers: { ...cloneDeep(this.params) }
149+
}
150+
151+
const response = await http.get(`${this.urlPath}/latestLiveDeployment`, headers)
152+
if (response.data) {
153+
const content = response.data.data
154+
return new Deployment(http, { data: content, app_uid: data.app_uid }, this.params)
155+
} else {
156+
throw error(response)
157+
}
158+
} catch (err) {
159+
throw error(err)
160+
}
161+
}
162+
163+
/**
164+
* @description Create instance of Hosting deployment.
165+
* @memberof Hosting
166+
* @func deployment
167+
* @returns {Deployment}
168+
*
169+
* @example
170+
* import * as contentstack from '@contentstack/management'
171+
* const client = contentstack.client({ authtoken: 'TOKEN'})
172+
* client.organization('organization_uid').app('manifest_uid').hosting().deployment()
173+
*
174+
*/
175+
this.deployment = (uid = null) => {
176+
const content = { app_uid: data.app_uid }
177+
if (uid) {
178+
content.data = {
179+
uid
180+
}
181+
}
182+
183+
return new Deployment(http, content, this.params)
184+
}
139185
}
140186
}

lib/app/installation/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function Installation (http, data, params = {}) {
104104
}
105105
} else {
106106
if (data.app_uid) {
107-
this.urlPath = `apps/${data.app_uid}/installations`
107+
this.urlPath = `manifests/${data.app_uid}/installations`
108108
/**
109109
* @description The find installation call is used to retrieve all installations of your Contentstack organization.
110110
* @memberof Installation

lib/contentstackCollection.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export default class ContentstackCollection {
77
if (stackHeaders) {
88
data.stackHeaders = stackHeaders
99
}
10-
this.items = wrapperCollection(http, data)
10+
if (wrapperCollection) {
11+
this.items = wrapperCollection(http, data)
12+
}
13+
1114
if (data.schema !== undefined) {
1215
this.schema = data.schema
1316
}

lib/core/contentstackError.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ export default function error (errorResponse) {
3030
}
3131

3232
if (data) {
33-
errorDetails.errorMessage = data.error_message || ''
33+
errorDetails.errorMessage = data.error_message || data.message || ''
3434
errorDetails.errorCode = data.error_code || 0
3535
errorDetails.errors = data.errors || {}
36+
errorDetails.error = data.error || ''
3637
}
3738

3839
var error = new Error()

0 commit comments

Comments
 (0)