Skip to content

Commit 7188ce8

Browse files
Merge pull request #368 from contentstack/development
Development
2 parents 68bb5e4 + e8b7f3e commit 7188ce8

File tree

13 files changed

+377
-85
lines changed

13 files changed

+377
-85
lines changed

.talismanrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ fileignoreconfig:
1717
- filename: test/sanity-check/api/stack-test.js
1818
checksum: 198d5cf7ead33b079249dc3ecdee61a9c57453e93f1073ed0341400983e5aa53
1919
version: "1.0"
20+
fileignoreconfig:
21+
- filename: test/sanity-check/api/previewToken-test.js
22+
checksum: 9a42e079b7c71f76932896a0d2390d86ac626678ab20d36821dcf962820a886c
23+
- filename: lib/stack/deliveryToken/index.js
24+
checksum: 51ae00f07f4cc75c1cd832b311c2e2482f04a8467a0139da6013ceb88fbdda2f
25+
- filename: lib/stack/deliveryToken/previewToken/index.js
26+
checksum: b506f33bffdd20dfc701f964370707f5d7b28a2c05c70665f0edb7b3c53c165b
27+
version: "1.0"

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
# Changelog
2+
## [v1.21.5](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.5) (2025-06-09)
3+
- Enhancement
4+
- Preview token support added
5+
6+
## [v1.21.4](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.4) (2025-06-02)
7+
- Enhancement
8+
- Retry Logic modification on x-ratelimit-remaining Header
9+
210
## [v1.21.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.3) (2025-05-26)
311
- Enhancement
412
- Update addSettings Method to Support Generic Stack Settings Update

lib/core/concurrency-queue.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ export function ConcurrencyQueue ({ axios, config }) {
229229
if (!this.config.retryOnError || networkError > this.config.retryLimit) {
230230
return Promise.reject(responseHandler(error))
231231
}
232+
// Check rate limit remaining header before retrying
232233

233234
// Error handling
234235
const wait = this.config.retryDelay
@@ -244,19 +245,26 @@ export function ConcurrencyQueue ({ axios, config }) {
244245
} else {
245246
return Promise.reject(responseHandler(error))
246247
}
247-
} else if ((response.status === 401 && this.config.refreshToken)) {
248-
retryErrorType = `Error with status: ${response.status}`
249-
networkError++
250-
251-
if (networkError > this.config.retryLimit) {
248+
} else {
249+
const rateLimitRemaining = response.headers['x-ratelimit-remaining']
250+
if (rateLimitRemaining !== undefined && parseInt(rateLimitRemaining) <= 0) {
252251
return Promise.reject(responseHandler(error))
253252
}
254-
this.running.shift()
255-
// Cool down the running requests
256-
delay(wait, response.status === 401)
257-
error.config.retryCount = networkError
258-
// deepcode ignore Ssrf: URL is dynamic
259-
return axios(updateRequestConfig(error, retryErrorType, wait))
253+
254+
if ((response.status === 401 && this.config.refreshToken)) {
255+
retryErrorType = `Error with status: ${response.status}`
256+
networkError++
257+
258+
if (networkError > this.config.retryLimit) {
259+
return Promise.reject(responseHandler(error))
260+
}
261+
this.running.shift()
262+
// Cool down the running requests
263+
delay(wait, response.status === 401)
264+
error.config.retryCount = networkError
265+
// deepcode ignore Ssrf: URL is dynamic
266+
return axios(updateRequestConfig(error, retryErrorType, wait))
267+
}
260268
}
261269
if (this.config.retryCondition && this.config.retryCondition(error)) {
262270
retryErrorType = error.response ? `Error with status: ${response.status}` : `Error Code:${error.code}`

lib/entity.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,20 @@ export const upload = async ({ http, urlPath, stackHeaders, formData, params, me
8585
}
8686
}
8787

88-
export const create = ({ http, params = {}, createWithPreviewToken = false }) => {
88+
export const create = ({ http, params }) => {
8989
return async function (data, param) {
9090
this.stackHeaders = {
9191
...this.stackHeaders
9292
}
93-
const queryParams = {
94-
...(createWithPreviewToken ? { create_with_preview_token: true } : {}),
95-
...cloneDeep(param) // user param can override default
96-
}
93+
9794
const headers = {
9895
headers: {
9996
...cloneDeep(params),
10097
...cloneDeep(this.stackHeaders)
10198
},
102-
params: queryParams
99+
params: {
100+
...cloneDeep(param)
101+
}
103102
} || {}
104103

105104
try {

lib/stack/deliveryToken/index.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import cloneDeep from 'lodash/cloneDeep'
22
import { create, update, deleteEntity, fetch, query } from '../../entity'
3+
import { PreviewToken } from './previewToken'
34

45
/**
56
* Delivery tokens provide read-only access to the associated environments. Read more about <a href='https://www.contentstack.com/docs/developers/create-tokens/about-delivery-tokens'>DeliveryToken</a>.
@@ -59,6 +60,22 @@ export function DeliveryToken (http, data = {}) {
5960
*
6061
*/
6162
this.fetch = fetch(http, 'token')
63+
64+
/**
65+
* @description The Create a PreviewToken call creates a new previewToken in a particular stack of your Contentstack account.
66+
* @memberof DeliveryToken
67+
* @func previewToken
68+
* @returns {PreviewToken} Instance of PreviewToken.
69+
* @example
70+
* import * as contentstack from '@contentstack/management'
71+
* const client = contentstack.client()
72+
* const deliveryToken = client.stack({ api_key: 'api_key'}).deliveryToken('delivery_token_uid')
73+
* const previewToken = deliveryToken.previewToken()
74+
* console.log(previewToken)
75+
*/
76+
this.previewToken = () => {
77+
return new PreviewToken(http, { stackHeaders: this.stackHeaders, token: { uid: this.uid } })
78+
}
6279
} else {
6380
/**
6481
* @description The Create a DeliveryToken call creates a new deliveryToken in a particular stack of your Contentstack account.
@@ -84,7 +101,7 @@ export function DeliveryToken (http, data = {}) {
84101
* client.stack().deliveryToken().create({ token })
85102
* .then((deliveryToken) => console.log(deliveryToken))
86103
*/
87-
this.create = create({ http: http, createWithPreviewToken: true })
104+
this.create = create({ http: http })
88105

89106
/**
90107
* @description The ‘Get all deliveryToken’ request returns comprehensive information about all deliveryToken created in a stack.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import cloneDeep from 'lodash/cloneDeep'
2+
import { create, deleteEntity } from '../../../entity'
3+
4+
/**
5+
* Preview tokens provide read-only access to the associated environments. Read more about <a href='https://www.contentstack.com/docs/developers/create-tokens/about-preview-tokens'>PreviewToken</a>.
6+
* @namespace PreviewToken
7+
*/
8+
export function PreviewToken (http, data = {}) {
9+
this.stackHeaders = data.stackHeaders
10+
if (data.token) {
11+
Object.assign(this, cloneDeep(data.token))
12+
this.urlPath = `/stacks/delivery_tokens/${this.uid}/preview_token`
13+
14+
/**
15+
* @description The Delete PreviewToken call is used to delete an existing PreviewToken permanently from your Stack.
16+
* @memberof PreviewToken
17+
* @func delete
18+
* @returns {Object} Response Object.
19+
* @example
20+
* import * as contentstack from '@contentstack/management'
21+
* const client = contentstack.client()
22+
*
23+
* client.stack({ api_key: 'api_key'}).deliveryToken('delivery_token_uid').previewToken().delete()
24+
* .then((response) => console.log(response.notice))
25+
*/
26+
this.delete = deleteEntity(http)
27+
28+
/**
29+
* @description The Create a PreviewToken call creates a new previewToken in a particular stack of your Contentstack account.
30+
* @memberof PreviewToken
31+
* @func create
32+
* @returns {Promise<PreviewToken.PreviewToken>} Promise for PreviewToken instance
33+
*
34+
* @example
35+
* import * as contentstack from '@contentstack/management'
36+
* const client = contentstack.client()
37+
* client.stack().deliveryToken('delivery_token_uid').previewToken().create()
38+
* .then((previewToken) => console.log(previewToken))
39+
*/
40+
this.create = create({ http: http })
41+
}
42+
}
43+
44+
export function PreviewTokenCollection (http, data) {
45+
const obj = cloneDeep(data.tokens) || []
46+
const previewTokenCollection = obj.map((userdata) => {
47+
return new PreviewToken(http, { token: userdata, stackHeaders: data.stackHeaders })
48+
})
49+
return previewTokenCollection
50+
}

0 commit comments

Comments
 (0)