Skip to content

Commit

Permalink
Merge pull request #168 from contentstack/next-feature-update
Browse files Browse the repository at this point in the history
Implemented variants feature
  • Loading branch information
cs-raj authored Sep 12, 2024
2 parents c6556ea + 1e30ac1 commit 95e6054
Show file tree
Hide file tree
Showing 40 changed files with 2,896 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# contentstack-management-javascript-variants
[![Contentstack](https://www.contentstack.com/docs/static/images/contentstack.png)](https://www.contentstack.com/)

## Contentstack Management JavaScript SDK
Expand Down
1 change: 0 additions & 1 deletion lib/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ export const fetch = (http, type, params = {}) => {
if (this.organization_uid) {
headers.headers.organization_uid = this.organization_uid
}

const response = await http.get(this.urlPath, headers)
if (response.data) {
if (type === 'entry') {
Expand Down
63 changes: 60 additions & 3 deletions lib/stack/contentType/entry/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { create,
import FormData from 'form-data'
import { createReadStream } from 'fs'
import error from '../../../core/contentstackError'
import { Variants } from './variants/index'

/**
* An entry is the actual piece of content created using one of the defined content types. Read more about <a href='https://www.contentstack.com/docs/guide/content-management'>Entries</a>.
Expand Down Expand Up @@ -268,14 +269,69 @@ export function Entry (http, data) {
}

/**
* @description The get locales request allows to get the languages of an entry.
* @description The variants requestan entry call is used to fetch a specific entry with variants from a content type.
* @memberof Entry
* @func locales
* @func variants
* @returns {Promise<Object>} Response Object.
* @param {Object} publishing_rule Details for the publish request
* @param {String} locale Enter the code of the locale that the entry belongs to.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').variants('uid').fetch()
* .then((response) => console.log(response.notice));
*/
this.variants = (uid = null) => {
const data = { stackHeaders: this.stackHeaders }
data.content_type_uid = this.content_type_uid
data.entry_uid = this.uid
if (uid) {
data.variants_uid = uid
}
return new Variants(http, data)
}

/**
* @description The includeVariants an entry call is used to fetch a specific base entry with variants from a content type.
* @memberof Variants
* @func includeVariants
* @returns {Object} Response Object.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').includeVariants('true','variants_uid')
* .then((response) => console.log(response))
*/

this.includeVariants = async (include_variant, variants_uid) => {
try {
const headers = {
...cloneDeep(this.stackHeaders) // Clone existing headers
};

// Add custom header
headers['x-cs-variant-uid'] = variants_uid; // add variant UID
let params = {};
if (include_variant) {
params.include_variant = include_variant; // if include_variant present
}
const response = await http.get(this.urlPath, { headers, params });
if (response.data) {
return response.data;
} else {
throw error(response);
}
} catch (err) {
error(err);
}
};


/**
* @description The get locales request allows to get the languages of an entry.
* @memberof Entry
* @func locales
* @returns {Promise<Object>} Response Object.
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').locales()
* .then((response) => console.log(response));
*/
Expand All @@ -295,6 +351,7 @@ export function Entry (http, data) {
throw error(err)
}
}

} else {
/**
* @description The Create an entry call creates a new entry for the selected content type.
Expand Down
166 changes: 166 additions & 0 deletions lib/stack/contentType/entry/variants/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import cloneDeep from 'lodash/cloneDeep'
import {
update,
deleteEntity,
fetch,
upload,
query,
parseData
}
from '../../../../entity'
import FormData from 'form-data'
import {
createReadStream
} from 'fs'
import error from '../../../../core/contentstackError'
/**
* An variants is the actual piece of content created using one of the defined content types. Read more about <a href='https://www.contentstack.com/docs/guide/content-management'>Entries</a>.
* @namespace Variants
*/
export function Variants(http, data) {
Object.assign(this, cloneDeep(data))
this.urlPath = `/content_types/${this.content_type_uid}/entries/${this.entry_uid}/variants`
if (data && data.variants_uid) {
this.urlPath += `/${this.variants_uid}`
/**
* @description The Create an variants call creates a new variants for the selected content type.
* @memberof Variants
* @func update
* @returns {Promise<Variants.Variants>} Promise for Variants instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
* const data = {
* "entry": {
* "title": "example",
* "url": "/example",
* "_variant": {
* "_change_set": [
* "title",
* "url"
* ]
* }
* }
* }
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').update(data)
* .then((variants) => console.log(variants))
*/
this.update = async (data) => {
try {
const response = await http.put(this.urlPath,
data,
{
headers: {
...cloneDeep(this.stackHeaders)
}
})
if (response.data) {
return response.data
} else {
return error(response)
}
} catch (err) {
return error(err)
}
}

/**
* @description The Delete an variants call is used to delete a specific variants from a content type.
* @memberof Variants
* @func delete
* @returns {Object} Response Object.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').delete()
* .then((response) => console.log(response.notice))
*/
this.delete = deleteEntity(http)

/**
* @description The fetch Variants call fetches Variants details.
* @memberof Variants
* @func fetch
* @returns {Promise<Variants.Variants>} Promise for Variants instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').fetch()
* .then((variants) => console.log(variants))
*
*/
this.fetch = fetch(http, 'variants')

/**
* @description The version Variants call fetches Variants version details.
* @memberof Variants
* @func versions
* @returns {Promise<Variants.Variants>} Promise for Variants instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').versions()
* .then((variants) => console.log(variants))
*
*/
this.versions = async () => {
try {
const response = await http.get(`${this.urlPath}/versions`, {
headers: {
...cloneDeep(this.stackHeaders)
}
})
if (response.data) {
return response.data
} else {
return error(response)
}
} catch (err) {
return error(err)
}
}

} else {
/**
* @description The Query on Variants will allow to fetch details of all or specific Variants
* @memberof Variants
* @func query
* @param {Int} locale Enter the code of the language of which the entries need to be included. Only the entries published in this locale will be displayed.
* @param {Object} query Queries that you can use to fetch filtered results.
* @returns {Array<Variants>} Array of Variants.
*
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack().contentType('content_type_uid').entry('entry_uid').variants().query({ query: { title: 'Variants title' } }).find()
* .then((entries) => console.log(entries))
*/
this.query = query({ http: http, wrapperCollection: VariantsCollection })
}
}
export function VariantsCollection(http, data) {
const obj = cloneDeep(data.entries) || []
const variantCollection = obj.map((variant) => {
return new Variants(http, {
content_type_uid: data.content_type_uid,
entry_uid: variant.uid,
variants_uid: variant.variant_id,
stackHeaders: data.stackHeaders,
variants: variant
})
})
return variantCollection
}

export function createFormData(variants) {
return () => {
const formData = new FormData()
const uploadStream = createReadStream(variants)
formData.append('variants', uploadStream)
return formData
}
}
47 changes: 47 additions & 0 deletions lib/stack/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { BranchAlias } from './branchAlias'
import { AuditLog } from './auditlog'
import { Taxonomy } from './taxonomy'
import { ManagementToken } from './managementToken'
import { Variants } from './variants'
import { VariantGroup } from './variantGroup'

/**
* A stack is a space that stores the content of a project (a web or mobile property). Within a stack, you can create content structures, content entries, users, etc. related to the project. Read more about <a href='https://www.contentstack.com/docs/guide/stack'>Stacks</a>.
Expand Down Expand Up @@ -368,6 +370,29 @@ export function Stack (http, data) {
return new Label(http, data)
}

/**
* @description For creating ungrouped variants.
* @param {String} uid The UID of the variants you want to get details.
* @returns {Variants} Instance of variants.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).variants().create()
* .then((variants) => console.log(variants))
*
* client.stack({ api_key: 'api_key'}).variants('variants_uid').fetch()
* .then((variants) => console.log(variants))
*/
this.variants = (variantsUid = null) => {
const data = { stackHeaders: this.stackHeaders }
if (variantsUid) {
data.variants = { uid: variantsUid }
}
return new Variants(http, data)
}


/**
* @description You can pin a set of entries and assets (along with the deploy action, i.e., publish/unpublish) to a ‘release’, and then deploy this release to an environment.
* @param {String} releaseUid The UID of the Releases you want to get details.
Expand Down Expand Up @@ -676,6 +701,28 @@ export function Stack (http, data) {
}
}

/**
* @description Variant Group allows you to create a variant groups.
* @param {String} uid The UID of the variant group you want to get details.
* @returns {VariantGroup} Instance of VariantGroup.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).variantGroup().create()
* .then((variant_group) => console.log(variant_group))
*
* client.stack({ api_key: 'api_key'}).variantGroup('variant_group_uid').fetch()
* .then((variant_group) => console.log(variant_group))
*/
this.variantGroup = (variantGroupUid = null) => {
const data = { stackHeaders: this.stackHeaders }
if (variantGroupUid) {
data.variant_group = { uid: variantGroupUid }
}
return new VariantGroup(http, data)
}

/**
* @description A role is a collection of permissions that will be applicable to all the users who are assigned this role.
* @memberof Stack
Expand Down
Loading

0 comments on commit 95e6054

Please sign in to comment.