diff --git a/.talismanrc b/.talismanrc
index e784c309..632d61e1 100644
--- a/.talismanrc
+++ b/.talismanrc
@@ -17,3 +17,7 @@ fileignoreconfig:
- filename: test/sanity-check/api/stack-test.js
checksum: 198d5cf7ead33b079249dc3ecdee61a9c57453e93f1073ed0341400983e5aa53
version: "1.0"
+fileignoreconfig:
+- filename: test/sanity-check/api/previewToken-test.js
+ checksum: 9a42e079b7c71f76932896a0d2390d86ac626678ab20d36821dcf962820a886c
+version: "1.0"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6b74d43c..13e1c417 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
# Changelog
+## [v1.21.5](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.5) (2025-06-09)
+ - Enhancement
+ - Preview token support added
+
## [v1.21.4](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.4) (2025-06-02)
- Enhancement
- Retry Logic modification on x-ratelimit-remaining Header
diff --git a/lib/entity.js b/lib/entity.js
index 266c10e2..8088f720 100644
--- a/lib/entity.js
+++ b/lib/entity.js
@@ -85,21 +85,20 @@ export const upload = async ({ http, urlPath, stackHeaders, formData, params, me
}
}
-export const create = ({ http, params = {}, createWithPreviewToken = false }) => {
+export const create = ({ http, params }) => {
return async function (data, param) {
this.stackHeaders = {
...this.stackHeaders
}
- const queryParams = {
- ...(createWithPreviewToken ? { create_with_preview_token: true } : {}),
- ...cloneDeep(param) // user param can override default
- }
+
const headers = {
headers: {
...cloneDeep(params),
...cloneDeep(this.stackHeaders)
},
- params: queryParams
+ params: {
+ ...cloneDeep(param)
+ }
} || {}
try {
diff --git a/lib/stack/deliveryToken/index.js b/lib/stack/deliveryToken/index.js
index 763423c9..12f8ac10 100644
--- a/lib/stack/deliveryToken/index.js
+++ b/lib/stack/deliveryToken/index.js
@@ -1,5 +1,6 @@
import cloneDeep from 'lodash/cloneDeep'
import { create, update, deleteEntity, fetch, query } from '../../entity'
+import { PreviewToken } from './previewToken'
/**
* Delivery tokens provide read-only access to the associated environments. Read more about DeliveryToken.
@@ -59,6 +60,22 @@ export function DeliveryToken (http, data = {}) {
*
*/
this.fetch = fetch(http, 'token')
+
+ /**
+ * @description The Create a PreviewToken call creates a new previewToken in a particular stack of your Contentstack account.
+ * @memberof DeliveryToken
+ * @func previewToken
+ * @returns {PreviewToken} Instance of PreviewToken.
+ * @example
+ * import * as contentstack from '@contentstack/management'
+ * const client = contentstack.client()
+ * const deliveryToken = client.stack({ api_key: 'api_key'}).deliveryToken('delivery_token_uid')
+ * const previewToken = deliveryToken.previewToken()
+ * console.log(previewToken)
+ */
+ this.previewToken = () => {
+ return new PreviewToken(http, { stackHeaders: this.stackHeaders, token: { uid: this.uid } })
+ }
} else {
/**
* @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 = {}) {
* client.stack().deliveryToken().create({ token })
* .then((deliveryToken) => console.log(deliveryToken))
*/
- this.create = create({ http: http, createWithPreviewToken: true })
+ this.create = create({ http: http })
/**
* @description The ‘Get all deliveryToken’ request returns comprehensive information about all deliveryToken created in a stack.
diff --git a/lib/stack/deliveryToken/previewToken/index.js b/lib/stack/deliveryToken/previewToken/index.js
new file mode 100644
index 00000000..f438a09e
--- /dev/null
+++ b/lib/stack/deliveryToken/previewToken/index.js
@@ -0,0 +1,50 @@
+import cloneDeep from 'lodash/cloneDeep'
+import { create, deleteEntity } from '../../../entity'
+
+/**
+ * Preview tokens provide read-only access to the associated environments. Read more about PreviewToken.
+ * @namespace PreviewToken
+ */
+export function PreviewToken (http, data = {}) {
+ this.stackHeaders = data.stackHeaders
+ if (data.token) {
+ Object.assign(this, cloneDeep(data.token))
+ this.urlPath = `/stacks/delivery_tokens/${this.uid}/preview_token`
+
+ /**
+ * @description The Delete PreviewToken call is used to delete an existing PreviewToken permanently from your Stack.
+ * @memberof PreviewToken
+ * @func delete
+ * @returns {Object} Response Object.
+ * @example
+ * import * as contentstack from '@contentstack/management'
+ * const client = contentstack.client()
+ *
+ * client.stack({ api_key: 'api_key'}).deliveryToken('delivery_token_uid').previewToken().delete()
+ * .then((response) => console.log(response.notice))
+ */
+ this.delete = deleteEntity(http)
+
+ /**
+ * @description The Create a PreviewToken call creates a new previewToken in a particular stack of your Contentstack account.
+ * @memberof PreviewToken
+ * @func create
+ * @returns {Promise} Promise for PreviewToken instance
+ *
+ * @example
+ * import * as contentstack from '@contentstack/management'
+ * const client = contentstack.client()
+ * client.stack().deliveryToken('delivery_token_uid').previewToken().create()
+ * .then((previewToken) => console.log(previewToken))
+ */
+ this.create = create({ http: http })
+ }
+}
+
+export function PreviewTokenCollection (http, data) {
+ const obj = cloneDeep(data.tokens) || []
+ const previewTokenCollection = obj.map((userdata) => {
+ return new PreviewToken(http, { token: userdata, stackHeaders: data.stackHeaders })
+ })
+ return previewTokenCollection
+}
diff --git a/package-lock.json b/package-lock.json
index be7d6f59..15c34fe4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@contentstack/management",
- "version": "1.21.4",
+ "version": "1.21.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@contentstack/management",
- "version": "1.21.4",
+ "version": "1.21.5",
"license": "MIT",
"dependencies": {
"assert": "^2.1.0",
diff --git a/package.json b/package.json
index e2844460..2d302a11 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@contentstack/management",
- "version": "1.21.4",
+ "version": "1.21.5",
"description": "The Content Management API is used to manage the content of your Contentstack account",
"main": "./dist/node/contentstack-management.js",
"browser": "./dist/web/contentstack-management.js",
diff --git a/test/sanity-check/api/previewToken-test.js b/test/sanity-check/api/previewToken-test.js
new file mode 100644
index 00000000..a6a31047
--- /dev/null
+++ b/test/sanity-check/api/previewToken-test.js
@@ -0,0 +1,91 @@
+import { expect } from 'chai'
+import { describe, it, setup } from 'mocha'
+import { jsonReader } from '../utility/fileOperations/readwrite'
+import { createDeliveryToken3 } from '../mock/deliveryToken.js'
+import { contentstackClient } from '../utility/ContentstackClient.js'
+import dotenv from 'dotenv'
+
+dotenv.config()
+let client = {}
+
+let tokenUID = ''
+describe('Preview Token api Test', () => {
+ setup(() => {
+ const user = jsonReader('loggedinuser.json')
+ client = contentstackClient(user.authtoken)
+ })
+
+ it('should add a Delivery Token for development', (done) => {
+ makeDeliveryToken()
+ .create(createDeliveryToken3)
+ .then((token) => {
+ tokenUID = token.uid
+ expect(token.name).to.be.equal(createDeliveryToken3.token.name)
+ expect(token.description).to.be.equal(
+ createDeliveryToken3.token.description
+ )
+ expect(token.scope[0].environments[0].name).to.be.equal(
+ createDeliveryToken3.token.scope[0].environments[0]
+ )
+ expect(token.scope[0].module).to.be.equal(
+ createDeliveryToken3.token.scope[0].module
+ )
+ expect(token.uid).to.be.not.equal(null)
+ expect(token.preview_token).to.be.not.equal(null)
+ done()
+ })
+ .catch(done)
+ })
+
+ it('should add a Preview Token', (done) => {
+ makePreviewToken(tokenUID)
+ .create()
+ .then((token) => {
+ expect(token.name).to.be.equal(createDeliveryToken3.token.name)
+ expect(token.description).to.be.equal(
+ createDeliveryToken3.token.description
+ )
+ expect(token.scope[0].environments[0].name).to.be.equal(
+ createDeliveryToken3.token.scope[0].environments[0]
+ )
+ expect(token.scope[0].module).to.be.equal(
+ createDeliveryToken3.token.scope[0].module
+ )
+ expect(token.uid).to.be.not.equal(null)
+ expect(token.preview_token).to.be.not.equal(null)
+ done()
+ })
+ .catch(done)
+ })
+
+ it('should delete a Preview Token from uid', (done) => {
+ makePreviewToken(tokenUID)
+ .delete()
+ .then((data) => {
+ expect(data.notice).to.be.equal('Preview token deleted successfully.')
+ done()
+ })
+ .catch(done)
+ })
+
+ it('should delete a Delivery Token from uid', (done) => {
+ makeDeliveryToken(tokenUID)
+ .delete()
+ .then((data) => {
+ expect(data.notice).to.be.equal('Delivery Token deleted successfully.')
+ done()
+ })
+ .catch(done)
+ })
+})
+
+function makePreviewToken (uid = null) {
+ return client
+ .stack({ api_key: process.env.API_KEY })
+ .deliveryToken(uid)
+ .previewToken()
+}
+
+function makeDeliveryToken (uid = null) {
+ return client.stack({ api_key: process.env.API_KEY }).deliveryToken(uid)
+}
diff --git a/test/sanity-check/mock/deliveryToken.js b/test/sanity-check/mock/deliveryToken.js
index aaf386f6..29ebc770 100644
--- a/test/sanity-check/mock/deliveryToken.js
+++ b/test/sanity-check/mock/deliveryToken.js
@@ -70,5 +70,31 @@ const createDeliveryToken2 = {
]
}
}
+const createDeliveryToken3 = {
+ token: {
+ name: 'preview token test',
+ description: 'This is a demo token.',
+ scope: [
+ {
+ module: 'environment',
+ environments: [
+ 'development'
+ ],
+ acl: {
+ read: true
+ }
+ },
+ {
+ module: 'branch',
+ branches: [
+ 'main'
+ ],
+ acl: {
+ read: true
+ }
+ }
+ ]
+ }
+}
-export { createDeliveryToken, createDeliveryToken2 }
+export { createDeliveryToken, createDeliveryToken2, createDeliveryToken3 }
diff --git a/types/stack/deliveryToken/previewToken.ts b/types/stack/deliveryToken/previewToken.ts
new file mode 100644
index 00000000..1f5e6efb
--- /dev/null
+++ b/types/stack/deliveryToken/previewToken.ts
@@ -0,0 +1,78 @@
+import { AnyProperty, SystemFields } from "../../utility/fields";
+import { Creatable, SystemFunction } from "../../utility/operations";
+
+// Main preview token interface
+export interface PreviewToken
+ extends SystemFields,
+ Creatable,
+ SystemFunction {
+ name: string;
+ description: string;
+ scope: Scope[];
+ uid: string;
+ created_by: string;
+ updated_by: string;
+ created_at: string;
+ updated_at: string;
+ token: string;
+ type: string;
+ preview_token: string;
+}
+
+// API response shape for creating a preview token
+export interface PreviewTokenResponse {
+ notice: string;
+ token: PreviewTokenData;
+}
+
+// Data inside the response `token`
+export interface PreviewTokenData extends AnyProperty {
+ name: string;
+ description: string;
+ scope: Scope[];
+ uid: string;
+ created_by: string;
+ updated_by: string;
+ created_at: string;
+ updated_at: string;
+ token: string;
+ type: string;
+ preview_token: string;
+}
+
+export interface Scope {
+ module: string;
+ environments?: Environment[];
+ branches?: string[];
+ locales?: string[];
+ acl: ACL;
+ _metadata?: {
+ uid: string;
+ };
+}
+
+export interface Environment extends AnyProperty {
+ name: string;
+ uid: string;
+ urls?: UrlLocale[];
+ _version?: number;
+ app_user_object_uid?: string;
+ created_by?: string;
+ updated_by?: string;
+ created_at?: string;
+ updated_at?: string;
+ ACL?: unknown[];
+ tags?: string[];
+}
+
+export interface UrlLocale {
+ url: string;
+ locale: string;
+}
+
+export interface ACL extends AnyProperty {
+ read?: boolean;
+ write?: boolean;
+ create?: boolean;
+ update?: boolean;
+}
diff --git a/types/stack/index.d.ts b/types/stack/index.d.ts
index 055ab895..0105d881 100644
--- a/types/stack/index.d.ts
+++ b/types/stack/index.d.ts
@@ -66,9 +66,6 @@ export interface Stack extends SystemFields {
globalField(options: object): GlobalFields;
globalField(uidOrOptions?: string | object, option?: object): GlobalFields | GlobalField;
-
-
-
asset(): Assets
asset(uid: string): Asset