fix(adapters): hoist path-template validation into shared forward core, run at from_openapi import (JS-02)
Import-time path-template checks now run on both adapters:
- from_jsonschema: validate_path_template moves to forward.rs (same
checks, same messages, shared implementation)
- from_openapi: build_registration calls it before building each op, so
a template like /x{open fails import with 'unterminated placeholder'
instead of a per-call INTERNAL on first invoke
- new test: unterminated_path_template_fails_import_not_first_call
This commit is contained in:
@@ -32,7 +32,7 @@ use async_trait::async_trait;
|
||||
use reqwest::Method;
|
||||
use serde_json::Value;
|
||||
|
||||
use super::forward::{forward, forward_stream, HttpServiceConfig};
|
||||
use super::forward::{forward, forward_stream, validate_path_template, HttpServiceConfig};
|
||||
use crate::client::SharedHttpClient;
|
||||
|
||||
/// The HTTP-backed single-endpoint adapter (ADR-066): one caller-built
|
||||
@@ -139,30 +139,6 @@ fn validate_method(method: &str) -> Result<(), AdapterError> {
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_path_template(path_template: &str) -> Result<(), AdapterError> {
|
||||
let mut rest = path_template;
|
||||
while let Some(start) = rest.find('{') {
|
||||
let Some(end_rel) = rest[start..].find('}') else {
|
||||
return Err(AdapterError::SchemaParse {
|
||||
message: format!("path template `{path_template}` has an unterminated placeholder"),
|
||||
});
|
||||
};
|
||||
if rest[start + 1..start + end_rel].is_empty() {
|
||||
return Err(AdapterError::SchemaParse {
|
||||
message: format!("path template `{path_template}` has an empty placeholder name"),
|
||||
});
|
||||
}
|
||||
rest = &rest[start + end_rel + 1..];
|
||||
}
|
||||
if path_template.contains('}') && !path_template.contains('{') {
|
||||
return Err(AdapterError::SchemaParse {
|
||||
message: format!("path template `{path_template}` has `}}` without a matching `{{`"),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn spec_name_references_undeclared(spec: &OperationSpec, path_template: &str) -> bool {
|
||||
let properties = spec
|
||||
.input_schema
|
||||
|
||||
Reference in New Issue
Block a user