diff --git a/CHANGELOG.md b/CHANGELOG.md
index 435bb15c..1bdee9d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## [v1.12.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.12.0) (2023-10-17)
+ - Feature
+ - Types support for Taxonomy feature
+ - Types support for Terms feature
+- Fixes
+ - Correction in refreshToken error message
## [v1.11.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.11.0) (2023-09-03)
- Fixes and Enhancements
- Allows contenttype in asset upload
diff --git a/lib/core/concurrency-queue.js b/lib/core/concurrency-queue.js
index 21e3fef3..321383af 100644
--- a/lib/core/concurrency-queue.js
+++ b/lib/core/concurrency-queue.js
@@ -147,13 +147,13 @@ export function ConcurrencyQueue ({ axios, config }) {
axios.httpClientParams.headers.authtoken = token.authtoken
this.config.authtoken = token.authtoken
}
- }).catch(() => {
+ }).catch((error) => {
this.queue.forEach(queueItem => {
queueItem.reject({
errorCode: '401',
- errorMessage: 'Unable to refresh token',
+ errorMessage: (error instanceof Error) ? error.message : error,
code: 'Unauthorized',
- message: 'Request failed with status code 401',
+ message: 'Unable to refresh token',
name: 'Token Error',
config: queueItem.request
})
diff --git a/lib/stack/roles/index.js b/lib/stack/roles/index.js
index 31ff38eb..483440ad 100644
--- a/lib/stack/roles/index.js
+++ b/lib/stack/roles/index.js
@@ -1,7 +1,5 @@
import cloneDeep from 'lodash/cloneDeep'
import { create, update, deleteEntity, fetch, query, fetchAll } from '../../entity'
-import ContentstackCollection from '../../contentstackCollection'
-import error from '../../core/contentstackError'
/**
* A role is a collection of permissions that will be applicable to all the users who are assigned this role. Read more about Roles.
* @namespace Role
diff --git a/lib/stack/taxonomy/index.js b/lib/stack/taxonomy/index.js
index ffd13b79..b9d03df5 100644
--- a/lib/stack/taxonomy/index.js
+++ b/lib/stack/taxonomy/index.js
@@ -116,7 +116,7 @@ export function Taxonomy (http, data = {}) {
}
}
export function TaxonomyCollection (http, data) {
- const obj = cloneDeep(data.taxonomy) || []
+ const obj = cloneDeep(data.taxonomies) || []
const taxonomyCollection = obj.map((userdata) => {
return new Taxonomy(http, { taxonomy: userdata, stackHeaders: data.stackHeaders })
})
diff --git a/lib/stack/taxonomy/terms/index.js b/lib/stack/taxonomy/terms/index.js
index 8a98b5f7..cca55ca9 100644
--- a/lib/stack/taxonomy/terms/index.js
+++ b/lib/stack/taxonomy/terms/index.js
@@ -192,7 +192,7 @@ export function Terms (http, data) {
const headers = {
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) }
}
- const response = await http.get(`taxonomies/${this.taxonomy_uid}/terms?term=${term}`, headers)
+ const response = await http.get(`taxonomies/$all/terms?typeahead=${term}`, headers)
return parseData(response, this.stackHeaders)
} catch (err) {
console.error(err)
diff --git a/package.json b/package.json
index 3ab84b5e..9b6f911e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@contentstack/management",
- "version": "1.11.0",
+ "version": "1.12.0",
"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/typescript/index.test.ts b/test/typescript/index.test.ts
index 635c46c7..51e48762 100644
--- a/test/typescript/index.test.ts
+++ b/test/typescript/index.test.ts
@@ -17,6 +17,8 @@ import { createApp, deleteApp, fetchApp, installation, updateApp, updateAuth } f
import { deployment, hosting } from './hosting';
import { orgAppRequest } from './app-request';
import { authorization } from './authorization';
+import { testTaxonomy } from './taxonomy';
+import { testTerm } from './terms';
dotenv.config()
jest.setTimeout(10000);
@@ -100,6 +102,9 @@ describe('Typescript API test', () => {
deleteAsset(stack)
queryOnAsset(stack)
+ testTaxonomy(stack)
+ testTerm(stack)
+
deleteEnvironment(stack)
logout(client)
diff --git a/test/typescript/taxonomy.ts b/test/typescript/taxonomy.ts
new file mode 100644
index 00000000..adf200e1
--- /dev/null
+++ b/test/typescript/taxonomy.ts
@@ -0,0 +1,68 @@
+import { expect } from "chai";
+import { Stack } from "../../types/stack";
+
+var taxonomyUID = ''
+export function testTaxonomy(stack: Stack) {
+ describe('Taxonomy API test', () => {
+ test('Create taxonomy', done => {
+ const taxonomy = {
+ uid: 'uid',
+ name: 'taxonomy',
+ description: 'Description for Taxonomy'
+ }
+ stack.taxonomy().create({taxonomy})
+ .then((taxonomyResponse) => {
+ console.log(taxonomyResponse)
+ expect(taxonomyResponse.uid).to.be.equal(taxonomy.uid)
+ expect(taxonomyResponse.name).to.be.equal(taxonomy.name)
+ done()
+ })
+ .catch(done)
+ })
+ test('Fetch taxonomy from uid', done => {
+ stack.taxonomy(taxonomyUID).fetch()
+ .then((taxonomyResponse) => {
+ console.log(taxonomyResponse)
+ expect(taxonomyResponse.uid).to.be.equal(taxonomyUID)
+ expect(taxonomyResponse.name).not.to.be.equal('a')
+ done()
+ })
+ .catch(done)
+ })
+ test('Update taxonomy from uid', done => {
+ stack.taxonomy(taxonomyUID)
+ .fetch()
+ .then((taxonomyResponse) => {
+ taxonomyResponse.name = 'updated name'
+ return taxonomyResponse.update()
+ })
+ .then((taxonomyResponse) => {
+ console.log(taxonomyResponse)
+ expect(taxonomyResponse.uid).to.be.equal(taxonomyUID)
+ expect(taxonomyResponse.name).to.be.equal('updated name')
+ done()
+ })
+ .catch(done)
+ })
+ test('Delete taxonomy from uid', done => {
+ stack.taxonomy(taxonomyUID)
+ .delete()
+ .then((taxonomyResponse) => {
+ expect(taxonomyResponse.notice).to.be.equal('Taxonomy deleted successfully.')
+ done()
+ })
+ .catch(done)
+ })
+ test('Query to get all taxonomies', async () => {
+ await stack.taxonomy()
+ .query()
+ .find()
+ .then((response) => {
+ response.items.forEach((taxonomyResponse) => {
+ expect(taxonomyResponse.uid).to.be.not.equal(null)
+ expect(taxonomyResponse.name).to.be.not.equal(null)
+ })
+ })
+ })
+ })
+}
diff --git a/test/typescript/terms.ts b/test/typescript/terms.ts
new file mode 100644
index 00000000..ecf24dea
--- /dev/null
+++ b/test/typescript/terms.ts
@@ -0,0 +1,118 @@
+import { expect } from "chai";
+import { Stack } from "../../types/stack";
+var taxonomyUID = ''
+var termUID = ''
+export function testTerm(stack: Stack) {
+ describe('Term API test', () => {
+ test('Create Term', done => {
+ const term = {
+ uid: 'term_uid',
+ name: 'term name',
+ parent_uid: 'parent_uid',
+ order: 1
+ }
+ stack.taxonomy(taxonomyUID).terms().create({term})
+ .then((termResponse) => {
+ expect(termResponse.uid).to.be.equal(term.uid)
+ expect(termResponse.name).to.be.equal(term.name)
+ done()
+ })
+ .catch((err) => {
+ console.log(err)
+ })
+ })
+ test('Fetch term from uid', done => {
+ stack.taxonomy(taxonomyUID).terms(termUID).fetch()
+ .then((termResponse) => {
+ expect(termResponse.uid).to.be.equal(termUID)
+ expect(termResponse.name).not.to.be.equal(null)
+ done()
+ })
+ .catch(done)
+ })
+ test('Update term from uid', done => {
+ stack.taxonomy(taxonomyUID).terms(termUID)
+ .fetch()
+ .then((termResponse) => {
+ termResponse.name = 'Updated Name'
+ return termResponse.update()
+ })
+ .then((termResponse) => {
+ expect(termResponse.uid).to.be.equal(termUID)
+ expect(termResponse.name).to.be.equal('Updated Name')
+ done()
+ })
+ .catch(done)
+ })
+ test('Delete term from uid', done => {
+ stack.taxonomy(taxonomyUID).terms(termUID)
+ .delete()
+ .then((termResponse) => {
+ expect(termResponse.notice).to.be.equal('Term deleted successfully.')
+ done()
+ })
+ .catch(done)
+ })
+ test('Query to get all Terms', done => {
+ stack.taxonomy(taxonomyUID).terms()
+ .query()
+ .find()
+ .then((response) => {
+ response.items.forEach((termResponse) => {
+ expect(termResponse.uid).to.be.not.equal(null)
+ expect(termResponse.name).to.be.not.equal(null)
+ })
+ done()
+ })
+ .catch(done)
+ })
+ test('Ancestors of the term given', done => {
+ stack.taxonomy(taxonomyUID).terms(termUID)
+ .ancestors()
+ .then((termResponse) => {
+ expect(termResponse.terms[0].uid).not.to.be.equal(null)
+ expect(termResponse.terms[0].name).not.to.be.equal(null)
+ expect(termResponse.terms[0].created_by).not.to.be.equal(null)
+ expect(termResponse.terms[0].updated_by).not.to.be.equal(null)
+ done()
+ })
+ .catch(done)
+ })
+ test('Descendants of the term given', done => {
+ stack.taxonomy(taxonomyUID).terms(termUID)
+ .descendants()
+ .then((termResponse) => {
+ expect(termResponse.terms[0].uid).not.to.be.equal(null)
+ expect(termResponse.terms[0].name).not.to.be.equal(null)
+ expect(termResponse.terms[0].created_by).not.to.be.equal(null)
+ expect(termResponse.terms[0].updated_by).not.to.be.equal(null)
+ done()
+ })
+ .catch(done)
+ })
+ it('search term', done => {
+ const typeahead = 'term_string'
+ stack.taxonomy('$all').terms()
+ .search(typeahead)
+ .then((termResponse) => {
+ expect(termResponse.terms).to.be.an('array')
+ done()
+ })
+ .catch((err) => {console.log(err)})
+
+ })
+ it('move term', done => {
+ const term = {
+ parent_uid: 'parent_uid',
+ order: 2
+ }
+ stack.taxonomy(taxonomyUID).terms(termUID)
+ .move({ term })
+ .then((termResponse) => {
+ expect(termResponse.notice).to.be.equal('Term moved successfully.')
+ done()
+ })
+ .catch(done)
+ })
+ })
+}
diff --git a/test/unit/concurrency-Queue-test.js b/test/unit/concurrency-Queue-test.js
index 8d52fa7e..04a6fb58 100644
--- a/test/unit/concurrency-Queue-test.js
+++ b/test/unit/concurrency-Queue-test.js
@@ -163,6 +163,26 @@ describe('Concurrency queue test', () => {
.catch(done)
})
+ it('should give passed error message when refreshToken function fails', done => {
+ const axios = client({
+ baseURL: `${host}:${port}`,
+ authorization: 'Bearer ',
+ logHandler: logHandlerStub,
+ refreshToken: () => {
+ return new Promise((resolve, reject) => {
+ reject(new Error('Rejected in Promise'))
+ })
+ }
+ })
+ Promise.all(sequence(3).map(() => axios.axiosInstance.get('/unauthorized')))
+ .catch(err => {
+ expect(err.errorCode).to.equal('401')
+ expect(err.errorMessage).to.equal('Rejected in Promise')
+ expect(err.message).to.equal('Unable to refresh token')
+ done()
+ })
+ })
+
it('Initialize with bad axios instance', done => {
try {
new ConcurrencyQueue({ axios: undefined })
diff --git a/test/unit/taxonomy-test.js b/test/unit/taxonomy-test.js
index b9435185..b5f09386 100644
--- a/test/unit/taxonomy-test.js
+++ b/test/unit/taxonomy-test.js
@@ -44,7 +44,7 @@ describe('Contentstack Taxonomy test', () => {
it('Taxonomies query test', done => {
var mock = new MockAdapter(Axios)
mock.onGet('/taxonomies').reply(200, {
- taxonomy: [
+ taxonomies: [
taxonomyMock
]
})
diff --git a/test/unit/terms-test.js b/test/unit/terms-test.js
index 67e93420..39336346 100644
--- a/test/unit/terms-test.js
+++ b/test/unit/terms-test.js
@@ -169,7 +169,7 @@ describe('Contentstack Term test', () => {
})
it('term search test', done => {
var mock = new MockAdapter(Axios)
- mock.onGet(`/taxonomies/taxonomy_uid/terms?term=UID`).reply(200, {
+ mock.onGet(`/taxonomies/$all/terms?typeahead=UID`).reply(200, {
term: {
...termsMock
}
diff --git a/types/stack/index.d.ts b/types/stack/index.d.ts
index 913585ec..a1363af3 100644
--- a/types/stack/index.d.ts
+++ b/types/stack/index.d.ts
@@ -18,6 +18,7 @@ import { Release, Releases } from "./release";
import { Role, Roles } from "./role";
import { Webhook, Webhooks } from "./webhook";
import { Workflow, Workflows } from "./workflow";
+import { Taxonomy, Taxonomies } from "./taxonomy";
export interface StackConfig {
api_key:string
@@ -92,4 +93,7 @@ export interface Stack extends SystemFields {
unShare(email: string): Promise
role(): Roles
role(uid: string): Role
+
+ taxonomy(): Taxonomies
+ taxonomy(uid: string): Taxonomy
}
diff --git a/types/stack/taxonomy/index.d.ts b/types/stack/taxonomy/index.d.ts
new file mode 100644
index 00000000..c0a23a22
--- /dev/null
+++ b/types/stack/taxonomy/index.d.ts
@@ -0,0 +1,20 @@
+import { AnyProperty, SystemFields } from "../../utility/fields";
+import { Creatable, Queryable, SystemFunction } from "../../utility/operations";
+import { Term, Terms } from "../taxonomy/terms"
+
+export interface Taxonomy extends SystemFields, SystemFunction {
+ terms(): Terms
+ terms(uid: string): Term
+}
+
+export interface Taxonomies extends Queryable {
+}
+
+export interface Taxonomies extends Creatable {
+}
+
+export interface TaxonomyData extends AnyProperty {
+ name: string
+ uid: string
+ description: string
+}
diff --git a/types/stack/taxonomy/terms/index.d.ts b/types/stack/taxonomy/terms/index.d.ts
new file mode 100644
index 00000000..a95ab7c9
--- /dev/null
+++ b/types/stack/taxonomy/terms/index.d.ts
@@ -0,0 +1,24 @@
+import { AnyProperty, SystemFields } from "../../../utility/fields";
+import { Creatable, Queryable, Searchable, SystemFunction } from "../../../utility/operations";
+
+export interface Term extends SystemFields, SystemFunction {
+ ancestors(data?: { include_children_count?: boolean, include_referenced_entries_count?: boolean, include_count?: boolean, skip?: number, limit?: number}): Promise
+ descendants(data?: { include_children_count?: boolean, include_referenced_entries_count?: boolean, include_count?: boolean, skip?: number, limit?: number}): Promise
+ move(data: { term: { parent_uid?: string, order: number } }, force?: boolean): Promise
+}
+
+export interface Terms extends Creatable {
+}
+
+export interface Terms extends Searchable {
+}
+
+export interface Terms extends Queryable {
+}
+
+export interface TermData extends AnyProperty {
+ name: string
+ uid: string
+ parent_uid?: string
+ order: number
+}
diff --git a/types/utility/operations.d.ts b/types/utility/operations.d.ts
index 6e43cfed..89840f26 100644
--- a/types/utility/operations.d.ts
+++ b/types/utility/operations.d.ts
@@ -6,6 +6,10 @@ export interface Creatable {
create(data: D, param?: AnyProperty): Promise
}
+export interface Searchable {
+ search(string: D, param?: AnyProperty): Promise
+}
+
export interface SystemFunction {
update(param?: AnyProperty): Promise
fetch(param?: AnyProperty): Promise