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