pysof 0.1.31__tar.gz → 0.1.32__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. {pysof-0.1.31 → pysof-0.1.32}/Cargo.toml +2 -2
  2. {pysof-0.1.31 → pysof-0.1.32}/PKG-INFO +1 -1
  3. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/Cargo.toml +2 -2
  4. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/Cargo.toml +1 -1
  5. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/Cargo.toml +2 -2
  6. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Cargo.toml +2 -2
  7. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/Cargo.toml +3 -3
  8. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/README.md +19 -19
  9. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/cli.rs +40 -8
  10. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/handlers.rs +58 -25
  11. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/models.rs +2 -2
  12. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/server.rs +2 -2
  13. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/common/mod.rs +8 -8
  14. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/server_tests.rs +23 -19
  15. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_format_parameter_body.rs +7 -7
  16. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_header_parameter_body.rs +7 -7
  17. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_limit_parameter_body.rs +6 -6
  18. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parameter_validation.rs +1 -1
  19. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_patient_reference_formats.rs +4 -4
  20. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_query_parameter_combinations.rs +13 -13
  21. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_run_operation_parameters.rs +2 -2
  22. pysof-0.1.31/crates/sof/operations-run.md +0 -544
  23. {pysof-0.1.31 → pysof-0.1.32}/README.md +0 -0
  24. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/README.md +0 -0
  25. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/build.rs +0 -0
  26. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/lib.rs +0 -0
  27. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/parameters.rs +0 -0
  28. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r4.rs +0 -0
  29. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r4b.rs +0 -0
  30. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r5.rs +0 -0
  31. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r6.rs +0 -0
  32. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r6.rs.template +0 -0
  33. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/integer_string_integration.rs +0 -0
  34. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/simple_null_test.rs +0 -0
  35. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/test_examples.rs +0 -0
  36. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/test_serde.rs +0 -0
  37. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/README.md +0 -0
  38. {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/src/lib.rs +0 -0
  39. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/PRECISION_LIMITATION.md +0 -0
  40. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/README.md +0 -0
  41. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/cli_benches.rs +0 -0
  42. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/evaluator_benches.rs +0 -0
  43. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/parser_benches.rs +0 -0
  44. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/server_benches.rs +0 -0
  45. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/examples/test_ucum.rs +0 -0
  46. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/grammar/fhirpath.g4 +0 -0
  47. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/server-api.md +0 -0
  48. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/aggregate_function.rs +0 -0
  49. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/bin/fhirpath-cli.rs +0 -0
  50. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/bin/fhirpath-server.rs +0 -0
  51. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/boolean_functions.rs +0 -0
  52. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/boundary_functions.rs +0 -0
  53. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/cli.rs +0 -0
  54. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/collection_functions.rs +0 -0
  55. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/collection_navigation.rs +0 -0
  56. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/contains_function.rs +0 -0
  57. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/conversion_functions.rs +0 -0
  58. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/date_operation.rs +0 -0
  59. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/datetime_impl.rs +0 -0
  60. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/distinct_functions.rs +0 -0
  61. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/error.rs +0 -0
  62. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/evaluator.rs +0 -0
  63. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/extension_function.rs +0 -0
  64. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/fhir_type_hierarchy.rs +0 -0
  65. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/handlers.rs +0 -0
  66. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/json_utils.rs +0 -0
  67. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/lib.rs +0 -0
  68. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/long_conversion.rs +0 -0
  69. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/models.rs +0 -0
  70. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/not_function.rs +0 -0
  71. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/parse_debug.rs +0 -0
  72. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/parser.rs +0 -0
  73. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/polymorphic_access.rs +0 -0
  74. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/reference_key_functions.rs +0 -0
  75. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/repeat_function.rs +0 -0
  76. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/resource_type.rs +0 -0
  77. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/server.rs +0 -0
  78. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/set_operations.rs +0 -0
  79. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/subset_functions.rs +0 -0
  80. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/terminology_client.rs +0 -0
  81. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/terminology_functions.rs +0 -0
  82. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/trace_function.rs +0 -0
  83. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/type_function.rs +0 -0
  84. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/type_inference.rs +0 -0
  85. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/ucum.rs +0 -0
  86. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/all_function_tests.rs +0 -0
  87. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/boundary_debug_tests.rs +0 -0
  88. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/boundary_function_integration_tests.rs +0 -0
  89. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/comment_test.rs +0 -0
  90. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/context.rs +0 -0
  91. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/mod.rs +0 -0
  92. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/parser.rs +0 -0
  93. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/runner.rs +0 -0
  94. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/context_trace_test.rs +0 -0
  95. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/observation-example.json +0 -0
  96. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/observation-example.xml +0 -0
  97. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/patient-example.json +0 -0
  98. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/patient-example.xml +0 -0
  99. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/questionnaire-example.json +0 -0
  100. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/questionnaire-example.xml +0 -0
  101. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.json +0 -0
  102. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.xml +0 -0
  103. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/tests-fhir-r4.xml +0 -0
  104. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/appointment-examplereq.json +0 -0
  105. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/ccda.json +0 -0
  106. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/codesystem-example.json +0 -0
  107. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/conceptmap-example.json +0 -0
  108. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/explanationofbenefit-example.json +0 -0
  109. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/observation-example.json +0 -0
  110. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/observation-example.xml +0 -0
  111. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/parameters-example-types.json +0 -0
  112. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-container-example.json +0 -0
  113. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example-name.json +0 -0
  114. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example-period.json +0 -0
  115. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example.json +0 -0
  116. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-name-extensions.json +0 -0
  117. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/questionnaire-example.json +0 -0
  118. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/valueset-example-expansion.json +0 -0
  119. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/known-test-failures.json +0 -0
  120. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/tests-fhir-r5.xml +0 -0
  121. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/testSchema.xsd +0 -0
  122. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/date_operation_tests.rs +0 -0
  123. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/datetime_boundary_tests.rs +0 -0
  124. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/debug_datetime_boundary.rs +0 -0
  125. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/debug_string_boundary_tests.rs +0 -0
  126. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/define_variable_test.rs +0 -0
  127. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/enhanced_variable_tests.rs +0 -0
  128. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/evaluator_tests.rs +0 -0
  129. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/extension_tests.rs +0 -0
  130. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/fhir_boundary_tests.rs +0 -0
  131. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/is_as_method_tests.rs +0 -0
  132. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/join_function_test.rs +0 -0
  133. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/oftype_datetime_tests.rs +0 -0
  134. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/parse_debug_test.rs +0 -0
  135. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/parser_tests.rs +0 -0
  136. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/polymorphic_r4_tests.rs +0 -0
  137. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/polymorphic_tests.rs +0 -0
  138. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/precision_tests.rs +0 -0
  139. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/r4_tests.rs +0 -0
  140. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/r5_tests.rs +0 -0
  141. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/reference_key_debug.rs +0 -0
  142. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/test_boundary_zero.rs +0 -0
  143. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/trace_api_test.rs +0 -0
  144. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/trace_tests.rs +0 -0
  145. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/tree_navigation_tests.rs +0 -0
  146. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/truncate_tests.rs +0 -0
  147. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_operation_tests.rs +0 -0
  148. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_preservation_integration_test.rs +0 -0
  149. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_reflection_tests.rs +0 -0
  150. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/uri_type_test.rs +0 -0
  151. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/uuid_type_preservation_test.rs +0 -0
  152. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/Cargo.toml +0 -0
  153. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/README.md +0 -0
  154. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/src/lib.rs +0 -0
  155. {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/src/type_info.rs +0 -0
  156. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/.gitignore +0 -0
  157. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Cargo.lock +0 -0
  158. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Makefile +0 -0
  159. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/PYPI_CHECKLIST.md +0 -0
  160. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/README.md +0 -0
  161. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/WHEEL_BUILDING.md +0 -0
  162. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/multithreading_example.py +0 -0
  163. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/__init__.py +0 -0
  164. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_content_types.py +0 -0
  165. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_core_functions.py +0 -0
  166. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_error_handling.py +0 -0
  167. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_fhir_versions.py +0 -0
  168. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_import.py +0 -0
  169. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_package_metadata.py +0 -0
  170. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_source_errors.py +0 -0
  171. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/scripts/build-wheels.py +0 -0
  172. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/lib.rs +0 -0
  173. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/__init__.py +0 -0
  174. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/_pysof.pyi +0 -0
  175. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/py.typed +0 -0
  176. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/test_multithreading.py +0 -0
  177. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/content_types.rs +0 -0
  178. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/error_handling.rs +0 -0
  179. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/fhir_versions.rs +0 -0
  180. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/mod.rs +0 -0
  181. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration.rs +0 -0
  182. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/lib_coverage_tests.rs +0 -0
  183. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/lib_tests.rs +0 -0
  184. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/multithreading_integration.rs +0 -0
  185. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/threading_test.rs +0 -0
  186. {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/uv.lock +0 -0
  187. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/benches/parallel_processing_bench.rs +0 -0
  188. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/data_source.rs +0 -0
  189. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/error.rs +0 -0
  190. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/lib.rs +0 -0
  191. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/mod.rs +0 -0
  192. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/parquet_schema.rs +0 -0
  193. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/streaming.rs +0 -0
  194. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/traits.rs +0 -0
  195. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_boolean_test.rs +0 -0
  196. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_column_ordering.rs +0 -0
  197. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_datetime_instant_constants.rs +0 -0
  198. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_datetime_type_info.rs +0 -0
  199. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_enum_conversion.rs +0 -0
  200. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_evaluation_result_conversion.rs +0 -0
  201. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_function.rs +0 -0
  202. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_macro_fix.rs +0 -0
  203. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_simple.rs +0 -0
  204. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_fhir_resource_structure.rs +0 -0
  205. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_foreach_combinations.rs +0 -0
  206. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_inequality.rs +0 -0
  207. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_instant_constant.rs +0 -0
  208. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_instant_type_info.rs +0 -0
  209. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_raw_resource.rs +0 -0
  210. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_reference_key_types.rs +0 -0
  211. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/extension_debug_test.rs +0 -0
  212. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/foreach_test.rs +0 -0
  213. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/multiselect_test.rs +0 -0
  214. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/run_foreach_tests.rs +0 -0
  215. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/basic.json +0 -0
  216. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/collection.json +0 -0
  217. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/combinations.json +0 -0
  218. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/constant.json +0 -0
  219. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/constant_types.json +0 -0
  220. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath.json +0 -0
  221. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath_numbers.json +0 -0
  222. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_boundary.json +0 -0
  223. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_empty.json +0 -0
  224. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_extension.json +0 -0
  225. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_first.json +0 -0
  226. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_join.json +0 -0
  227. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_oftype.json +0 -0
  228. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_reference_keys.json +0 -0
  229. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/foreach.json +0 -0
  230. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/logic.json +0 -0
  231. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/repeat.json +0 -0
  232. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/union.json +0 -0
  233. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/validate.json +0 -0
  234. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/view_resource.json +0 -0
  235. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/where.json +0 -0
  236. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql_on_fhir_tests.rs +0 -0
  237. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_base64_binary_constant.rs +0 -0
  238. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug.rs +0 -0
  239. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug2.rs +0 -0
  240. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug3.rs +0 -0
  241. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_validation.rs +0 -0
  242. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_chunked_processing.rs +0 -0
  243. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_cli_file_source.rs +0 -0
  244. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_csv_quote_handling.rs +0 -0
  245. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_extension_fix_verification.rs +0 -0
  246. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_extension_value_access.rs +0 -0
  247. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_ndjson_input.rs +0 -0
  248. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parallel_working.rs +0 -0
  249. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_export.rs +0 -0
  250. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_large_dataset.rs +0 -0
  251. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_server_options.rs +0 -0
  252. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_runner_integration.rs +0 -0
  253. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_shortened_format_names.rs +0 -0
  254. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_where_clause_validation.rs +0 -0
  255. {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_x_ndjson_support.rs +0 -0
  256. {pysof-0.1.31 → pysof-0.1.32}/pyproject.toml +0 -0
  257. {pysof-0.1.31 → pysof-0.1.32}/src/lib.rs +0 -0
  258. {pysof-0.1.31 → pysof-0.1.32}/src/pysof/__init__.py +0 -0
  259. {pysof-0.1.31 → pysof-0.1.32}/src/pysof/_pysof.cpython-311-darwin.so +0 -0
  260. {pysof-0.1.31 → pysof-0.1.32}/src/pysof/_pysof.pyi +0 -0
  261. {pysof-0.1.31 → pysof-0.1.32}/src/pysof/py.typed +0 -0
@@ -15,8 +15,8 @@ crate-type = ["cdylib"]
15
15
 
16
16
  [dependencies]
17
17
  pyo3 = { version = ">=0.24.1", features = ["extension-module", "generate-import-lib"] }
18
- helios-sof = { path = "../sof", version = "0.1.31" }
19
- helios-fhir = { path = "../fhir", version = "0.1.31" }
18
+ helios-sof = { path = "../sof", version = "0.1.32" }
19
+ helios-fhir = { path = "../fhir", version = "0.1.32" }
20
20
  serde = { version = "=1.0.219", features = ["derive"] }
21
21
  serde_json = { version = "=1.0.143" }
22
22
  chrono = { version = "0.4", features = ["serde"] }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pysof
3
- Version: 0.1.31
3
+ Version: 0.1.32
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.10
6
6
  Classifier: Programming Language :: Python :: 3.11
@@ -22,8 +22,8 @@ skip-r6-download = []
22
22
  serde = { workspace = true }
23
23
  serde_json = { workspace = true, features = ["raw_value"] }
24
24
  clap = { version = "4.0", features = ["derive"] }
25
- helios-fhir-macro = { path = "../fhir-macro", version = "0.1.31" }
26
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.31" }
25
+ helios-fhir-macro = { path = "../fhir-macro", version = "0.1.32" }
26
+ helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
27
27
  time = "0.3"
28
28
  chrono = { workspace = true }
29
29
  # Re-add serde-with-arbitrary-precision, keep macros
@@ -19,4 +19,4 @@ proc-macro2 = "1.0"
19
19
  serde = { workspace = true }
20
20
  serde_json = { workspace = true }
21
21
  heck = "0.5" # For case conversion
22
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.31" }
22
+ helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
@@ -17,8 +17,8 @@ R5 = ["helios-fhir/R5"]
17
17
  R6 = ["helios-fhir/R6"]
18
18
 
19
19
  [dependencies]
20
- helios-fhir = { path = "../fhir", version = "0.1.31" }
21
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.31" }
20
+ helios-fhir = { path = "../fhir", version = "0.1.32" }
21
+ helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
22
22
  chumsky = "0.10"
23
23
  roxmltree = "0.20"
24
24
  chrono = { workspace = true } # For date/time parsing and functions
@@ -16,8 +16,8 @@ crate-type = ["cdylib"]
16
16
 
17
17
  [dependencies]
18
18
  pyo3 = { version = ">=0.24.1", features = ["extension-module", "generate-import-lib"] }
19
- helios-sof = { path = "../sof", version = "0.1.31" }
20
- helios-fhir = { path = "../fhir", version = "0.1.31" }
19
+ helios-sof = { path = "../sof", version = "0.1.32" }
20
+ helios-fhir = { path = "../fhir", version = "0.1.32" }
21
21
  serde = { version = "=1.0.219", features = ["derive"] }
22
22
  serde_json = { version = "=1.0.143" }
23
23
  chrono = { version = "0.4", features = ["serde"] }
@@ -27,9 +27,9 @@ R6 = ["helios-fhir/R6", "helios-fhirpath/R6"]
27
27
  [dependencies]
28
28
  clap = { version = "4.0", features = ["derive", "env"] }
29
29
  tokio = { version = "1.0", features = ["full"] }
30
- helios-fhir = { path = "../fhir", version = "0.1.31" }
31
- helios-fhirpath = { path = "../fhirpath", version = "0.1.31" }
32
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.31" }
30
+ helios-fhir = { path = "../fhir", version = "0.1.32" }
31
+ helios-fhirpath = { path = "../fhirpath", version = "0.1.32" }
32
+ helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
33
33
  serde = { workspace = true }
34
34
  serde_json = { workspace = true }
35
35
  csv = "1.3"
@@ -263,7 +263,7 @@ sof-cli -v view.json -s s3://bucket/patients.ndjson -f json
263
263
  sof-cli -v view.json -s file:///data.ndjson -b additional-data.json -f csv
264
264
 
265
265
  # Server API with NDJSON
266
- curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://bucket/data.ndjson" \
266
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=s3://bucket/data.ndjson" \
267
267
  -H "Content-Type: application/json" \
268
268
  -d '{"resourceType": "Parameters", "parameter": [{"name": "viewResource", "resource": {...}}]}'
269
269
  ```
@@ -472,12 +472,12 @@ Returns the server's CapabilityStatement describing supported operations:
472
472
  curl http://localhost:8080/metadata
473
473
  ```
474
474
 
475
- ##### POST /ViewDefinition/$run
475
+ ##### POST /ViewDefinition/$viewdefinition-run
476
476
  Execute a ViewDefinition transformation:
477
477
 
478
478
  ```bash
479
479
  # JSON output (default)
480
- curl -X POST http://localhost:8080/ViewDefinition/$run \
480
+ curl -X POST http://localhost:8080/ViewDefinition/$viewdefinition-run \
481
481
  -H "Content-Type: application/json" \
482
482
  -d '{
483
483
  "resourceType": "Parameters",
@@ -508,17 +508,17 @@ curl -X POST http://localhost:8080/ViewDefinition/$run \
508
508
  }'
509
509
 
510
510
  # CSV output (includes headers by default)
511
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
511
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv" \
512
512
  -H "Content-Type: application/json" \
513
513
  -d '{...}'
514
514
 
515
515
  # CSV output without headers
516
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv&header=false" \
516
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv&header=false" \
517
517
  -H "Content-Type: application/json" \
518
518
  -d '{...}'
519
519
 
520
520
  # NDJSON output
521
- curl -X POST http://localhost:8080/ViewDefinition/$run \
521
+ curl -X POST http://localhost:8080/ViewDefinition/$viewdefinition-run \
522
522
  -H "Content-Type: application/json" \
523
523
  -H "Accept: application/ndjson" \
524
524
  -d '{...}'
@@ -526,7 +526,7 @@ curl -X POST http://localhost:8080/ViewDefinition/$run \
526
526
 
527
527
  #### Parameters
528
528
 
529
- The `$run` POST operation accepts parameters either as query parameters or in a FHIR Parameters resource.
529
+ The `$viewdefinition-run` POST operation accepts parameters either as query parameters or in a FHIR Parameters resource.
530
530
 
531
531
  Parameter table:
532
532
 
@@ -617,17 +617,17 @@ The server automatically sets appropriate response headers based on the output f
617
617
 
618
618
  ```bash
619
619
  # Limit results - first 50 records as CSV
620
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_limit=50&_format=text/csv" \
620
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_limit=50&_format=text/csv" \
621
621
  -H "Content-Type: application/json" \
622
622
  -d '{...}'
623
623
 
624
624
  # CSV without headers, limited to 20 results
625
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv&header=false&_limit=20" \
625
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv&header=false&_limit=20" \
626
626
  -H "Content-Type: application/json" \
627
627
  -d '{...}'
628
628
 
629
629
  # Using header parameter in request body (overrides query params)
630
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
630
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv" \
631
631
  -H "Content-Type: application/json" \
632
632
  -d '{
633
633
  "resourceType": "Parameters",
@@ -641,12 +641,12 @@ curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
641
641
  }'
642
642
 
643
643
  # Filter by modification time (requires resources with lastUpdated metadata)
644
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_since=2024-01-01T00:00:00Z" \
644
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_since=2024-01-01T00:00:00Z" \
645
645
  -H "Content-Type: application/json" \
646
646
  -d '{...}'
647
647
 
648
648
  # Load data from S3 bucket
649
- curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://my-bucket/bundle.json" \
649
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=s3://my-bucket/bundle.json" \
650
650
  -H "Content-Type: application/json" \
651
651
  -d '{
652
652
  "resourceType": "Parameters",
@@ -657,24 +657,24 @@ curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://my-bucket/bu
657
657
  }'
658
658
 
659
659
  # Load data from Azure with filtering
660
- curl -X POST "http://localhost:8080/ViewDefinition/$run?source=azure://container/data.json&_limit=100" \
660
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=azure://container/data.json&_limit=100" \
661
661
  -H "Content-Type: application/json" \
662
662
  -d '{...}'
663
663
 
664
664
  # Generate Parquet with custom compression and row group size
665
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&compression=zstd&rowGroupSize=512" \
665
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&compression=zstd&rowGroupSize=512" \
666
666
  -H "Content-Type: application/json" \
667
667
  -d '{...}' \
668
668
  --output result.parquet
669
669
 
670
670
  # Generate large Parquet with file splitting (returns ZIP if multiple files)
671
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&maxFileSize=100" \
671
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&maxFileSize=100" \
672
672
  -H "Content-Type: application/json" \
673
673
  -d '{...}' \
674
674
  --output result.zip
675
675
 
676
676
  # Using Parquet parameters in request body
677
- curl -X POST "http://localhost:8080/ViewDefinition/$run" \
677
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run" \
678
678
  -H "Content-Type: application/json" \
679
679
  -d '{
680
680
  "resourceType": "Parameters",
@@ -901,19 +901,19 @@ sof-cli --view view.json --bundle large-data.json --format parquet \
901
901
  # output_003.parquet (remaining data)
902
902
 
903
903
  # Server API - single Parquet file
904
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet" \
904
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet" \
905
905
  -H "Content-Type: application/json" \
906
906
  -d '{"resourceType": "Parameters", ...}' \
907
907
  --output result.parquet
908
908
 
909
909
  # Server API - with file splitting (returns ZIP archive if multiple files)
910
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&maxFileSize=100" \
910
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&maxFileSize=100" \
911
911
  -H "Content-Type: application/json" \
912
912
  -d '{"resourceType": "Parameters", ...}' \
913
913
  --output result.zip
914
914
 
915
915
  # Server API - optimized settings for large datasets
916
- curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&compression=zstd&rowGroupSize=512&maxFileSize=500" \
916
+ curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&compression=zstd&rowGroupSize=512&maxFileSize=500" \
917
917
  -H "Content-Type: application/json" \
918
918
  -d '{"resourceType": "Parameters", ...}' \
919
919
  --output result.zip
@@ -276,7 +276,19 @@ fn normalize_source_path(source: &str) -> Result<String, Box<dyn std::error::Err
276
276
  .unwrap_or_else(|_| absolute_path.clone());
277
277
 
278
278
  // Convert to file:// URL
279
- Ok(format!("file://{}", canonical_path.display()))
279
+ // On Windows, paths like C:\foo need to become file:///C:/foo
280
+ // On Unix, paths like /foo become file:///foo
281
+ #[cfg(windows)]
282
+ let url = {
283
+ let path_str = canonical_path.to_string_lossy();
284
+ // Replace backslashes with forward slashes for URL format
285
+ let normalized = path_str.replace('\\', "/");
286
+ format!("file:///{}", normalized)
287
+ };
288
+ #[cfg(not(windows))]
289
+ let url = format!("file://{}", canonical_path.display());
290
+
291
+ Ok(url)
280
292
  }
281
293
 
282
294
  /// Main entry point for the SQL-on-FHIR CLI application.
@@ -774,20 +786,40 @@ mod tests {
774
786
  #[test]
775
787
  fn test_normalize_source_path_absolute_path() {
776
788
  // Absolute paths should be converted to file:// URLs
777
- let result = normalize_source_path("/tmp/test.json").unwrap();
778
- assert!(result.starts_with("file:///"));
779
- assert!(result.contains("/tmp/test.json") || result.contains("private/tmp/test.json"));
789
+ // Use a platform-appropriate absolute path
790
+ #[cfg(windows)]
791
+ let test_path = "C:\\tmp\\test.json";
792
+ #[cfg(not(windows))]
793
+ let test_path = "/tmp/test.json";
794
+
795
+ let result = normalize_source_path(test_path).unwrap();
796
+ assert!(
797
+ result.starts_with("file:///"),
798
+ "Expected file:/// prefix, got: {}",
799
+ result
800
+ );
801
+ // On macOS, /tmp may be symlinked to /private/tmp
802
+ assert!(
803
+ result.contains("tmp") && result.contains("test.json"),
804
+ "Expected path to contain tmp and test.json, got: {}",
805
+ result
806
+ );
780
807
  }
781
808
 
782
809
  #[test]
783
810
  fn test_normalize_source_path_relative_path() {
784
811
  // Relative paths should be converted to absolute file:// URLs
785
812
  let result = normalize_source_path("./test.json").unwrap();
786
- assert!(result.starts_with("file:///"));
787
- // Should contain the current working directory
788
- let cwd = std::env::current_dir().unwrap();
789
813
  assert!(
790
- result.contains(&cwd.to_string_lossy().to_string()) || result.starts_with("file:///")
814
+ result.starts_with("file:///"),
815
+ "Expected file:/// prefix, got: {}",
816
+ result
817
+ );
818
+ // Should contain test.json somewhere in the path
819
+ assert!(
820
+ result.contains("test.json"),
821
+ "Expected path to contain test.json, got: {}",
822
+ result
791
823
  );
792
824
  }
793
825
  }
@@ -1,7 +1,7 @@
1
1
  //! Request handlers for the SQL-on-FHIR server
2
2
  //!
3
3
  //! This module implements the HTTP request handlers for all server endpoints,
4
- //! including the CapabilityStatement and ViewDefinition/$run operations.
4
+ //! including the CapabilityStatement and ViewDefinition/$viewdefinition-run operations.
5
5
 
6
6
  use axum::{
7
7
  Json,
@@ -39,9 +39,9 @@ pub async fn capability_statement() -> ServerResult<impl IntoResponse> {
39
39
  ))
40
40
  }
41
41
 
42
- /// Handler for POST /ViewDefinition/$run - executes a ViewDefinition
42
+ /// Handler for POST /ViewDefinition/$viewdefinition-run - executes a ViewDefinition
43
43
  ///
44
- /// The `$run` operation on a ViewDefinition resource applies the view definition to
44
+ /// The `$viewdefinition-run` operation on a ViewDefinition resource applies the view definition to
45
45
  /// transform FHIR resources into a tabular format and returns the results synchronously.
46
46
  ///
47
47
  /// # Arguments
@@ -78,7 +78,7 @@ pub async fn run_view_definition_handler(
78
78
  headers: HeaderMap,
79
79
  Json(body): Json<serde_json::Value>,
80
80
  ) -> ServerResult<Response> {
81
- info!("Handling ViewDefinition/$run request");
81
+ info!("Handling ViewDefinition/$viewdefinition-run request");
82
82
  debug!("Query params: {:?}", params);
83
83
 
84
84
  // Validate and parse query parameters
@@ -105,8 +105,6 @@ pub async fn run_view_definition_handler(
105
105
  ));
106
106
  }
107
107
 
108
- // Source parameter is now handled below
109
-
110
108
  // For backward compatibility, extract the legacy tuple format
111
109
  let view_def_json = extracted_params.view_definition;
112
110
  let resources_json = if extracted_params.resources.is_empty() {
@@ -155,9 +153,6 @@ pub async fn run_view_definition_handler(
155
153
  validated_params.format = content_type;
156
154
  }
157
155
 
158
- // Create ViewDefinition
159
- let view_definition = parse_view_definition(view_def_json)?;
160
-
161
156
  // Apply patient and group filters from body parameters to resources if provided
162
157
  let mut filtered_resources = resources_json.unwrap_or_default();
163
158
 
@@ -220,14 +215,23 @@ pub async fn run_view_definition_handler(
220
215
  }
221
216
 
222
217
  // Handle source parameter - load data from external source if provided
218
+ // IMPORTANT: We load the source bundle FIRST so we can determine its FHIR version
219
+ // and parse the ViewDefinition using the same version
223
220
  let mut source_bundle = None;
221
+ let mut source_fhir_version = None;
224
222
  if let Some(source) = &source_param {
225
223
  info!("Loading data from source: {}", source);
226
224
  let data_source = UniversalDataSource::new();
227
- let mut loaded_bundle = data_source.load(source).await?;
225
+ let loaded_bundle = data_source.load(source).await?;
226
+
227
+ // Capture the FHIR version from the loaded source bundle
228
+ source_fhir_version = Some(loaded_bundle.version());
228
229
 
229
230
  // Apply filters to source bundle if needed
230
- if patient_filter.is_some() || group_filter.is_some() || validated_params.since.is_some() {
231
+ let loaded_bundle = if patient_filter.is_some()
232
+ || group_filter.is_some()
233
+ || validated_params.since.is_some()
234
+ {
231
235
  // Extract resources from source bundle for filtering
232
236
  let mut source_resources = extract_resources_from_bundle(&loaded_bundle)?;
233
237
 
@@ -244,13 +248,30 @@ pub async fn run_view_definition_handler(
244
248
  source_resources = filter_resources_by_since(source_resources, since)?;
245
249
  }
246
250
 
247
- // Recreate bundle with filtered resources
248
- loaded_bundle = create_bundle_from_resources(source_resources)?;
249
- }
251
+ // Recreate bundle with filtered resources using the same FHIR version
252
+ create_bundle_from_resources_for_version(
253
+ source_resources,
254
+ source_fhir_version.unwrap(),
255
+ )?
256
+ } else {
257
+ loaded_bundle
258
+ };
250
259
 
251
260
  source_bundle = Some(loaded_bundle);
252
261
  }
253
262
 
263
+ // Create ViewDefinition - use the source bundle's version if available,
264
+ // otherwise use the default (newest enabled) version
265
+ let view_definition = if let Some(version) = source_fhir_version {
266
+ info!(
267
+ "Parsing ViewDefinition as {:?} (matching source bundle)",
268
+ version
269
+ );
270
+ parse_view_definition_for_version(view_def_json, version)?
271
+ } else {
272
+ parse_view_definition(view_def_json)?
273
+ };
274
+
254
275
  // Apply filters to provided resources
255
276
  if patient_filter.is_some() || group_filter.is_some() {
256
277
  filtered_resources = filter_resources_by_patient_and_group(
@@ -400,9 +421,9 @@ fn create_capability_statement() -> serde_json::Value {
400
421
  "rest": [{
401
422
  "mode": "server",
402
423
  "operation": [{
403
- "name": "run",
404
- "definition": "http://sql-on-fhir.org/OperationDefinition/ViewDefinition-run",
405
- "documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats. This is a type-level operation invoked at /ViewDefinition/$run"
424
+ "name": "viewdefinition-run",
425
+ "definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
426
+ "documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats. This is a type-level operation invoked at /ViewDefinition/$viewdefinition-run"
406
427
  }]
407
428
  }]
408
429
  })
@@ -454,11 +475,17 @@ fn resolve_view_reference(reference: &str) -> ServerResult<SofViewDefinition> {
454
475
  )))
455
476
  }
456
477
 
457
- /// Parse a ViewDefinition from JSON
478
+ /// Parse a ViewDefinition from JSON using the newest enabled FHIR version
458
479
  fn parse_view_definition(json: serde_json::Value) -> ServerResult<SofViewDefinition> {
459
- let newest_version = get_newest_enabled_fhir_version();
480
+ parse_view_definition_for_version(json, get_newest_enabled_fhir_version())
481
+ }
460
482
 
461
- match newest_version {
483
+ /// Parse a ViewDefinition from JSON using a specific FHIR version
484
+ fn parse_view_definition_for_version(
485
+ json: serde_json::Value,
486
+ version: helios_fhir::FhirVersion,
487
+ ) -> ServerResult<SofViewDefinition> {
488
+ match version {
462
489
  #[cfg(feature = "R4")]
463
490
  helios_fhir::FhirVersion::R4 => {
464
491
  let view_def: helios_fhir::r4::ViewDefinition =
@@ -539,10 +566,16 @@ fn parse_parameters(json: serde_json::Value) -> ServerResult<RunParameters> {
539
566
  }
540
567
  }
541
568
 
542
- /// Create a Bundle from a list of resources
569
+ /// Create a Bundle from a list of resources using the newest enabled FHIR version
543
570
  fn create_bundle_from_resources(resources: Vec<serde_json::Value>) -> ServerResult<SofBundle> {
544
- let newest_version = get_newest_enabled_fhir_version();
571
+ create_bundle_from_resources_for_version(resources, get_newest_enabled_fhir_version())
572
+ }
545
573
 
574
+ /// Create a Bundle from a list of resources using a specific FHIR version
575
+ fn create_bundle_from_resources_for_version(
576
+ resources: Vec<serde_json::Value>,
577
+ version: helios_fhir::FhirVersion,
578
+ ) -> ServerResult<SofBundle> {
546
579
  let bundle_json = serde_json::json!({
547
580
  "resourceType": "Bundle",
548
581
  "type": "collection",
@@ -553,7 +586,7 @@ fn create_bundle_from_resources(resources: Vec<serde_json::Value>) -> ServerResu
553
586
  }).collect::<Vec<_>>()
554
587
  });
555
588
 
556
- match newest_version {
589
+ match version {
557
590
  #[cfg(feature = "R4")]
558
591
  helios_fhir::FhirVersion::R4 => {
559
592
  let bundle: helios_fhir::r4::Bundle =
@@ -700,7 +733,7 @@ fn merge_bundles(
700
733
  /// Filter resources by patient and/or group reference
701
734
  ///
702
735
  /// This function implements the patient and group filtering as specified in the
703
- /// SQL-on-FHIR $run operation:
736
+ /// SQL-on-FHIR $viewdefinition-run operation:
704
737
  ///
705
738
  /// - **Patient filter**: Returns only resources in the patient compartment of specified patients
706
739
  /// - **Group filter**: Returns only resources that are members of the specified group
@@ -868,7 +901,7 @@ mod tests {
868
901
  // Check that operation is listed at rest level (type-level operation)
869
902
  let operations = &cap_stmt["rest"][0]["operation"];
870
903
  assert!(operations.as_array().is_some());
871
- assert_eq!(operations[0]["name"], "run");
904
+ assert_eq!(operations[0]["name"], "viewdefinition-run");
872
905
  }
873
906
 
874
907
  #[test]
@@ -8,7 +8,7 @@ use helios_sof::{ContentType, SofParameters};
8
8
  use serde::Deserialize;
9
9
  use tracing::debug;
10
10
 
11
- /// Query parameters for ViewDefinition/$run endpoint
11
+ /// Query parameters for ViewDefinition/$viewdefinition-run endpoint
12
12
  #[derive(Debug, Deserialize)]
13
13
  pub struct RunQueryParams {
14
14
  /// Output format override (alternative to Accept header)
@@ -89,7 +89,7 @@ pub struct ValidatedRunParams {
89
89
  pub parquet_options: Option<helios_sof::ParquetOptions>,
90
90
  }
91
91
 
92
- /// Parameters for ViewDefinition/$run operation - now using proper FHIR Parameters
92
+ /// Parameters for ViewDefinition/$viewdefinition-run operation - now using proper FHIR Parameters
93
93
  pub type RunParameters = SofParameters;
94
94
 
95
95
  /// Validate and parse query parameters into structured format
@@ -26,7 +26,7 @@
26
26
  //! GET /metadata
27
27
  //! Returns: CapabilityStatement
28
28
  //!
29
- //! POST /ViewDefinition/$run
29
+ //! POST /ViewDefinition/$viewdefinition-run
30
30
  //! Body: Parameters resource containing ViewDefinition and data
31
31
  //! Query Parameters (except viewReference, viewResource, patient, group, resource):
32
32
  //! _format: Output format - application/json, application/ndjson, text/csv, application/parquet
@@ -290,7 +290,7 @@ fn create_app_with_config(config: &ServerConfig) -> Router {
290
290
  // FHIR endpoints
291
291
  .route("/metadata", get(handlers::capability_statement))
292
292
  .route(
293
- "/ViewDefinition/$run",
293
+ "/ViewDefinition/$viewdefinition-run",
294
294
  post(handlers::run_view_definition_handler),
295
295
  )
296
296
  // Health check endpoint
@@ -30,11 +30,11 @@ fn create_test_app() -> Router {
30
30
  Router::new()
31
31
  .route("/metadata", get(capability_statement_handler))
32
32
  .route(
33
- "/ViewDefinition/$run",
33
+ "/ViewDefinition/$viewdefinition-run",
34
34
  post(run_view_definition_handler).get(run_view_definition_get_handler),
35
35
  )
36
36
  .route(
37
- "/ViewDefinition/{id}/$run",
37
+ "/ViewDefinition/{id}/$viewdefinition-run",
38
38
  get(run_view_definition_by_id_handler),
39
39
  )
40
40
  .route("/health", get(health_check))
@@ -70,14 +70,14 @@ async fn capability_statement_handler() -> axum::response::Response {
70
70
  "resource": [{
71
71
  "type": "ViewDefinition",
72
72
  "operation": [{
73
- "name": "run",
74
- "definition": "http://sql-on-fhir.org/OperationDefinition/ViewDefinition-run",
73
+ "name": "viewdefinition-run",
74
+ "definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
75
75
  "documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format"
76
76
  }]
77
77
  }],
78
78
  "operation": [{
79
- "name": "run",
80
- "definition": "http://sql-on-fhir.org/OperationDefinition/ViewDefinition-run",
79
+ "name": "viewdefinition-run",
80
+ "definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
81
81
  "documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats."
82
82
  }]
83
83
  }]
@@ -546,7 +546,7 @@ async fn run_view_definition_get_handler(
546
546
  // For GET requests without a ViewDefinition, we cannot proceed
547
547
  error_response(
548
548
  axum::http::StatusCode::BAD_REQUEST,
549
- "GET /ViewDefinition/$run requires a ViewDefinition to be provided. Since complex parameters cannot be used in GET requests, please use POST with viewResource or viewReference parameter.",
549
+ "GET /ViewDefinition/$viewdefinition-run requires a ViewDefinition to be provided. Since complex parameters cannot be used in GET requests, please use POST with viewResource or viewReference parameter.",
550
550
  )
551
551
  }
552
552
 
@@ -558,7 +558,7 @@ async fn run_view_definition_by_id_handler(
558
558
  error_response(
559
559
  axum::http::StatusCode::NOT_IMPLEMENTED,
560
560
  &format!(
561
- "ViewDefinition lookup by ID '{}' is not implemented. Use POST /ViewDefinition/$run with the ViewDefinition in the request body.",
561
+ "ViewDefinition lookup by ID '{}' is not implemented. Use POST /ViewDefinition/$viewdefinition-run with the ViewDefinition in the request body.",
562
562
  id
563
563
  ),
564
564
  )