Skip to content

Commit 4a2add3

Browse files
Merge pull request #521 from contentstack/feat/taxonomy-publishing
Feat/taxonomy publishing
2 parents e9e7595 + 74b7d96 commit 4a2add3

File tree

6 files changed

+145
-2
lines changed

6 files changed

+145
-2
lines changed

lib/stack/taxonomy/index.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,59 @@ export function Taxonomy (http, data = {}) {
266266
throw error(err)
267267
}
268268
}
269+
270+
/**
271+
* @description The Publish taxonomy call initiates a job to publish a taxonomy and/or specific terms to the specified environments and locales.
272+
* @memberof Taxonomy
273+
* @func publish
274+
* @param {Object} data - Publish details
275+
* @param {string} [api_version=''] - Optional API version (e.g., '3.2')
276+
* @param {Object=} params - Optional query parameters. If params.branch is set, it is sent as the branch request header.
277+
* @returns {Promise<Object>} Response object with publish job details
278+
* @example
279+
* import * as contentstack from '@contentstack/management'
280+
* const client = contentstack.client()
281+
*
282+
* const publishData = {
283+
* locales: ["en-us"],
284+
* environments: ["development"],
285+
* items: [
286+
* {
287+
* uid: "taxonomy_testing",
288+
* term_uid: "vehicles"
289+
* },
290+
* {
291+
* uid: "taxonomy_testing",
292+
* term_uid: "cars"
293+
* }
294+
* ]
295+
* }
296+
* client.stack({ api_key: 'api_key'}).taxonomy().publish(publishData, '3.2')
297+
* .then((response) => console.log(response))
298+
*/
299+
this.publish = async function (data, api_version = '', params = {}) {
300+
try {
301+
const { branch, ...queryParams } = params
302+
const headers = {
303+
headers: { ...cloneDeep(this.stackHeaders) },
304+
params: queryParams
305+
}
306+
if (api_version) {
307+
headers.headers.api_version = api_version
308+
}
309+
if (branch) {
310+
headers.headers.branch = branch
311+
}
312+
const response = await http.post(`${this.urlPath}/publish`, data, headers)
313+
if (response.data) {
314+
return response.data
315+
} else {
316+
throw error(response)
317+
}
318+
} catch (err) {
319+
throw error(err)
320+
}
321+
}
269322
}
270323
}
271324
export function TaxonomyCollection (http, data) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"test": "npm run test:api && npm run test:unit",
3333
"test:sanity-test": "BABEL_ENV=test nyc --reporter=html mocha --require @babel/register ./test/sanity-check/sanity.js -t 30000 --reporter mochawesome --require babel-polyfill --reporter-options reportDir=mochawesome-report,reportFilename=mochawesome.json",
3434
"test:sanity": "npm run test:sanity-test || true",
35-
"test:sanity-report": "marge mochawesome-report/mochawesome.json -f sanity-report.html --inline && node sanity-report.mjs",
35+
"test:sanity-report": "node sanity-report.mjs",
3636
"test:unit": "BABEL_ENV=test nyc --reporter=html --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter mochawesome --require babel-polyfill",
3737
"test:unit:report:json": "BABEL_ENV=test nyc --reporter=clover --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter json --reporter-options output=report.json --require babel-polyfill",
3838
"test:typescript": "jest --testPathPattern=test/typescript --config ./jest.config.js --coverage",

sanity-report.mjs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ import Slack from '@slack/bolt'
22
const { App } = Slack
33
import dotenv from 'dotenv'
44
import fs from 'fs'
5+
import { execSync } from 'child_process'
6+
import path from 'path'
57

68
dotenv.config()
79

10+
// Marge expects meta.marge.options to be an Object; mochawesome leaves it null. Patch before marge.
11+
const reportJsonPath = path.join(process.cwd(), 'mochawesome-report', 'mochawesome.json')
12+
const json = JSON.parse(fs.readFileSync(reportJsonPath, 'utf8'))
13+
if (json.meta?.marge?.options == null) {
14+
json.meta.marge.options = {}
15+
fs.writeFileSync(reportJsonPath, JSON.stringify(json))
16+
}
17+
execSync('marge mochawesome-report/mochawesome.json -f sanity-report.html --inline', { stdio: 'inherit', cwd: process.cwd() })
18+
819
const mochawesomeJsonOutput = fs.readFileSync('./mochawesome-report/mochawesome.json', 'utf8')
920
const mochawesomeReport = JSON.parse(mochawesomeJsonOutput)
1021
const report = `./mochawesome-report/sanity-report.html`
@@ -58,7 +69,6 @@ async function publishMessage (text, report) {
5869
token: process.env.SLACK_BOT_TOKEN,
5970
channel_id: process.env.SLACK_CHANNEL_ID,
6071
initial_comment: '*Here is the report generated*',
61-
filetype: 'html',
6272
filename: 'sanity-report.html',
6373
file: fs.createReadStream(report)
6474
})

test/sanity-check/api/terms-test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, it, beforeEach } from 'mocha'
22
import { expect } from 'chai'
33
import { jsonReader } from '../utility/fileOperations/readwrite'
44
import { contentstackClient } from '../utility/ContentstackClient.js'
5+
import { environmentCreate } from '../mock/environment.js'
56
import { stageBranch } from '../mock/branch.js'
67

78
var client = {}
@@ -42,6 +43,7 @@ describe('Terms API Test', () => {
4243
})
4344
it('should create taxonomy', async () => {
4445
const response = await client.stack({ api_key: process.env.API_KEY }).taxonomy().create({ taxonomy })
46+
await client.stack({ api_key: process.env.API_KEY }).environment().create(environmentCreate)
4547
expect(response.uid).to.be.equal(taxonomy.uid)
4648
await new Promise(resolve => setTimeout(resolve, 5000))
4749
}, 10000)
@@ -127,6 +129,35 @@ describe('Terms API Test', () => {
127129
.catch(done)
128130
})
129131

132+
it.skip('should publish with api_version', done => {
133+
const publishData = {
134+
locales: ['en-us'],
135+
environments: ['development'],
136+
items: [
137+
{
138+
uid: taxonomy.uid,
139+
term_uid: 'term_test'
140+
},
141+
{
142+
uid: taxonomy.uid,
143+
term_uid: 'term_test_child1'
144+
},
145+
{
146+
uid: taxonomy.uid,
147+
term_uid: 'term_test_child2'
148+
}
149+
]
150+
}
151+
makeTaxonomy()
152+
.publish(publishData, '3.2')
153+
.then((response) => {
154+
expect(response.notice).to.not.equal(null)
155+
expect(response.job_id).to.not.equal(undefined)
156+
done()
157+
})
158+
.catch(done)
159+
})
160+
130161
it('should search the term with the string passed', done => {
131162
makeTerms(taxonomy.uid).search(termString)
132163
.then((response) => {
@@ -195,6 +226,10 @@ function makeTerms (taxonomyUid, termUid = null) {
195226
return client.stack({ api_key: process.env.API_KEY }).taxonomy(taxonomyUid).terms(termUid)
196227
}
197228

229+
function makeTaxonomy () {
230+
return client.stack({ api_key: process.env.API_KEY }).taxonomy()
231+
}
232+
198233
describe('Terms Query Parameters Sanity Tests', () => {
199234
beforeEach(async () => {
200235
const user = jsonReader('loggedinuser.json')
@@ -359,6 +394,7 @@ describe('Terms Query Parameters Sanity Tests', () => {
359394
skip: 0,
360395
limit: 10
361396
})
397+
await client.stack({ api_key: process.env.API_KEY }).environment(environmentCreate.environment.name).delete()
362398
expect(terms).to.have.property('items')
363399
expect(terms.items).to.be.an('array')
364400
// Count property might not be available in all environments

test/unit/taxonomy-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,33 @@ describe('Contentstack Taxonomy test', () => {
759759
})
760760
.catch(done)
761761
})
762+
763+
it('Taxonomy publish test with api_version', done => {
764+
var mock = new MockAdapter(Axios)
765+
mock.onPost('/taxonomies/publish').reply(200, {
766+
notice: 'Taxonomy publish job initiated successfully.',
767+
job_id: 'job_456'
768+
})
769+
const publishData = {
770+
locales: ['en-us', 'fr-fr'],
771+
environments: ['production'],
772+
scheduled_at: '2025-10-01T10:00:00.000Z',
773+
items: [
774+
{
775+
uid: 'taxonomy_testing',
776+
term_uid: 'vehicles'
777+
}
778+
]
779+
}
780+
makeTaxonomy()
781+
.publish(publishData, '3.2')
782+
.then((response) => {
783+
expect(response.notice).to.be.equal('Taxonomy publish job initiated successfully.')
784+
expect(response.job_id).to.be.equal('job_456')
785+
done()
786+
})
787+
.catch(done)
788+
})
762789
})
763790

764791
function makeTaxonomy (data = {}) {

types/stack/taxonomy/index.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,27 @@ export interface Taxonomy extends SystemFields, SystemFunction<Taxonomy> {
1010

1111
export interface Taxonomies extends Creatable<Taxonomy, {taxonomy: TaxonomyData}>, Queryable<Taxonomy, {taxonomy: TaxonomyData}> {
1212
import(data: TaxonomyData, params?: any): Promise<Taxonomy>
13+
publish(data: TaxonomyPublishData, api_version?: string): Promise<TaxonomyPublishResponse>
1314
}
1415

1516
export interface TaxonomyData extends AnyProperty {
1617
name: string
1718
uid: string
1819
description: string
1920
}
21+
22+
export interface TaxonomyPublishData {
23+
locales: Array<string>
24+
environments: Array<string>
25+
items: Array<TaxonomyPublishItem>
26+
}
27+
28+
export interface TaxonomyPublishItem {
29+
uid: string
30+
term_uid: string
31+
}
32+
33+
export interface TaxonomyPublishResponse extends AnyProperty {
34+
notice?: string
35+
job_id?: string
36+
}

0 commit comments

Comments
 (0)