@atproto/lexicon 0.0.1
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/README.md +31 -0
- package/build.js +22 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +3897 -0
- package/dist/index.js.map +7 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/lexicons.d.ts +15 -0
- package/dist/src/record/index.d.ts +4 -0
- package/dist/src/record/schema.d.ts +9 -0
- package/dist/src/record/schemas.d.ts +10 -0
- package/dist/src/record/util.d.ts +1 -0
- package/dist/src/record/validation.d.ts +24 -0
- package/dist/src/record/validator.d.ts +17 -0
- package/dist/src/record-validator.d.ts +17 -0
- package/dist/src/schema.d.ts +9 -0
- package/dist/src/schemas.d.ts +10 -0
- package/dist/src/types.d.ts +30268 -0
- package/dist/src/util.d.ts +6 -0
- package/dist/src/validation.d.ts +6 -0
- package/dist/src/validators/blob.d.ts +6 -0
- package/dist/src/validators/complex.d.ts +5 -0
- package/dist/src/validators/primitives.d.ts +9 -0
- package/dist/src/validators/xrpc.d.ts +3 -0
- package/dist/src/view-validator.d.ts +13 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.js +35 -0
- package/jest.config.js +6 -0
- package/package.json +21 -0
- package/src/index.ts +2 -0
- package/src/lexicons.ts +203 -0
- package/src/types.ts +318 -0
- package/src/util.ts +107 -0
- package/src/validation.ts +48 -0
- package/src/validators/blob.ts +57 -0
- package/src/validators/complex.ts +152 -0
- package/src/validators/primitives.ts +300 -0
- package/src/validators/xrpc.ts +50 -0
- package/tests/_scaffolds/lexicons.ts +379 -0
- package/tests/general.test.ts +611 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { Lexicons } from '../lexicons'
|
|
2
|
+
import {
|
|
3
|
+
LexUserType,
|
|
4
|
+
LexBoolean,
|
|
5
|
+
LexNumber,
|
|
6
|
+
LexInteger,
|
|
7
|
+
LexString,
|
|
8
|
+
LexDatetime,
|
|
9
|
+
ValidationResult,
|
|
10
|
+
ValidationError,
|
|
11
|
+
} from '../types'
|
|
12
|
+
|
|
13
|
+
export function validate(
|
|
14
|
+
lexicons: Lexicons,
|
|
15
|
+
path: string,
|
|
16
|
+
def: LexUserType,
|
|
17
|
+
value: unknown,
|
|
18
|
+
): ValidationResult {
|
|
19
|
+
switch (def.type) {
|
|
20
|
+
case 'boolean':
|
|
21
|
+
return boolean(lexicons, path, def, value)
|
|
22
|
+
case 'number':
|
|
23
|
+
return number(lexicons, path, def, value)
|
|
24
|
+
case 'integer':
|
|
25
|
+
return integer(lexicons, path, def, value)
|
|
26
|
+
case 'string':
|
|
27
|
+
return string(lexicons, path, def, value)
|
|
28
|
+
case 'datetime':
|
|
29
|
+
return datetime(lexicons, path, def, value)
|
|
30
|
+
case 'unknown':
|
|
31
|
+
return unknown(lexicons, path, def, value)
|
|
32
|
+
default:
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: new ValidationError(`Unexpected lexicon type: ${def.type}`),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function boolean(
|
|
41
|
+
lexicons: Lexicons,
|
|
42
|
+
path: string,
|
|
43
|
+
def: LexUserType,
|
|
44
|
+
value: unknown,
|
|
45
|
+
): ValidationResult {
|
|
46
|
+
def = def as LexBoolean
|
|
47
|
+
|
|
48
|
+
// type
|
|
49
|
+
const type = typeof value
|
|
50
|
+
if (type == 'undefined') {
|
|
51
|
+
if (typeof def.default === 'boolean') {
|
|
52
|
+
return { success: true }
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: new ValidationError(`${path} must be a boolean`),
|
|
57
|
+
}
|
|
58
|
+
} else if (type !== 'boolean') {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: new ValidationError(`${path} must be a boolean`),
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// const
|
|
66
|
+
if (typeof def.const === 'boolean') {
|
|
67
|
+
if (value !== def.const) {
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
error: new ValidationError(`${path} must be ${def.const}`),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { success: true }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function number(
|
|
79
|
+
lexicons: Lexicons,
|
|
80
|
+
path: string,
|
|
81
|
+
def: LexUserType,
|
|
82
|
+
value: unknown,
|
|
83
|
+
): ValidationResult {
|
|
84
|
+
def = def as LexNumber
|
|
85
|
+
|
|
86
|
+
// type
|
|
87
|
+
const type = typeof value
|
|
88
|
+
if (type == 'undefined') {
|
|
89
|
+
if (typeof def.default === 'number') {
|
|
90
|
+
return { success: true }
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
error: new ValidationError(`${path} must be a number`),
|
|
95
|
+
}
|
|
96
|
+
} else if (type !== 'number') {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error: new ValidationError(`${path} must be a number`),
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// const
|
|
104
|
+
if (typeof def.const === 'number') {
|
|
105
|
+
if (value !== def.const) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
error: new ValidationError(`${path} must be ${def.const}`),
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// enum
|
|
114
|
+
if (Array.isArray(def.enum)) {
|
|
115
|
+
if (!def.enum.includes(value as number)) {
|
|
116
|
+
return {
|
|
117
|
+
success: false,
|
|
118
|
+
error: new ValidationError(
|
|
119
|
+
`${path} must be one of (${def.enum.join('|')})`,
|
|
120
|
+
),
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// maximum
|
|
126
|
+
if (typeof def.maximum === 'number') {
|
|
127
|
+
if ((value as number) > def.maximum) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: new ValidationError(
|
|
131
|
+
`${path} can not be greater than ${def.maximum}`,
|
|
132
|
+
),
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// minimum
|
|
138
|
+
if (typeof def.minimum === 'number') {
|
|
139
|
+
if ((value as number) < def.minimum) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
error: new ValidationError(
|
|
143
|
+
`${path} can not be less than ${def.minimum}`,
|
|
144
|
+
),
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { success: true }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function integer(
|
|
153
|
+
lexicons: Lexicons,
|
|
154
|
+
path: string,
|
|
155
|
+
def: LexUserType,
|
|
156
|
+
value: unknown,
|
|
157
|
+
): ValidationResult {
|
|
158
|
+
def = def as LexInteger
|
|
159
|
+
|
|
160
|
+
// run number validation
|
|
161
|
+
const numRes = number(lexicons, path, def, value)
|
|
162
|
+
if (!numRes.success) {
|
|
163
|
+
return numRes
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// whole numbers only
|
|
167
|
+
if (!Number.isInteger(value)) {
|
|
168
|
+
return {
|
|
169
|
+
success: false,
|
|
170
|
+
error: new ValidationError(`${path} must be an integer`),
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return { success: true }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function string(
|
|
178
|
+
lexicons: Lexicons,
|
|
179
|
+
path: string,
|
|
180
|
+
def: LexUserType,
|
|
181
|
+
value: unknown,
|
|
182
|
+
): ValidationResult {
|
|
183
|
+
def = def as LexString
|
|
184
|
+
|
|
185
|
+
// type
|
|
186
|
+
const type = typeof value
|
|
187
|
+
if (type == 'undefined') {
|
|
188
|
+
if (typeof def.default === 'string') {
|
|
189
|
+
return { success: true }
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
error: new ValidationError(`${path} must be a string`),
|
|
194
|
+
}
|
|
195
|
+
} else if (type !== 'string') {
|
|
196
|
+
return {
|
|
197
|
+
success: false,
|
|
198
|
+
error: new ValidationError(`${path} must be a string`),
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// const
|
|
203
|
+
if (typeof def.const === 'string') {
|
|
204
|
+
if (value !== def.const) {
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: new ValidationError(`${path} must be ${def.const}`),
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// enum
|
|
213
|
+
if (Array.isArray(def.enum)) {
|
|
214
|
+
if (!def.enum.includes(value as string)) {
|
|
215
|
+
return {
|
|
216
|
+
success: false,
|
|
217
|
+
error: new ValidationError(
|
|
218
|
+
`${path} must be one of (${def.enum.join('|')})`,
|
|
219
|
+
),
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// maxLength
|
|
225
|
+
if (typeof def.maxLength === 'number') {
|
|
226
|
+
if ((value as string).length > def.maxLength) {
|
|
227
|
+
return {
|
|
228
|
+
success: false,
|
|
229
|
+
error: new ValidationError(
|
|
230
|
+
`${path} must not be longer than ${def.maxLength} characters`,
|
|
231
|
+
),
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// minLength
|
|
237
|
+
if (typeof def.minLength === 'number') {
|
|
238
|
+
if ((value as string).length < def.minLength) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
error: new ValidationError(
|
|
242
|
+
`${path} must not be shorter than ${def.minLength} characters`,
|
|
243
|
+
),
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return { success: true }
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function datetime(
|
|
252
|
+
lexicons: Lexicons,
|
|
253
|
+
path: string,
|
|
254
|
+
def: LexUserType,
|
|
255
|
+
value: unknown,
|
|
256
|
+
): ValidationResult {
|
|
257
|
+
def = def as LexDatetime
|
|
258
|
+
|
|
259
|
+
// type
|
|
260
|
+
const type = typeof value
|
|
261
|
+
if (type !== 'string') {
|
|
262
|
+
return {
|
|
263
|
+
success: false,
|
|
264
|
+
error: new ValidationError(`${path} must be a string`),
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// valid iso-8601
|
|
269
|
+
{
|
|
270
|
+
try {
|
|
271
|
+
const date = new Date(Date.parse(value as string))
|
|
272
|
+
if (value !== date.toISOString()) {
|
|
273
|
+
throw new ValidationError(
|
|
274
|
+
`${path} must be an iso8601 formatted datetime`,
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
} catch {
|
|
278
|
+
throw new ValidationError(`${path} must be an iso8601 formatted datetime`)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return { success: true }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function unknown(
|
|
286
|
+
lexicons: Lexicons,
|
|
287
|
+
path: string,
|
|
288
|
+
def: LexUserType,
|
|
289
|
+
value: unknown,
|
|
290
|
+
): ValidationResult {
|
|
291
|
+
// type
|
|
292
|
+
if (!value || typeof value !== 'object') {
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: new ValidationError(`${path} must be an object`),
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return { success: true }
|
|
300
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Lexicons } from '../lexicons'
|
|
2
|
+
import { LexXrpcParameters, ValidationResult, ValidationError } from '../types'
|
|
3
|
+
|
|
4
|
+
import * as PrimitiveValidators from './primitives'
|
|
5
|
+
|
|
6
|
+
export function params(
|
|
7
|
+
lexicons: Lexicons,
|
|
8
|
+
path: string,
|
|
9
|
+
def: LexXrpcParameters,
|
|
10
|
+
value: unknown,
|
|
11
|
+
): ValidationResult {
|
|
12
|
+
def = def as LexXrpcParameters
|
|
13
|
+
|
|
14
|
+
// type
|
|
15
|
+
if (!value || typeof value !== 'object') {
|
|
16
|
+
// in this case, we just fall back to an object
|
|
17
|
+
value = {}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// required
|
|
21
|
+
if (Array.isArray(def.required)) {
|
|
22
|
+
for (const key of def.required) {
|
|
23
|
+
if (!(key in (value as Record<string, unknown>))) {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
error: new ValidationError(`${path} must have the property "${key}"`),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// properties
|
|
33
|
+
for (const key in def.properties) {
|
|
34
|
+
if (typeof (value as Record<string, unknown>)[key] === 'undefined') {
|
|
35
|
+
continue // skip- if required, will have already failed
|
|
36
|
+
}
|
|
37
|
+
const paramDef = def.properties[key]
|
|
38
|
+
const res = PrimitiveValidators.validate(
|
|
39
|
+
lexicons,
|
|
40
|
+
key,
|
|
41
|
+
paramDef,
|
|
42
|
+
(value as Record<string, unknown>)[key],
|
|
43
|
+
)
|
|
44
|
+
if (!res.success) {
|
|
45
|
+
return res
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { success: true }
|
|
50
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
export default [
|
|
2
|
+
{
|
|
3
|
+
lexicon: 1,
|
|
4
|
+
id: 'com.example.kitchenSink',
|
|
5
|
+
defs: {
|
|
6
|
+
main: {
|
|
7
|
+
type: 'record',
|
|
8
|
+
description: 'A record',
|
|
9
|
+
key: 'tid',
|
|
10
|
+
record: {
|
|
11
|
+
type: 'object',
|
|
12
|
+
required: [
|
|
13
|
+
'object',
|
|
14
|
+
'array',
|
|
15
|
+
'boolean',
|
|
16
|
+
'number',
|
|
17
|
+
'integer',
|
|
18
|
+
'string',
|
|
19
|
+
'datetime',
|
|
20
|
+
],
|
|
21
|
+
properties: {
|
|
22
|
+
object: { type: 'ref', ref: '#object' },
|
|
23
|
+
array: { type: 'array', items: { type: 'string' } },
|
|
24
|
+
boolean: { type: 'boolean' },
|
|
25
|
+
number: { type: 'number' },
|
|
26
|
+
integer: { type: 'integer' },
|
|
27
|
+
string: { type: 'string' },
|
|
28
|
+
datetime: { type: 'datetime' },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
object: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
required: ['object', 'array', 'boolean', 'number', 'integer', 'string'],
|
|
35
|
+
properties: {
|
|
36
|
+
object: { type: 'ref', ref: '#subobject' },
|
|
37
|
+
array: { type: 'array', items: { type: 'string' } },
|
|
38
|
+
boolean: { type: 'boolean' },
|
|
39
|
+
number: { type: 'number' },
|
|
40
|
+
integer: { type: 'integer' },
|
|
41
|
+
string: { type: 'string' },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
subobject: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
required: ['boolean'],
|
|
47
|
+
properties: {
|
|
48
|
+
boolean: { type: 'boolean' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
lexicon: 1,
|
|
55
|
+
id: 'com.example.query',
|
|
56
|
+
defs: {
|
|
57
|
+
main: {
|
|
58
|
+
type: 'query',
|
|
59
|
+
description: 'A query',
|
|
60
|
+
parameters: {
|
|
61
|
+
type: 'params',
|
|
62
|
+
required: ['boolean', 'number', 'integer'],
|
|
63
|
+
properties: {
|
|
64
|
+
boolean: { type: 'boolean' },
|
|
65
|
+
number: { type: 'number' },
|
|
66
|
+
integer: { type: 'integer' },
|
|
67
|
+
string: { type: 'string' },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
output: {
|
|
71
|
+
encoding: 'application/json',
|
|
72
|
+
schema: { type: 'ref', ref: 'com.example.kitchenSink#object' },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
lexicon: 1,
|
|
79
|
+
id: 'com.example.procedure',
|
|
80
|
+
defs: {
|
|
81
|
+
main: {
|
|
82
|
+
type: 'procedure',
|
|
83
|
+
description: 'A procedure',
|
|
84
|
+
parameters: {
|
|
85
|
+
type: 'params',
|
|
86
|
+
required: ['boolean', 'number', 'integer'],
|
|
87
|
+
properties: {
|
|
88
|
+
boolean: { type: 'boolean' },
|
|
89
|
+
number: { type: 'number' },
|
|
90
|
+
integer: { type: 'integer' },
|
|
91
|
+
string: { type: 'string' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
input: {
|
|
95
|
+
encoding: 'application/json',
|
|
96
|
+
schema: { type: 'ref', ref: 'com.example.kitchenSink#object' },
|
|
97
|
+
},
|
|
98
|
+
output: {
|
|
99
|
+
encoding: 'application/json',
|
|
100
|
+
schema: { type: 'ref', ref: 'com.example.kitchenSink#object' },
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
lexicon: 1,
|
|
107
|
+
id: 'com.example.optional',
|
|
108
|
+
defs: {
|
|
109
|
+
main: {
|
|
110
|
+
type: 'record',
|
|
111
|
+
record: {
|
|
112
|
+
type: 'object',
|
|
113
|
+
properties: {
|
|
114
|
+
object: { type: 'ref', ref: 'com.example.kitchenSink#object' },
|
|
115
|
+
array: { type: 'array', items: { type: 'string' } },
|
|
116
|
+
boolean: { type: 'boolean' },
|
|
117
|
+
number: { type: 'number' },
|
|
118
|
+
integer: { type: 'integer' },
|
|
119
|
+
string: { type: 'string' },
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
lexicon: 1,
|
|
127
|
+
id: 'com.example.union',
|
|
128
|
+
defs: {
|
|
129
|
+
main: {
|
|
130
|
+
type: 'record',
|
|
131
|
+
description: 'A record',
|
|
132
|
+
key: 'tid',
|
|
133
|
+
record: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
required: ['unionOpen', 'unionClosed'],
|
|
136
|
+
properties: {
|
|
137
|
+
unionOpen: {
|
|
138
|
+
type: 'union',
|
|
139
|
+
refs: [
|
|
140
|
+
'com.example.kitchenSink#object',
|
|
141
|
+
'com.example.kitchenSink#subobject',
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
unionClosed: {
|
|
145
|
+
type: 'union',
|
|
146
|
+
closed: true,
|
|
147
|
+
refs: [
|
|
148
|
+
'com.example.kitchenSink#object',
|
|
149
|
+
'com.example.kitchenSink#subobject',
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
lexicon: 1,
|
|
159
|
+
id: 'com.example.unknown',
|
|
160
|
+
defs: {
|
|
161
|
+
main: {
|
|
162
|
+
type: 'record',
|
|
163
|
+
description: 'A record',
|
|
164
|
+
key: 'tid',
|
|
165
|
+
record: {
|
|
166
|
+
type: 'object',
|
|
167
|
+
required: ['unknown'],
|
|
168
|
+
properties: {
|
|
169
|
+
unknown: { type: 'unknown' },
|
|
170
|
+
optUnknown: { type: 'unknown' },
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
lexicon: 1,
|
|
178
|
+
id: 'com.example.arrayLength',
|
|
179
|
+
defs: {
|
|
180
|
+
main: {
|
|
181
|
+
type: 'record',
|
|
182
|
+
record: {
|
|
183
|
+
type: 'object',
|
|
184
|
+
properties: {
|
|
185
|
+
array: {
|
|
186
|
+
type: 'array',
|
|
187
|
+
minLength: 2,
|
|
188
|
+
maxLength: 4,
|
|
189
|
+
items: { type: 'number' },
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
lexicon: 1,
|
|
198
|
+
id: 'com.example.boolConst',
|
|
199
|
+
defs: {
|
|
200
|
+
main: {
|
|
201
|
+
type: 'record',
|
|
202
|
+
record: {
|
|
203
|
+
type: 'object',
|
|
204
|
+
properties: {
|
|
205
|
+
boolean: {
|
|
206
|
+
type: 'boolean',
|
|
207
|
+
const: false,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
lexicon: 1,
|
|
216
|
+
id: 'com.example.numberRange',
|
|
217
|
+
defs: {
|
|
218
|
+
main: {
|
|
219
|
+
type: 'record',
|
|
220
|
+
record: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: {
|
|
223
|
+
number: {
|
|
224
|
+
type: 'number',
|
|
225
|
+
minimum: 2,
|
|
226
|
+
maximum: 4,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
lexicon: 1,
|
|
235
|
+
id: 'com.example.numberEnum',
|
|
236
|
+
defs: {
|
|
237
|
+
main: {
|
|
238
|
+
type: 'record',
|
|
239
|
+
record: {
|
|
240
|
+
type: 'object',
|
|
241
|
+
properties: {
|
|
242
|
+
number: {
|
|
243
|
+
type: 'number',
|
|
244
|
+
enum: [1, 1.5, 2],
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
lexicon: 1,
|
|
253
|
+
id: 'com.example.numberConst',
|
|
254
|
+
defs: {
|
|
255
|
+
main: {
|
|
256
|
+
type: 'record',
|
|
257
|
+
record: {
|
|
258
|
+
type: 'object',
|
|
259
|
+
properties: {
|
|
260
|
+
number: {
|
|
261
|
+
type: 'number',
|
|
262
|
+
const: 0,
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
lexicon: 1,
|
|
271
|
+
id: 'com.example.integerRange',
|
|
272
|
+
defs: {
|
|
273
|
+
main: {
|
|
274
|
+
type: 'record',
|
|
275
|
+
record: {
|
|
276
|
+
type: 'object',
|
|
277
|
+
properties: {
|
|
278
|
+
integer: {
|
|
279
|
+
type: 'integer',
|
|
280
|
+
minimum: 2,
|
|
281
|
+
maximum: 4,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
lexicon: 1,
|
|
290
|
+
id: 'com.example.integerEnum',
|
|
291
|
+
defs: {
|
|
292
|
+
main: {
|
|
293
|
+
type: 'record',
|
|
294
|
+
record: {
|
|
295
|
+
type: 'object',
|
|
296
|
+
properties: {
|
|
297
|
+
integer: {
|
|
298
|
+
type: 'integer',
|
|
299
|
+
enum: [1, 2],
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
lexicon: 1,
|
|
308
|
+
id: 'com.example.integerConst',
|
|
309
|
+
defs: {
|
|
310
|
+
main: {
|
|
311
|
+
type: 'record',
|
|
312
|
+
record: {
|
|
313
|
+
type: 'object',
|
|
314
|
+
properties: {
|
|
315
|
+
integer: {
|
|
316
|
+
type: 'integer',
|
|
317
|
+
const: 0,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
lexicon: 1,
|
|
326
|
+
id: 'com.example.stringLength',
|
|
327
|
+
defs: {
|
|
328
|
+
main: {
|
|
329
|
+
type: 'record',
|
|
330
|
+
record: {
|
|
331
|
+
type: 'object',
|
|
332
|
+
properties: {
|
|
333
|
+
string: {
|
|
334
|
+
type: 'string',
|
|
335
|
+
minLength: 2,
|
|
336
|
+
maxLength: 4,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
lexicon: 1,
|
|
345
|
+
id: 'com.example.stringEnum',
|
|
346
|
+
defs: {
|
|
347
|
+
main: {
|
|
348
|
+
type: 'record',
|
|
349
|
+
record: {
|
|
350
|
+
type: 'object',
|
|
351
|
+
properties: {
|
|
352
|
+
string: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
enum: ['a', 'b'],
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
lexicon: 1,
|
|
363
|
+
id: 'com.example.stringConst',
|
|
364
|
+
defs: {
|
|
365
|
+
main: {
|
|
366
|
+
type: 'record',
|
|
367
|
+
record: {
|
|
368
|
+
type: 'object',
|
|
369
|
+
properties: {
|
|
370
|
+
string: {
|
|
371
|
+
type: 'string',
|
|
372
|
+
const: 'a',
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
]
|