Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
6 changes: 1 addition & 5 deletions .commitlintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"subject-case": [
2,
"always",
["sentence-case", "start-case", "pascal-case", "upper-case", "lower-case"]
],
"subject-case": [0],
"subject-empty": [2, "never"],
"subject-full-stop": [2, "never", "."],
"type-enum": [
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ dist/
coverage/
.dccache
snyk_output.log
talisman_output.log
talisman_output.log
regions.json
4 changes: 3 additions & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ fileignoreconfig:
ignore_detectors:
- filecontent
- filename: package-lock.json
checksum: fb18e620409c9476503edb301ef7b1360681e7d03d8c9b93c2e7a6453c744631
checksum: 497081f339bddec3868c2469b5266cb248a1aed8ce6fbab57bbc77fb9f412be6
- filename: src/entry-editable.ts
checksum: 3ba7af9ed1c1adef2e2bd5610099716562bebb8ba750d4b41ddda99fc9eaf115
- filename: .husky/pre-commit
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
- filename: src/endpoints.ts
checksum: 721a1df93b02d04c1c19a76c171fe2748e4abb1fc3e43452e76fecfd8f384751
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## [1.6.0](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.6.0)
- Feat: Adds Helper functions for Contentstack Endpoints

## [1.5.0](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.5) (2025-10-27)
- fix: handle null and undefined values in getTag function
- fix: refernce variant cslp generation fix
Expand Down
344 changes: 344 additions & 0 deletions __test__/endpoints.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
import { getContentstackEndpoint, ContentstackEndpoints, RegionData, RegionsResponse } from '../src/endpoints';

// Mock console.warn to avoid noise in tests
const originalConsoleWarn = console.warn;
beforeAll(() => {
console.warn = jest.fn();
});

afterAll(() => {
console.warn = originalConsoleWarn;
});

describe('getContentstackEndpoint', () => {
describe('Basic functionality', () => {
it('should return default endpoints for valid region without service', () => {
const result = getContentstackEndpoint('us');

expect(result).toBeDefined();
expect(typeof result).toBe('object');
expect((result as ContentstackEndpoints).contentDelivery).toBe('https://cdn.contentstack.io');
expect((result as ContentstackEndpoints).contentManagement).toBe('https://api.contentstack.io');
});

it('should return specific service endpoint for valid region and service', () => {
const result = getContentstackEndpoint('us', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should return EU endpoints for EU region', () => {
const result = getContentstackEndpoint('eu', 'contentDelivery');

expect(result).toBe('https://eu-cdn.contentstack.com');
});

it('should return undefined for invalid service', () => {
const result = getContentstackEndpoint('us', 'invalidService');

expect(result).toBeUndefined();
});
});

describe('Region alias matching', () => {
it('should match region by alias "na"', () => {
const result = getContentstackEndpoint('na', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should match region by alias "aws-na"', () => {
const result = getContentstackEndpoint('aws-na', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should match region by alias "aws_na"', () => {
const result = getContentstackEndpoint('aws_na', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should be case insensitive for region matching', () => {
const result = getContentstackEndpoint('US', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should trim whitespace from region input', () => {
const result = getContentstackEndpoint(' us ', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});
});

describe('omitHttps parameter', () => {
it('should strip https from string endpoint when omitHttps is true', () => {
const result = getContentstackEndpoint('us', 'contentDelivery', true);

expect(result).toBe('cdn.contentstack.io');
});

it('should strip https from all endpoints when omitHttps is true and no service specified', () => {
const result = getContentstackEndpoint('us', '', true) as ContentstackEndpoints;

expect(result.contentDelivery).toBe('cdn.contentstack.io');
expect(result.contentManagement).toBe('api.contentstack.io');
expect(result.application).toBe('app.contentstack.com');
});

it('should preserve https when omitHttps is false', () => {
const result = getContentstackEndpoint('us', 'contentDelivery', false);

expect(result).toBe('https://cdn.contentstack.io');
});
});

describe('Error handling and edge cases', () => {
it('should throw error for empty region', () => {
expect(() => {
getContentstackEndpoint('');
}).toThrow('Unable to set the host. Please put valid host');
});

it('should return default endpoint for invalid region', () => {
const result = getContentstackEndpoint('invalid-region', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should return default endpoint for region with underscores/dashes', () => {
const result = getContentstackEndpoint('invalid_region_format', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should handle malformed regions data gracefully', () => {
const malformedData: RegionsResponse = {
regions: null as any
};

const result = getContentstackEndpoint('us', 'contentDelivery', false, malformedData);

expect(result).toBe('https://cdn.contentstack.io');
});

it('should fallback to default when region is not found', () => {
const result = getContentstackEndpoint('nonexistent', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});
});

describe('Default parameters', () => {
it('should use default region "us" when no region provided', () => {
const result = getContentstackEndpoint();

expect(result).toBeDefined();
expect(typeof result).toBe('object');
expect((result as ContentstackEndpoints).contentDelivery).toBe('https://cdn.contentstack.io');
});

it('should use default service "" when no service provided', () => {
const result = getContentstackEndpoint('us');

expect(result).toBeDefined();
expect(typeof result).toBe('object');
});

it('should use default omitHttps false when not provided', () => {
const result = getContentstackEndpoint('us', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});
});

describe('Service-specific endpoints', () => {
it('should return correct application endpoint', () => {
const result = getContentstackEndpoint('us', 'application');

expect(result).toBe('https://app.contentstack.com');
});

it('should return correct auth endpoint', () => {
const result = getContentstackEndpoint('us', 'auth');

expect(result).toBe('https://auth-api.contentstack.com');
});

it('should return correct graphqlDelivery endpoint', () => {
const result = getContentstackEndpoint('us', 'graphqlDelivery');

expect(result).toBe('https://graphql.contentstack.com');
});

it('should return correct preview endpoint', () => {
const result = getContentstackEndpoint('us', 'preview');

expect(result).toBe('https://rest-preview.contentstack.com');
});

it('should return correct images endpoint', () => {
const result = getContentstackEndpoint('us', 'images');

expect(result).toBe('https://images.contentstack.io');
});

it('should return correct assets endpoint', () => {
const result = getContentstackEndpoint('us', 'assets');

expect(result).toBe('https://assets.contentstack.io');
});

it('should return correct automate endpoint', () => {
const result = getContentstackEndpoint('us', 'automate');

expect(result).toBe('https://automations-api.contentstack.com');
});

it('should return correct launch endpoint', () => {
const result = getContentstackEndpoint('us', 'launch');

expect(result).toBe('https://launch-api.contentstack.com');
});

it('should return correct developerHub endpoint', () => {
const result = getContentstackEndpoint('us', 'developerHub');

expect(result).toBe('https://developerhub-api.contentstack.com');
});

it('should return correct brandKit endpoint', () => {
const result = getContentstackEndpoint('us', 'brandKit');

expect(result).toBe('https://brand-kits-api.contentstack.com');
});

it('should return correct genAI endpoint', () => {
const result = getContentstackEndpoint('us', 'genAI');

expect(result).toBe('https://ai.contentstack.com');
});

it('should return correct personalize endpoint', () => {
const result = getContentstackEndpoint('us', 'personalize');

expect(result).toBe('https://personalize-api.contentstack.com');
});

it('should return correct personalizeEdge endpoint', () => {
const result = getContentstackEndpoint('us', 'personalizeEdge');

expect(result).toBe('https://personalize-edge.contentstack.com');
});
});

describe('Different regions', () => {
it('should return correct EU endpoints', () => {
const result = getContentstackEndpoint('eu', 'contentDelivery');

expect(result).toBe('https://eu-cdn.contentstack.com');
});

it('should return correct Azure NA endpoints', () => {
const result = getContentstackEndpoint('azure-na', 'contentDelivery');

expect(result).toBe('https://azure-na-cdn.contentstack.com');
});

it('should return correct GCP NA endpoints', () => {
const result = getContentstackEndpoint('gcp-na', 'contentDelivery');

expect(result).toBe('https://gcp-na-cdn.contentstack.com');
});
});

describe('Additional regions and aliases', () => {
it('should return correct Australia endpoints', () => {
const result = getContentstackEndpoint('au', 'contentDelivery');

expect(result).toBe('https://au-cdn.contentstack.com');
});

it('should match Australia region by alias "aws-au"', () => {
const result = getContentstackEndpoint('aws-au', 'contentDelivery');

expect(result).toBe('https://au-cdn.contentstack.com');
});

it('should return correct Azure EU endpoints', () => {
const result = getContentstackEndpoint('azure-eu', 'contentDelivery');

expect(result).toBe('https://azure-eu-cdn.contentstack.com');
});

it('should return correct GCP EU endpoints', () => {
const result = getContentstackEndpoint('gcp-eu', 'contentDelivery');

expect(result).toBe('https://gcp-eu-cdn.contentstack.com');
});

it('should match Azure region by underscore alias', () => {
const result = getContentstackEndpoint('azure_na', 'contentDelivery');

expect(result).toBe('https://azure-na-cdn.contentstack.com');
});

it('should match GCP region by underscore alias', () => {
const result = getContentstackEndpoint('gcp_na', 'contentDelivery');

expect(result).toBe('https://gcp-na-cdn.contentstack.com');
});
});

describe('Edge cases and error scenarios', () => {
it('should handle null region gracefully', () => {
const result = getContentstackEndpoint(null as any, 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should handle undefined region gracefully', () => {
const result = getContentstackEndpoint(undefined as any, 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should handle region with only whitespace', () => {
const result = getContentstackEndpoint(' ', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should handle region with special characters', () => {
const result = getContentstackEndpoint('region@#$%', 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});

it('should handle very long region name', () => {
const longRegion = 'a'.repeat(1000);
const result = getContentstackEndpoint(longRegion, 'contentDelivery');

expect(result).toBe('https://cdn.contentstack.io');
});
});

describe('Console warnings', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should warn for invalid region', () => {
getContentstackEndpoint('invalid-region', 'contentDelivery');

expect(console.warn).toHaveBeenCalledWith('Invalid region combination.');
});

it('should warn for failed endpoint fetch', () => {
getContentstackEndpoint('invalid-region', 'contentDelivery');

expect(console.warn).toHaveBeenCalledWith('Failed to fetch endpoints:', expect.any(Error));
});
});
});
Loading
Loading