Skip to content

Commit fc15140

Browse files
Fixed the url endpoint issue
1 parent 907782e commit fc15140

6 files changed

Lines changed: 202 additions & 84 deletions

File tree

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
contentstack (0.8.5)
4+
contentstack (0.9.0)
55
activesupport (>= 3.2)
66
contentstack_utils (~> 1.2)
77

@@ -119,7 +119,7 @@ CHECKSUMS
119119
bundler (4.0.11) sha256=5bcec0fb78302e48d02ee46f10ee6e6942be647ba5b44a6d1ddfda9a240ce785
120120
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
121121
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
122-
contentstack (0.8.5)
122+
contentstack (0.9.0)
123123
contentstack_utils (1.2.3) sha256=cf2f5f996eb487559fd2d7d48a99262710f53dec62c84c6e325b9a598cd31ba7
124124
crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e
125125
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962

contentstack.gemspec

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Gem::Specification.new do |s|
1818
s.summary = %q{Contentstack Ruby client for the Content Delivery API}
1919
s.description = %q{Contentstack Ruby client for the Content Delivery API}
2020

21-
s.files = `git ls-files`.split("\n")
21+
s.files = `git ls-files`.split("\n") +
22+
Dir['ext/**/*'].select { |f| File.file?(f) }
23+
s.extensions = ['ext/download_regions/extconf.rb']
2224
s.require_paths = ["lib"]
2325

2426
s.add_dependency 'activesupport', '>= 3.2'

ext/download_regions/extconf.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'net/http'
2+
require 'uri'
3+
require 'json'
4+
require 'fileutils'
5+
6+
REGISTRY_URL = 'https://artifacts.contentstack.com/regions.json'
7+
8+
gem_root = File.expand_path('../..', __dir__)
9+
data_dir = File.join(gem_root, 'lib', 'data')
10+
dest_file = File.join(data_dir, 'regions.json')
11+
12+
FileUtils.mkdir_p(data_dir)
13+
14+
begin
15+
uri = URI.parse(REGISTRY_URL)
16+
response = Net::HTTP.get_response(uri)
17+
if response.is_a?(Net::HTTPSuccess)
18+
File.write(dest_file, JSON.pretty_generate(JSON.parse(response.body)))
19+
$stdout.puts "[Contentstack] regions.json downloaded successfully."
20+
else
21+
$stdout.puts "[Contentstack] Warning: Could not download regions.json (HTTP #{response.code}). Runtime fallback will be used."
22+
end
23+
rescue => e
24+
$stdout.puts "[Contentstack] Warning: Could not download regions.json — #{e.message}. Runtime fallback will be used."
25+
end
26+
27+
# RubyGems requires a Makefile to exist after extconf.rb runs.
28+
# We create a no-op one since this extension has no C code to compile.
29+
File.write('Makefile', "all:\n\ninstall:\n\nclean:\n\n")

lib/contentstack/endpoint.rb

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,44 @@
55
require 'contentstack/error'
66

77
module Contentstack
8-
# Centralised endpoint resolver. Reads region→service→URL mappings from the
9-
# bundled regions.json and falls back to the live registry when the file is
10-
# absent. Delegating to ContentstackUtils.get_contentstack_endpoint is
11-
# preferred when that gem exposes the method (PR #41 of contentstack-utils-ruby).
8+
# Centralised endpoint resolver. Reads region metadata from the local
9+
# regions.json (downloaded from https://artifacts.contentstack.com/regions.json
10+
# at gem install time) and falls back to a live fetch when the file is absent.
11+
#
12+
# Delegates to ContentstackUtils.get_contentstack_endpoint when that gem
13+
# ships the method (contentstack-utils-ruby PR #41).
1214
class Endpoint
13-
REGISTRY_URL = 'https://raw.githubusercontent.com/contentstack/contentstack-utils-ruby/main/lib/data/regions.json'
15+
REGISTRY_URL = 'https://artifacts.contentstack.com/regions.json'
1416
DATA_FILE_PATH = File.join(File.dirname(File.dirname(__FILE__)), 'data', 'regions.json')
1517

16-
DEFAULT_SERVICE = 'cda'
18+
# Maps the SDK's short service keys to the camelCase keys used in regions.json,
19+
# preserving backward compatibility for callers using Service::CDA / Service::CMA.
20+
SERVICE_MAP = {
21+
'cda' => 'contentDelivery',
22+
'cma' => 'contentManagement',
23+
'preview' => 'preview'
24+
}.freeze
25+
26+
DEFAULT_SERVICE = 'contentDelivery'
1727

1828
# Resolve a Contentstack service URL for the given region and service.
1929
#
2030
# Contentstack::Endpoint.get_contentstack_endpoint('eu')
2131
# # => "https://eu-cdn.contentstack.com"
2232
#
23-
# Contentstack::Endpoint.get_contentstack_endpoint('us', 'cma')
33+
# Contentstack::Endpoint.get_contentstack_endpoint('us', 'contentManagement')
2434
# # => "https://api.contentstack.io"
2535
#
36+
# Contentstack::Endpoint.get_contentstack_endpoint('eu', 'cda') # short alias
37+
# # => "https://eu-cdn.contentstack.com"
38+
#
2639
# When +custom_host+ is supplied the region CDN prefix is derived from
27-
# regions.json and prepended to the custom domain, preserving the
28-
# existing SDK behaviour for host-override configurations.
40+
# regions.json and prepended to the custom domain.
2941
def self.get_contentstack_endpoint(region, service = DEFAULT_SERVICE, custom_host = nil)
3042
region_key = region.to_s.downcase
31-
service_key = service.to_s.downcase
43+
service_key = SERVICE_MAP.fetch(service.to_s, service.to_s)
3244

3345
if custom_host.nil? || custom_host.to_s.empty?
34-
# Prefer the utils SDK when it ships endpoint resolution (PR #41)
3546
if defined?(ContentstackUtils) && ContentstackUtils.respond_to?(:get_contentstack_endpoint)
3647
return ContentstackUtils.get_contentstack_endpoint(region_key, service_key)
3748
end
@@ -41,10 +52,9 @@ def self.get_contentstack_endpoint(region, service = DEFAULT_SERVICE, custom_hos
4152
end
4253
end
4354

44-
# Download and persist the latest region metadata from the registry.
45-
# Equivalent to `composer refresh-regions` in the PHP SDK.
46-
#
47-
# Rake: bundle exec rake refresh_regions
55+
# Download the latest regions.json from https://artifacts.contentstack.com/regions.json
56+
# and persist it locally. Called automatically by ext/download_regions/extconf.rb
57+
# during bundle install / bundle update, and by `bundle exec rake refresh_regions`.
4858
def self.refresh_regions
4959
data = fetch_from_registry
5060
FileUtils.mkdir_p(File.dirname(DATA_FILE_PATH))
@@ -55,34 +65,43 @@ def self.refresh_regions
5565
private
5666

5767
def self.resolve_standard(region_key, service_key)
58-
regions = load_regions
59-
unless regions.key?(region_key)
68+
region_data = find_region(region_key)
69+
unless region_data
6070
raise Contentstack::Error.new(
61-
Contentstack::ErrorMessages.region_invalid(region_key, regions.keys)
71+
Contentstack::ErrorMessages.region_invalid(region_key, all_region_ids)
6272
)
6373
end
64-
unless regions[region_key].key?(service_key)
74+
unless region_data['endpoints'].key?(service_key)
6575
raise Contentstack::Error.new(
66-
Contentstack::ErrorMessages.service_invalid(service_key, regions[region_key].keys)
76+
Contentstack::ErrorMessages.service_invalid(service_key, region_data['endpoints'].keys)
6777
)
6878
end
69-
regions[region_key][service_key]
79+
region_data['endpoints'][service_key]
7080
end
7181

72-
# Derive the CDN subdomain prefix from regions.json and combine with the
73-
# caller-supplied custom domain, e.g. "eu-cdn" + "example.com" →
74-
# "https://eu-cdn.example.com".
7582
def self.resolve_custom_host(region_key, service_key, custom_host)
76-
regions = load_regions
77-
if regions.key?(region_key) && regions[region_key].key?(service_key)
78-
standard_url = regions[region_key][service_key]
83+
region_data = find_region(region_key)
84+
if region_data && region_data['endpoints'].key?(service_key)
85+
standard_url = region_data['endpoints'][service_key]
7986
prefix = URI.parse(standard_url).host.split('.').first
8087
"https://#{prefix}.#{custom_host}"
8188
else
8289
"https://cdn.#{custom_host}"
8390
end
8491
end
8592

93+
# Find a region by its canonical id or any of its declared aliases.
94+
def self.find_region(region_key)
95+
load_regions['regions'].find do |r|
96+
r['id'] == region_key ||
97+
r['alias'].any? { |a| a.downcase == region_key }
98+
end
99+
end
100+
101+
def self.all_region_ids
102+
load_regions['regions'].map { |r| r['id'] }
103+
end
104+
86105
def self.load_regions
87106
if File.exist?(DATA_FILE_PATH)
88107
JSON.parse(File.read(DATA_FILE_PATH))

lib/contentstack/region.rb

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,38 @@
11
module Contentstack
22
class Region
33
EU = 'eu'
4-
US = 'us'
4+
US = 'us' # alias for the 'na' region in regions.json
55
AZURE_NA = 'azure-na'
66
AZURE_EU = 'azure-eu'
77
GCP_NA = 'gcp-na'
88
GCP_EU = 'gcp-eu'
9+
AU = 'au'
910
end
1011

1112
class Service
12-
CDA = 'cda'
13-
CMA = 'cma'
14-
PREVIEW = 'preview'
13+
# Full camelCase keys matching regions.json
14+
CONTENT_DELIVERY = 'contentDelivery'
15+
CONTENT_MANAGEMENT = 'contentManagement'
16+
PREVIEW = 'preview'
17+
AUTH = 'auth'
18+
GRAPHQL_DELIVERY = 'graphqlDelivery'
19+
GRAPHQL_PREVIEW = 'graphqlPreview'
20+
IMAGES = 'images'
21+
ASSETS = 'assets'
22+
AUTOMATE = 'automate'
23+
LAUNCH = 'launch'
24+
DEVELOPER_HUB = 'developerHub'
25+
BRAND_KIT = 'brandKit'
26+
GEN_AI = 'genAI'
27+
PERSONALIZE_MGMT = 'personalizeManagement'
28+
PERSONALIZE_EDGE = 'personalizeEdge'
29+
COMPOSABLE_STUDIO = 'composableStudio'
30+
ASSET_MANAGEMENT = 'assetManagement'
31+
APPLICATION = 'application'
32+
33+
# Short aliases kept for backward compatibility
34+
CDA = CONTENT_DELIVERY
35+
CMA = CONTENT_MANAGEMENT
1536
end
1637

1738
class Host

0 commit comments

Comments
 (0)