+64
-18
api/src/graphql/schema_builder.rs
+64
-18
api/src/graphql/schema_builder.rs
···
3522
3522
input
3523
3523
}
3524
3524
3525
-
/// Transforms blob fields in record data from GraphQL format to AT Protocol format
3525
+
/// Transforms fields in record data from GraphQL format to AT Protocol format
3526
3526
///
3527
-
/// GraphQL format: `{ref: "bafyrei...", mimeType: "...", size: 123}`
3528
-
/// AT Protocol format: `{ref: {$link: "bafyrei..."}, mimeType: "...", size: 123}`
3529
-
fn transform_blob_fields_for_atproto(
3527
+
/// Blob fields:
3528
+
/// - GraphQL format: `{ref: "bafyrei...", mimeType: "...", size: 123}`
3529
+
/// - AT Protocol format: `{$type: "blob", ref: {$link: "bafyrei..."}, mimeType: "...", size: 123}`
3530
+
///
3531
+
/// Lexicon ref fields:
3532
+
/// - Adds `$type: "{ref_nsid}"` to objects (e.g., `{$type: "community.lexicon.location.hthree#main", ...}`)
3533
+
///
3534
+
/// Nested objects:
3535
+
/// - Recursively processes nested objects and arrays
3536
+
fn transform_fields_for_atproto(
3530
3537
mut data: serde_json::Value,
3531
3538
fields: &[GraphQLField],
3532
3539
) -> serde_json::Value {
···
3537
3544
GraphQLType::Blob => {
3538
3545
// Transform single blob field
3539
3546
if let Some(blob_obj) = field_value.as_object_mut() {
3547
+
// Add $type: "blob"
3548
+
blob_obj.insert("$type".to_string(), serde_json::Value::String("blob".to_string()));
3549
+
3540
3550
// Check if ref is a string (GraphQL format)
3541
3551
if let Some(serde_json::Value::String(cid)) = blob_obj.get("ref") {
3542
3552
// Transform to {$link: "cid"} (AT Protocol format)
···
3547
3557
}
3548
3558
}
3549
3559
}
3550
-
GraphQLType::Array(inner) if matches!(inner.as_ref(), GraphQLType::Blob) => {
3551
-
// Transform array of blobs
3552
-
if let Some(arr) = field_value.as_array_mut() {
3553
-
for blob_value in arr {
3554
-
if let Some(blob_obj) = blob_value.as_object_mut() {
3555
-
if let Some(serde_json::Value::String(cid)) = blob_obj.get("ref") {
3556
-
let link_obj = serde_json::json!({
3557
-
"$link": cid
3558
-
});
3559
-
blob_obj.insert("ref".to_string(), link_obj);
3560
+
GraphQLType::LexiconRef(ref_nsid) => {
3561
+
// Transform lexicon ref field by adding $type
3562
+
if let Some(ref_obj) = field_value.as_object_mut() {
3563
+
ref_obj.insert("$type".to_string(), serde_json::Value::String(ref_nsid.clone()));
3564
+
}
3565
+
}
3566
+
GraphQLType::Object(nested_fields) => {
3567
+
// Recursively transform nested objects
3568
+
*field_value = transform_fields_for_atproto(field_value.clone(), nested_fields);
3569
+
}
3570
+
GraphQLType::Array(inner) => {
3571
+
match inner.as_ref() {
3572
+
GraphQLType::Blob => {
3573
+
// Transform array of blobs
3574
+
if let Some(arr) = field_value.as_array_mut() {
3575
+
for blob_value in arr {
3576
+
if let Some(blob_obj) = blob_value.as_object_mut() {
3577
+
// Add $type: "blob"
3578
+
blob_obj.insert("$type".to_string(), serde_json::Value::String("blob".to_string()));
3579
+
3580
+
if let Some(serde_json::Value::String(cid)) = blob_obj.get("ref") {
3581
+
let link_obj = serde_json::json!({
3582
+
"$link": cid
3583
+
});
3584
+
blob_obj.insert("ref".to_string(), link_obj);
3585
+
}
3586
+
}
3560
3587
}
3561
3588
}
3562
3589
}
3590
+
GraphQLType::LexiconRef(ref_nsid) => {
3591
+
// Transform array of lexicon refs
3592
+
if let Some(arr) = field_value.as_array_mut() {
3593
+
for ref_value in arr {
3594
+
if let Some(ref_obj) = ref_value.as_object_mut() {
3595
+
ref_obj.insert("$type".to_string(), serde_json::Value::String(ref_nsid.clone()));
3596
+
}
3597
+
}
3598
+
}
3599
+
}
3600
+
GraphQLType::Object(nested_fields) => {
3601
+
// Transform array of objects recursively
3602
+
if let Some(arr) = field_value.as_array_mut() {
3603
+
for item in arr {
3604
+
*item = transform_fields_for_atproto(item.clone(), nested_fields);
3605
+
}
3606
+
}
3607
+
}
3608
+
_ => {} // Other array types don't need transformation
3563
3609
}
3564
3610
}
3565
3611
_ => {} // Other field types don't need transformation
···
3612
3658
let mut record_data: serde_json::Value = input.deserialize()
3613
3659
.map_err(|e| Error::new(format!("Failed to deserialize input: {:?}", e)))?;
3614
3660
3615
-
// Transform blob fields from GraphQL format (ref: "cid") to AT Protocol format (ref: {$link: "cid"})
3616
-
record_data = transform_blob_fields_for_atproto(record_data, &fields);
3661
+
// Transform fields from GraphQL to AT Protocol format (adds $type, transforms blob refs)
3662
+
record_data = transform_fields_for_atproto(record_data, &fields);
3617
3663
3618
3664
// Optional rkey argument
3619
3665
let rkey = ctx.args.get("rkey")
···
3784
3830
let mut record_data: serde_json::Value = input.deserialize()
3785
3831
.map_err(|e| Error::new(format!("Failed to deserialize input: {:?}", e)))?;
3786
3832
3787
-
// Transform blob fields from GraphQL format (ref: "cid") to AT Protocol format (ref: {$link: "cid"})
3788
-
record_data = transform_blob_fields_for_atproto(record_data, &fields);
3833
+
// Transform fields from GraphQL to AT Protocol format (adds $type, transforms blob refs)
3834
+
record_data = transform_fields_for_atproto(record_data, &fields);
3789
3835
3790
3836
// Verify OAuth token and get user info
3791
3837
let user_info = crate::auth::verify_oauth_token_cached(