fix(file): preserve legacy JSON on INDD paths

This commit is contained in:
Dylan M. Taylor committed 2026-11-14 00:40:59 +00:00
1 parent b681b10733
commit 77991abe6f
3 files changed
+32 -10

No files matched your search

Generated
+1 -1
View File
@@ -1085,7 +1085,7 @@ source = "git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad605
[[package]]
name = "craft-csv"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=69e457a8eb0fcdc824434ae12d67ab7d68a240ae#69e457a8eb0fcdc824434ae12d67ab7d68a240ae"
source = "git+https://github.com/storytold/craft-libs?rev=387c64892b30fdad491b263cc3d9eac660d88dcc#387c64892b30fdad491b263cc3d9eac660d88dcc"
dependencies = [
"thiserror 2.0.21",
]
+1 -1
View File
@@ -25,7 +25,7 @@ craft-rtf = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435
craft-xlsx = { git = "https://github.com/storytold/craft-libs", rev = "2b9a325f57624804ed423aded16695eddb815119", version = "=0.1.0" }
craft-docx = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
craft-wordmodel = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
craft-csv = { git = "https://github.com/storytold/craft-libs", rev = "69e457a8eb0fcdc824434ae12d67ab7d68a240ae", version = "=0.1.0" }
craft-csv = { git = "https://github.com/storytold/craft-libs", rev = "387c64892b30fdad491b263cc3d9eac660d88dcc", version = "=0.1.0" }
craft-image-codecs = { git = "https://github.com/dylanmtaylor/craft-libs", rev = "2e670cf9377b523112f3fe4b409399772c745895", version = "=0.1.0" }
craft-psd = { git = "https://github.com/dylanmtaylor/craft-libs", rev = "2e670cf9377b523112f3fe4b409399772c745895", version = "=0.1.0" }
craft-file-formats = { git = "https://github.com/storytold/craft-libs", rev = "eed3c28cf016723d004d6f2c79c61424c15d4558", version = "=0.1.0" }
+30 -8
View File
@@ -85,14 +85,21 @@ fn open_path(s: &mut Session, p: &Value) -> Result<Value> {
// The content decides first: a file's extension may be missing or wrong. The extension
// then routes files whose content isn't recognised to the reader that explains why.
let format = craft_file_formats::detect(path, &bytes);
let native = matches!(format, Some(craft_file_formats::Format::DesignCraft | craft_file_formats::Format::DesignCraftJson));
if format == Some(craft_file_formats::Format::Idml) || (!native && format == Some(craft_file_formats::Format::Indd)) {
let native = matches!(
craft_file_formats::detect("", &bytes),
Some(craft_file_formats::Format::DesignCraft | craft_file_formats::Format::DesignCraftJson)
);
let legacy = (format == Some(craft_file_formats::Format::Indd) && !native).then(|| load_bytes(&bytes).ok()).flatten();
if format == Some(craft_file_formats::Format::Idml) || (!native && format == Some(craft_file_formats::Format::Indd) && legacy.is_none()) {
return crate::cmd::interchange::open_idml(s, p);
}
if !native {
if !native && legacy.is_none() {
return Err(bad("file.open", format!("{path}: not a DesignCraft or IDML file")));
}
let (mut d, mut warnings) = load_bytes(&bytes)?;
let (mut d, mut warnings) = match legacy {
Some(loaded) => loaded,
None => load_bytes(&bytes)?,
};
crate::cmd::interchange::resolve_packaged_links(&mut d, Some(std::path::Path::new(path)));
crate::cmd::datamerge::resolve_sources_on_open(&mut d, Some(std::path::Path::new(path)));
let (fonts, faces, font_warnings) = load_document_fonts(&mut d, path);
@@ -158,11 +165,16 @@ pub(super) fn file_open_bytes(s: &mut Session, p: &Value) -> Result<Value> {
// signature (or their name).
let name = str_param(p, "name").unwrap_or_default();
let format = craft_file_formats::detect(name, &b);
let native = matches!(format, Some(craft_file_formats::Format::DesignCraft | craft_file_formats::Format::DesignCraftJson));
if format == Some(craft_file_formats::Format::Idml) || (!native && format == Some(craft_file_formats::Format::Indd)) {
let native =
matches!(craft_file_formats::detect("", &b), Some(craft_file_formats::Format::DesignCraft | craft_file_formats::Format::DesignCraftJson));
let legacy = (format == Some(craft_file_formats::Format::Indd) && !native).then(|| load_bytes(&b).ok()).flatten();
if format == Some(craft_file_formats::Format::Idml) || (!native && format == Some(craft_file_formats::Format::Indd) && legacy.is_none()) {
return crate::cmd::interchange::open_idml(s, p);
}
let (mut d, warnings) = load_bytes(&b)?;
let (mut d, warnings) = match legacy {
Some(loaded) => loaded,
None => load_bytes(&b)?,
};
crate::cmd::datamerge::resolve_sources_on_open(&mut d, None);
if let Some(n) = str_param(p, "name") {
// Titled as an IDML file opened from bytes is: without its extension.
@@ -510,7 +522,17 @@ mod open_bytes_tests {
maker.execute("file.new", &json!({})).unwrap();
let idml = designcraft_idml::export_idml(&maker.doc().unwrap().doc);
let base64 = super::super::bytes::base64_encode(&idml);
let legacy = super::super::bytes::base64_encode(&serde_json::to_vec(&maker.doc().unwrap().doc).unwrap());
let legacy_bytes = serde_json::to_vec(&maker.doc().unwrap().doc).unwrap();
let legacy = super::super::bytes::base64_encode(&legacy_bytes);
#[cfg(not(target_arch = "wasm32"))]
{
let legacy_path = std::env::temp_dir().join(format!("dc-legacy-indd-{}.indd", std::process::id()));
std::fs::write(&legacy_path, &legacy_bytes).unwrap();
let mut by_path = Session::new();
by_path.execute("file.open", &json!({"path": legacy_path})).unwrap();
assert_eq!(by_path.documents().len(), 1, "legacy JSON must win over an InDesign extension");
let _ = std::fs::remove_file(&legacy_path);
}
for name in ["Brochure.indd", "Brochure.INDT"] {
let mut s = Session::new();
s.execute("file.openBytes", &json!({"name": name, "base64": legacy})).unwrap();