Skip to content
This repository has been archived by the owner on Mar 25, 2023. It is now read-only.

dynamic urls fixes #695

Merged
merged 11 commits into from
Jan 5, 2023
47 changes: 47 additions & 0 deletions examples/dynamic-urls/FPM.ftd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

-- import: fpm

-- fpm.package: dynamic-urls
download-base-url: https://www.github.com/


-- fpm.sitemap:

# Page 1: /foo/a/
document: /bar/b/


-- fpm.dynamic-urls:

# TOC00
url: /a/ < integer : age > /person/
document: index.ftd

## TOC01
url: /a/ < string : username > /person/
document: index1.ftd

- TOC1
url: /b/<integer:age>/person/
document: index.ftd

- TOC1
url: /b/<string:username>/person/
document: index1.ftd

- TOC1
url: /b/<string:username>/person/foo/
document: index.ftd


- TOC3
url: /d/<string:username>/<integer:age>/
document: index.ftd

- TOC3
url: /<string:username>/<integer:age>/
document: index1.ftd

- TOC3
url: /<string:username>/<string:class>/
document: index.ftd
1 change: 1 addition & 0 deletions examples/dynamic-urls/bar/b.ftd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- ftd.text: I am from bar/b.ftd
1 change: 1 addition & 0 deletions examples/dynamic-urls/foo/a.ftd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- ftd.text: I am inside the foo/a
1 change: 1 addition & 0 deletions examples/dynamic-urls/index.ftd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- ftd.text: Hello From Index
1 change: 1 addition & 0 deletions examples/dynamic-urls/index1.ftd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- ftd.text: Hello From Index 1
68 changes: 40 additions & 28 deletions src/commands/create_package.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
async fn template_contents(project_name: &str) -> (String, String) {
let ftd = format!("-- import: fpm\n\n-- fpm.package: {}", project_name);
async fn template_contents(project_name: &str, download_base_url: &str) -> (String, String) {
let ftd = format!(
r#"-- import: fpm

-- fpm.package: {}
download-base-url: {}
"#,
project_name, download_base_url
);
let index = "-- ftd.text: Hello world".to_string();

(ftd, index)
}

pub async fn create_package(name: &str, path: Option<&str>) -> fpm::Result<()> {
pub async fn create_package(
name: &str,
path: Option<&str>,
download_base_url: Option<&str>,
) -> fpm::Result<()> {
use colored::Colorize;

let base_path = {
Expand Down Expand Up @@ -36,38 +47,39 @@ pub async fn create_package(name: &str, path: Option<&str>) -> fpm::Result<()> {
// Create all directories if not present
tokio::fs::create_dir_all(final_dir.as_str()).await?;

let tmp_contents = template_contents(name).await;
let tmp_contents = template_contents(name, download_base_url.unwrap_or(name)).await;
let tmp_fpm = tmp_contents.0;
let tmp_index = tmp_contents.1;

fpm::utils::update(&final_dir.join("FPM.ftd"), tmp_fpm.as_bytes()).await?;
fpm::utils::update(&final_dir.join("index.ftd"), tmp_index.as_bytes()).await?;

let sync_message = "Initial sync".to_string();
let file_list: std::collections::BTreeMap<String, fpm::history::FileEditTemp> =
IntoIterator::into_iter([
(
"FPM.ftd".to_string(),
fpm::history::FileEditTemp {
message: Some(sync_message.to_string()),
author: None,
src_cr: None,
operation: fpm::history::FileOperation::Added,
},
),
(
"index.ftd".to_string(),
fpm::history::FileEditTemp {
message: Some(sync_message.to_string()),
author: None,
src_cr: None,
operation: fpm::history::FileOperation::Added,
},
),
])
.collect();
// Note: Not required for now
// let sync_message = "Initial sync".to_string();
// let file_list: std::collections::BTreeMap<String, fpm::history::FileEditTemp> =
// IntoIterator::into_iter([
// (
// "FPM.ftd".to_string(),
// fpm::history::FileEditTemp {
// message: Some(sync_message.to_string()),
// author: None,
// src_cr: None,
// operation: fpm::history::FileOperation::Added,
// },
// ),
// (
// "index.ftd".to_string(),
// fpm::history::FileEditTemp {
// message: Some(sync_message.to_string()),
// author: None,
// src_cr: None,
// operation: fpm::history::FileOperation::Added,
// },
// ),
// ])
// .collect();

fpm::history::insert_into_history(&final_dir, &file_list, &mut Default::default()).await?;
// fpm::history::insert_into_history(&final_dir, &file_list, &mut Default::default()).await?;

println!(
"FPM Package Created: {}\nPath: {}",
Expand Down
2 changes: 1 addition & 1 deletion src/commands/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pub async fn serve(
// pass the url if the file is not static
// So final check would be file is not static and path is not present in the package's sitemap
tracing::info!(
"executing proxy: file-status: {}, path: {}",
"before executing proxy: file-status: {}, path: {}",
file_response.status(),
&path
);
Expand Down
18 changes: 4 additions & 14 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,20 +719,10 @@ impl Config {
};

// Getting `document` with dynamic parameters, if exists
let (document, path_params) = match sanitized_package.sitemap.as_ref() {
//1. First resolve document in sitemap
Some(sitemap) => match sitemap.resolve_document(sanitized_path.as_str()) {
Some(document) => (Some(document), vec![]),
//2. Else resolve document in dynamic urls
None => match sanitized_package.dynamic_urls.as_ref() {
Some(dynamic_urls) => {
dynamic_urls.resolve_document(sanitized_path.as_str())?
}
None => (None, vec![]),
},
},
None => (None, vec![]),
};
// It will first resolve in sitemap
// Then it will resolve in the dynamic urls
let (document, path_params) =
fpm::sitemap::resolve(sanitized_package, &sanitized_path)?;

// document with package-name prefix
let document = document.map(|doc| {
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Error {
Self::GenericError(error.to_string())
}

pub fn generic_err<T: AsRef<str> + ToString>(error: T) -> fpm::Result<()> {
pub fn generic_err<T: AsRef<str> + ToString, O>(error: T) -> fpm::Result<O> {
Err(Self::generic(error))
}
}
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ async fn async_main() -> fpm::Result<()> {
let name = project.value_of_("name").unwrap();
// project-path is optional
let path = project.value_of_("path");
return fpm::create_package(name, path).await;
let download_base_url = project.value_of_("download-base-url");
return fpm::create_package(name, path, download_base_url).await;
}

if let Some(mark) = matches.subcommand_matches("serve") {
Expand Down Expand Up @@ -208,6 +209,7 @@ fn app(version: &'static str) -> clap::Command {
.about("Create a new FPM package")
.arg(clap::arg!(name: <NAME> "The name of the package to create"))
.arg(clap::arg!(-p --path [PATH] "Where to create the package (relative or absolute path, default value: the name)"))
.arg(clap::arg!(--"download-base-url" <DOWNLOAD_BASE_URL> "base url of the package where it can downloaded"))
)
.subcommand(
clap::Command::new("build")
Expand Down
57 changes: 31 additions & 26 deletions src/sitemap/dynamic_urls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// document and path-parameters
type ResolveDocOutput = (Option<String>, Vec<(String, ftd::Value)>);
pub(crate) type ResolveDocOutput = (Option<String>, Vec<(String, ftd::Value)>);

#[derive(Debug, serde::Deserialize, Clone)]
pub struct DynamicUrlsTemp {
Expand Down Expand Up @@ -98,6 +98,7 @@ impl DynamicUrls {
false
}

#[tracing::instrument(name = "dynamic-urls-resolve-document")]
pub fn resolve_document(&self, path: &str) -> fpm::Result<ResolveDocOutput> {
fn resolve_in_toc(
toc: &fpm::sitemap::toc::TocItem,
Expand All @@ -108,14 +109,10 @@ impl DynamicUrls {
// request: arpita foo 28
// sitemap: [string,integer]
// Mapping: arpita -> string, foo -> foo, 28 -> integer
let params = fpm::sitemap::utils::parse_named_params(
path,
toc.id.as_str(),
toc.path_parameters.as_slice(),
);
let params = fpm::sitemap::utils::url_match(path, toc.path_parameters.as_slice())?;

if params.is_ok() {
return Ok((toc.document.clone(), params?));
if params.0 {
return Ok((toc.document.clone(), params.1));
}
}

Expand All @@ -138,16 +135,11 @@ impl DynamicUrls {
// request: arpita foo 28
// sitemap: [string,integer]
// Mapping: arpita -> string, foo -> foo, 28 -> integer
if let Some(id) = sub_section.id.as_ref() {
let params = fpm::sitemap::utils::parse_named_params(
path,
id.as_str(),
sub_section.path_parameters.as_slice(),
);
let params =
fpm::sitemap::utils::url_match(path, sub_section.path_parameters.as_slice())?;

if params.is_ok() {
return Ok((sub_section.document.clone(), params?));
}
if params.0 {
return Ok((sub_section.document.clone(), params.1));
}
}
for toc in sub_section.toc.iter() {
Expand All @@ -171,14 +163,11 @@ impl DynamicUrls {
// request: abrark foo 28
// sitemap: [string,integer]
// params_matches: abrark -> string, foo -> foo, 28 -> integer
let params = fpm::sitemap::utils::parse_named_params(
path,
section.id.as_str(),
section.path_parameters.as_slice(),
);
let params =
fpm::sitemap::utils::url_match(path, section.path_parameters.as_slice())?;

if params.is_ok() {
return Ok((section.document.clone(), params?));
if params.0 {
return Ok((section.document.clone(), params.1));
}
}

Expand All @@ -194,10 +183,12 @@ impl DynamicUrls {
for section in self.sections.iter() {
let (document, path_params) = resolve_in_section(section, path)?;
if document.is_some() {
tracing::info!(msg = "return: document found", path = path);
return Ok((document, path_params));
}
}

tracing::info!(msg = "return: document not found", path = path);
Ok((None, vec![]))
}
}
Expand Down Expand Up @@ -273,7 +264,14 @@ mod tests {
readers: vec!["readers/person".to_string()],
writers: vec!["writers/person".to_string()],
document: Some("person.ftd".to_string()),
path_parameters: vec![("string".to_string(), "name".to_string())],
path_parameters: vec![
fpm::sitemap::PathParams::value(0, "person".to_string()),
fpm::sitemap::PathParams::named(
1,
"name".to_string(),
"string".to_string(),
),
],
confidential: true,
},
fpm::sitemap::toc::TocItem {
Expand All @@ -299,7 +297,14 @@ mod tests {
readers: vec!["readers/person".to_string()],
writers: vec!["writers/person".to_string()],
document: Some("person.ftd".to_string()),
path_parameters: vec![("string".to_string(), "name".to_string())],
path_parameters: vec![
fpm::sitemap::PathParams::value(0, "person".to_string()),
fpm::sitemap::PathParams::named(
1,
"name".to_string(),
"string".to_string(),
),
],
confidential: true,
},
],
Expand Down
Loading