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
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