Skip to content

Commit 88d522c

Browse files
committed
Add autodiscovery of api-root for WpOrg sites too
1 parent 65e811e commit 88d522c

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

wp_rs_cli/src/bin/wp_rs_cli/main.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ fn build_login_client() -> WpLoginClient {
179179
#[derive(Debug, Parser)]
180180
#[command(group(
181181
ArgGroup::new("target")
182-
.required(true)
183182
.args(["wpcom_site", "api_root"]),
184183
), group(
185184
ArgGroup::new("post_ref")
@@ -240,20 +239,47 @@ enum TargetSiteResolver {
240239
WpOrg { api_root: Arc<ParsedUrl> },
241240
}
242241

243-
fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
242+
async fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
243+
let request_executor = Arc::new(ReqwestRequestExecutor::new(false, Duration::from_secs(60)));
244+
let middleware_pipeline = Arc::new(WpApiMiddlewarePipeline::default());
244245
// Determine target and auth
245246
let target = if let Some(site) = &args.wpcom_site {
247+
// Explicit WordPress.com site takes priority
246248
TargetSiteResolver::WpCom { site: site.clone() }
247249
} else if let Some(api_root) = &args.api_root {
248-
let parsed = ParsedUrl::try_from(api_root.as_str()).map_err(|_| {
249-
anyhow!("Invalid api_root URL: must be a valid URL ending with /wp-json")
250-
})?;
251-
TargetSiteResolver::WpOrg {
252-
api_root: Arc::new(parsed),
250+
// Explicit api_root takes priority for wp.org/Jetpack
251+
let parsed = ParsedUrl::try_from(api_root.as_str())
252+
.map_err(|_| anyhow!("Invalid api_root URL: must be a valid URL ending with /wp-json"))?;
253+
TargetSiteResolver::WpOrg { api_root: Arc::new(parsed) }
254+
} else if let Some(post_url) = &args.post_url {
255+
// Derive from post_url if possible
256+
if let Ok(u) = Url::parse(post_url) {
257+
let host = u.host_str().unwrap_or("");
258+
if host.ends_with(".wordpress.com") {
259+
TargetSiteResolver::WpCom { site: host.to_string() }
260+
} else {
261+
// Attempt autodiscovery of API root from post URL
262+
let login_client = WpLoginClient::new_with_default_middleware_pipeline(request_executor.clone());
263+
match login_client
264+
.api_discovery(post_url.clone())
265+
.await
266+
.combined_result()
267+
.cloned()
268+
{
269+
Ok(success) => TargetSiteResolver::WpOrg { api_root: success.api_root_url },
270+
Err(_) => {
271+
return Err(anyhow!(
272+
"Could not autodiscover API root from --post-url. Please provide --api-root explicitly."
273+
));
274+
}
275+
}
276+
}
277+
} else {
278+
return Err(anyhow!("Invalid --post-url; could not parse URL"));
253279
}
254280
} else {
255281
return Err(anyhow!(
256-
"Either --wpcom-site or --api-root must be provided"
282+
"Provide either --wpcom-site, or --api-root, or a wordpress.com --post-url"
257283
));
258284
};
259285

@@ -294,9 +320,6 @@ fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
294320
}
295321
};
296322

297-
let request_executor = Arc::new(ReqwestRequestExecutor::new(false, Duration::from_secs(60)));
298-
let middleware_pipeline = Arc::new(WpApiMiddlewarePipeline::default());
299-
300323
#[derive(Debug)]
301324
struct NoopNotifier;
302325
#[async_trait::async_trait]
@@ -316,7 +339,7 @@ fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
316339
}
317340

318341
async fn fetch_post_and_comments(args: FetchPostArgs) -> Result<()> {
319-
let client = build_api_client(&args)?;
342+
let client = build_api_client(&args).await?;
320343

321344
let post_id = resolve_post_id(&client, &args).await?;
322345

0 commit comments

Comments
 (0)