Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/taxonomy-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class TaxonomyQuery extends Query {
/**
* @method find
* @memberof TaxonomyQuery
* @description Fetches all taxonomies of the stack using /taxonomy-manager endpoint
* @description Fetches a list of all published taxonomies available in the stack.
* @returns {Promise<FindResponse<T>>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
Expand Down
35 changes: 35 additions & 0 deletions src/lib/taxonomy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,43 @@ import { AxiosInstance, getData } from '@contentstack/core';
import { TermQuery } from './term-query';
import { Term } from './term';

/**
* @class Taxonomy
* @description Represents a published taxonomy with methods to fetch taxonomy data and manage terms. Requires taxonomy_publish feature flag to be enabled.
*/
export class Taxonomy {
private _client: AxiosInstance;
private _taxonomyUid: string;
private _urlPath: string;

_queryParams: { [key: string]: string | number } = {};

/**
* @constructor
* @param {AxiosInstance} client - The HTTP client instance
* @param {string} taxonomyUid - The taxonomy UID
*/
constructor(client: AxiosInstance, taxonomyUid: string) {
this._client = client;
this._taxonomyUid = taxonomyUid;
this._urlPath = `/taxonomy-manager/${this._taxonomyUid}`; // TODO: change to /taxonomies/${this._taxonomyUid}
}

/**
* @method term
* @memberof Taxonomy
* @description Gets a specific term or creates a term query
* @param {string} [uid] - Optional term UID. If provided, returns a Term instance. If not provided, returns a TermQuery instance.
* @returns {Term | TermQuery}
* @example
* import contentstack from '@contentstack/delivery-sdk'
*
* const stack = contentstack.stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" });
* // Get a specific term
* const term = stack.taxonomy('taxonomy_uid').term('term_uid');
* // Get all terms
* const termQuery = stack.taxonomy('taxonomy_uid').term();
*/
term(uid: string): Term;
term(): TermQuery;
term(uid?: string): Term | TermQuery {
Expand All @@ -23,6 +47,17 @@ export class Taxonomy {
return new TermQuery(this._client, this._taxonomyUid);
}

/**
* @method fetch
* @memberof Taxonomy
* @description Fetches the taxonomy data by UID
* @returns {Promise<T>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
*
* const stack = contentstack.stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" });
* const result = await stack.taxonomy('taxonomy_uid').fetch();
*/
async fetch<T>(): Promise<T> {
const response = await getData(this._client, this._urlPath);

Expand Down
20 changes: 20 additions & 0 deletions src/lib/term-query.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import { AxiosInstance, getData } from '@contentstack/core';
import { FindResponse } from './types';

/**
* @class TermQuery
* @description Represents a query for fetching multiple published terms from a taxonomy. Requires taxonomy_publish feature flag to be enabled.
*/
export class TermQuery {
private _taxonomyUid: string;
private _client: AxiosInstance;
private _urlPath: string;
_queryParams: { [key: string]: string | number } = {};

/**
* @constructor
* @param {AxiosInstance} client - The HTTP client instance
* @param {string} taxonomyUid - The taxonomy UID
*/
constructor(client: AxiosInstance, taxonomyUid: string) {
this._client = client;
this._taxonomyUid = taxonomyUid;
this._urlPath = `/taxonomy-manager/${this._taxonomyUid}/terms`;
}

/**
* @method find
* @memberof TermQuery
* @description Fetches a list of all published terms within a specific taxonomy.
* @returns {Promise<FindResponse<T>>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
*
* const stack = contentstack.stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" });
* const result = await stack.taxonomy('taxonomy_uid').term().find();
*/
async find<T>(): Promise<FindResponse<T>> {
const response = await getData(this._client, this._urlPath, { params: this._queryParams });
return response as FindResponse<T>;
Expand Down
44 changes: 40 additions & 4 deletions src/lib/term.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { AxiosInstance, getData } from "@contentstack/core";

/**
* @class Term
* @description Represents a published taxonomy term with methods to fetch term data, locales, ancestors, and descendants. Requires taxonomy_publish feature flag to be enabled.
*/
export class Term {
protected _client: AxiosInstance;
private _taxonomyUid: string;
private _termUid: string;
private _urlPath: string;

/**
* @constructor
* @param {AxiosInstance} client - The HTTP client instance
* @param {string} taxonomyUid - The taxonomy UID
* @param {string} termUid - The term UID
*/
constructor(client: AxiosInstance, taxonomyUid: string, termUid: string) {
this._client = client;
this._taxonomyUid = taxonomyUid;
Expand All @@ -16,7 +26,7 @@ export class Term {
/**
* @method locales
* @memberof Term
* @description Fetches locales for the term
* @description Fetches all published, localized versions of a single term.
* @returns {Promise<T>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
Expand All @@ -33,7 +43,7 @@ export class Term {
/**
* @method ancestors
* @memberof Term
* @description Fetches ancestors for the term
* @description Fetches all ancestors of a single published term, up to the root.
* @returns {Promise<T>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
Expand All @@ -47,11 +57,37 @@ export class Term {
return response;
}

/**
* @method descendants
* @memberof Term
* @description Fetches all descendants of a single published term.
* @returns {Promise<T>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
*
* const stack = contentstack.stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" });
* const result = await stack.taxonomy('taxonomy_uid').term('term_uid').descendants();
*/
async descendants<T>(): Promise<T> {
const response = await getData(this._client, `${this._urlPath}/descendants`);
if (response.descendants) return response.descendants as T;
return response;
}

/**
* @method fetch
* @memberof Term
* @description Fetches all descendants of a single published term.
* @returns {Promise<T>}
* @example
* import contentstack from '@contentstack/delivery-sdk'
*
* const stack = contentstack.stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" });
* const result = await stack.taxonomy('taxonomy_uid').term('term_uid').fetch();
*/
async fetch<T>(): Promise<T> {
const response = await getData(this._client, this._urlPath);

if (response.term) return response.term as T;

return response;
}
}
36 changes: 32 additions & 4 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ export type queryParams = {

/**
* Interface for creating Contentstack plugins
*
*
* @example
* ```typescript
* import { ContentstackPlugin } from '@contentstack/delivery-sdk';
*
*
* class MyPlugin implements ContentstackPlugin {
* onRequest(config: any): any {
* // Modify request configuration
* console.log('Processing request:', config.url);
* return { ...config, headers: { ...config.headers, 'X-Custom-Header': 'value' } };
* }
*
*
* onResponse(request: any, response: any, data: any): any {
* // Process response data
* console.log('Processing response:', response.status);
* return { ...response, data: { ...data, processed: true } };
* }
* }
*
*
* const stack = contentstack.stack({
* apiKey: 'your-api-key',
* deliveryToken: 'your-delivery-token',
Expand Down Expand Up @@ -342,3 +342,31 @@ export type LivePreview = {
management_token?: string;
preview_token?: string;
};

export interface BaseTaxonomy {
uid: string;
name: string;
description?: string;
terms_count?: number;
created_at: string;
updated_at: string;
created_by: string;
updated_by: string;
type: string;
ACL: ACL;
publish_details?: PublishDetails;
}

export interface BaseTerm {
taxonomy_uid: string;
uid: string;
name: string;
created_by: string;
created_at: string;
updated_by: string;
updated_at: string;
children_count?: number;
depth?: number;
ACL: ACL;
publish_details?: PublishDetails;
}
2 changes: 1 addition & 1 deletion test/api/taxonomy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('ContentType API test cases', () => {
});

it('should give a single taxonomy when taxonomy method is called with taxonomyUid', async () => {
const result = await makeTaxonomy('taxonomy_testing_3').fetch<TTaxonomy>();
const result = await makeTaxonomy('taxonomy_testing').fetch<TTaxonomy>();
expect(result).toBeDefined();
});
});
Expand Down
2 changes: 1 addition & 1 deletion test/api/term-query.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const stack = stackInstance();

describe("Terms API test cases", () => {
it("should check for terms is defined", async () => {
const result = await makeTerms("taxonomy_testing_3").find<TTerm>();
const result = await makeTerms("taxonomy_testing").find<TTerm>();
if (result.terms) {
expect(result.terms).toBeDefined();
expect(result.terms[0].taxonomy_uid).toBeDefined();
Expand Down
9 changes: 8 additions & 1 deletion test/api/term.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ describe("Terms API test cases", () => {
expect(result.terms).toBeDefined();
expect(result.terms[0].name).toBeDefined();
});

it("should get descendants for a term", async () => {
const result = await makeTerms("vrl").descendants<TTerms>();
expect(result).toBeDefined();
expect(result.terms).toBeDefined();
expect(result.terms[0].name).toBeDefined();
});
});

function makeTerms(termUid = ""): Term {
const terms = stack.taxonomy("taxonomy_testing_3").term(termUid);
const terms = stack.taxonomy("taxonomy_testing").term(termUid);
return terms;
}
9 changes: 8 additions & 1 deletion test/unit/term.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AxiosInstance, httpClient } from '@contentstack/core';
import MockAdapter from 'axios-mock-adapter';
import { termQueryFindResponseDataMock, termLocalesResponseDataMock, termAncestorsResponseDataMock } from '../utils/mocks';
import { termQueryFindResponseDataMock, termLocalesResponseDataMock, termAncestorsResponseDataMock, termDescendantsResponseDataMock } from '../utils/mocks';
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
import { Term } from '../../src/lib/term';
import { Taxonomy } from '../../src/lib/taxonomy';
Expand Down Expand Up @@ -39,4 +39,11 @@ describe('Term class', () => {
const response = await term.ancestors();
expect(response).toEqual(termAncestorsResponseDataMock);
});

it('should fetch descendants for a term when descendants() is called', async () => {
mockClient.onGet('/taxonomy-manager/taxonomy_testing/terms/term1/descendants').reply(200, termDescendantsResponseDataMock);

const response = await term.descendants();
expect(response).toEqual(termDescendantsResponseDataMock);
});
});
Loading