@@ -493,11 +493,17 @@ final class ExportService: ObservableObject {
493493 return result
494494 }
495495
496- /// Format a value for JSON output
496+ /// Format a value for JSON output with optional type detection
497+ ///
497498 /// - Parameters:
498499 /// - value: The value to format
499500 /// - preserveAsString: If true, always output as string without type detection
500501 /// (preserves leading zeros in ZIP codes, phone numbers, etc.)
502+ ///
503+ /// - Note: When type detection is enabled (preserveAsString = false), integers beyond
504+ /// JavaScript's Number.MAX_SAFE_INTEGER (2^53-1 = 9007199254740991) may lose precision
505+ /// when parsed by JavaScript. For large IDs or precise numeric data, enable the
506+ /// "Preserve All Values as Strings" option in export settings.
501507 private func formatJSONValue( _ value: String ? , preserveAsString: Bool ) -> String {
502508 guard let val = value else { return " null " }
503509
@@ -507,6 +513,7 @@ final class ExportService: ObservableObject {
507513 }
508514
509515 // Try to detect numbers and booleans
516+ // Note: Large integers (> 2^53-1) may lose precision in JavaScript consumers
510517 if let intVal = Int ( val) {
511518 return String ( intVal)
512519 }
@@ -695,14 +702,23 @@ final class ExportService: ObservableObject {
695702 private func compressFileToFile( source: URL , destination: URL ) async throws {
696703 // Run compression on background thread to avoid blocking main thread
697704 try await Task . detached ( priority: . userInitiated) {
705+ // Pre-flight check: verify gzip is available
706+ let gzipPath = " /usr/bin/gzip "
707+ guard FileManager . default. isExecutableFile ( atPath: gzipPath) else {
708+ throw ExportError . exportFailed (
709+ " Compression unavailable: gzip not found at \( gzipPath) . " +
710+ " Please install gzip or disable compression in export options. "
711+ )
712+ }
713+
698714 // Create output file
699715 guard FileManager . default. createFile ( atPath: destination. path, contents: nil ) else {
700716 throw ExportError . fileWriteFailed ( destination. path)
701717 }
702718
703719 // Use gzip to compress the file
704720 let process = Process ( )
705- process. executableURL = URL ( fileURLWithPath: " /usr/bin/gzip " )
721+ process. executableURL = URL ( fileURLWithPath: gzipPath )
706722 process. arguments = [ " -c " , source. path]
707723
708724 let outputFile = try FileHandle ( forWritingTo: destination)
0 commit comments