Skip to content

Commit 06cb2dc

Browse files
Added support for preview token and optimize the create method
1 parent e09bd18 commit 06cb2dc

File tree

10 files changed

+277
-14
lines changed

10 files changed

+277
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
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+
26
## [v1.21.4](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.4) (2025-06-02)
37
- Enhancement
48
- Retry Logic modification on x-ratelimit-remaining Header

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: 19 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,23 @@ 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+
}
79+
6280
} else {
6381
/**
6482
* @description The Create a DeliveryToken call creates a new deliveryToken in a particular stack of your Contentstack account.
@@ -84,7 +102,7 @@ export function DeliveryToken (http, data = {}) {
84102
* client.stack().deliveryToken().create({ token })
85103
* .then((deliveryToken) => console.log(deliveryToken))
86104
*/
87-
this.create = create({ http: http, createWithPreviewToken: true })
105+
this.create = create({ http: http })
88106

89107
/**
90108
* @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+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/management",
3-
"version": "1.21.4",
3+
"version": "1.21.5",
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",
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { expect } from 'chai'
2+
import { describe, it, setup } from 'mocha'
3+
import { jsonReader } from '../utility/fileOperations/readwrite'
4+
import { createDeliveryToken3 } from '../mock/deliveryToken.js'
5+
import { contentstackClient } from '../utility/ContentstackClient.js'
6+
import dotenv from 'dotenv'
7+
8+
dotenv.config();
9+
let client = {};
10+
11+
let tokenUID = "";
12+
describe("Preview Token api Test", () => {
13+
setup(() => {
14+
const user = jsonReader("loggedinuser.json");
15+
client = contentstackClient(user.authtoken);
16+
});
17+
18+
it("should add a Delivery Token for development", (done) => {
19+
makeDeliveryToken()
20+
.create(createDeliveryToken3)
21+
.then((token) => {
22+
tokenUID = token.uid
23+
expect(token.name).to.be.equal(createDeliveryToken3.token.name);
24+
expect(token.description).to.be.equal(
25+
createDeliveryToken3.token.description
26+
);
27+
expect(token.scope[0].environments[0].name).to.be.equal(
28+
createDeliveryToken3.token.scope[0].environments[0]
29+
);
30+
expect(token.scope[0].module).to.be.equal(
31+
createDeliveryToken3.token.scope[0].module
32+
);
33+
expect(token.uid).to.be.not.equal(null);
34+
expect(token.preview_token).to.be.not.equal(null);
35+
done();
36+
})
37+
.catch(done);
38+
});
39+
40+
it("should add a Preview Token", (done) => {
41+
makePreviewToken(tokenUID)
42+
.create()
43+
.then((token) => {
44+
expect(token.name).to.be.equal(createDeliveryToken3.token.name);
45+
expect(token.description).to.be.equal(
46+
createDeliveryToken3.token.description
47+
);
48+
expect(token.scope[0].environments[0].name).to.be.equal(
49+
createDeliveryToken3.token.scope[0].environments[0]
50+
);
51+
expect(token.scope[0].module).to.be.equal(
52+
createDeliveryToken3.token.scope[0].module
53+
);
54+
expect(token.uid).to.be.not.equal(null);
55+
expect(token.preview_token).to.be.not.equal(null);
56+
done();
57+
})
58+
.catch(done);
59+
});
60+
61+
it("should delete a Preview Token from uid", (done) => {
62+
makePreviewToken(tokenUID)
63+
.delete()
64+
.then((data) => {
65+
expect(data.notice).to.be.equal("Preview token deleted successfully.");
66+
done();
67+
})
68+
.catch(done);
69+
});
70+
71+
it("should delete a Delivery Token from uid", (done) => {
72+
makeDeliveryToken(tokenUID)
73+
.delete()
74+
.then((data) => {
75+
expect(data.notice).to.be.equal("Delivery Token deleted successfully.");
76+
done();
77+
})
78+
.catch(done);
79+
});
80+
});
81+
82+
function makePreviewToken(uid = null) {
83+
return client
84+
.stack({ api_key: process.env.API_KEY })
85+
.deliveryToken(uid)
86+
.previewToken();
87+
}
88+
89+
function makeDeliveryToken(uid = null) {
90+
return client.stack({ api_key: process.env.API_KEY }).deliveryToken(uid);
91+
}

test/sanity-check/mock/deliveryToken.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,31 @@ const createDeliveryToken2 = {
7070
]
7171
}
7272
}
73+
const createDeliveryToken3 = {
74+
token: {
75+
name: 'preview token test',
76+
description: 'This is a demo token.',
77+
scope: [
78+
{
79+
module: 'environment',
80+
environments: [
81+
'development'
82+
],
83+
acl: {
84+
read: true
85+
}
86+
},
87+
{
88+
module: 'branch',
89+
branches: [
90+
'main',
91+
],
92+
acl: {
93+
read: true
94+
}
95+
}
96+
]
97+
}
98+
}
7399

74-
export { createDeliveryToken, createDeliveryToken2 }
100+
export { createDeliveryToken, createDeliveryToken2, createDeliveryToken3 }
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { AnyProperty, SystemFields } from "../../utility/fields";
2+
import { Creatable, SystemFunction } from "../../utility/operations";
3+
4+
// Main preview token interface
5+
export interface PreviewToken
6+
extends SystemFields,
7+
Creatable<PreviewToken, PreviewToken>,
8+
SystemFunction<PreviewToken> {
9+
name: string;
10+
description: string;
11+
scope: Scope[];
12+
uid: string;
13+
created_by: string;
14+
updated_by: string;
15+
created_at: string;
16+
updated_at: string;
17+
token: string;
18+
type: string;
19+
preview_token: string;
20+
}
21+
22+
// API response shape for creating a preview token
23+
export interface PreviewTokenResponse {
24+
notice: string;
25+
token: PreviewTokenData;
26+
}
27+
28+
// Data inside the response `token`
29+
export interface PreviewTokenData extends AnyProperty {
30+
name: string;
31+
description: string;
32+
scope: Scope[];
33+
uid: string;
34+
created_by: string;
35+
updated_by: string;
36+
created_at: string;
37+
updated_at: string;
38+
token: string;
39+
type: string;
40+
preview_token: string;
41+
}
42+
43+
export interface Scope {
44+
module: string;
45+
environments?: Environment[];
46+
branches?: string[];
47+
locales?: string[];
48+
acl: ACL;
49+
_metadata?: {
50+
uid: string;
51+
};
52+
}
53+
54+
export interface Environment extends AnyProperty {
55+
name: string;
56+
uid: string;
57+
urls?: UrlLocale[];
58+
_version?: number;
59+
app_user_object_uid?: string;
60+
created_by?: string;
61+
updated_by?: string;
62+
created_at?: string;
63+
updated_at?: string;
64+
ACL?: unknown[];
65+
tags?: string[];
66+
}
67+
68+
export interface UrlLocale {
69+
url: string;
70+
locale: string;
71+
}
72+
73+
export interface ACL extends AnyProperty {
74+
read?: boolean;
75+
write?: boolean;
76+
create?: boolean;
77+
update?: boolean;
78+
}

types/stack/index.d.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ export interface Stack extends SystemFields {
6666
globalField(options: object): GlobalFields;
6767
globalField(uidOrOptions?: string | object, option?: object): GlobalFields | GlobalField;
6868

69-
70-
71-
7269
asset(): Assets
7370
asset(uid: string): Asset
7471

0 commit comments

Comments
 (0)