Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ endif()
include(CMakeFindDependencyMacro)
find_dependency(Core COMPONENTS
unicode punycode idna regex uri uritemplate json
jsonpointer io yaml crypto html email ip dns time css)
jsonpointer jsonld io yaml crypto html email ip dns time css)

foreach(component ${BLAZE_COMPONENTS})
if(component STREQUAL "foundation")
Expand Down
17 changes: 17 additions & 0 deletions contrib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ if(BLAZE_COMPILER AND BLAZE_EVALUATOR)
target_link_libraries(sourcemeta_blaze_contrib_trace
PRIVATE sourcemeta::blaze::output)

sourcemeta_executable(NAMESPACE sourcemeta PROJECT blaze NAME contrib_jsonld
FOLDER "Blaze/Contrib" SOURCES jsonld.cc)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::core::io)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::core::json)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::core::jsonpointer)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::blaze::foundation)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::blaze::compiler)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::blaze::evaluator)
target_link_libraries(sourcemeta_blaze_contrib_jsonld
PRIVATE sourcemeta::blaze::output)

if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
sourcemeta_executable(NAMESPACE sourcemeta PROJECT blaze NAME contrib_perf
FOLDER "Blaze/Contrib" SOURCES perf.cc)
Expand Down
78 changes: 78 additions & 0 deletions contrib/jsonld.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <sourcemeta/blaze/foundation.h>
#include <sourcemeta/core/io.h>
#include <sourcemeta/core/json.h>
#include <sourcemeta/core/jsonpointer.h>

#include <sourcemeta/blaze/compiler.h>
#include <sourcemeta/blaze/evaluator.h>
#include <sourcemeta/blaze/output.h>

#include <cstdlib> // EXIT_SUCCESS, EXIT_FAILURE
#include <exception> // std::exception
#include <iostream> // std::cerr, std::cout
#include <unordered_set> // std::unordered_set
#include <variant> // std::get, std::holds_alternative

// A convenience script to evaluate an instance against a JSON Schema whose
// atoms carry JSON-LD annotations, and print the resulting expanded JSON-LD,
// the schema validation errors, or the JSON-LD resolution error.

static auto run(const char *schema_path, const char *instance_path) -> int;

auto main(int argc, char *argv[]) -> int {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <schema.json> <instance.json>\n";
return EXIT_FAILURE;
}

try {
return run(argv[1], argv[2]);
} catch (const std::exception &error) {
std::cerr << "Error: " << error.what() << "\n";
return EXIT_FAILURE;
}
}

static auto run(const char *schema_path, const char *instance_path) -> int {
const auto schema{sourcemeta::core::read_json(schema_path)};
const auto instance{sourcemeta::core::read_json(instance_path)};

sourcemeta::blaze::Tweaks tweaks;
tweaks.annotations = std::unordered_set<sourcemeta::core::JSON::StringView>{
"x-jsonld-id", "x-jsonld-type"};
const auto schema_template{sourcemeta::blaze::compile(
schema, sourcemeta::blaze::schema_walker,
sourcemeta::blaze::schema_resolver,
sourcemeta::blaze::default_schema_compiler,
sourcemeta::blaze::Mode::FastValidation, "", "", "", tweaks)};

sourcemeta::blaze::Evaluator evaluator;
const auto outcome{
sourcemeta::blaze::jsonld(evaluator, schema_template, instance)};

if (std::holds_alternative<sourcemeta::core::JSON>(outcome)) {
sourcemeta::core::prettify(std::get<sourcemeta::core::JSON>(outcome),
std::cout);
std::cout << "\n";
return EXIT_SUCCESS;
}

if (std::holds_alternative<sourcemeta::blaze::JSONLDInvalid>(outcome)) {
std::cerr << "The instance does not conform to the schema:\n";
for (const auto &entry :
std::get<sourcemeta::blaze::JSONLDInvalid>(outcome)) {
std::cerr << " - " << entry.message << "\n at instance location \""
<< sourcemeta::core::to_string(entry.instance_location)
<< "\"\n at evaluate path \""
<< sourcemeta::core::to_string(entry.evaluate_path) << "\"\n";
}
return EXIT_FAILURE;
}

const auto &error{
std::get<sourcemeta::blaze::JSONLDResolutionError>(outcome)};
std::cerr << "The instance conforms but could not be resolved into JSON-LD:\n"
<< " - " << error.message << "\n at instance location \""
<< sourcemeta::core::to_string(error.instance_location) << "\"\n";
return EXIT_FAILURE;
}
7 changes: 5 additions & 2 deletions src/output/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME output
FOLDER "Blaze/Output"
PRIVATE_HEADERS simple.h trace.h standard.h
PRIVATE_HEADERS simple.h trace.h standard.h jsonld.h
SOURCES
output_simple.cc
output_trace.cc
output_standard.cc)
output_standard.cc
output_jsonld.cc)

if(BLAZE_INSTALL)
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME output)
Expand All @@ -14,6 +15,8 @@ target_link_libraries(sourcemeta_blaze_output PUBLIC
sourcemeta::core::json)
target_link_libraries(sourcemeta_blaze_output PUBLIC
sourcemeta::core::jsonpointer)
target_link_libraries(sourcemeta_blaze_output PRIVATE

@augmentcode augmentcode Bot Jul 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/output/CMakeLists.txt:18: sourcemeta_blaze_output links sourcemeta::core::jsonld as PRIVATE, which can break downstream links in static builds when calling blaze::jsonld (e.g. contrib_jsonld only links blaze::output). Consider making this dependency PUBLIC (or explicitly linking core::jsonld from dependents) so consumers get the required transitive link interface.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

sourcemeta::core::jsonld)
target_link_libraries(sourcemeta_blaze_output PUBLIC
sourcemeta::blaze::foundation)
target_link_libraries(sourcemeta_blaze_output PUBLIC
Expand Down
1 change: 1 addition & 0 deletions src/output/include/sourcemeta/blaze/output.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SOURCEMETA_BLAZE_OUTPUT_H_
#define SOURCEMETA_BLAZE_OUTPUT_H_

#include <sourcemeta/blaze/output_jsonld.h>
#include <sourcemeta/blaze/output_simple.h>
#include <sourcemeta/blaze/output_standard.h>
#include <sourcemeta/blaze/output_trace.h>
Expand Down
97 changes: 97 additions & 0 deletions src/output/include/sourcemeta/blaze/output_jsonld.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#ifndef SOURCEMETA_BLAZE_OUTPUT_JSONLD_H_
#define SOURCEMETA_BLAZE_OUTPUT_JSONLD_H_

#ifndef SOURCEMETA_BLAZE_OUTPUT_EXPORT
#include <sourcemeta/blaze/output_export.h>
#endif

#include <sourcemeta/core/json.h>
#include <sourcemeta/core/jsonpointer.h>

#include <sourcemeta/blaze/evaluator.h>
#include <sourcemeta/blaze/output_simple.h>

#include <cstdint> // std::uint8_t
#include <string> // std::string
#include <variant> // std::variant
#include <vector> // std::vector

namespace sourcemeta::blaze {

/// @ingroup output
/// The descriptor facet that a JSON-LD resolution error is about
enum class JSONLDFacet : std::uint8_t { Type, Predicate };

/// @ingroup output
/// The instance conforms but one of its JSON-LD annotations cannot be resolved
/// into a consistent mapping. Reported as a single failure at the instance
/// location where resolution stopped, distinct from a schema validation error.
struct JSONLDResolutionError {
sourcemeta::core::Pointer instance_location;
JSONLDFacet facet;
std::string message;
};

/// @ingroup output
/// The instance does not conform to the schema, so no JSON-LD is produced.
/// These are the schema validation errors.
using JSONLDInvalid = std::vector<SimpleOutput::Entry>;

/// @ingroup output
/// The tri-state outcome of a JSON-LD evaluation: the expanded document (as
/// expanded JSON-LD), schema validation errors, or a JSON-LD resolution error.
using JSONLDOutcome =
std::variant<sourcemeta::core::JSON, JSONLDInvalid, JSONLDResolutionError>;

/// @ingroup output
///
/// Evaluate an instance against a JSON Schema whose atoms carry JSON-LD
/// annotations and, on success, return the instance promoted to expanded
/// JSON-LD. The schema must have been compiled with annotation collection
/// enabled for its JSON-LD keywords, as shown below. For example:
///
/// ```cpp
/// #include <sourcemeta/blaze/compiler.h>
/// #include <sourcemeta/blaze/evaluator.h>
/// #include <sourcemeta/blaze/output.h>
///
/// #include <sourcemeta/core/json.h>
/// #include <sourcemeta/blaze/foundation.h>
///
/// #include <unordered_set>
/// #include <variant>
///
/// const sourcemeta::core::JSON schema =
/// sourcemeta::core::parse_json(R"JSON({
/// "$schema": "https://json-schema.org/draft/2020-12/schema",
/// "type": "object",
/// "x-jsonld-type": "https://schema.org/Person",
/// "properties": {
/// "name": { "type": "string", "x-jsonld-id": "https://schema.org/name" }
/// }
/// })JSON");
///
/// sourcemeta::blaze::Tweaks tweaks;
/// tweaks.annotations = std::unordered_set<sourcemeta::core::JSON::StringView>{
/// "x-jsonld-id", "x-jsonld-type"};
///
/// const auto schema_template{sourcemeta::blaze::compile(
/// schema, sourcemeta::blaze::schema_walker,
/// sourcemeta::blaze::schema_resolver,
/// sourcemeta::blaze::default_schema_compiler,
/// sourcemeta::blaze::Mode::FastValidation, "", "", "", tweaks)};
///
/// const sourcemeta::core::JSON instance{
/// sourcemeta::core::parse_json(R"JSON({ "name": "Ada" })JSON")};
///
/// sourcemeta::blaze::Evaluator evaluator;
/// const auto outcome{
/// sourcemeta::blaze::jsonld(evaluator, schema_template, instance)};
/// ```
auto SOURCEMETA_BLAZE_OUTPUT_EXPORT
jsonld(Evaluator &evaluator, const Template &schema,
const sourcemeta::core::JSON &instance) -> JSONLDOutcome;

} // namespace sourcemeta::blaze

#endif
Loading
Loading