-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose the schema of a resource while being compiled by an extension compiler #151
base: master
Are you sure you want to change the base?
Expose the schema of a resource while being compiled by an extension compiler #151
Conversation
Can you explain the use case why you need schema location in your case. Ideally only keywords like |
Here's an example: One of the schema extensions I am building, uses external meta information stored in a map provided to the extension compiler. When the compiler compiles a given instance of the extension keyword, it needs to lookup this map based on the location of the keyword in the schema. The provided metadata is attached to the compiled schema and it is used by the schema's Validate method. |
Can you give specific example. I see none of the keywords in specification require this info |
I'm not sure what you mean by this. The example I gave above is specific to the validation I am building. That validation revolves around testing the validity of data based on an external piece of information which is stored in a dictionary whose keys are the paths to the schema elements that use the extension keyword. |
@santhosh-tekuri can you please provide an example of how to use CompilerContext |
for simple keywords like shown in example, you will not need but if you want to implement keywords that have:
consider an example of implementing [
{
"kind": "fuelled-vehicle",
"fuel": "petrol"
},
{
"kind": "electric-vehicle",
"battery-capacity": "4000mah"
}
] we support two types of vehicles, we can implement {
"type": "array",
"items": {
"discriminator": {
"kind": {
"fuelled-vehicle": {
"type": "object",
"required": ["fuel"]
},
"electric-vehicle": {
"type": "object",
"required": ["battery-capacity"]
}
}
}
}
} below is the implementation: type discriminator struct {
property string
valueSchemas map[string]*Schema
}
func (d * discriminator) Compile(ctx jsonschema.CompilerContext, m map[string]interface{}) (jsonschema.ExtSchema, error) {
v, ok := m["discriminator"]
If !ok {
return nil, nil
}
vmap, ok := v.(map[string]interface{})
if !ok {
return nil, nil
}
for pname, pvalue := range map {
d.property = name
obj := value.(map[string]interface{})
for value, _ := range obj {
sch, err = ctx.Compile("discriminator/"+value, true)
if err!=nil {
return nil, err
}
d.valueSchemas[value] = such
}
break
}
} suppose you want {
"$defs": {
"fuelled-vehicle": {
"type": "object",
"required": ["fuel"]
},
"electric-vehicle": {
"type": "object",
"required": ["battery-capacity"]
}
}
"type": "array",
"items": {
"discriminator": {
"kind": {
"fuelled-vehicle": "#/$defs/fuelled-vehicle",
"electric-vehicle": "#/$defs/electric-vehicle",
}
}
}
} to implement this you use func (d * discriminator) Compile(ctx jsonschema.CompilerContext, m map[string]interface{}) (jsonschema.ExtSchema, error) {
v, ok := m["discriminator"]
If !ok {
return nil, nil
}
vmap, ok := v.(map[string]interface{})
if !ok {
return nil, nil
}
for pname, pvalue := range map {
d.property = name
obj := value.(map[string]interface{})
for value, ref := range obj {
sch, err = ctx.CompileRef(ref, "discriminator/"+value, true)
if err!=nil {
return nil, err
}
d.valueSchemas[value] = such
}
break
}
} note that, I have not tested this functionality myself. but this is how it is supposed to be used. |
I am looking to bump cdevents https://github.com/cdevents/sdk-go to version 4. The error comes because this line https://github.com/cdevents/spec/blob/v0.4.0/schemas/artifactdeleted.json#L41 the I am looking for a way to create a map at compile time. i can use the map aswell, right? // ysf |
@debuggerpk That will help others with similar question. I will answer it there. |
Sorry for late reply. Link to discussion. |
Sometimes an extension compiler needs to collect metadata about the instance of the keyword being compiled - most notably, its location.
With the proposed method, one can collect the location of the keyword in the compiler method like so: