Skip to content

Commit 747bfc7

Browse files
authored
Merge pull request #52 from contentstack/next
Feat: Branches Compare and Merge [CS-36487]
2 parents fff5f72 + 0522fd7 commit 747bfc7

File tree

20 files changed

+15469
-1162
lines changed

20 files changed

+15469
-1162
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [v1.8.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.8.0) (2023-05-11)
4+
- Feature
5+
- Branches Compare and Merge feature added.
36
## [v1.7.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.7.0) (2023-04-04)
47
- Feature
58
- Marketplace API support added.

lib/app/installation/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,4 @@ export function InstallationCollection (http, data) {
250250
return obj.map((installationData) => {
251251
return new Installation(http, { data: installationData })
252252
})
253-
}
253+
}

lib/entity.js

+22
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,25 @@ export function parseData (response, stackHeaders, contentTypeUID) {
267267
}
268268
return data
269269
}
270+
271+
export async function get (http, url, params, data) {
272+
const headers = {
273+
params: {
274+
...cloneDeep(data.branches),
275+
...cloneDeep(params)
276+
},
277+
headers: {
278+
...cloneDeep(data.stackHeaders)
279+
}
280+
} || {}
281+
try {
282+
const response = await http.get(url, headers)
283+
if (response.data) {
284+
return response.data
285+
} else {
286+
throw error(response)
287+
}
288+
} catch (err) {
289+
throw error(err)
290+
}
291+
}

lib/stack/branch/compare.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { get } from '../../entity'
2+
3+
/**
4+
*
5+
* @namespace Branch
6+
*/
7+
export function Compare (http, data = {}) {
8+
this.stackHeaders = data.stackHeaders
9+
this.urlPath = `/stacks/branches_compare`
10+
11+
/**
12+
* @description List of content types and global fields that exist in only one branch or are different between the two branches.
13+
* @memberof Compare
14+
* @func all
15+
* @returns {Promise<Response>} Promise for response.
16+
* @example
17+
* import * as contentstack from '@contentstack/management'
18+
* const client = contentstack.client()
19+
*
20+
* client.stack({ api_key: 'api_key'}).branch('branch_uid').compare('compare_branch_uid').all({skip: 0, limit: 100})
21+
* .then(response)
22+
* .catch(error)
23+
*
24+
*/
25+
this.all = async (params = {}) => {
26+
return get(http, this.urlPath, params, data)
27+
}
28+
29+
/**
30+
* @description List of all or specific content types that exist in only one branch or are different between the two branches.
31+
* @memberof Compare
32+
* @func contentTypes
33+
* @param {string} params.uid Optional uid for Content Type to compare.
34+
* @returns {Promise<Response>} Promise for response.
35+
* @example
36+
* import * as contentstack from '@contentstack/management'
37+
* const client = contentstack.client()
38+
*
39+
* client.stack({ api_key: 'api_key'}).branch('branch_uid').compare().all({skip: 0, limit: 100})
40+
* .then(response)
41+
* .catch(error)
42+
*
43+
*/
44+
this.contentTypes = async (params = {}) => {
45+
let url = `${this.urlPath}/content_types`
46+
if (params.uid) {
47+
url = `${url}/${params.uid}`
48+
delete params.uid
49+
}
50+
return get(http, url, params, data)
51+
}
52+
53+
/**
54+
* @description Compare allows you compare any or specific ContentType or GlobalFields.
55+
* @memberof Compare
56+
* @func globalFields
57+
* @param {string} params.uid Optional uid for Global Field to compare.
58+
* @returns {Promise<Response>} Promise for response.
59+
* @example
60+
* import * as contentstack from '@contentstack/management'
61+
* const client = contentstack.client()
62+
*
63+
* client.stack({ api_key: 'api_key'}).branch('branch_uid').compare().all({skip: 0, limit: 100})
64+
* .then(response)
65+
* .catch(error)
66+
*
67+
*/
68+
this.globalFields = async (params = {}) => {
69+
let url = `${this.urlPath}/global_fields`
70+
if (params.uid) {
71+
url = `${url}/${params.uid}`
72+
delete params.uid
73+
}
74+
return get(http, url, params, data)
75+
}
76+
77+
return this
78+
}

lib/stack/branch/index.js

+89-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import cloneDeep from 'lodash/cloneDeep'
22
import { create, query, fetch, deleteEntity } from '../../entity'
3+
import { Compare } from './compare'
4+
import { MergeQueue } from './mergeQueue'
5+
import error from '../../core/contentstackError'
36

47
/**
58
*
@@ -44,6 +47,29 @@ export function Branch (http, data = {}) {
4447
*
4548
*/
4649
this.fetch = fetch(http, 'branch')
50+
51+
/**
52+
* @description Compare allows you compare any or specific ContentType or GlobalFields.
53+
* @memberof Branch
54+
* @func compare
55+
* @returns {Compare} Instance of Compare.
56+
* @example
57+
* import * as contentstack from '@contentstack/management'
58+
* const client = contentstack.client()
59+
*
60+
* client.stack({ api_key: 'api_key'}).branch('branch_uid').compare('compare_uid')
61+
*
62+
*/
63+
this.compare = (compareBranchUid) => {
64+
const compareData = { stackHeaders: this.stackHeaders }
65+
if (compareBranchUid) {
66+
compareData.branches = {
67+
base_branch: this.uid,
68+
compare_branch: compareBranchUid
69+
}
70+
}
71+
return new Compare(http, compareData)
72+
}
4773
} else {
4874
/**
4975
* @description The Create a Branch call creates a new branch in a particular stack of your Contentstack account.
@@ -54,7 +80,7 @@ export function Branch (http, data = {}) {
5480
* @example
5581
* import * as contentstack from '@contentstack/management'
5682
* const client = contentstack.client()
57-
* const branch = {
83+
* const branch = {
5884
* name: 'branch_name',
5985
* source: 'master'
6086
* }
@@ -77,6 +103,68 @@ export function Branch (http, data = {}) {
77103
* .then((collection) => { console.log(collection) })
78104
*/
79105
this.query = query({ http, wrapperCollection: BranchCollection })
106+
107+
/**
108+
* @description Merge allows user to merge branches in a Stack.
109+
* @memberof Branch
110+
* @func merge
111+
* @returns {Object} Response Object
112+
*
113+
* @example
114+
* import * as contentstack from '@contentstack/management'
115+
* const client = contentstack.client()
116+
*
117+
* const params = {
118+
* base_branch: "main",
119+
* compare_branch: "dev",
120+
* default_merge_strategy: "merge_prefer_base",
121+
* merge_comment: "Merging dev into main",
122+
* no_revert: true,
123+
* }
124+
* const mergeObj = {
125+
* item_merge_strategies: [
126+
* {
127+
* uid: "global_field_uid",
128+
* type: "global_field",
129+
* merge_strategy: "merge_prefer_base"
130+
* }
131+
* ],
132+
* }
133+
*
134+
* client.stack({ api_key: 'api_key'}).branch().merge(mergeObj, params)
135+
*/
136+
this.merge = async (mergeObj, params) => {
137+
const url = '/stacks/branches_merge'
138+
const header = {
139+
headers: { ...cloneDeep(this.stackHeaders) },
140+
params: params
141+
}
142+
try {
143+
const response = await http.post(url, mergeObj, header)
144+
if (response.data) return response.data
145+
else throw error(response)
146+
} catch (e) {
147+
throw error(e)
148+
}
149+
}
150+
151+
/**
152+
* @description Merge Queue provides list of all recent merge jobs in a Stack.
153+
* @memberof Branch
154+
* @func mergeQueue
155+
* @returns {MergeQueue} Instance of MergeQueue
156+
*
157+
* @example
158+
* import * as contentstack from '@contentstack/management'
159+
* const client = contentstack.client()
160+
*
161+
* client.stack({ api_key: 'api_key'}).branch().mergeQueue()
162+
*
163+
*/
164+
this.mergeQueue = (uid) => {
165+
const mergeData = { stackHeaders: this.stackHeaders, uid }
166+
return new MergeQueue(http, mergeData)
167+
}
80168
}
81169
return this
82170
}

lib/stack/branch/mergeQueue.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { get } from '../../entity'
2+
3+
export function MergeQueue (http, data = {}) {
4+
this.stackHeaders = data.stackHeaders
5+
this.urlPath = `/stacks/branches_queue`
6+
7+
if (data.uid) {
8+
/**
9+
* @description Fetch function gets the status of a merge job and it's configuration details.
10+
* @memberof MergeQueue
11+
* @func fetch
12+
* @returns {Promise<Response>} Promise for response.
13+
* @example
14+
* import * as contentstack from '@contentstack/management'
15+
* const client = contentstack.client()
16+
*
17+
* client.stack({ api_key: 'api_key'}).branch().mergeQueue('UID').fetch()
18+
* .then(response)
19+
* .catch(error)
20+
*
21+
*/
22+
this.fetch = async () => {
23+
const url = `${this.urlPath}/${data.uid}`
24+
return get(http, url, {}, data)
25+
}
26+
} else {
27+
/**
28+
* @description Find function lists all recent merge jobs.
29+
* @memberof MergeQueue
30+
* @func find
31+
* @returns {Promise<Response>} Promise for response.
32+
* @example
33+
* import * as contentstack from '@contentstack/management'
34+
* const client = contentstack.client()
35+
*
36+
* client.stack({ api_key: 'api_key'}).branch().mergeQueue().find()
37+
* .then(response)
38+
* .catch(error)
39+
*
40+
*/
41+
this.find = async (params = {}) => {
42+
return get(http, this.urlPath, params, data)
43+
}
44+
}
45+
46+
return this
47+
}

lib/stack/bulkOperation/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function BulkOperation (http, data = {}) {
6969
* .then((response) => { console.log(response.notice) })
7070
*
7171
*/
72-
this.publish = async ({ details, skip_workflow_stage = false, approvals = false, is_nested = false }) => {
72+
this.publish = async ({ details, skip_workflow_stage = false, approvals = false, is_nested = false, api_version = '' }) => {
7373
var httpBody = {}
7474
if (details) {
7575
httpBody = cloneDeep(details)
@@ -91,6 +91,9 @@ export function BulkOperation (http, data = {}) {
9191
if (approvals) {
9292
headers.headers.approvals = approvals
9393
}
94+
95+
if (api_version) headers.headers.api_version = api_version
96+
9497
return publishUnpublish(http, '/bulk/publish', httpBody, headers)
9598
}
9699

@@ -153,7 +156,7 @@ export function BulkOperation (http, data = {}) {
153156
* client.stack({ api_key: 'api_key'}).bulkOperation().unpublish({ details: publishDetails, is_nested: true })
154157
* .then((response) => { console.log(response.notice) })
155158
*/
156-
this.unpublish = async ({ details, skip_workflow_stage = false, approvals = false, is_nested = false}) => {
159+
this.unpublish = async ({ details, skip_workflow_stage = false, approvals = false, is_nested = false, api_version = ''}) => {
157160
var httpBody = {}
158161
if (details) {
159162
httpBody = cloneDeep(details)
@@ -175,6 +178,7 @@ export function BulkOperation (http, data = {}) {
175178
if (approvals) {
176179
headers.headers.approvals = approvals
177180
}
181+
if (api_version) headers.headers.api_version = api_version
178182
return publishUnpublish(http, '/bulk/unpublish', httpBody, headers)
179183
}
180184

0 commit comments

Comments
 (0)