or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdeditor-core.mdindex.mdmode-management.mdpreview-mode.mdschema-validation.mdtext-operations.mdtransform-operations.mdtree-operations.md
tile.json

schema-validation.mddocs/

0

# Schema Validation

1

2

JSON schema validation system with comprehensive error reporting, custom validation support, and real-time validation feedback powered by the Ajv library.

3

4

## Capabilities

5

6

### Set JSON Schema

7

8

Configure JSON schema for automatic validation of editor content.

9

10

```javascript { .api }

11

/**

12

* Set a JSON schema for validation of the JSON object

13

* @param schema - JSON schema object, or null to remove validation

14

* @param schemaRefs - Optional referenced schemas for $ref properties

15

*/

16

setSchema(schema: object | null, schemaRefs?: { [key: string]: object }): void;

17

```

18

19

**Usage Example:**

20

21

```javascript

22

// Define a schema

23

const userSchema = {

24

type: "object",

25

properties: {

26

name: {

27

type: "string",

28

minLength: 1

29

},

30

email: {

31

type: "string",

32

format: "email"

33

},

34

age: {

35

type: "number",

36

minimum: 0,

37

maximum: 150

38

},

39

active: {

40

type: "boolean"

41

}

42

},

43

required: ["name", "email"],

44

additionalProperties: false

45

};

46

47

// Set the schema

48

editor.setSchema(userSchema);

49

50

// Remove schema validation

51

editor.setSchema(null);

52

```

53

54

### Schema with References

55

56

Use referenced schemas for complex validation scenarios.

57

58

```javascript { .api }

59

// Example with schema references

60

const mainSchema = {

61

type: "object",

62

properties: {

63

user: { $ref: "#/definitions/User" },

64

company: { $ref: "company.json" }

65

}

66

};

67

68

const schemaRefs = {

69

"#/definitions/User": {

70

type: "object",

71

properties: {

72

name: { type: "string" },

73

email: { type: "string", format: "email" }

74

}

75

},

76

"company.json": {

77

type: "object",

78

properties: {

79

name: { type: "string" },

80

industry: { type: "string" }

81

}

82

}

83

};

84

85

editor.setSchema(mainSchema, schemaRefs);

86

```

87

88

### Validate Content

89

90

Manually trigger validation and retrieve validation errors.

91

92

```javascript { .api }

93

/**

94

* Validate current JSON object against the configured JSON schema

95

* @returns Promise resolving to array of validation errors

96

*/

97

validate(): Promise<ValidationError[]>;

98

```

99

100

**Usage Example:**

101

102

```javascript

103

// Trigger validation manually

104

const errors = await editor.validate();

105

106

if (errors.length > 0) {

107

console.log("Validation errors found:");

108

errors.forEach(error => {

109

console.log(`- ${error.message} at path: ${error.path.join('.')}`);

110

});

111

} else {

112

console.log("Validation passed!");

113

}

114

```

115

116

### Validation Error Structure

117

118

Structure of validation error objects returned by the validation system.

119

120

```javascript { .api }

121

interface ValidationError {

122

/** Type of validation error */

123

type: "validation" | "customValidation" | "error";

124

125

/** Path to the invalid data as an array */

126

path: (string | number)[];

127

128

/** Human-readable error message */

129

message: string;

130

131

/** Original error object (for type: "error") */

132

error?: Error;

133

134

/** Schema keyword that failed (for type: "validation") */

135

keyword?: string;

136

137

/** Schema path where validation failed */

138

schemaPath?: string;

139

140

/** Additional error data from Ajv */

141

data?: any;

142

}

143

```

144

145

### Custom Validation Function

146

147

Implement custom validation logic beyond JSON schema capabilities.

148

149

```javascript { .api }

150

/**

151

* Custom validation function in editor options

152

*/

153

interface ValidationOptions {

154

onValidate?: (json: any) => ValidationError[] | Promise<ValidationError[]> | null;

155

}

156

```

157

158

**Usage Example:**

159

160

```javascript

161

const options = {

162

mode: "tree",

163

onValidate: (json) => {

164

const errors = [];

165

166

// Custom business logic validation

167

if (json.users && Array.isArray(json.users)) {

168

json.users.forEach((user, index) => {

169

if (user.email && user.email.endsWith('@tempmail.com')) {

170

errors.push({

171

type: "customValidation",

172

path: ['users', index, 'email'],

173

message: "Temporary email addresses are not allowed"

174

});

175

}

176

});

177

}

178

179

// Async validation example

180

if (json.username) {

181

return fetch(`/api/validate-username/${json.username}`)

182

.then(response => response.json())

183

.then(result => {

184

if (!result.available) {

185

return [{

186

type: "customValidation",

187

path: ['username'],

188

message: "Username is already taken"

189

}];

190

}

191

return [];

192

});

193

}

194

195

return errors;

196

}

197

};

198

199

const editor = new JSONEditor(container, options);

200

```

201

202

### Validation Error Callback

203

204

Handle validation errors with a dedicated callback function.

205

206

```javascript { .api }

207

/**

208

* Validation error callback in editor options

209

*/

210

interface ValidationOptions {

211

onValidationError?: (errors: ValidationError[]) => void;

212

}

213

```

214

215

**Usage Example:**

216

217

```javascript

218

const options = {

219

mode: "tree",

220

schema: userSchema,

221

onValidationError: (errors) => {

222

const errorContainer = document.getElementById('validation-errors');

223

224

if (errors.length > 0) {

225

const errorList = errors.map(error => {

226

const pathStr = error.path.length > 0 ? ` at ${error.path.join('.')}` : '';

227

return `<li>${error.message}${pathStr}</li>`;

228

}).join('');

229

230

errorContainer.innerHTML = `<ul class="errors">${errorList}</ul>`;

231

errorContainer.style.display = 'block';

232

} else {

233

errorContainer.style.display = 'none';

234

}

235

}

236

};

237

```

238

239

### Custom Ajv Instance

240

241

Provide a custom Ajv instance with specific configuration.

242

243

```javascript { .api }

244

/**

245

* Custom Ajv configuration in editor options

246

*/

247

interface ValidationOptions {

248

ajv?: any; // Ajv instance

249

}

250

```

251

252

**Usage Example:**

253

254

```javascript

255

import Ajv from 'ajv';

256

import addFormats from 'ajv-formats';

257

258

// Create custom Ajv instance

259

const ajv = new Ajv({

260

allErrors: true,

261

verbose: true,

262

$data: true,

263

strictSchema: false

264

});

265

266

// Add format validation

267

addFormats(ajv);

268

269

// Add custom keyword

270

ajv.addKeyword({

271

keyword: 'isEven',

272

type: 'number',

273

schemaType: 'boolean',

274

validate: (schemaValue, data) => {

275

return schemaValue ? data % 2 === 0 : data % 2 !== 0;

276

}

277

});

278

279

const options = {

280

mode: "tree",

281

ajv: ajv,

282

schema: {

283

type: "object",

284

properties: {

285

evenNumber: {

286

type: "number",

287

isEven: true

288

}

289

}

290

}

291

};

292

293

const editor = new JSONEditor(container, options);

294

```

295

296

### Schema-based Autocomplete

297

298

Enable autocomplete suggestions based on JSON schema properties and enums.

299

300

```javascript { .api }

301

/**

302

* Schema autocomplete configuration in editor options

303

*/

304

interface ValidationOptions {

305

allowSchemaSuggestions?: boolean;

306

}

307

```

308

309

**Usage Example:**

310

311

```javascript

312

const schemaWithEnums = {

313

type: "object",

314

properties: {

315

status: {

316

type: "string",

317

enum: ["draft", "published", "archived"],

318

examples: ["draft"]

319

},

320

category: {

321

type: "string",

322

enum: ["tech", "business", "lifestyle"]

323

}

324

}

325

};

326

327

const options = {

328

mode: "code", // Only works in code mode

329

schema: schemaWithEnums,

330

allowSchemaSuggestions: true

331

};

332

333

const editor = new JSONEditor(container, options);

334

```

335

336

## Real-time Validation

337

338

JSONEditor automatically validates content in real-time as users edit:

339

340

- **Tree/View/Form modes**: Invalid nodes are highlighted with error styling

341

- **Code/Text modes**: Error annotations appear in the editor gutter

342

- **All modes**: Error table can be displayed showing all validation issues

343

- **Debounced**: Validation is debounced (150ms default) to avoid excessive validation calls

344

345

## Validation Error Display

346

347

Control how validation errors are displayed to users:

348

349

```javascript

350

const options = {

351

mode: "tree",

352

schema: userSchema,

353

354

// Show error table for specific modes

355

showErrorTable: true, // boolean

356

// or

357

showErrorTable: ["text", "code"], // array of modes

358

359

// Custom error handling

360

onValidationError: (errors) => {

361

// Custom error display logic

362

displayCustomErrorUI(errors);

363

}

364

};

365

```

366

367

## Validation Best Practices

368

369

### Schema Design

370

```javascript

371

// Good: Comprehensive schema with clear constraints

372

const goodSchema = {

373

type: "object",

374

properties: {

375

id: { type: "string", pattern: "^[a-zA-Z0-9_-]+$" },

376

name: { type: "string", minLength: 1, maxLength: 100 },

377

email: { type: "string", format: "email" },

378

age: { type: "integer", minimum: 0, maximum: 150 },

379

tags: {

380

type: "array",

381

items: { type: "string" },

382

maxItems: 10

383

}

384

},

385

required: ["id", "name"],

386

additionalProperties: false

387

};

388

```

389

390

### Error Handling

391

```javascript

392

// Handle validation errors gracefully

393

const options = {

394

onValidationError: (errors) => {

395

// Group errors by type

396

const schemaErrors = errors.filter(e => e.type === 'validation');

397

const customErrors = errors.filter(e => e.type === 'customValidation');

398

const parseErrors = errors.filter(e => e.type === 'error');

399

400

// Display appropriate user feedback

401

if (parseErrors.length > 0) {

402

showMessage("Invalid JSON format", "error");

403

} else if (schemaErrors.length > 0 || customErrors.length > 0) {

404

showMessage(`${errors.length} validation error(s) found`, "warning");

405

}

406

}

407

};

408

```

409

410

### Performance Optimization

411

```javascript

412

// For large schemas or frequent validation

413

const ajv = new Ajv({

414

allErrors: false, // Stop on first error for better performance

415

verbose: false, // Reduce error object size

416

validateSchema: false // Skip schema validation if schema is trusted

417

});

418

```