Enhance project cloning and initialization process

- Updated CloneCommand to support multiple place IDs, allowing the creation of multi-place projects with individual project files for each place.
- Refactored the initialization logic in InitCommand to streamline project setup and ensure proper handling of project templates.
- Added a new function to fetch place names from the Roblox API, improving the user experience during project creation.
- Updated TODO.txt with a new entry for fixing the luau-lsp sourcemap generator command.
This commit is contained in:
Joe 2026-03-06 22:49:32 -06:00
parent cf31e9b914
commit 093e62af8e
4 changed files with 575 additions and 168 deletions

View file

@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::io::{self, Write as _};
use anyhow::{bail, Context};
@ -250,6 +251,56 @@ pub fn fetch_experience_name(place_id: u64, auth: &RobloxAuth) -> anyhow::Result
Ok(None)
}
#[derive(Debug, Deserialize)]
struct PlaceDetail {
#[serde(rename = "placeId")]
place_id: u64,
name: String,
}
/// Fetch place names for one or more place IDs via the multiget-place-details endpoint.
///
/// Returns a map of place_id -> place_name. Places that cannot be resolved are omitted.
/// Falls back to no-auth if API key auth fails (games.roblox.com may not support it).
pub fn fetch_place_names(
place_ids: &[u64],
auth: &RobloxAuth,
) -> anyhow::Result<HashMap<u64, String>> {
let client = reqwest::blocking::Client::new();
let mut url = "https://games.roblox.com/v1/games/multiget-place-details?".to_string();
for (i, id) in place_ids.iter().enumerate() {
if i > 0 {
url.push('&');
}
url.push_str(&format!("placeIds={id}"));
}
let try_parse = |resp: reqwest::blocking::Response| -> Option<HashMap<u64, String>> {
let details: Vec<PlaceDetail> = resp.json().ok()?;
let map: HashMap<u64, String> = details.into_iter().map(|d| (d.place_id, d.name)).collect();
Some(map)
};
let req = apply_auth(client.get(&url), auth);
if let Ok(resp) = req.send() {
if let Some(map) = try_parse(resp) {
return Ok(map);
}
}
if matches!(auth, RobloxAuth::ApiKey(_)) {
let req = client.get(&url);
if let Ok(resp) = req.send() {
if let Some(map) = try_parse(resp) {
return Ok(map);
}
}
}
Ok(HashMap::new())
}
fn apply_auth(
req: reqwest::blocking::RequestBuilder,
auth: &RobloxAuth,