Skip to content

Commit d1641b1

Browse files
authored
Merge pull request #25 from contentstack/bugs/entry-workflow-stage
Entry workflow stage, Asset Download
2 parents 55ae2da + 618bf1e commit d1641b1

File tree

23 files changed

+362
-45
lines changed

23 files changed

+362
-45
lines changed

.github/workflows/npm-publish.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# This workflow will publish a package to GitHub Packages when a release is created
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3+
4+
name: Publish package to NPM repository
5+
on:
6+
release:
7+
types: [created]
8+
9+
jobs:
10+
publish-npm:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- uses: actions/setup-node@v3
15+
with:
16+
node-version: '12.x'
17+
registry-url: 'https://registry.npmjs.org'
18+
- run: npm ci
19+
- run: npm publish
20+
env:
21+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
22+
publish-git:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v3
26+
- uses: actions/setup-node@v3
27+
with:
28+
node-version: '12.x'
29+
registry-url: 'https://npm.pkg.github.com'
30+
scope: '@contentstack'
31+
- run: npm ci
32+
- run: npm publish
33+
env:
34+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.npmignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ docdash-template/
2222
.babel-preset.js
2323
.eslintrc.js
2424
.talismanrc
25-
lib/
25+
lib/
26+
.github

lib/contentstack.js

+13
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ import httpClient from './core/contentstackHTTPClient.js'
3434
* import * as contentstack from '@contentstack/management'
3535
* const client = contentstack.client({ headers: { 'headerkey': 'value'} })
3636
*
37+
* @prop {string=} params.authtoken - Optional Authtoken is a read-write token used to make authorized CMA requests, but it is a user-specific token.
38+
* @example //Set the `authtoken`
39+
* import * as contentstack from '@contentstack/management'
40+
* const client = contentstack.client({ authtoken: 'value' })
41+
*
42+
* @prop {string=} params.authorization - Optional authorization token is a read-write token used to make authorized CMA requests, but it is a user-specific token.
43+
* @example //Set the `authorization`
44+
* import * as contentstack from '@contentstack/management'
45+
* const client = contentstack.client({ authorization: 'Bearer <token_value>' })
46+
*
3747
* @prop {number=} params.timeout - Optional number of milliseconds before the request times out. Default is 30000ms
3848
* @example //Set the `timeout` to 50000ms
3949
* import * as contentstack from '@contentstack/management'
@@ -132,6 +142,9 @@ export function client (params = {}) {
132142
if (params.authtoken) {
133143
requiredHeaders.authtoken = params.authtoken
134144
}
145+
if (params.authorization) {
146+
requiredHeaders.authorization = params.authorization
147+
}
135148
params = {
136149
...defaultParameter,
137150
...clonedeep(params)

lib/stack/asset/index.js

+42-1
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,52 @@ export function Asset (http, data = {}) {
217217
* import * as contentstack from '@contentstack/management'
218218
* const client = contentstack.client()
219219
*
220-
* client.stack().asset().query({ query: { filename: 'Asset Name' } }).find()
220+
* client.stack({ api_key: 'api_key'}).asset().query({ query: { filename: 'Asset Name' } }).find()
221221
* .then((asset) => console.log(asset))
222222
*/
223223
this.query = query({ http: http, wrapperCollection: AssetCollection })
224224
}
225+
/**
226+
* @description The Download function will get downloadable file in specified format.
227+
* @memberof Asset
228+
* @func download
229+
* @returns {Array<AssetResponse>} Array of Asset.
230+
* @param {*} param.url The url for the asset to download
231+
* @param {*} param.responseType Optional parameter to specify the response type.
232+
* @example
233+
*
234+
* import * as contentstack from '@contentstack/management'
235+
* const client = contentstack.client()
236+
*
237+
* client.stack({ api_key: 'api_key'}).asset('uid').fetch()
238+
* .then((asset) => asset.download({responseType: 'blob'}))
239+
* .then((response) => // Write response data to destination file. )
240+
* @example
241+
*
242+
* import * as contentstack from '@contentstack/management'
243+
* const client = contentstack.client()
244+
*
245+
* client.stack({ api_key: 'api_key'}).asset().download({url: 'asset_url_to_download', responseType: 'blob'})
246+
* .then((response) => // Write response data to destination file. )
247+
*/
248+
this.download = async function ({ url, responseType, params }) {
249+
try {
250+
const headers = {
251+
headers: {
252+
...params,
253+
...cloneDeep(this.stackHeaders)
254+
},
255+
responseType
256+
} || { responseType }
257+
const requestUrl = url || this.url
258+
if (!requestUrl || requestUrl === undefined) {
259+
throw new Error('Asset URL can not be empty')
260+
}
261+
return http.get(requestUrl, headers)
262+
} catch (err) {
263+
throw error(err)
264+
}
265+
}
225266
return this
226267
}
227268

lib/stack/contentType/entry/index.js

+87-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ export function Entry (http, data) {
5858
* })
5959
* .then((entry) => console.log(entry))
6060
*
61+
* @example
62+
* // To update entry with asset field
63+
* import * as contentstack from '@contentstack/management'
64+
* const client = contentstack.client()
65+
*
66+
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').fetch()
67+
* .then((entry) => {
68+
* entry.title = 'My New Entry'
69+
* entry.file = entry.file.uid // for single asset pass asset uid to entry asset field value
70+
* entry.multiple_file = ['asset_uid_1', 'asset_uid_2'] // for multiple asset pass array of asset uid to entry asset field values
71+
* return entry.update({ locale: 'en-at' })
72+
* })
73+
* .then((entry) => console.log(entry))
74+
*
75+
* @example
76+
* // To update entry with reference field
77+
* import * as contentstack from '@contentstack/management'
78+
* const client = contentstack.client()
79+
*
80+
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').fetch()
81+
* .then((entry) => {
82+
* entry.title = 'My New Entry'
83+
* entry.reference = entry.reference.uid // for single reference pass reference uid to entry reference field value
84+
* entry.multiple_reference = ['reference_uid_1', 'reference_uid_2'] // for multiple reference pass array of reference uid to entry reference field values
85+
* entry.multiple_content_type_reference = [{_content_type_uid: 'content_type_uid_1', uid: 'reference_uid_1'}, {_content_type_uid: 'content_type_uid_2', uid: 'reference_uid_2'}] // for multiple reference pass array of reference uid to entry reference field values
86+
* return entry.update({ locale: 'en-at' })
87+
* })
88+
* .then((entry) => console.log(entry))
6189
*/
6290
this.update = update(http, 'entry')
6391

@@ -185,6 +213,58 @@ export function Entry (http, data) {
185213
throw error(err)
186214
}
187215
}
216+
217+
/**
218+
* @description The Set Entry Workflow Stage request allows you to either set a particular workflow stage of an entry or update the workflow stage details of an entry.
219+
* @memberof Entry
220+
* @func setWorkflowStage
221+
* @returns {Promise<Object>} Response Object.
222+
* @param {Object} publishing_rule Details for the publish request
223+
* @param {String} locale Enter the code of the locale that the entry belongs to.
224+
* @example
225+
* import * as contentstack from '@contentstack/management'
226+
* const client = contentstack.client()
227+
*
228+
* const workflow_stage = {
229+
* "comment": "Workflow Comment",
230+
* "due_date": "Thu Dec 01 2018",
231+
* "notify": false,
232+
* "uid": "workflow_stage_uid",
233+
* "assigned_to": [{
234+
* "uid": "user_uid",
235+
* "name": "Username",
236+
* "email": "user_email_id"
237+
* }],
238+
* "assigned_by_roles": [{
239+
* "uid": "role_uid",
240+
* "name": "Role name"
241+
* }]
242+
* }
243+
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').setWorkflowStage({ workflow_stage, locale: 'en-us'})
244+
* .then((response) => console.log(response.notice));
245+
*/
246+
this.setWorkflowStage = async ({ workflow_stage, locale }) => {
247+
const publishDetails = {
248+
workflow: { workflow_stage }
249+
}
250+
const headers = {}
251+
if (this.stackHeaders) {
252+
headers.headers = this.stackHeaders
253+
}
254+
headers.params = {
255+
locale
256+
}
257+
try {
258+
const response = await http.post(`${this.urlPath}/workflow`, publishDetails, headers)
259+
if (response.data) {
260+
return response.data
261+
} else {
262+
throw error(response)
263+
}
264+
} catch (err) {
265+
throw error(err)
266+
}
267+
}
188268
} else {
189269
/**
190270
* @description The Create an entry call creates a new entry for the selected content type.
@@ -197,7 +277,12 @@ export function Entry (http, data) {
197277
* const client = contentstack.client()
198278
* const entry = {
199279
* title: 'Sample Entry',
200-
* url: '/sampleEntry'
280+
* url: '/sampleEntry',
281+
* file: 'asset_uid', // for single asset pass asset uid to entry asset field value
282+
* multiple_file = ['asset_uid_1', 'asset_uid_2'], // for multiple asset pass array of asset uid to entry asset field values
283+
* reference: reference.uid, // for single reference pass reference uid to entry reference field value
284+
* multiple_reference: ['reference_uid_1', 'reference_uid_2'], // for multiple reference pass array of reference uid to entry reference field values
285+
* multiple_content_type_reference: [{_content_type_uid: 'content_type_uid_1', uid: 'reference_uid_1'}, {_content_type_uid: 'content_type_uid_2', uid: 'reference_uid_2'}] // for multiple reference pass array of reference uid to entry reference field values
201286
* }
202287
* client.stack().contentType('content_type_uid').entry().create({ entry })
203288
* .then((entry) => console.log(entry))
@@ -239,7 +324,7 @@ export function Entry (http, data) {
239324
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry()
240325
* .import({
241326
* entry: 'path/to/file.json',
242-
* overright: true
327+
* overwrite: true
243328
* })
244329
* .then((entry) => console.log(entry))
245330
*

lib/stack/index.js

+37
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,43 @@ export function Stack (http, data) {
434434
}
435435
}
436436

437+
/**
438+
* @description The Update User Role API Request updates the roles of an existing user account.
439+
* This API Request will override the existing roles assigned to a user
440+
* @memberof Stack
441+
* @func updateUsersRoles
442+
* @param {*} users object containing userId and array of roles to assign user.
443+
* @returns {Object} Response Object.
444+
* @example
445+
* import * as contentstack from '@contentstack/management'
446+
* const client = contentstack.client()
447+
* const users = {
448+
* user_uid: ['role_uid_1', 'role_uid_2' ]
449+
* }
450+
*
451+
* client.stack({ api_key: 'api_key'}).updateUsersRoles(users)
452+
* .then((response) => console.log(response.notice))
453+
*
454+
*/
455+
this.updateUsersRoles = async (users) => {
456+
try {
457+
const response = await http.post(`${this.urlPath}/users/roles`,
458+
{ users },
459+
{
460+
headers: {
461+
...cloneDeep(this.stackHeaders)
462+
}
463+
})
464+
if (response.data) {
465+
return UserCollection(http, response.data.stack)
466+
} else {
467+
return error(response)
468+
}
469+
} catch (err) {
470+
return error(err)
471+
}
472+
}
473+
437474
/**
438475
* @description The Transfer stack ownership to other users call sends the specified user an email invitation for accepting the ownership of a particular stack.
439476
* @memberof Stack

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/management",
3-
"version": "1.3.1",
3+
"version": "1.4.0",
44
"description": "The Content Management API is used to manage the content of your Contentstack account",
55
"main": "./dist/node/contentstack-management.js",
66
"browser": "./dist/web/contentstack-management.js",

test/api/asset-test.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path'
22
import { expect } from 'chai'
33
import { describe, it, setup } from 'mocha'
4-
import { jsonReader } from '../utility/fileOperations/readwrite'
4+
import { jsonReader, writeDownloadedFile } from '../utility/fileOperations/readwrite'
55
import { contentstackClient } from '../utility/ContentstackClient.js'
66

77
var client = {}
@@ -10,6 +10,7 @@ var stack = {}
1010
var folderUID = ''
1111
var assetUID = ''
1212
var publishAssetUID = ''
13+
var assetURL = ''
1314
describe('Assets api Test', () => {
1415
setup(() => {
1516
const user = jsonReader('loggedinuser.json')
@@ -27,6 +28,7 @@ describe('Assets api Test', () => {
2728
makeAsset().create(asset)
2829
.then((asset) => {
2930
assetUID = asset.uid
31+
assetURL = asset.url
3032
expect(asset.uid).to.be.not.equal(null)
3133
expect(asset.url).to.be.not.equal(null)
3234
expect(asset.filename).to.be.equal('customUpload.html')
@@ -38,6 +40,22 @@ describe('Assets api Test', () => {
3840
.catch(done)
3941
})
4042

43+
it('Download asset from URL.', done => {
44+
makeAsset().download({ url: assetURL, responseType: 'stream' })
45+
.then((response) => {
46+
writeDownloadedFile(response, 'asset1')
47+
done()
48+
}).catch(done)
49+
})
50+
it('Download asset from fetch details ', done => {
51+
makeAsset(assetUID).fetch()
52+
.then((asset) => asset.download({ responseType: 'stream' }))
53+
.then((response) => {
54+
writeDownloadedFile(response, 'asset2')
55+
done()
56+
}).catch(done)
57+
})
58+
4159
it('Create folder ', done => {
4260
makeAsset().folder().create({ asset: { name: 'Sample Folder' } })
4361
.then((asset) => {

test/typescript/asset.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from "path";
44
var assetUID = ''
55
var folderUID = ''
66
var publishAssetUID = ''
7-
7+
var assetURL = ''
88
export function createAsset(stack: Stack) {
99
describe('Asset create', () => {
1010
test('Asset Upload', done => {
@@ -17,6 +17,7 @@ export function createAsset(stack: Stack) {
1717
stack.asset().create(asset)
1818
.then((asset) => {
1919
assetUID = asset.uid
20+
assetURL = asset.url
2021
expect(asset.uid).to.be.not.equal(null)
2122
expect(asset.url).to.be.not.equal(null)
2223
expect(asset.filename).to.be.equal('customUpload.html')
@@ -67,6 +68,27 @@ export function createAsset(stack: Stack) {
6768
})
6869
}
6970

71+
export function downloadAsset(stack: Stack) {
72+
describe('Asset download', () => {
73+
test('Download asset from url', done => {
74+
stack.asset().download({url: assetURL, responseType: 'stream'})
75+
.then((_) => {
76+
done()
77+
})
78+
.catch(done)
79+
})
80+
81+
test('Download asset from uid', done => {
82+
stack.asset(assetUID).fetch()
83+
.then((asset) => asset.download({responseType: 'stream'}))
84+
.then((_) => {
85+
done()
86+
})
87+
.catch(done)
88+
})
89+
})
90+
}
91+
7092
export function replaceAsset(stack: Stack) {
7193
describe('Asset replace', () => {
7294
test('Replace Asset', done => {

0 commit comments

Comments
 (0)