yaml-dsl-spec 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaml-dsl-spec",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "The YAML DSL standard: the JSON Schemas of yaml-dsl.yml and of a DSL's function table, and a reader returning a yaml-dsl.yml's DSL definitions validated.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/litebitus/yaml-dsl-spec/schemas/x-yaml-dsl-functions-v1.1.schema.json",
|
|
4
|
+
"title": "x-yaml-dsl-functions v1.1",
|
|
5
|
+
"description": "A DSL's function table: each function name maps to its description, its arguments in call order and what it returns, or, for a macro, what its preprocessor does with a call.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_:-]*$" },
|
|
8
|
+
"additionalProperties": {
|
|
9
|
+
"oneOf": [
|
|
10
|
+
{ "$ref": "#/$defs/function" },
|
|
11
|
+
{ "$ref": "#/$defs/argumentList" }
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"$defs": {
|
|
15
|
+
"function": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["description", "arguments"],
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"if": { "required": ["macro"] },
|
|
20
|
+
"then": { "not": { "required": ["return"] } },
|
|
21
|
+
"properties": {
|
|
22
|
+
"description": { "type": "string", "minLength": 1, "description": "What the function does, in markdown." },
|
|
23
|
+
"arguments": {
|
|
24
|
+
"type": "array",
|
|
25
|
+
"description": "The function's arguments in call order. Optional arguments follow required ones, and a repeated argument is last.",
|
|
26
|
+
"items": {
|
|
27
|
+
"allOf": [{ "$ref": "#/$defs/argument" }],
|
|
28
|
+
"required": ["description"],
|
|
29
|
+
"properties": {
|
|
30
|
+
"description": { "type": "string", "minLength": 1, "description": "What the argument holds, in markdown." }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"return": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"required": ["type", "description"],
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"description": "What the function returns. Left out for a function that returns nothing, and for a macro.",
|
|
39
|
+
"properties": {
|
|
40
|
+
"type": { "$ref": "#/$defs/valueType" },
|
|
41
|
+
"description": { "type": "string", "minLength": 1, "description": "What the returned value holds, in markdown." }
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"macro": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": ["kind"],
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"description": "Present only on a macro: what the DSL's preprocessor does with a call.",
|
|
49
|
+
"allOf": [
|
|
50
|
+
{
|
|
51
|
+
"if": { "properties": { "kind": { "const": "function_call" } } },
|
|
52
|
+
"then": { "required": ["callee"] },
|
|
53
|
+
"else": { "not": { "anyOf": [{ "required": ["callee"] }, { "required": ["callee_arguments"] }] } }
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"if": { "properties": { "kind": { "const": "merge" } } },
|
|
57
|
+
"then": { "required": ["merge_behavior", "content"] },
|
|
58
|
+
"else": { "not": { "anyOf": [{ "required": ["merge_behavior"] }, { "required": ["content"] }] } }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"if": { "properties": { "kind": { "const": "loop" } } },
|
|
62
|
+
"then": {
|
|
63
|
+
"required": ["collection", "body"],
|
|
64
|
+
"anyOf": [{ "required": ["loop_variables"] }, { "required": ["loop_variable"] }]
|
|
65
|
+
},
|
|
66
|
+
"else": {
|
|
67
|
+
"not": {
|
|
68
|
+
"anyOf": [
|
|
69
|
+
{ "required": ["loop_variables"] },
|
|
70
|
+
{ "required": ["loop_variable"] },
|
|
71
|
+
{ "required": ["collection"] },
|
|
72
|
+
{ "required": ["body"] }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"properties": {
|
|
79
|
+
"kind": {
|
|
80
|
+
"enum": ["function_call", "merge", "loop", "transform"],
|
|
81
|
+
"description": "What a call expands to."
|
|
82
|
+
},
|
|
83
|
+
"callee": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"minLength": 1,
|
|
86
|
+
"description": "On a function_call macro, required: the argument naming the macro or function called."
|
|
87
|
+
},
|
|
88
|
+
"callee_arguments": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"minLength": 1,
|
|
91
|
+
"description": "On a function_call macro: the argument holding the callee's arguments by name."
|
|
92
|
+
},
|
|
93
|
+
"content": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"minLength": 1,
|
|
96
|
+
"description": "On a merge macro, required: the argument holding the content or its location."
|
|
97
|
+
},
|
|
98
|
+
"loop_variables": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"minLength": 1,
|
|
101
|
+
"description": "On a loop macro, required: the argument holding the loop variables, a text or a list of one or two."
|
|
102
|
+
},
|
|
103
|
+
"loop_variable": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"minLength": 1,
|
|
106
|
+
"deprecated": true,
|
|
107
|
+
"description": "Use loop_variables."
|
|
108
|
+
},
|
|
109
|
+
"collection": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"minLength": 1,
|
|
112
|
+
"description": "On a loop macro, required: the argument holding the collection."
|
|
113
|
+
},
|
|
114
|
+
"body": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"minLength": 1,
|
|
117
|
+
"description": "On a loop macro, required: the argument holding the body."
|
|
118
|
+
},
|
|
119
|
+
"name_suffix_pattern": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"minLength": 1,
|
|
122
|
+
"description": "The regular expression of the text after the macro's name that keeps sibling calls distinct. Left out, nothing follows the name."
|
|
123
|
+
},
|
|
124
|
+
"unmarked_key_paths": {
|
|
125
|
+
"type": "array",
|
|
126
|
+
"items": { "type": "string", "pattern": "^\\$." },
|
|
127
|
+
"description": "The JSONPaths of the keys that call the macro without the call marker. Left out, none."
|
|
128
|
+
},
|
|
129
|
+
"merge_behavior": {
|
|
130
|
+
"enum": ["shallow", "deep", "join"],
|
|
131
|
+
"description": "How a merge macro combines the holding map with its content. Required on a merge macro."
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"argumentList": {
|
|
138
|
+
"type": "array",
|
|
139
|
+
"deprecated": true,
|
|
140
|
+
"description": "Use a mapping with description and arguments. The function's arguments in call order.",
|
|
141
|
+
"items": { "$ref": "#/$defs/argument" }
|
|
142
|
+
},
|
|
143
|
+
"argument": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"required": ["name", "type", "required", "repeated"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"name": { "type": "string", "minLength": 1, "description": "Argument name." },
|
|
148
|
+
"type": { "$ref": "#/$defs/valueType" },
|
|
149
|
+
"required": { "type": "boolean", "description": "Whether a call must pass the argument." },
|
|
150
|
+
"repeated": { "type": "boolean", "description": "Whether the argument takes every remaining value." },
|
|
151
|
+
"default": { "description": "On an optional argument, the value it takes when a call leaves it out." }
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"valueType": {
|
|
155
|
+
"enum": ["text", "number", "whole_number", "boolean", "list", "map", "function", "macro", "any"],
|
|
156
|
+
"description": "The kind of value; `function` and `macro` are the name of a table entry of that kind."
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/litebitus/yaml-dsl-spec/schemas/yaml-dsl-v1.1.schema.json",
|
|
4
|
+
"title": "yaml-dsl.yml v1.1",
|
|
5
|
+
"description": "The workspace's YAML DSLs: which files each one owns and the syntax of its names, references, placeholders and calls.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["version", "dsls"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"version": {
|
|
11
|
+
"enum": ["1", "1.1"],
|
|
12
|
+
"description": "Config format version: `1.1`, or `1` for the newest 1.x the reader knows."
|
|
13
|
+
},
|
|
14
|
+
"dsls": {
|
|
15
|
+
"type": "array",
|
|
16
|
+
"description": "One entry per DSL.",
|
|
17
|
+
"items": { "$ref": "#/$defs/dsl" }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"$defs": {
|
|
21
|
+
"dsl": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"required": [
|
|
24
|
+
"id",
|
|
25
|
+
"file_includes",
|
|
26
|
+
"file_excludes",
|
|
27
|
+
"schema_search_paths",
|
|
28
|
+
"key_sort_orders",
|
|
29
|
+
"scopes",
|
|
30
|
+
"declarations",
|
|
31
|
+
"references"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"properties": {
|
|
35
|
+
"id": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1,
|
|
38
|
+
"description": "Name of the DSL."
|
|
39
|
+
},
|
|
40
|
+
"file_includes": {
|
|
41
|
+
"$ref": "#/$defs/globs",
|
|
42
|
+
"description": "Globs of the files the DSL owns. A glob starting with {config_root}/ matches below the config's folder."
|
|
43
|
+
},
|
|
44
|
+
"file_excludes": {
|
|
45
|
+
"$ref": "#/$defs/globs",
|
|
46
|
+
"description": "Globs of files the DSL does not own, even when file_includes matches them. A glob starting with {config_root}/ matches below the config's folder."
|
|
47
|
+
},
|
|
48
|
+
"schema_search_paths": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": { "type": "string", "minLength": 1 },
|
|
51
|
+
"description": "Schemas tried in order when a file names none, or the one it names is not on disk. Each path is relative to the file, or to the config's folder when it starts with {config_root}/, and a * in a step matches within it; a URL is fetched."
|
|
52
|
+
},
|
|
53
|
+
"tag_keys": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"required": ["tag", "key"],
|
|
58
|
+
"additionalProperties": false,
|
|
59
|
+
"properties": {
|
|
60
|
+
"tag": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"pattern": "^![^\\s!]+$",
|
|
63
|
+
"description": "The YAML tag as written, such as !Ref."
|
|
64
|
+
},
|
|
65
|
+
"key": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1,
|
|
68
|
+
"description": "The key the tagged node stands for, such as Ref."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"description": "YAML tags that stand for keys: a tagged node reads as a map holding the key, the node its value."
|
|
73
|
+
},
|
|
74
|
+
"layers": { "$ref": "#/$defs/layers" },
|
|
75
|
+
"placeholder": { "$ref": "#/$defs/placeholder" },
|
|
76
|
+
"function": { "$ref": "#/$defs/function" },
|
|
77
|
+
"locals": { "$ref": "#/$defs/locals" },
|
|
78
|
+
"loops": { "$ref": "#/$defs/loops" },
|
|
79
|
+
"validator": { "$ref": "#/$defs/validator" },
|
|
80
|
+
"performance": { "$ref": "#/$defs/performance" },
|
|
81
|
+
"key_sort_orders": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": { "$ref": "#/$defs/key_sort_order" },
|
|
84
|
+
"description": "Where an edit places a new key in each map. The first entry whose path covers the map applies."
|
|
85
|
+
},
|
|
86
|
+
"scopes": { "$ref": "#/$defs/scopes" },
|
|
87
|
+
"declarations": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"items": { "$ref": "#/$defs/declaration" },
|
|
90
|
+
"description": "Where names are declared."
|
|
91
|
+
},
|
|
92
|
+
"references": {
|
|
93
|
+
"type": "array",
|
|
94
|
+
"items": { "$ref": "#/$defs/reference" },
|
|
95
|
+
"description": "How names are referenced. Rules reading the same text are tried in order."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"layers": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"description": "The common layer and its overlays. Left out for a DSL without layers.",
|
|
102
|
+
"required": ["common_layer_discovery", "duplicate_check"],
|
|
103
|
+
"additionalProperties": false,
|
|
104
|
+
"if": { "properties": { "common_layer_discovery": { "const": "overlay_includes" } } },
|
|
105
|
+
"then": {
|
|
106
|
+
"required": ["overlay_includes"],
|
|
107
|
+
"not": { "anyOf": [{ "required": ["overlay_folders"] }, { "required": ["common_layer_files"] }] }
|
|
108
|
+
},
|
|
109
|
+
"else": {
|
|
110
|
+
"required": ["overlay_folders"],
|
|
111
|
+
"not": { "required": ["overlay_includes"] }
|
|
112
|
+
},
|
|
113
|
+
"properties": {
|
|
114
|
+
"overlay_folders": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": { "type": "string", "minLength": 1 },
|
|
117
|
+
"description": "Folder names of the overlays."
|
|
118
|
+
},
|
|
119
|
+
"common_layer_discovery": {
|
|
120
|
+
"enum": ["parent", "ancestor", "overlay_includes"],
|
|
121
|
+
"description": "How an overlay and its common layer are paired: by the overlay folder's parent, by the nearest ancestor above an overlay folder, or by an include in the overlay."
|
|
122
|
+
},
|
|
123
|
+
"overlay_includes": {
|
|
124
|
+
"type": "array",
|
|
125
|
+
"items": { "$ref": "#/$defs/overlay_include" },
|
|
126
|
+
"description": "How an include in an overlay names its common layer. Read only with common_layer_discovery overlay_includes."
|
|
127
|
+
},
|
|
128
|
+
"common_layer_files": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": {
|
|
131
|
+
"type": "array",
|
|
132
|
+
"minItems": 1,
|
|
133
|
+
"uniqueItems": true,
|
|
134
|
+
"items": { "type": "string", "minLength": 1, "pattern": "^[^/\\\\]+$" }
|
|
135
|
+
},
|
|
136
|
+
"description": "A layer file name to the names its common layer may take, the first that exists taken. {concern} in a name stands for a concern below its overlays, and each list holds a name without it. Left out, the common layer takes the layer file's own name."
|
|
137
|
+
},
|
|
138
|
+
"duplicate_check": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"description": "The unit a suggestion takes, a node of the overlays it moves or deletes whole.",
|
|
141
|
+
"required": ["depth", "key_depths", "skip_keys"],
|
|
142
|
+
"additionalProperties": false,
|
|
143
|
+
"properties": {
|
|
144
|
+
"depth": {
|
|
145
|
+
"type": "integer",
|
|
146
|
+
"minimum": 1,
|
|
147
|
+
"description": "How many levels below the document root the unit sits, under a top-level key key_depths does not list."
|
|
148
|
+
},
|
|
149
|
+
"key_depths": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"additionalProperties": { "type": "integer", "minimum": 1 },
|
|
152
|
+
"description": "The unit's depth under a given top-level key, {} when every key takes depth."
|
|
153
|
+
},
|
|
154
|
+
"skip_keys": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"items": { "type": "string" },
|
|
157
|
+
"description": "Keys no suggestion compares or moves, at any depth."
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"overlay_include": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"description": "An include: a key whose value names the common layer merged in place of the include.",
|
|
166
|
+
"required": ["key_paths", "value_conditions", "location_path", "location_mappings"],
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"properties": {
|
|
169
|
+
"key_paths": {
|
|
170
|
+
"type": "array",
|
|
171
|
+
"items": { "type": "string", "minLength": 1 },
|
|
172
|
+
"description": "JSONPaths of the keys whose values are includes, such as $..['Fn::Transform']. A value that is a list holds one include per map."
|
|
173
|
+
},
|
|
174
|
+
"value_conditions": {
|
|
175
|
+
"type": "array",
|
|
176
|
+
"items": {
|
|
177
|
+
"type": "object",
|
|
178
|
+
"required": ["key", "value"],
|
|
179
|
+
"additionalProperties": false,
|
|
180
|
+
"properties": {
|
|
181
|
+
"key": { "type": "string", "minLength": 1, "description": "A key the include value holds." },
|
|
182
|
+
"value": { "type": "string", "minLength": 1, "description": "The value it holds at that key." }
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"description": "The key and value pairs an include value holds, [] for none."
|
|
186
|
+
},
|
|
187
|
+
"location_path": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"minLength": 1,
|
|
190
|
+
"description": "A JSONPath of names from the include value to its location, such as $.Parameters.Location."
|
|
191
|
+
},
|
|
192
|
+
"location_mappings": {
|
|
193
|
+
"type": "array",
|
|
194
|
+
"items": {
|
|
195
|
+
"type": "object",
|
|
196
|
+
"required": ["local", "remote"],
|
|
197
|
+
"additionalProperties": false,
|
|
198
|
+
"properties": {
|
|
199
|
+
"local": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"minLength": 1,
|
|
202
|
+
"description": "The local path a remote location stands for, relative to the overlay, or to the config's folder when it starts with {config_root}/."
|
|
203
|
+
},
|
|
204
|
+
"remote": { "type": "string", "minLength": 1, "description": "The start of a location." }
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"description": "A location starting with remote names the file at local followed by the rest of the location. A location none covers names no file."
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"placeholder": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"description": "The placeholder syntax. Left out for a DSL without placeholders.",
|
|
214
|
+
"required": ["pattern", "unscanned_paths"],
|
|
215
|
+
"additionalProperties": false,
|
|
216
|
+
"properties": {
|
|
217
|
+
"pattern": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"pattern": "\\(\\?<body>",
|
|
220
|
+
"description": "Regular expression of a placeholder, with a (?<body>...) group."
|
|
221
|
+
},
|
|
222
|
+
"escape_prefix": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1,
|
|
225
|
+
"description": "Text that, written right before a placeholder, keeps it as literal text. Left out for none."
|
|
226
|
+
},
|
|
227
|
+
"unscanned_paths": {
|
|
228
|
+
"type": "array",
|
|
229
|
+
"items": { "$ref": "#/$defs/path_entry" },
|
|
230
|
+
"description": "Paths whose text is another language's and is not read for placeholders."
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"function": {
|
|
235
|
+
"type": "object",
|
|
236
|
+
"description": "Function calls. Left out for a DSL without calls.",
|
|
237
|
+
"required": ["definitions", "call_result_reference_positions", "calls_not_allowed_at"],
|
|
238
|
+
"additionalProperties": false,
|
|
239
|
+
"properties": {
|
|
240
|
+
"definitions": {
|
|
241
|
+
"type": "array",
|
|
242
|
+
"items": { "enum": ["terraform", "schema"] },
|
|
243
|
+
"uniqueItems": true,
|
|
244
|
+
"description": "Sources of the function table, merged in order."
|
|
245
|
+
},
|
|
246
|
+
"call_result_reference_positions": {
|
|
247
|
+
"$ref": "#/$defs/positions",
|
|
248
|
+
"description": "Positions from which a name a call declares may be referenced."
|
|
249
|
+
},
|
|
250
|
+
"calls_not_allowed_at": {
|
|
251
|
+
"type": "array",
|
|
252
|
+
"items": { "$ref": "#/$defs/path_entry" },
|
|
253
|
+
"description": "Paths where a call is a problem."
|
|
254
|
+
},
|
|
255
|
+
"marker_function": { "$ref": "#/$defs/marker_function" }
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
"loops": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"description": "The loop variables a loop macro binds within its body. Left out for a DSL that reads no loop variables.",
|
|
261
|
+
"required": ["scope_name"],
|
|
262
|
+
"additionalProperties": false,
|
|
263
|
+
"properties": {
|
|
264
|
+
"scope_name": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"minLength": 1,
|
|
267
|
+
"description": "The scope, declared under scopes, whose reference rules read loop variables."
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"locals": {
|
|
272
|
+
"type": "object",
|
|
273
|
+
"description": "Named values. Left out for a DSL without locals.",
|
|
274
|
+
"required": ["scope_name"],
|
|
275
|
+
"additionalProperties": false,
|
|
276
|
+
"properties": {
|
|
277
|
+
"scope_name": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"minLength": 1,
|
|
280
|
+
"description": "The scope, declared under scopes, whose declarations are the locals."
|
|
281
|
+
},
|
|
282
|
+
"path_separator": {
|
|
283
|
+
"type": "string",
|
|
284
|
+
"minLength": 1,
|
|
285
|
+
"description": "The text between the steps of a path into a local, read after the local's name. Left out, a local is read whole."
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"performance": {
|
|
290
|
+
"type": "object",
|
|
291
|
+
"description": "How the editor keeps a large schema fast. Left out for a DSL that needs none of it.",
|
|
292
|
+
"required": ["compiled_schema_cache"],
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"properties": {
|
|
295
|
+
"compiled_schema_cache": {
|
|
296
|
+
"type": "boolean",
|
|
297
|
+
"description": "Whether the compiled schema is kept in the extension's storage and loaded in later sessions instead of compiled."
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"validator": {
|
|
302
|
+
"type": "object",
|
|
303
|
+
"description": "How a document is read before it is validated against its schema. Left out for a DSL whose documents are validated as written.",
|
|
304
|
+
"required": ["child_values_from_parent_key"],
|
|
305
|
+
"additionalProperties": false,
|
|
306
|
+
"properties": {
|
|
307
|
+
"merge_base_keys": {
|
|
308
|
+
"type": "array",
|
|
309
|
+
"items": { "type": "string", "minLength": 1 },
|
|
310
|
+
"description": "Deprecated: call a `merge` macro whose argument is the content instead.",
|
|
311
|
+
"deprecated": true
|
|
312
|
+
},
|
|
313
|
+
"child_values_from_parent_key": {
|
|
314
|
+
"type": "array",
|
|
315
|
+
"items": {
|
|
316
|
+
"type": "object",
|
|
317
|
+
"required": ["pattern"],
|
|
318
|
+
"additionalProperties": false,
|
|
319
|
+
"properties": {
|
|
320
|
+
"pattern": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"pattern": "\\(\\?<field>[\\s\\S]*\\(\\?<value>|\\(\\?<value>[\\s\\S]*\\(\\?<field>",
|
|
323
|
+
"description": "Regular expression of a key that sets a field of its own entry, with (?<field>...) and (?<value>...) groups."
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
"description": "Keys that set a field of the entry they key."
|
|
328
|
+
},
|
|
329
|
+
"allow_quoted_values": {
|
|
330
|
+
"type": "array",
|
|
331
|
+
"items": { "enum": ["boolean", "integer", "number"] },
|
|
332
|
+
"uniqueItems": true,
|
|
333
|
+
"description": "Types a quoted value is validated as, where the schema expects that type and the string spells one. Defaults to []."
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
"marker_function": {
|
|
338
|
+
"type": "object",
|
|
339
|
+
"description": "A call written in a key: <name> <call_marker><function>. Left out when the DSL's calls take another shape.",
|
|
340
|
+
"required": ["call_marker", "splat_operator", "calls_without_name_allowed"],
|
|
341
|
+
"additionalProperties": false,
|
|
342
|
+
"properties": {
|
|
343
|
+
"call_marker": {
|
|
344
|
+
"type": "string",
|
|
345
|
+
"minLength": 1,
|
|
346
|
+
"description": "Text that opens a call in a key."
|
|
347
|
+
},
|
|
348
|
+
"splat_operator": {
|
|
349
|
+
"type": ["string", "null"],
|
|
350
|
+
"minLength": 1,
|
|
351
|
+
"description": "Suffix after the function that spreads a list value into the arguments; `null` where the function table decides how a value binds the arguments."
|
|
352
|
+
},
|
|
353
|
+
"calls_without_name_allowed": {
|
|
354
|
+
"type": "boolean",
|
|
355
|
+
"description": "Whether a key that is the marker alone is a call, the only key of its map."
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"scopes": {
|
|
360
|
+
"type": "object",
|
|
361
|
+
"description": "The DSL's scopes. A name in capitals is a logical scope; any other name is the DSL's own word.",
|
|
362
|
+
"patternProperties": {
|
|
363
|
+
"^[A-Z][A-Z0-9_]*$": { "$ref": "#/$defs/scope" }
|
|
364
|
+
},
|
|
365
|
+
"additionalProperties": {
|
|
366
|
+
"allOf": [
|
|
367
|
+
{ "$ref": "#/$defs/scope" },
|
|
368
|
+
{
|
|
369
|
+
"properties": {
|
|
370
|
+
"named_by_parent_key": { "const": false },
|
|
371
|
+
"builtin_names": { "maxItems": 0 }
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
]
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
"scope": {
|
|
378
|
+
"type": "object",
|
|
379
|
+
"required": ["regions", "later_items_of_declaring_list", "named_by_parent_key", "builtin_names"],
|
|
380
|
+
"additionalProperties": false,
|
|
381
|
+
"properties": {
|
|
382
|
+
"regions": {
|
|
383
|
+
"type": "array",
|
|
384
|
+
"items": { "$ref": "#/$defs/path" },
|
|
385
|
+
"description": "Paths whose subtree in any file of the fold sees the scope's names; $ is the whole fold."
|
|
386
|
+
},
|
|
387
|
+
"later_items_of_declaring_list": {
|
|
388
|
+
"type": "boolean",
|
|
389
|
+
"description": "Whether a name is also visible in the later items of the list that declares it."
|
|
390
|
+
},
|
|
391
|
+
"named_by_parent_key": {
|
|
392
|
+
"type": "boolean",
|
|
393
|
+
"description": "Whether the mapping key enclosing a declaration is the scope its name is in. Logical scopes only."
|
|
394
|
+
},
|
|
395
|
+
"builtin_names": {
|
|
396
|
+
"type": "array",
|
|
397
|
+
"items": { "type": "string", "minLength": 1 },
|
|
398
|
+
"description": "Names the scope holds without a declaration. Logical scopes only."
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
"if": { "properties": { "regions": { "maxItems": 0 } } },
|
|
402
|
+
"then": { "properties": { "later_items_of_declaring_list": { "const": true } } }
|
|
403
|
+
},
|
|
404
|
+
"declaration": {
|
|
405
|
+
"type": "object",
|
|
406
|
+
"required": [
|
|
407
|
+
"path",
|
|
408
|
+
"skip_keys",
|
|
409
|
+
"exclude_candidates",
|
|
410
|
+
"name_source",
|
|
411
|
+
"key_token",
|
|
412
|
+
"name_spelling",
|
|
413
|
+
"meta_argument_name",
|
|
414
|
+
"declares_every_name",
|
|
415
|
+
"scope_name"
|
|
416
|
+
],
|
|
417
|
+
"additionalProperties": false,
|
|
418
|
+
"properties": {
|
|
419
|
+
"path": { "$ref": "#/$defs/path" },
|
|
420
|
+
"skip_keys": {
|
|
421
|
+
"type": "array",
|
|
422
|
+
"items": { "type": "string" },
|
|
423
|
+
"description": "Keys a .*, [*] or ..* step does not descend into."
|
|
424
|
+
},
|
|
425
|
+
"exclude_candidates": {
|
|
426
|
+
"type": "array",
|
|
427
|
+
"items": { "type": "string" },
|
|
428
|
+
"description": "Keys at the last step that declare nothing."
|
|
429
|
+
},
|
|
430
|
+
"name_source": {
|
|
431
|
+
"enum": ["key", "value", "meta_argument"],
|
|
432
|
+
"description": "Where the name is read: the key, the scalar value, or a meta argument of the key."
|
|
433
|
+
},
|
|
434
|
+
"key_token": {
|
|
435
|
+
"enum": ["all_words", "first_word", "last_word", null],
|
|
436
|
+
"description": "The words of the key that are the name; null when the name is not read from the key."
|
|
437
|
+
},
|
|
438
|
+
"name_spelling": {
|
|
439
|
+
"enum": ["as_written", "dashes_as_underscores"],
|
|
440
|
+
"description": "How the name is spelled for references."
|
|
441
|
+
},
|
|
442
|
+
"meta_argument_name": {
|
|
443
|
+
"type": ["string", "null"],
|
|
444
|
+
"minLength": 1,
|
|
445
|
+
"description": "The meta argument holding the name; null when the name is not read from a meta argument."
|
|
446
|
+
},
|
|
447
|
+
"declares_every_name": {
|
|
448
|
+
"type": "boolean",
|
|
449
|
+
"description": "Whether the key declares every name of the scope, for names defined in a document the editor does not read."
|
|
450
|
+
},
|
|
451
|
+
"scope_name": {
|
|
452
|
+
"type": "string",
|
|
453
|
+
"minLength": 1,
|
|
454
|
+
"description": "A scope declared under scopes."
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
"allOf": [
|
|
458
|
+
{
|
|
459
|
+
"if": { "properties": { "name_source": { "const": "key" } } },
|
|
460
|
+
"then": { "properties": { "key_token": { "type": "string" } } }
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"if": { "properties": { "name_source": { "const": "meta_argument" } } },
|
|
464
|
+
"then": { "properties": { "meta_argument_name": { "type": "string" } } }
|
|
465
|
+
}
|
|
466
|
+
]
|
|
467
|
+
},
|
|
468
|
+
"reference": {
|
|
469
|
+
"type": "object",
|
|
470
|
+
"required": [
|
|
471
|
+
"pattern",
|
|
472
|
+
"positions",
|
|
473
|
+
"text_after_name_allowed",
|
|
474
|
+
"scope_name",
|
|
475
|
+
"scope_group",
|
|
476
|
+
"name_group"
|
|
477
|
+
],
|
|
478
|
+
"additionalProperties": false,
|
|
479
|
+
"properties": {
|
|
480
|
+
"pattern": {
|
|
481
|
+
"type": "string",
|
|
482
|
+
"minLength": 1,
|
|
483
|
+
"description": "Regular expression of a reference, with named groups."
|
|
484
|
+
},
|
|
485
|
+
"positions": {
|
|
486
|
+
"$ref": "#/$defs/positions",
|
|
487
|
+
"description": "Positions the reference may stand in."
|
|
488
|
+
},
|
|
489
|
+
"text_after_name_allowed": {
|
|
490
|
+
"type": "boolean",
|
|
491
|
+
"description": "Whether text such as a field path may follow the name."
|
|
492
|
+
},
|
|
493
|
+
"scope_name": {
|
|
494
|
+
"type": "string",
|
|
495
|
+
"minLength": 1,
|
|
496
|
+
"description": "The scope the reference resolves in, declared under scopes."
|
|
497
|
+
},
|
|
498
|
+
"scope_group": {
|
|
499
|
+
"type": ["string", "null"],
|
|
500
|
+
"minLength": 1,
|
|
501
|
+
"description": "The pattern group holding the scope of a named_by_parent_key scope; null for any other scope."
|
|
502
|
+
},
|
|
503
|
+
"name_group": {
|
|
504
|
+
"type": "string",
|
|
505
|
+
"minLength": 1,
|
|
506
|
+
"description": "The pattern group holding the name."
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
"positions": {
|
|
511
|
+
"type": "array",
|
|
512
|
+
"items": { "enum": ["whole_scalar", "whole_placeholder", "placeholder_in_text", "anywhere_in_scalar"] },
|
|
513
|
+
"uniqueItems": true
|
|
514
|
+
},
|
|
515
|
+
"key_sort_order": {
|
|
516
|
+
"type": "object",
|
|
517
|
+
"required": ["path", "skip_keys", "order", "first_keys", "last_keys"],
|
|
518
|
+
"additionalProperties": false,
|
|
519
|
+
"properties": {
|
|
520
|
+
"path": { "$ref": "#/$defs/path" },
|
|
521
|
+
"skip_keys": {
|
|
522
|
+
"type": "array",
|
|
523
|
+
"items": { "type": "string" },
|
|
524
|
+
"description": "Keys a .*, [*] or ..* step does not select or descend into."
|
|
525
|
+
},
|
|
526
|
+
"order": {
|
|
527
|
+
"enum": ["alphabetical", "significance"],
|
|
528
|
+
"description": "Where a new key goes among the map's keys."
|
|
529
|
+
},
|
|
530
|
+
"first_keys": {
|
|
531
|
+
"type": "array",
|
|
532
|
+
"items": { "type": "string", "minLength": 1 },
|
|
533
|
+
"uniqueItems": true,
|
|
534
|
+
"description": "Under significance, keys at the top of the map, in this order. [] under alphabetical."
|
|
535
|
+
},
|
|
536
|
+
"last_keys": {
|
|
537
|
+
"type": "array",
|
|
538
|
+
"items": { "type": "string", "minLength": 1 },
|
|
539
|
+
"uniqueItems": true,
|
|
540
|
+
"description": "Under significance, keys at the bottom of the map, in this order. [] under alphabetical."
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
"path_entry": {
|
|
545
|
+
"type": "object",
|
|
546
|
+
"required": ["path", "skip_keys"],
|
|
547
|
+
"additionalProperties": false,
|
|
548
|
+
"properties": {
|
|
549
|
+
"path": { "$ref": "#/$defs/path" },
|
|
550
|
+
"skip_keys": {
|
|
551
|
+
"type": "array",
|
|
552
|
+
"items": { "type": "string" },
|
|
553
|
+
"description": "Keys a .*, [*] or ..* step does not select or descend into."
|
|
554
|
+
},
|
|
555
|
+
"includes_subtree": {
|
|
556
|
+
"type": "boolean",
|
|
557
|
+
"description": "Deprecated: list the path ending in ..* as its own entry instead.",
|
|
558
|
+
"deprecated": true
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
"path": {
|
|
563
|
+
"type": "string",
|
|
564
|
+
"pattern": "^\\$(\\.(\\*|[^.\\[*][^.\\[]*)|\\[\\*\\]|\\['[^']+'\\]|\\.\\.([^.\\[*][^.\\[]*|\\['[^']+'\\]))*(\\.\\.\\*)?$",
|
|
565
|
+
"description": "A JSONPath (RFC 9535) from $, with .name, ['name'], ..name, .* and [*] steps and an optional final ..*."
|
|
566
|
+
},
|
|
567
|
+
"globs": {
|
|
568
|
+
"type": "array",
|
|
569
|
+
"items": { "type": "string", "minLength": 1 }
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/litebitus/yaml-dsl-spec/schemas/yaml-dsl-v1.2.schema.json",
|
|
4
|
+
"title": "yaml-dsl.yml v1.2",
|
|
5
|
+
"description": "The workspace's YAML DSLs: which files each one owns and the syntax of its names, references, placeholders and calls.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["version", "dsls"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"version": {
|
|
11
|
+
"enum": ["1", "1.2"],
|
|
12
|
+
"description": "Config format version: `1.2`, or `1` for the newest 1.x the reader knows."
|
|
13
|
+
},
|
|
14
|
+
"dsls": {
|
|
15
|
+
"type": "array",
|
|
16
|
+
"description": "One entry per DSL.",
|
|
17
|
+
"items": { "$ref": "#/$defs/dsl" }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"$defs": {
|
|
21
|
+
"dsl": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"required": [
|
|
24
|
+
"id",
|
|
25
|
+
"file_includes",
|
|
26
|
+
"file_excludes",
|
|
27
|
+
"schema_search_paths",
|
|
28
|
+
"key_sort_orders",
|
|
29
|
+
"scopes",
|
|
30
|
+
"declarations",
|
|
31
|
+
"references"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"properties": {
|
|
35
|
+
"id": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1,
|
|
38
|
+
"description": "Name of the DSL."
|
|
39
|
+
},
|
|
40
|
+
"file_includes": {
|
|
41
|
+
"$ref": "#/$defs/globs",
|
|
42
|
+
"description": "Globs of the files the DSL owns. A glob starting with {config_root}/ matches below the config's folder."
|
|
43
|
+
},
|
|
44
|
+
"file_excludes": {
|
|
45
|
+
"$ref": "#/$defs/globs",
|
|
46
|
+
"description": "Globs of files the DSL does not own, even when file_includes matches them. A glob starting with {config_root}/ matches below the config's folder."
|
|
47
|
+
},
|
|
48
|
+
"schema_search_paths": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": { "type": "string", "minLength": 1 },
|
|
51
|
+
"description": "Schemas tried in order when a file names none, or the one it names is not on disk. Each path is relative to the file, or to the config's folder when it starts with {config_root}/, and a * in a step matches within it; a URL is fetched."
|
|
52
|
+
},
|
|
53
|
+
"tag_keys": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"required": ["tag", "key"],
|
|
58
|
+
"additionalProperties": false,
|
|
59
|
+
"properties": {
|
|
60
|
+
"tag": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"pattern": "^![^\\s!]+$",
|
|
63
|
+
"description": "The YAML tag as written, such as !Ref."
|
|
64
|
+
},
|
|
65
|
+
"key": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1,
|
|
68
|
+
"description": "The key the tagged node stands for, such as Ref."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"description": "YAML tags that stand for keys: a tagged node reads as a map holding the key, the node its value."
|
|
73
|
+
},
|
|
74
|
+
"layers": { "$ref": "#/$defs/layers" },
|
|
75
|
+
"placeholder": { "$ref": "#/$defs/placeholder" },
|
|
76
|
+
"function": { "$ref": "#/$defs/function" },
|
|
77
|
+
"locals": { "$ref": "#/$defs/locals" },
|
|
78
|
+
"loops": { "$ref": "#/$defs/loops" },
|
|
79
|
+
"validator": { "$ref": "#/$defs/validator" },
|
|
80
|
+
"performance": { "$ref": "#/$defs/performance" },
|
|
81
|
+
"key_sort_orders": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": { "$ref": "#/$defs/key_sort_order" },
|
|
84
|
+
"description": "Where an edit places a new key in each map. The first entry whose path covers the map applies."
|
|
85
|
+
},
|
|
86
|
+
"scopes": { "$ref": "#/$defs/scopes" },
|
|
87
|
+
"declarations": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"items": { "$ref": "#/$defs/declaration" },
|
|
90
|
+
"description": "Where names are declared."
|
|
91
|
+
},
|
|
92
|
+
"references": {
|
|
93
|
+
"type": "array",
|
|
94
|
+
"items": { "$ref": "#/$defs/reference" },
|
|
95
|
+
"description": "How names are referenced. Rules reading the same text are tried in order."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"layers": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"description": "The common layer and its overlays. Left out for a DSL without layers.",
|
|
102
|
+
"required": ["common_layer_discovery", "duplicate_check"],
|
|
103
|
+
"additionalProperties": false,
|
|
104
|
+
"if": { "properties": { "common_layer_discovery": { "const": "overlay_includes" } } },
|
|
105
|
+
"then": {
|
|
106
|
+
"required": ["overlay_includes"],
|
|
107
|
+
"not": { "anyOf": [{ "required": ["overlay_folders"] }, { "required": ["common_layer_files"] }] }
|
|
108
|
+
},
|
|
109
|
+
"else": {
|
|
110
|
+
"required": ["overlay_folders"],
|
|
111
|
+
"not": { "required": ["overlay_includes"] }
|
|
112
|
+
},
|
|
113
|
+
"properties": {
|
|
114
|
+
"overlay_folders": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": { "type": "string", "minLength": 1 },
|
|
117
|
+
"description": "Folder names of the overlays."
|
|
118
|
+
},
|
|
119
|
+
"common_layer_discovery": {
|
|
120
|
+
"enum": ["parent", "ancestor", "overlay_includes"],
|
|
121
|
+
"description": "How an overlay and its common layer are paired: by the overlay folder's parent, by the nearest ancestor above an overlay folder, or by an include in the overlay."
|
|
122
|
+
},
|
|
123
|
+
"overlay_includes": {
|
|
124
|
+
"type": "array",
|
|
125
|
+
"items": { "$ref": "#/$defs/overlay_include" },
|
|
126
|
+
"description": "How an include in an overlay names its common layer. Read only with common_layer_discovery overlay_includes."
|
|
127
|
+
},
|
|
128
|
+
"common_layer_files": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": {
|
|
131
|
+
"type": "array",
|
|
132
|
+
"minItems": 1,
|
|
133
|
+
"uniqueItems": true,
|
|
134
|
+
"items": { "type": "string", "minLength": 1, "pattern": "^[^/\\\\]+$" }
|
|
135
|
+
},
|
|
136
|
+
"description": "A layer file name to the names its common layer may take, the first that exists taken. {concern} in a name stands for a concern below its overlays, and each list holds a name without it. Left out, the common layer takes the layer file's own name."
|
|
137
|
+
},
|
|
138
|
+
"duplicate_check": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"description": "The unit a suggestion takes, a node of the overlays it moves or deletes whole.",
|
|
141
|
+
"required": ["depth", "key_depths", "skip_keys"],
|
|
142
|
+
"additionalProperties": false,
|
|
143
|
+
"properties": {
|
|
144
|
+
"depth": {
|
|
145
|
+
"type": "integer",
|
|
146
|
+
"minimum": 1,
|
|
147
|
+
"description": "How many levels below the document root the unit sits, under a top-level key key_depths does not list."
|
|
148
|
+
},
|
|
149
|
+
"key_depths": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"additionalProperties": { "type": "integer", "minimum": 1 },
|
|
152
|
+
"description": "The unit's depth under a given top-level key, {} when every key takes depth."
|
|
153
|
+
},
|
|
154
|
+
"skip_keys": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"items": { "type": "string" },
|
|
157
|
+
"description": "Keys no suggestion compares or moves, at any depth."
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"overlay_include": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"description": "An include: a key whose value names the common layer merged in place of the include.",
|
|
166
|
+
"required": ["key_paths", "value_conditions", "location_path", "location_mappings"],
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"properties": {
|
|
169
|
+
"key_paths": {
|
|
170
|
+
"type": "array",
|
|
171
|
+
"items": { "type": "string", "minLength": 1 },
|
|
172
|
+
"description": "JSONPaths of the keys whose values are includes, such as $..['Fn::Transform']. A value that is a list holds one include per map."
|
|
173
|
+
},
|
|
174
|
+
"value_conditions": {
|
|
175
|
+
"type": "array",
|
|
176
|
+
"items": {
|
|
177
|
+
"type": "object",
|
|
178
|
+
"required": ["key", "value"],
|
|
179
|
+
"additionalProperties": false,
|
|
180
|
+
"properties": {
|
|
181
|
+
"key": { "type": "string", "minLength": 1, "description": "A key the include value holds." },
|
|
182
|
+
"value": { "type": "string", "minLength": 1, "description": "The value it holds at that key." }
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"description": "The key and value pairs an include value holds, [] for none."
|
|
186
|
+
},
|
|
187
|
+
"location_path": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"minLength": 1,
|
|
190
|
+
"description": "A JSONPath of names from the include value to its location, such as $.Parameters.Location."
|
|
191
|
+
},
|
|
192
|
+
"location_mappings": {
|
|
193
|
+
"type": "array",
|
|
194
|
+
"items": {
|
|
195
|
+
"type": "object",
|
|
196
|
+
"required": ["local", "remote"],
|
|
197
|
+
"additionalProperties": false,
|
|
198
|
+
"properties": {
|
|
199
|
+
"local": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"minLength": 1,
|
|
202
|
+
"description": "The local path a remote location stands for, relative to the overlay, or to the config's folder when it starts with {config_root}/."
|
|
203
|
+
},
|
|
204
|
+
"remote": { "type": "string", "minLength": 1, "description": "The start of a location." }
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"description": "A location starting with remote names the file at local followed by the rest of the location. A location none covers names no file."
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"placeholder": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"description": "The placeholder syntax. Left out for a DSL without placeholders.",
|
|
214
|
+
"required": ["pattern", "unscanned_paths"],
|
|
215
|
+
"additionalProperties": false,
|
|
216
|
+
"properties": {
|
|
217
|
+
"pattern": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"pattern": "\\(\\?<body>",
|
|
220
|
+
"description": "Regular expression of a placeholder, with a (?<body>...) group."
|
|
221
|
+
},
|
|
222
|
+
"escape_prefix": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1,
|
|
225
|
+
"description": "Text that, written right before a placeholder, keeps it as literal text. Left out for none."
|
|
226
|
+
},
|
|
227
|
+
"unscanned_paths": {
|
|
228
|
+
"type": "array",
|
|
229
|
+
"items": { "$ref": "#/$defs/path_entry" },
|
|
230
|
+
"description": "Paths whose text is another language's and is not read for placeholders."
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"function": {
|
|
235
|
+
"type": "object",
|
|
236
|
+
"description": "Function calls. Left out for a DSL without calls.",
|
|
237
|
+
"required": ["definitions", "call_result_reference_positions", "calls_not_allowed_at"],
|
|
238
|
+
"additionalProperties": false,
|
|
239
|
+
"properties": {
|
|
240
|
+
"definitions": {
|
|
241
|
+
"type": "array",
|
|
242
|
+
"items": { "enum": ["terraform", "schema"] },
|
|
243
|
+
"uniqueItems": true,
|
|
244
|
+
"description": "Sources of the function table, merged in order."
|
|
245
|
+
},
|
|
246
|
+
"call_result_reference_positions": {
|
|
247
|
+
"$ref": "#/$defs/positions",
|
|
248
|
+
"description": "Positions from which a name a call declares may be referenced."
|
|
249
|
+
},
|
|
250
|
+
"calls_not_allowed_at": {
|
|
251
|
+
"type": "array",
|
|
252
|
+
"items": { "$ref": "#/$defs/path_entry" },
|
|
253
|
+
"description": "Paths where a call is a problem."
|
|
254
|
+
},
|
|
255
|
+
"marker_function": { "$ref": "#/$defs/marker_function" }
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
"loops": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"description": "The loop variables a loop macro binds within its body. Left out for a DSL that reads no loop variables.",
|
|
261
|
+
"required": ["scope_name"],
|
|
262
|
+
"additionalProperties": false,
|
|
263
|
+
"properties": {
|
|
264
|
+
"scope_name": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"minLength": 1,
|
|
267
|
+
"description": "The scope, declared under scopes, whose reference rules read loop variables."
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"locals": {
|
|
272
|
+
"type": "object",
|
|
273
|
+
"description": "Named values. Left out for a DSL without locals.",
|
|
274
|
+
"required": ["scope_name"],
|
|
275
|
+
"additionalProperties": false,
|
|
276
|
+
"properties": {
|
|
277
|
+
"scope_name": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"minLength": 1,
|
|
280
|
+
"description": "The scope, declared under scopes, whose declarations are the locals."
|
|
281
|
+
},
|
|
282
|
+
"path_separator": {
|
|
283
|
+
"type": "string",
|
|
284
|
+
"minLength": 1,
|
|
285
|
+
"description": "The text between the steps of a path into a local, read after the local's name. Left out, a local is read whole."
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"performance": {
|
|
290
|
+
"type": "object",
|
|
291
|
+
"description": "How the editor keeps a large schema fast. Left out for a DSL that needs none of it.",
|
|
292
|
+
"required": ["compiled_schema_cache"],
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"properties": {
|
|
295
|
+
"compiled_schema_cache": {
|
|
296
|
+
"type": "boolean",
|
|
297
|
+
"description": "Whether the compiled schema is kept in the extension's storage and loaded in later sessions instead of compiled."
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"validator": {
|
|
302
|
+
"type": "object",
|
|
303
|
+
"description": "How a document is read before it is validated against its schema. Left out for a DSL whose documents are validated as written.",
|
|
304
|
+
"required": ["child_values_from_parent_key"],
|
|
305
|
+
"additionalProperties": false,
|
|
306
|
+
"properties": {
|
|
307
|
+
"merge_base_keys": {
|
|
308
|
+
"type": "array",
|
|
309
|
+
"items": { "type": "string", "minLength": 1 },
|
|
310
|
+
"description": "The keys whose content is merged into their sibling entries before validation."
|
|
311
|
+
},
|
|
312
|
+
"child_values_from_parent_key": {
|
|
313
|
+
"type": "array",
|
|
314
|
+
"items": {
|
|
315
|
+
"type": "object",
|
|
316
|
+
"required": ["pattern"],
|
|
317
|
+
"additionalProperties": false,
|
|
318
|
+
"properties": {
|
|
319
|
+
"pattern": {
|
|
320
|
+
"type": "string",
|
|
321
|
+
"pattern": "\\(\\?<field>[\\s\\S]*\\(\\?<value>|\\(\\?<value>[\\s\\S]*\\(\\?<field>",
|
|
322
|
+
"description": "Regular expression of a key that sets a field of its own entry, with (?<field>...) and (?<value>...) groups."
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
"description": "Keys that set a field of the entry they key."
|
|
327
|
+
},
|
|
328
|
+
"allow_quoted_values": {
|
|
329
|
+
"type": "array",
|
|
330
|
+
"items": { "enum": ["boolean", "integer", "number"] },
|
|
331
|
+
"uniqueItems": true,
|
|
332
|
+
"description": "Types a quoted value is validated as, where the schema expects that type and the string spells one. Defaults to []."
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"marker_function": {
|
|
337
|
+
"type": "object",
|
|
338
|
+
"description": "A call written in a key: <name> <call_marker><function>. Left out when the DSL's calls take another shape.",
|
|
339
|
+
"required": ["call_marker", "splat_operator", "calls_without_name_allowed"],
|
|
340
|
+
"additionalProperties": false,
|
|
341
|
+
"properties": {
|
|
342
|
+
"call_marker": {
|
|
343
|
+
"type": "string",
|
|
344
|
+
"minLength": 1,
|
|
345
|
+
"description": "Text that opens a call in a key."
|
|
346
|
+
},
|
|
347
|
+
"splat_operator": {
|
|
348
|
+
"type": ["string", "null"],
|
|
349
|
+
"minLength": 1,
|
|
350
|
+
"description": "Suffix after the function that spreads a list value into the arguments; `null` where the function table decides how a value binds the arguments."
|
|
351
|
+
},
|
|
352
|
+
"calls_without_name_allowed": {
|
|
353
|
+
"type": "boolean",
|
|
354
|
+
"description": "Whether a key that is the marker alone is a call, the only key of its map."
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"scopes": {
|
|
359
|
+
"type": "object",
|
|
360
|
+
"description": "The DSL's scopes. A name in capitals is a logical scope; any other name is the DSL's own word.",
|
|
361
|
+
"patternProperties": {
|
|
362
|
+
"^[A-Z][A-Z0-9_]*$": { "$ref": "#/$defs/scope" }
|
|
363
|
+
},
|
|
364
|
+
"additionalProperties": {
|
|
365
|
+
"allOf": [
|
|
366
|
+
{ "$ref": "#/$defs/scope" },
|
|
367
|
+
{
|
|
368
|
+
"properties": {
|
|
369
|
+
"named_by_parent_key": { "const": false },
|
|
370
|
+
"builtin_names": { "maxItems": 0 }
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
"scope": {
|
|
377
|
+
"type": "object",
|
|
378
|
+
"required": ["regions", "later_items_of_declaring_list", "named_by_parent_key", "builtin_names"],
|
|
379
|
+
"additionalProperties": false,
|
|
380
|
+
"properties": {
|
|
381
|
+
"regions": {
|
|
382
|
+
"type": "array",
|
|
383
|
+
"items": { "$ref": "#/$defs/path" },
|
|
384
|
+
"description": "Paths whose subtree in any file of the fold sees the scope's names; $ is the whole fold."
|
|
385
|
+
},
|
|
386
|
+
"later_items_of_declaring_list": {
|
|
387
|
+
"type": "boolean",
|
|
388
|
+
"description": "Whether a name is also visible in the later items of the list that declares it."
|
|
389
|
+
},
|
|
390
|
+
"named_by_parent_key": {
|
|
391
|
+
"type": "boolean",
|
|
392
|
+
"description": "Whether the mapping key enclosing a declaration is the scope its name is in. Logical scopes only."
|
|
393
|
+
},
|
|
394
|
+
"builtin_names": {
|
|
395
|
+
"type": "array",
|
|
396
|
+
"items": { "type": "string", "minLength": 1 },
|
|
397
|
+
"description": "Names the scope holds without a declaration. Logical scopes only."
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
"if": { "properties": { "regions": { "maxItems": 0 } } },
|
|
401
|
+
"then": { "properties": { "later_items_of_declaring_list": { "const": true } } }
|
|
402
|
+
},
|
|
403
|
+
"declaration": {
|
|
404
|
+
"type": "object",
|
|
405
|
+
"required": [
|
|
406
|
+
"path",
|
|
407
|
+
"skip_keys",
|
|
408
|
+
"exclude_candidates",
|
|
409
|
+
"name_source",
|
|
410
|
+
"key_token",
|
|
411
|
+
"name_spelling",
|
|
412
|
+
"meta_argument_name",
|
|
413
|
+
"declares_every_name",
|
|
414
|
+
"scope_name"
|
|
415
|
+
],
|
|
416
|
+
"additionalProperties": false,
|
|
417
|
+
"properties": {
|
|
418
|
+
"path": { "$ref": "#/$defs/path" },
|
|
419
|
+
"skip_keys": {
|
|
420
|
+
"type": "array",
|
|
421
|
+
"items": { "type": "string" },
|
|
422
|
+
"description": "Keys a .*, [*] or ..* step does not descend into."
|
|
423
|
+
},
|
|
424
|
+
"exclude_candidates": {
|
|
425
|
+
"type": "array",
|
|
426
|
+
"items": { "type": "string" },
|
|
427
|
+
"description": "Keys at the last step that declare nothing."
|
|
428
|
+
},
|
|
429
|
+
"name_source": {
|
|
430
|
+
"enum": ["key", "value", "meta_argument"],
|
|
431
|
+
"description": "Where the name is read: the key, the scalar value, or a meta argument of the key."
|
|
432
|
+
},
|
|
433
|
+
"key_token": {
|
|
434
|
+
"enum": ["all_words", "first_word", "last_word", null],
|
|
435
|
+
"description": "The words of the key that are the name; null when the name is not read from the key."
|
|
436
|
+
},
|
|
437
|
+
"name_spelling": {
|
|
438
|
+
"enum": ["as_written", "dashes_as_underscores"],
|
|
439
|
+
"description": "How the name is spelled for references."
|
|
440
|
+
},
|
|
441
|
+
"meta_argument_name": {
|
|
442
|
+
"type": ["string", "null"],
|
|
443
|
+
"minLength": 1,
|
|
444
|
+
"description": "The meta argument holding the name; null when the name is not read from a meta argument."
|
|
445
|
+
},
|
|
446
|
+
"declares_every_name": {
|
|
447
|
+
"type": "boolean",
|
|
448
|
+
"description": "Whether the key declares every name of the scope, for names defined in a document the editor does not read."
|
|
449
|
+
},
|
|
450
|
+
"scope_name": {
|
|
451
|
+
"type": "string",
|
|
452
|
+
"minLength": 1,
|
|
453
|
+
"description": "A scope declared under scopes."
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
"allOf": [
|
|
457
|
+
{
|
|
458
|
+
"if": { "properties": { "name_source": { "const": "key" } } },
|
|
459
|
+
"then": { "properties": { "key_token": { "type": "string" } } }
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"if": { "properties": { "name_source": { "const": "meta_argument" } } },
|
|
463
|
+
"then": { "properties": { "meta_argument_name": { "type": "string" } } }
|
|
464
|
+
}
|
|
465
|
+
]
|
|
466
|
+
},
|
|
467
|
+
"reference": {
|
|
468
|
+
"type": "object",
|
|
469
|
+
"required": [
|
|
470
|
+
"pattern",
|
|
471
|
+
"positions",
|
|
472
|
+
"text_after_name_allowed",
|
|
473
|
+
"scope_name",
|
|
474
|
+
"scope_group",
|
|
475
|
+
"name_group"
|
|
476
|
+
],
|
|
477
|
+
"additionalProperties": false,
|
|
478
|
+
"properties": {
|
|
479
|
+
"pattern": {
|
|
480
|
+
"type": "string",
|
|
481
|
+
"minLength": 1,
|
|
482
|
+
"description": "Regular expression of a reference, with named groups."
|
|
483
|
+
},
|
|
484
|
+
"positions": {
|
|
485
|
+
"$ref": "#/$defs/positions",
|
|
486
|
+
"description": "Positions the reference may stand in."
|
|
487
|
+
},
|
|
488
|
+
"text_after_name_allowed": {
|
|
489
|
+
"type": "boolean",
|
|
490
|
+
"description": "Whether text such as a field path may follow the name."
|
|
491
|
+
},
|
|
492
|
+
"scope_name": {
|
|
493
|
+
"type": "string",
|
|
494
|
+
"minLength": 1,
|
|
495
|
+
"description": "The scope the reference resolves in, declared under scopes."
|
|
496
|
+
},
|
|
497
|
+
"scope_group": {
|
|
498
|
+
"type": ["string", "null"],
|
|
499
|
+
"minLength": 1,
|
|
500
|
+
"description": "The pattern group holding the scope of a named_by_parent_key scope; null for any other scope."
|
|
501
|
+
},
|
|
502
|
+
"name_group": {
|
|
503
|
+
"type": "string",
|
|
504
|
+
"minLength": 1,
|
|
505
|
+
"description": "The pattern group holding the name."
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
"positions": {
|
|
510
|
+
"type": "array",
|
|
511
|
+
"items": { "enum": ["whole_scalar", "whole_placeholder", "placeholder_in_text", "anywhere_in_scalar"] },
|
|
512
|
+
"uniqueItems": true
|
|
513
|
+
},
|
|
514
|
+
"key_sort_order": {
|
|
515
|
+
"type": "object",
|
|
516
|
+
"required": ["path", "skip_keys", "order", "first_keys", "last_keys"],
|
|
517
|
+
"additionalProperties": false,
|
|
518
|
+
"properties": {
|
|
519
|
+
"path": { "$ref": "#/$defs/path" },
|
|
520
|
+
"skip_keys": {
|
|
521
|
+
"type": "array",
|
|
522
|
+
"items": { "type": "string" },
|
|
523
|
+
"description": "Keys a .*, [*] or ..* step does not select or descend into."
|
|
524
|
+
},
|
|
525
|
+
"order": {
|
|
526
|
+
"enum": ["alphabetical", "significance"],
|
|
527
|
+
"description": "Where a new key goes among the map's keys."
|
|
528
|
+
},
|
|
529
|
+
"first_keys": {
|
|
530
|
+
"type": "array",
|
|
531
|
+
"items": { "type": "string", "minLength": 1 },
|
|
532
|
+
"uniqueItems": true,
|
|
533
|
+
"description": "Under significance, keys at the top of the map, in this order. [] under alphabetical."
|
|
534
|
+
},
|
|
535
|
+
"last_keys": {
|
|
536
|
+
"type": "array",
|
|
537
|
+
"items": { "type": "string", "minLength": 1 },
|
|
538
|
+
"uniqueItems": true,
|
|
539
|
+
"description": "Under significance, keys at the bottom of the map, in this order. [] under alphabetical."
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"path_entry": {
|
|
544
|
+
"type": "object",
|
|
545
|
+
"required": ["path", "skip_keys"],
|
|
546
|
+
"additionalProperties": false,
|
|
547
|
+
"properties": {
|
|
548
|
+
"path": { "$ref": "#/$defs/path" },
|
|
549
|
+
"skip_keys": {
|
|
550
|
+
"type": "array",
|
|
551
|
+
"items": { "type": "string" },
|
|
552
|
+
"description": "Keys a .*, [*] or ..* step does not select or descend into."
|
|
553
|
+
},
|
|
554
|
+
"includes_subtree": {
|
|
555
|
+
"type": "boolean",
|
|
556
|
+
"description": "List the path ending in ..* as its own entry instead.",
|
|
557
|
+
"deprecated": true
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"path": {
|
|
562
|
+
"type": "string",
|
|
563
|
+
"pattern": "^\\$(\\.(\\*|[^.\\[*][^.\\[]*)|\\[\\*\\]|\\['[^']+'\\]|\\.\\.([^.\\[*][^.\\[]*|\\['[^']+'\\]))*(\\.\\.\\*)?$",
|
|
564
|
+
"description": "A JSONPath (RFC 9535) from $, with .name, ['name'], ..name, .* and [*] steps and an optional final ..*."
|
|
565
|
+
},
|
|
566
|
+
"globs": {
|
|
567
|
+
"type": "array",
|
|
568
|
+
"items": { "type": "string", "minLength": 1 }
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|