Summary
When using codemirror-json-schema@0.8.1 with YAML mode, property completions with const, enum, or default string values insert unquoted values that YAML parses as non-strings (numbers, booleans, etc.).
Reproduction
Schema
{
"type": "object",
"properties": {
"version": {
"type": "string",
"const": "3.0",
"description": "Version string"
}
}
}
Steps
- Start typing
v in an empty YAML document
- Autocomplete suggests
version as a property
- Accept the completion (Tab or Enter)
Expected Result
Actual Result
Problem
YAML parses 3.0 as the number 3 (float), not the string "3.0". This causes schema validation to fail with:
Expected value at version to be 3.0, but value given is 3
The library's apply() function for property completions inserts key: defaultValue without considering YAML's type inference rules. Values that look like:
- Numbers (
3.0, 123, .5)
- Booleans (
true, false, yes, no, on, off)
- Null (
null, ~)
...all need to be quoted when the schema expects a string type.
Workaround
Wrap the completion's apply function to detect unquoted string values and re-insert them with quotes:
yamlLanguage.data.of({
autocomplete: async (context) => {
const result = await yamlCompletion()(context);
if (result?.options) {
result.options = result.options.map(opt => {
if (opt.type === 'property' && typeof opt.apply === 'function') {
const originalApply = opt.apply;
opt.apply = (view, completion, from, to) => {
originalApply(view, completion, from, to);
// Post-process: quote string values that look like non-strings
const propSchema = schema?.properties?.[opt.label];
if (propSchema?.type === 'string' && (propSchema.const || propSchema.enum)) {
const line = view.state.doc.lineAt(view.state.selection.main.head);
const match = line.text.match(/^(\s*\w+:\s*)([^"'\s].*)$/);
if (match && /^[\d.]/.test(match[2])) {
const quotedLine = match[1] + '"' + match[2] + '"';
view.dispatch({
changes: { from: line.from, to: line.to, insert: quotedLine },
selection: { anchor: line.from + quotedLine.length }
});
}
}
};
}
return opt;
});
}
return result;
}
})
Suggested Fix
The library should be YAML-aware when inserting default values. For string-typed properties with const/enum/default values, it should:
- Check if the value would be parsed as a non-string by YAML
- If so, wrap the value in quotes (either
"value" or 'value')
This could be implemented in the apply function generator for property completions in src/yaml-completion.ts (or equivalent).
Environment
codemirror-json-schema: 0.8.1
@codemirror/lang-yaml: 6.1.1
- CodeMirror 6
Related
This issue affects any schema property where:
type: "string"
- Has
const, enum, or default value
- The value looks like a YAML scalar (number, boolean, null)
Summary
When using
codemirror-json-schema@0.8.1with YAML mode, property completions withconst,enum, ordefaultstring values insert unquoted values that YAML parses as non-strings (numbers, booleans, etc.).Reproduction
Schema
{ "type": "object", "properties": { "version": { "type": "string", "const": "3.0", "description": "Version string" } } }Steps
vin an empty YAML documentversionas a propertyExpected Result
Actual Result
Problem
YAML parses
3.0as the number3(float), not the string"3.0". This causes schema validation to fail with:The library's
apply()function for property completions insertskey: defaultValuewithout considering YAML's type inference rules. Values that look like:3.0,123,.5)true,false,yes,no,on,off)null,~)...all need to be quoted when the schema expects a string type.
Workaround
Wrap the completion's
applyfunction to detect unquoted string values and re-insert them with quotes:Suggested Fix
The library should be YAML-aware when inserting default values. For string-typed properties with
const/enum/defaultvalues, it should:"value"or'value')This could be implemented in the
applyfunction generator for property completions insrc/yaml-completion.ts(or equivalent).Environment
codemirror-json-schema: 0.8.1@codemirror/lang-yaml: 6.1.1Related
This issue affects any schema property where:
type: "string"const,enum, ordefaultvalue