or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extensions-customization.mdindex.mdreferences-expressions.mdschema-types.mdutility-functions.mdvalidation-methods.md
tile.json

references-expressions.mddocs/

0

# References and Expressions

1

2

Dynamic validation system supporting field references, context access, and template expressions for advanced validation scenarios.

3

4

## Capabilities

5

6

### Reference Function

7

8

Creates references to other fields or context values for dynamic validation.

9

10

```typescript { .api }

11

/**

12

* Creates reference to another field for dynamic validation

13

* @param key - Reference key (field path or context path)

14

* @param options - Optional reference configuration

15

* @returns Reference object for dynamic value access

16

*/

17

function ref(key: string, options?: ReferenceOptions): Reference;

18

19

interface ReferenceOptions {

20

// Separator for key path parsing (default: '.')

21

separator?: string;

22

23

// Context options

24

contextPrefix?: string; // Prefix for context references (default: '$')

25

26

// Path options

27

ancestor?: number; // Number of parent levels to traverse

28

prefix?: {

29

global?: string; // Global context prefix (default: '/')

30

local?: string; // Local context prefix (default: '#')

31

root?: string; // Root value prefix (default: '#')

32

};

33

34

// Rendering options

35

render?: boolean; // Enable template rendering (default: true)

36

37

// Adjustment function

38

adjust?: (value: any) => any; // Value adjustment function

39

40

// Mapping function

41

map?: Array<[any, any]> | Map<any, any>; // Value mapping

42

43

// In-references

44

in?: boolean; // Enable in-reference mode

45

}

46

47

interface Reference {

48

readonly isContext: boolean; // True if reference points to context

49

readonly isGlobal: boolean; // True if reference is global

50

readonly key: string; // Reference key

51

readonly path: string[]; // Parsed key path

52

readonly ancestor: number; // Ancestor level count

53

readonly prefix: string; // Reference prefix type

54

readonly root: string; // Root identifier

55

readonly display: string; // Display representation

56

readonly type: string; // Reference type ('value' | 'context' | 'global')

57

}

58

```

59

60

**Usage Examples:**

61

62

```javascript

63

const Joi = require('joi');

64

65

// Basic field reference

66

const schema = Joi.object({

67

password: Joi.string().min(8),

68

confirmPassword: Joi.string().valid(Joi.ref('password'))

69

});

70

71

// Context reference

72

const contextSchema = Joi.object({

73

minValue: Joi.number().min(Joi.ref('$minAllowed'))

74

});

75

76

const { error, value } = contextSchema.validate(

77

{ minValue: 5 },

78

{ context: { minAllowed: 10 } }

79

);

80

81

// Nested field reference

82

const nestedSchema = Joi.object({

83

user: Joi.object({

84

name: Joi.string(),

85

email: Joi.string().email()

86

}),

87

contact: Joi.object({

88

primaryEmail: Joi.string().valid(Joi.ref('..user.email'))

89

})

90

});

91

92

// Reference with ancestor traversal

93

const hierarchySchema = Joi.object({

94

level1: Joi.object({

95

value: Joi.string(),

96

level2: Joi.object({

97

compare: Joi.string().valid(Joi.ref('value', { ancestor: 1 }))

98

})

99

})

100

});

101

102

// Reference with custom separator

103

const customRefSchema = Joi.object({

104

'field/name': Joi.string(),

105

compare: Joi.string().valid(Joi.ref('field/name', { separator: '/' }))

106

});

107

```

108

109

### In Reference Function

110

111

Creates array references for rule matching and validation.

112

113

```typescript { .api }

114

/**

115

* Creates array reference for rule matching

116

* @param ref - Reference key or Reference object

117

* @param options - Optional reference configuration

118

* @returns Reference configured for array matching

119

*/

120

function in(ref: string | Reference, options?: ReferenceOptions): Reference;

121

```

122

123

**Usage Examples:**

124

125

```javascript

126

// Array membership validation

127

const membershipSchema = Joi.object({

128

allowedValues: Joi.array().items(Joi.string()),

129

selectedValue: Joi.string().valid(Joi.in('allowedValues'))

130

});

131

132

const { error, value } = membershipSchema.validate({

133

allowedValues: ['red', 'green', 'blue'],

134

selectedValue: 'red' // Valid - 'red' is in allowedValues array

135

});

136

137

// Dynamic validation based on array context

138

const dynamicSchema = Joi.object({

139

category: Joi.string().valid(Joi.in('$availableCategories'))

140

});

141

142

const contextValidation = dynamicSchema.validate(

143

{ category: 'electronics' },

144

{

145

context: {

146

availableCategories: ['electronics', 'clothing', 'books']

147

}

148

}

149

);

150

```

151

152

### Expression Function

153

154

Creates template expressions for dynamic content generation and validation.

155

156

```typescript { .api }

157

/**

158

* Creates template expressions with dynamic placeholders

159

* @param template - Template string with placeholder syntax

160

* @param options - Optional template configuration

161

* @returns Template object for dynamic rendering

162

*/

163

function expression(template: string, options?: TemplateOptions): Template;

164

165

// Alias for expression function

166

const x: typeof expression;

167

168

interface TemplateOptions {

169

// Custom functions for template rendering

170

functions?: Record<string, Function>;

171

172

// Variable references

173

reference?: boolean; // Enable reference resolution (default: true)

174

}

175

176

interface Template {

177

readonly isTemplate: boolean; // Always true for template objects

178

readonly source: string; // Original template string

179

180

/**

181

* Renders template with provided context

182

* @param context - Rendering context with variables

183

* @param prefs - Optional preferences

184

* @param local - Local context variables

185

* @param options - Rendering options

186

* @returns Rendered string

187

*/

188

render(

189

context: any,

190

prefs?: any,

191

local?: any,

192

options?: any

193

): string;

194

}

195

```

196

197

**Usage Examples:**

198

199

```javascript

200

// Basic template expression

201

const messageTemplate = Joi.expression('Hello {#name}, you are {#age} years old');

202

203

// Custom error messages with templates

204

const customSchema = Joi.string()

205

.min(3)

206

.message(Joi.expression('Field {#label} must be at least {#limit} characters, got {#value}'));

207

208

// Dynamic validation with templates

209

const dynamicValidation = Joi.object({

210

name: Joi.string().required(),

211

greeting: Joi.string().valid(Joi.expression('Hello {#name}'))

212

});

213

214

// Template with functions

215

const advancedTemplate = Joi.expression('User {#name|uppercase} has {#posts|length} posts', {

216

functions: {

217

uppercase: (value) => value.toUpperCase(),

218

length: (array) => array ? array.length : 0

219

}

220

});

221

222

// Using x alias

223

const shortTemplate = Joi.x('Welcome {#user.name}!');

224

```

225

226

### Reference Utilities

227

228

Utility functions for working with references and templates.

229

230

```typescript { .api }

231

/**

232

* Checks if value is a reference object

233

* @param ref - Value to check

234

* @returns True if value is Reference object

235

*/

236

function isRef(ref: any): ref is Reference;

237

238

/**

239

* Checks if value is a template expression

240

* @param expression - Value to check

241

* @returns True if value is Template object

242

*/

243

function isExpression(expression: any): expression is Template;

244

```

245

246

**Usage Examples:**

247

248

```javascript

249

const ref = Joi.ref('field');

250

const template = Joi.expression('Hello {#name}');

251

const string = 'regular string';

252

253

console.log(Joi.isRef(ref)); // true

254

console.log(Joi.isRef(template)); // false

255

console.log(Joi.isRef(string)); // false

256

257

console.log(Joi.isExpression(template)); // true

258

console.log(Joi.isExpression(ref)); // false

259

console.log(Joi.isExpression(string)); // false

260

```

261

262

## Advanced Reference Patterns

263

264

### Conditional Validation with References

265

266

```javascript

267

const conditionalSchema = Joi.object({

268

type: Joi.string().valid('user', 'admin'),

269

permissions: Joi.array()

270

.when('type', {

271

is: 'admin',

272

then: Joi.array().min(1),

273

otherwise: Joi.array().max(0)

274

})

275

});

276

```

277

278

### Complex Object Relationships

279

280

```javascript

281

const relationshipSchema = Joi.object({

282

startDate: Joi.date(),

283

endDate: Joi.date().greater(Joi.ref('startDate')),

284

duration: Joi.number().when('startDate', {

285

is: Joi.exist(),

286

then: Joi.number().min(1),

287

otherwise: Joi.forbidden()

288

})

289

});

290

```

291

292

### Dynamic Array Validation

293

294

```javascript

295

const dynamicArraySchema = Joi.object({

296

maxItems: Joi.number().integer().min(1),

297

items: Joi.array().max(Joi.ref('maxItems')),

298

selectedItems: Joi.array()

299

.items(Joi.string().valid(Joi.in('items')))

300

.unique()

301

});

302

```

303

304

### Template-Based Error Messages

305

306

```javascript

307

const customErrorSchema = Joi.object({

308

username: Joi.string()

309

.min(3)

310

.max(20)

311

.messages({

312

'string.min': Joi.expression('Username {#label} must be at least {#limit} characters'),

313

'string.max': Joi.expression('Username {#label} cannot exceed {#limit} characters')

314

}),

315

316

email: Joi.string()

317

.email()

318

.message(Joi.expression('Please provide a valid email address for {#label}'))

319

});

320

```

321

322

## Context-Aware Validation

323

324

### Global Context References

325

326

```javascript

327

const globalContextSchema = Joi.object({

328

userLevel: Joi.string().valid(Joi.ref('/user.level')),

329

maxUpload: Joi.number().max(Joi.ref('/limits.upload'))

330

});

331

332

// Validation with global context

333

const result = globalContextSchema.validate(data, {

334

context: {

335

'/': {

336

user: { level: 'premium' },

337

limits: { upload: 1000000 }

338

}

339

}

340

});

341

```

342

343

### Local Context References

344

345

```javascript

346

const localContextSchema = Joi.object({

347

priority: Joi.string().valid(Joi.ref('#priorities')),

348

category: Joi.string().valid(Joi.ref('#categories'))

349

});

350

351

// Local context validation

352

const localResult = localContextSchema.validate(data, {

353

context: {

354

priorities: ['low', 'medium', 'high'],

355

categories: ['bug', 'feature', 'enhancement']

356

}

357

});

358

```

359

360

## Template Functions

361

362

### Built-in Template Functions

363

364

```javascript

365

// String manipulation functions

366

const stringTemplate = Joi.expression('{#name|lowercase|trim}');

367

368

// Array functions

369

const arrayTemplate = Joi.expression('Found {#items|length} items');

370

371

// Date functions

372

const dateTemplate = Joi.expression('Created on {#createdAt|date("YYYY-MM-DD")}');

373

374

// Custom functions

375

const customTemplate = Joi.expression('{#value|multiply(2)|format}', {

376

functions: {

377

multiply: (value, factor) => value * factor,

378

format: (value) => `$${value.toFixed(2)}`

379

}

380

});

381

```