diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a67b4..c92f049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Change log +### Version: 4.2.0 +#### Date: Septmber-04-2024 +Feat: Variants support added + ### Version: 4.1.0 #### Date: August-07-2024 Feat: Live Preview configuration changes diff --git a/package-lock.json b/package-lock.json index 7836ecc..947f608 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.1.0", + "version": "4.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/delivery-sdk", - "version": "4.1.0", + "version": "4.2.0", "dependencies": { "@contentstack/core": "^1.1.0", "@contentstack/utils": "^1.3.8", "@types/humps": "^2.0.6", - "axios": "^1.7.2", + "axios": "^1.7.4", "dotenv": "^16.3.1", "humps": "^2.0.1" }, @@ -4205,9 +4205,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 3993c54..b212054 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.1.0", + "version": "4.2.0", "type": "commonjs", "main": "./dist/cjs/src/index.js", "types": "./dist/types/src/index.d.ts", @@ -23,7 +23,7 @@ "@contentstack/core": "^1.1.0", "@contentstack/utils": "^1.3.8", "@types/humps": "^2.0.6", - "axios": "^1.7.2", + "axios": "^1.7.4", "dotenv": "^16.3.1", "humps": "^2.0.1" }, diff --git a/src/lib/contentstack.ts b/src/lib/contentstack.ts index 3535c51..895eb82 100644 --- a/src/lib/contentstack.ts +++ b/src/lib/contentstack.ts @@ -3,7 +3,7 @@ import { InternalAxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from ' import { handleRequest } from './cache'; import { Stack as StackClass } from './stack'; import { Policy, StackConfig } from './types'; -import { getHost } from './utils'; +import * as Utility from './utils'; export * as Utils from '@contentstack/utils'; let version = '{{VERSION}}'; @@ -40,7 +40,7 @@ export function stack(config: StackConfig): StackClass { live_preview: {} as any }; - defaultConfig.defaultHostname = config.host || getHost(config.region, config.host); + defaultConfig.defaultHostname = config.host || Utility.getHost(config.region, config.host); config.host = defaultConfig.defaultHostname; if (config.apiKey) { @@ -59,6 +59,21 @@ export function stack(config: StackConfig): StackClass { throw new Error('Environment for Stack is required'); } + if (config.live_preview) { + if (Utility.isBrowser()) { + const params = new URL(document.location.toString()).searchParams; + if (params.has('live_preview')) { + config.live_preview.live_preview = params.get('live_preview') || config.live_preview.live_preview; + } + if (params.has('release_id')) { + defaultConfig.headers['release_id'] = params.get('release_id'); + } + if (params.has('preview_timestamp')) { + defaultConfig.headers['preview_timestamp'] = params.get('preview_timestamp'); + } + } + } + if (config.branch) { defaultConfig.headers.branch = config.branch; } diff --git a/src/lib/entries.ts b/src/lib/entries.ts index 9502389..b886ab9 100644 --- a/src/lib/entries.ts +++ b/src/lib/entries.ts @@ -184,4 +184,25 @@ export class Entries extends EntryQueryable { return new Query(this._client, this._parameters, this._queryParams, this._contentTypeUid); } + + /** + * @method variants + * @memberof Entry + * @description The variant header will be added to axios client + * @returns {Entry} + * @example + * import contentstack from '@contentstack/delivery-sdk' + * + * const stack = contentstack.Stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" }); + * const result = await stack.contentType('abc').entry().variant('xyz').find(); + */ + variants(variants: string | string[]): Entries { + if (Array.isArray(variants) && variants.length > 0) { + this._client.defaults.headers['x-cs-variant-uid'] = variants.join(','); + } else if (typeof variants == 'string' && variants.length > 0) { + this._client.defaults.headers['x-cs-variant-uid'] = variants; + } + + return this; + } } diff --git a/src/lib/entry.ts b/src/lib/entry.ts index 77078d2..e764645 100644 --- a/src/lib/entry.ts +++ b/src/lib/entry.ts @@ -4,7 +4,7 @@ interface EntryResponse { entry: T; } export class Entry { - private _client: AxiosInstance; + protected _client: AxiosInstance; private _contentTypeUid: string; private _entryUid: string; private _urlPath: string; @@ -34,6 +34,27 @@ export class Entry { return this; } + /** + * @method variants + * @memberof Entry + * @description The variant header will be added to axios client + * @returns {Entry} + * @example + * import contentstack from '@contentstack/delivery-sdk' + * + * const stack = contentstack.Stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" }); + * const result = await stack.contentType('abc').entry('entry_uid').variant('xyz').fetch(); + */ + variants(variants: string | string[]): Entry { + if (Array.isArray(variants) && variants.length > 0) { + this._client.defaults.headers['x-cs-variant-uid'] = variants.join(','); + } else if (typeof variants == 'string' && variants.length > 0) { + this._client.defaults.headers['x-cs-variant-uid'] = variants; + } + + return this; + } + /** * @method includeMetadata * @memberof Entry diff --git a/src/lib/stack.ts b/src/lib/stack.ts index f73a0cd..484ead0 100644 --- a/src/lib/stack.ts +++ b/src/lib/stack.ts @@ -153,5 +153,12 @@ export class Stack { } this._client.stackConfig.live_preview = livePreviewParams; } + + if (query.hasOwnProperty('release_id')) { + this._client.defaults.headers['release_id'] = query.release_id; + } + if (query.hasOwnProperty('preview_timestamp')) { + this._client.defaults.headers['preview_timestamp'] = query.preview_timestamp; + } } } diff --git a/src/lib/types.ts b/src/lib/types.ts index c6bf640..254bcc4 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -261,6 +261,8 @@ export interface LivePreviewQuery { live_preview: string contentTypeUid: string entryUid?: any; + preview_timestamp?: string + release_id?: string } export type LivePreview = { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index ec1f217..8b9d047 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -10,3 +10,7 @@ export function getHost(region: Region = Region.US, host?: string) { return url; } + +export function isBrowser() { + return (typeof window !== "undefined"); +} \ No newline at end of file diff --git a/test/unit/entries.spec.ts b/test/unit/entries.spec.ts index 31496e2..9e7aa4d 100644 --- a/test/unit/entries.spec.ts +++ b/test/unit/entries.spec.ts @@ -137,3 +137,31 @@ describe('Entries class', () => { expect(query._parameters).toEqual({"taxonomies.taxonomy_uid": {"$above": "term_uid", "levels": 4 }}); }); }); + +class TestVariants extends Entries { + + constructor(client: AxiosInstance) { + super(client, 'xyz'); + this._client = client; + } + + getVariantsHeaders(): string { + return this._client.defaults.headers['x-cs-variant-uid'] || ""; + } +} + +describe('Variants test', () => { + let client: AxiosInstance; + let mockClient: MockAdapter; + + beforeAll(() => { + client = httpClient(MOCK_CLIENT_OPTIONS); + mockClient = new MockAdapter(client as any); + }); + it('should get the correct variant headers added to client', async () => { + const testVariantObj = new TestVariants(httpClient(MOCK_CLIENT_OPTIONS)) + + testVariantObj.variants(['variant1', 'variant2']); + expect(testVariantObj.getVariantsHeaders()).toBe('variant1,variant2'); + }); +}) \ No newline at end of file diff --git a/test/unit/entry.spec.ts b/test/unit/entry.spec.ts index b3de6b2..a97aa94 100644 --- a/test/unit/entry.spec.ts +++ b/test/unit/entry.spec.ts @@ -62,3 +62,30 @@ describe('Entry class', () => { expect(returnedValue).toEqual(entryFetchMock.entry); }); }); + +class TestVariants extends Entry { + constructor(client: AxiosInstance) { + super(client, 'xyz', 'abc'); + this._client = client; + } + + getVariantsHeaders(): string { + return this._client.defaults.headers['x-cs-variant-uid'] || ""; + } +} + +describe('Variants test', () => { + let client: AxiosInstance; + let mockClient: MockAdapter; + + beforeAll(() => { + client = httpClient(MOCK_CLIENT_OPTIONS); + mockClient = new MockAdapter(client as any); + }); + it('should get the correct variant headers added to client', async () => { + const testVariantObj = new TestVariants(httpClient(MOCK_CLIENT_OPTIONS)) + + testVariantObj.variants(['variant1', 'variant2']); + expect(testVariantObj.getVariantsHeaders()).toBe('variant1,variant2'); + }); +})