-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathendpoints.ts
More file actions
144 lines (118 loc) · 4.58 KB
/
endpoints.ts
File metadata and controls
144 lines (118 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/// <reference types="node" />
import * as path from 'path';
import * as fs from 'fs';
export interface ContentstackEndpoints {
[key: string]: string | ContentstackEndpoints;
}
export interface RegionData {
id: string;
name: string;
cloudProvider: string;
location: string;
alias: string[];
isDefault: boolean;
endpoints: ContentstackEndpoints;
}
export interface RegionsResponse {
regions: RegionData[];
}
// Load regions.json at runtime from the dist/lib directory
function loadRegions(): RegionsResponse {
// Only look for regions.json in dist/lib directory
const regionsPath = path.join(process.cwd(), 'dist', 'lib', 'regions.json');
if (fs.existsSync(regionsPath)) {
try {
const regionsData = fs.readFileSync(regionsPath, 'utf-8');
return JSON.parse(regionsData);
} catch (error) {
throw new Error(`Failed to parse regions.json: ${error instanceof Error ? error.message : String(error)}`);
}
}
// If not found, throw clear error
throw new Error('regions.json file not found at dist/lib/regions.json. Please ensure the package is properly installed and postinstall script has run.');
}
// Cache the loaded regions data
let cachedRegions: RegionsResponse | null = null;
function getRegions(): RegionsResponse {
if (!cachedRegions) {
cachedRegions = loadRegions();
}
return cachedRegions;
}
export function getContentstackEndpoint(region: string = 'us', service: string = '', omitHttps: boolean = false): string | ContentstackEndpoints {
// Validate empty region before any processing
if (region === '') {
console.warn('Invalid region: empty or invalid region provided');
throw new Error('Unable to set the host. Please put valid host');
}
try {
const regionsData: RegionsResponse = getRegions();
// Normalize the region input
const normalizedRegion = region.toLowerCase().trim() || 'us';
// Check if regions data is malformed
if (!Array.isArray(regionsData.regions)) {
throw new Error('Invalid Regions file. Please install the SDK again to fix this issue.');
}
// Find the region by ID or alias
const regionData = findRegionByIDOrAlias(regionsData.regions, normalizedRegion);
if (!regionData) {
// Check if this looks like a legacy format that should throw an error
if (region.includes('_') || region.includes('-')) {
const parts = region.split(/[-_]/);
if (parts.length >= 2) {
console.warn(`Invalid region combination.`);
throw new Error('Region Invalid. Please use a valid region identifier.');
}
}
console.warn('Invalid region:', region, '(normalized:', normalizedRegion + ')');
console.warn('Failed to fetch endpoints:', new Error(`Invalid region: ${region}`));
return getDefaultEndpoint(service, omitHttps);
}
// Get the endpoint(s)
let endpoint: string | ContentstackEndpoints;
if (service) {
// Return specific service endpoint
endpoint = regionData.endpoints[service];
if (!endpoint) {
// For invalid services, return undefined (as expected by some tests)
return undefined as unknown as ContentstackEndpoints;
}
} else {
return omitHttps ? stripHttps(regionData.endpoints) : regionData.endpoints;
}
return omitHttps ? stripHttps(endpoint) : endpoint;
} catch (error) {
console.warn('Failed to fetch endpoints:', error);
return getDefaultEndpoint(service, omitHttps);
}
}
function getDefaultEndpoint(service: string, omitHttps: boolean): string {
const regions = getRegions();
const defaultEndpoints: ContentstackEndpoints = regions.regions.find((r: RegionData) => r.isDefault)?.endpoints || {};
const value = defaultEndpoints[service];
const endpoint = typeof value === 'string' ? value : 'https://cdn.contentstack.io';
return omitHttps ? endpoint.replace(/^https?:\/\//, '') : endpoint;
}
function findRegionByIDOrAlias(regions: RegionData[], regionInput: string): RegionData | null {
// First try to find by exact ID match
let region = regions.find(r => r.id === regionInput);
if (region) {
return region;
}
// Then try to find by alias
region = regions.find(r =>
r.alias.some(alias => alias.toLowerCase() === regionInput.toLowerCase())
);
return region || null;
}
function stripHttps(endpoint: string | ContentstackEndpoints): string | ContentstackEndpoints {
if (typeof endpoint === 'string') {
return endpoint.replace(/^https?:\/\//, '');
} else {
const result: ContentstackEndpoints = {};
for (const key in endpoint) {
result[key] = stripHttps(endpoint[key]);
}
return result;
}
}