Skip to content

Commit 5594816

Browse files
committed
👷 Apps API implementation
1 parent 55ae2da commit 5594816

File tree

12 files changed

+773
-75
lines changed

12 files changed

+773
-75
lines changed

lib/app/index.js

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import cloneDeep from 'lodash/cloneDeep'
2+
import error from '../core/contentstackError'
3+
import { create, deleteEntity, fetch, fetchAll, update } from '../entity'
4+
export function App (http, data) {
5+
http.defaults.versioningStrategy = undefined
6+
this.urlPath = '/apps'
7+
this.params = {}
8+
if (data) {
9+
if (data.organization_uid) {
10+
this.params = {
11+
organization_uid: data.organization_uid
12+
}
13+
}
14+
if (data.data) {
15+
Object.assign(this, cloneDeep(data.data))
16+
if (this.organization_uid) {
17+
this.params = {
18+
organization_uid: this.organization_uid
19+
}
20+
}
21+
this.urlPath = `/apps/${this.uid}`
22+
23+
/**
24+
* @description The update an app call is used to update the app details such as name, description, icon, and so on.
25+
* @memberof App
26+
* @func update
27+
* @returns {Promise<App>}
28+
*
29+
* @example
30+
* import * as contentstack from '@contentstack/management'
31+
* const client = contentstack.client({ authtoken: 'TOKEN'})
32+
* const app = {
33+
* name: 'APP_NAME',
34+
* description: 'APP_DESCRIPTION',
35+
* target_type: 'stack'/'organization',
36+
* webhook: // optional
37+
* {
38+
* target_url: 'TARGET_URL',
39+
* channel: 'CHANNEL'
40+
* },
41+
* oauth: // optional
42+
* {
43+
* redirect_uri: 'REDIRECT_URI',
44+
* enabled: true,
45+
* }
46+
* }
47+
*
48+
* client.organization('organization_uid').app('app_uid').update({app})
49+
* .then((app) => console.log(app))
50+
*
51+
*/
52+
this.update = update(http, undefined, this.params)
53+
54+
/**
55+
* @description The get app details call is used to fetch details of a particular app with its ID.
56+
* @memberof App
57+
* @func fetch
58+
* @returns {Promise<App>}
59+
*
60+
* @example
61+
* import * as contentstack from '@contentstack/management'
62+
* const client = contentstack.client({ authtoken: 'TOKEN'})
63+
*
64+
* client.organization('organization_uid').app('app_uid').fetch()
65+
* .then((app) => console.log(app))
66+
*
67+
*/
68+
this.fetch = fetch(http, 'data', this.params)
69+
70+
/**
71+
* @description The delete an app call is used to delete the app.
72+
* @memberof App
73+
* @func delete
74+
* @returns {Promise<App>}
75+
*
76+
* @example
77+
* import * as contentstack from '@contentstack/management'
78+
* const client = contentstack.client({ authtoken: 'TOKEN'})
79+
*
80+
* client.organization('organization_uid').app('app_uid').delete()
81+
* .then((app) => console.log(app))
82+
*/
83+
this.delete = deleteEntity(http, false, this.params)
84+
85+
/**
86+
* @description The get oauth call is used to fetch the OAuth details of the app.
87+
* @memberof App
88+
* @func fetchOAuth
89+
* @returns {Promise<AppOAuth>}
90+
*
91+
* @example
92+
* import * as contentstack from '@contentstack/management'
93+
* const client = contentstack.client({ authtoken: 'TOKEN'})
94+
*
95+
* client.organization('organization_uid').app('app_uid').fetchOAuth()
96+
* .then((oAuthConfig) => console.log(oAuthConfig))
97+
*/
98+
this.fetchOAuth = async (param = {}) => {
99+
try {
100+
const headers = {
101+
headers: { ...cloneDeep(this.params) },
102+
params: {
103+
...cloneDeep(param)
104+
}
105+
} || {}
106+
107+
const response = await http.get(`${this.urlPath}/oauth`, headers)
108+
if (response.data) {
109+
return response.data.data || {}
110+
} else {
111+
throw error(response)
112+
}
113+
} catch (err) {
114+
throw error(err)
115+
}
116+
}
117+
118+
/**
119+
* @description The change oauth details call is used to update the OAuth details, (redirect url and permission scope) of an app.
120+
* @memberof App
121+
* @func updateOAuth
122+
* @returns {Promise<AppOAuth>}
123+
*
124+
* @example
125+
* import * as contentstack from '@contentstack/management'
126+
* const client = contentstack.client({ authtoken: 'TOKEN'})
127+
* const config = {
128+
* redirect_uri: 'REDIRECT_URI',
129+
* app_token_config: {
130+
* enabled: true,
131+
* scopes: ['scope1', 'scope2']
132+
* },
133+
* user_token_config: {
134+
* enabled: true,
135+
* scopes: ['scope1', 'scope2']
136+
* }
137+
* }
138+
* client.organization('organization_uid').app('app_uid').updateOAuth({ config })
139+
* .then((oAuthConfig) => console.log(oAuthConfig))
140+
*/
141+
this.updateOAuth = async ({ config, param = {} }) => {
142+
try {
143+
const headers = {
144+
headers: { ...cloneDeep(this.params) },
145+
params: {
146+
...cloneDeep(param)
147+
}
148+
} || {}
149+
150+
const response = await http.put(`${this.urlPath}/oauth`, config, headers)
151+
if (response.data) {
152+
return response.data.data || {}
153+
} else {
154+
throw error(response)
155+
}
156+
} catch (err) {
157+
throw error(err)
158+
}
159+
}
160+
} else {
161+
/**
162+
* @description The create an app call is used for creating a new app in your Contentstack organization.
163+
* @memberof App
164+
* @func create
165+
* @returns {Promise<App>}
166+
*
167+
* @example
168+
* import * as contentstack from '@contentstack/management'
169+
* const client = contentstack.client({ authtoken: 'TOKEN'})
170+
* const app = {
171+
* name: 'APP_NAME',
172+
* description: 'APP_DESCRIPTION',
173+
* target_type: 'stack'/'organization',
174+
* webhook: // optional
175+
* {
176+
* target_url: 'TARGET_URL',
177+
* channel: 'CHANNEL'
178+
* },
179+
* oauth: // optional
180+
* {
181+
* redirect_uri: 'REDIRECT_URI',
182+
* enabled: true,
183+
* }
184+
* }
185+
*
186+
* client.organization('organization_uid').app().create(app)
187+
* .then((app) => console.log(app))
188+
*
189+
*/
190+
this.create = create({ http, params: this.params })
191+
192+
/**
193+
* @description The create an app call is used for creating a new app in your Contentstack organization.
194+
* @memberof App
195+
* @func create
196+
* @returns {Promise<App>}
197+
*
198+
* @example
199+
* import * as contentstack from '@contentstack/management'
200+
* const client = contentstack.client({ authtoken: 'TOKEN'})
201+
*
202+
* client.organization('organization_uid').app().fetchAll()
203+
* .then((app) => console.log(app))
204+
*
205+
*/
206+
this.findAll = fetchAll(http, AppCollection, this.params)
207+
}
208+
}
209+
return this
210+
}
211+
212+
export function AppCollection (http, data) {
213+
const obj = cloneDeep(data.data) || []
214+
return obj.map((appData) => {
215+
return new App(http, { data: appData, stackHeaders: data.stackHeaders })
216+
})
217+
}

lib/core/contentstackHTTPClient.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default function contentstackHttpClient (options) {
6060
if (config.basePath) {
6161
config.basePath = `/${config.basePath.split('/').filter(Boolean).join('/')}`
6262
}
63-
const baseURL = config.endpoint || `${protocol}://${hostname}:${port}${config.basePath}/${version}`
63+
const baseURL = config.endpoint || `${protocol}://${hostname}:${port}${config.basePath}/{api-version}`
6464
const axiosOptions = {
6565
// Axios
6666
baseURL,
@@ -74,10 +74,19 @@ export default function contentstackHttpClient (options) {
7474
}
7575
params.query = query
7676
return qs
77-
}
77+
},
78+
versioningStrategy: 'path'
7879
}
7980
const instance = axios.create(axiosOptions)
8081
instance.httpClientParams = options
81-
instance.concurrencyQueue = new ConcurrencyQueue({axios: instance, config})
82+
instance.concurrencyQueue = new ConcurrencyQueue({ axios: instance, config })
83+
instance.interceptors.request.use((request) => {
84+
if (request.versioningStrategy && request.versioningStrategy === 'path') {
85+
request.baseURL = request.baseURL.replace('{api-version}', version)
86+
} else {
87+
request.baseURL = request.baseURL.replace('/{api-version}', '')
88+
}
89+
return request
90+
})
8291
return instance
8392
}

lib/entity.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ export const query = ({ http, wrapperCollection }) => {
132132
}
133133
}
134134

135-
export const update = (http, type) => {
135+
export const update = (http, type, params = {}) => {
136136
return async function (param = {}) {
137-
const updateData = {}
137+
let updateData = {}
138138
const json = cloneDeep(this)
139139
delete json.stackHeaders
140140
delete json.urlPath
@@ -147,11 +147,15 @@ export const update = (http, type) => {
147147
delete json.updated_at
148148
delete json.updated_by
149149
delete json.updated_at
150-
151-
updateData[type] = json
150+
if (type) {
151+
updateData[type] = json
152+
} else {
153+
updateData = json
154+
}
152155
try {
153156
const response = await http.put(this.urlPath, updateData, { headers: {
154-
...cloneDeep(this.stackHeaders)
157+
...cloneDeep(this.stackHeaders),
158+
...cloneDeep(params)
155159
},
156160
params: {
157161
...cloneDeep(param)
@@ -168,11 +172,11 @@ export const update = (http, type) => {
168172
}
169173
}
170174

171-
export const deleteEntity = (http, force = false) => {
175+
export const deleteEntity = (http, force = false, params = {}) => {
172176
return async function (param = {}) {
173177
try {
174178
const headers = {
175-
headers: { ...cloneDeep(this.stackHeaders) },
179+
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) },
176180
params: {
177181
...cloneDeep(param)
178182
}
@@ -199,11 +203,11 @@ export const deleteEntity = (http, force = false) => {
199203
}
200204
}
201205

202-
export const fetch = (http, type) => {
206+
export const fetch = (http, type, params = {}) => {
203207
return async function (param = {}) {
204208
try {
205209
const headers = {
206-
headers: { ...cloneDeep(this.stackHeaders) },
210+
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) },
207211
params: {
208212
...cloneDeep(param)
209213
}
@@ -224,17 +228,15 @@ export const fetch = (http, type) => {
224228
}
225229
}
226230
}
227-
export const fetchAll = (http, wrapperCollection) => {
228-
return async function (params = {}) {
229-
const headers = {}
230-
if (this.stackHeaders) {
231-
headers.headers = this.stackHeaders
232-
}
233-
if (params) {
234-
headers.params = {
235-
...cloneDeep(params)
231+
export const fetchAll = (http, wrapperCollection, params = {}) => {
232+
return async function (param = {}) {
233+
const headers = {
234+
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) },
235+
params: {
236+
...cloneDeep(param)
236237
}
237-
}
238+
} || {}
239+
238240
try {
239241
const response = await http.get(this.urlPath, headers)
240242
if (response.data) {

lib/organization/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ContentstackCollection from '../contentstackCollection'
55
import { RoleCollection } from '../stack/roles'
66
import { StackCollection } from '../stack'
77
import { UserCollection } from '../user'
8+
import { App } from '../app'
89
/**
910
* Organization is the top-level entity in the hierarchy of Contentstack, consisting of stacks and stack resources, and users. Organization allows easy management of projects as well as users within the Organization. Read more about <a href='https://www.contentstack.com/docs/guide/organization'>Organizations.</a>.
1011
* @namespace Organization
@@ -202,6 +203,24 @@ export function Organization (http, data) {
202203
}
203204
}
204205
}
206+
207+
/**
208+
* @description
209+
* @memberof Organization
210+
* @func app
211+
* @param {String} uid: App uid.
212+
* @returns {App} Instance of App
213+
*
214+
* @example
215+
* import * as contentstack from '@contentstack/management'
216+
* const client = contentstack.client({ authtoken: 'TOKEN'})
217+
*
218+
* client.organization('organization_uid').app('app_uid').fetch()
219+
* .then((app) => console.log(app))
220+
*/
221+
this.app = (uid = null) => {
222+
return new App(http, uid !== null ? { data: { uid, organization_uid: this.uid } } : { organization_uid: this.uid })
223+
}
205224
} else {
206225
/**
207226
* @description The Get all organizations call lists all organizations related to the system user in the order that they were created.

lib/stack/workflow/index.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,7 @@ export function Workflow (http, data = {}) {
297297

298298
export function WorkflowCollection (http, data) {
299299
const obj = cloneDeep(data.workflows) || []
300-
const workflowCollection = obj.map((userdata) => {
301-
return new Workflow(http, { workflow: userdata, stackHeaders: data.stackHeaders })
300+
return obj.map((userData) => {
301+
return new Workflow(http, { workflow: userData, stackHeaders: data.stackHeaders })
302302
})
303-
return workflowCollection
304303
}

0 commit comments

Comments
 (0)