or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-execution.mdcommand-line.mdconfiguration.mdcore-generator.mdfile-system.mdgit-integration.mdindex.mdpackage-management.mdtask-lifecycle.mduser-interaction.md

configuration.mddocs/

0

# Configuration Management

1

2

Persistent storage system for generator configurations, user preferences, and project settings using JSON files with support for namespacing and hierarchical storage.

3

4

## Capabilities

5

6

### Storage Class

7

8

Core storage class for persistent configuration management.

9

10

```typescript { .api }

11

/**

12

* Storage instances handle a JSON file where Generator authors can store data

13

* The Generator class instantiates the storage named 'config' by default

14

*/

15

class Storage {

16

constructor(name: string | undefined, fs: MemFsEditor, configPath: string, options?: StorageOptions);

17

constructor(fs: MemFsEditor, configPath: string, options?: StorageOptions);

18

19

// File system properties

20

readonly path: string;

21

readonly name?: string;

22

readonly fs: MemFsEditor;

23

readonly existed: boolean;

24

25

// Configuration options

26

readonly lodashPath: boolean;

27

readonly disableCache: boolean;

28

readonly disableCacheByFile: boolean;

29

readonly sorted: boolean;

30

readonly indent: number;

31

}

32

```

33

34

**Usage Example:**

35

36

```typescript

37

export default class MyGenerator extends Generator {

38

constructor(args, opts) {

39

super(args, opts);

40

41

// Storage is automatically available as this.config

42

console.log(this.config.path); // ~/.yo-rc.json (or project-specific)

43

console.log(this.config.existed); // true if config existed before

44

}

45

}

46

```

47

48

### Data Operations

49

50

Core methods for storing and retrieving configuration data.

51

52

```typescript { .api }

53

/**

54

* Get a stored value

55

* @param key - The key under which the value is stored

56

* @returns The stored value (any JSON valid type)

57

*/

58

get<T extends StorageValue = StorageValue>(key: string): T;

59

60

/**

61

* Get a stored value from a lodash path

62

* @param path - The path under which the value is stored

63

* @returns The stored value (any JSON valid type)

64

*/

65

getPath<T extends StorageValue = StorageValue>(path: string): T;

66

67

/**

68

* Get all the stored values

69

* @returns Key-value object with all stored data

70

*/

71

getAll(): StorageRecord;

72

73

/**

74

* Assign a key to a value and schedule a save

75

* @param key - The key under which the value is stored

76

* @param value - Any valid JSON type value

77

* @returns Whatever was passed in as value

78

*/

79

set<V = StorageValue>(value: V): V;

80

set<V = StorageValue>(key: string | number, value?: V): V | undefined;

81

82

/**

83

* Assign a lodash path to a value and schedule a save

84

* @param path - The lodash path under which the value is stored

85

* @param value - Any valid JSON type value

86

* @returns Whatever was passed in as value

87

*/

88

setPath(path: string | number, value: StorageValue): StorageValue;

89

90

/**

91

* Delete a key from the store and schedule a save

92

* @param key - The key under which the value is stored

93

*/

94

delete(key: string): void;

95

96

/**

97

* Save current state to disk

98

*/

99

save(): void;

100

```

101

102

**Usage Examples:**

103

104

```typescript

105

export default class MyGenerator extends Generator {

106

configuring() {

107

// Basic get/set operations

108

this.config.set('projectName', this.answers.name);

109

this.config.set('version', '1.0.0');

110

111

// Get stored values

112

const projectName = this.config.get('projectName');

113

const allConfig = this.config.getAll();

114

115

// Object storage

116

this.config.set({

117

author: this.answers.author,

118

license: this.answers.license,

119

features: this.answers.features

120

});

121

122

// Lodash path operations

123

this.config.setPath('database.host', 'localhost');

124

this.config.setPath('database.port', 5432);

125

const dbHost = this.config.getPath('database.host');

126

127

// Delete keys

128

this.config.delete('temporaryData');

129

130

// Manual save (usually automatic)

131

this.config.save();

132

}

133

}

134

```

135

136

### Merge and Defaults

137

138

Methods for combining configuration data and setting default values.

139

140

```typescript { .api }

141

/**

142

* Setup the store with defaults value and schedule a save

143

* If keys already exist, the initial value is kept

144

* @param defaults - Key-value object to store

145

* @returns The merged options

146

*/

147

defaults(defaults: StorageRecord): StorageRecord;

148

149

/**

150

* Merge source data with existing store data

151

* @param source - Key-value object to merge

152

* @returns The merged object

153

*/

154

merge(source: StorageRecord): StorageRecord;

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

export default class MyGenerator extends Generator {

161

configuring() {

162

// Set defaults (won't overwrite existing values)

163

this.config.defaults({

164

version: '1.0.0',

165

main: 'index.js',

166

scripts: {

167

start: 'node index.js',

168

test: 'echo "No tests yet"'

169

}

170

});

171

172

// Merge additional configuration

173

this.config.merge({

174

keywords: this.answers.keywords?.split(',') || [],

175

dependencies: this.answers.dependencies || {},

176

author: {

177

name: this.answers.authorName,

178

email: this.answers.authorEmail

179

}

180

});

181

}

182

}

183

```

184

185

### Storage Creation and Hierarchy

186

187

Create child storage instances and manage storage hierarchies.

188

189

```typescript { .api }

190

/**

191

* Return a storage instance for the specified path

192

* @param storePath - The path of the JSON file

193

* @param options - Storage options or the storage name

194

* @returns New Storage instance

195

*/

196

createStorage(storePath: string, options?: string | StorageOptions): Storage;

197

198

/**

199

* Create a child storage

200

* @param path - Relative path of the key to create a new storage

201

* @returns New Storage instance with namespaced access

202

*/

203

createStorage(path: string): Storage;

204

205

/**

206

* Creates a proxy object for direct property access

207

* @returns Proxy that allows direct property access

208

*/

209

createProxy(): StorageRecord;

210

```

211

212

**Usage Examples:**

213

214

```typescript

215

export default class MyGenerator extends Generator {

216

constructor(args, opts) {

217

super(args, opts);

218

219

// Create separate storage files

220

this.userPrefs = this.createStorage('.yo-preferences.json', 'userPrefs');

221

this.projectMeta = this.createStorage('project-meta.json');

222

223

// Create child storage (namespaced within same file)

224

this.dbConfig = this.config.createStorage('database');

225

this.apiConfig = this.config.createStorage('api');

226

227

// Create proxy for direct access

228

this.configProxy = this.config.createProxy();

229

}

230

231

configuring() {

232

// Use separate storage instances

233

this.userPrefs.set('theme', 'dark');

234

this.projectMeta.set('created', new Date().toISOString());

235

236

// Use child storage (stored as nested objects)

237

this.dbConfig.set('host', 'localhost');

238

this.dbConfig.set('port', 5432);

239

this.apiConfig.set('version', 'v1');

240

241

// Use proxy for direct access

242

this.configProxy.projectName = this.answers.name;

243

this.configProxy.version = '1.0.0';

244

}

245

}

246

```

247

248

### Package.json Storage

249

250

Special storage instance for package.json manipulation.

251

252

```typescript { .api }

253

/**

254

* Package.json Storage resolved to this.destinationPath('package.json')

255

* Environment watches for package.json changes and triggers package manager install

256

*/

257

readonly packageJson: Storage;

258

```

259

260

**Usage Examples:**

261

262

```typescript

263

export default class MyGenerator extends Generator {

264

configuring() {

265

// Modify package.json using storage interface

266

this.packageJson.merge({

267

name: this.answers.name,

268

version: '1.0.0',

269

description: this.answers.description,

270

main: 'index.js',

271

scripts: {

272

start: 'node index.js',

273

test: 'npm run test:unit',

274

'test:unit': 'jest'

275

},

276

keywords: this.answers.keywords?.split(','),

277

author: this.answers.author,

278

license: this.answers.license

279

});

280

281

// Add dependencies conditionally

282

if (this.answers.includeExpress) {

283

this.packageJson.merge({

284

dependencies: {

285

express: '^4.18.0'

286

}

287

});

288

}

289

290

if (this.answers.includeTests) {

291

this.packageJson.merge({

292

devDependencies: {

293

jest: '^29.0.0',

294

'@types/jest': '^29.0.0'

295

}

296

});

297

}

298

}

299

}

300

```

301

302

### Generator Storage Instances

303

304

Built-in storage instances available in generators.

305

306

```typescript { .api }

307

/**

308

* Generator config Storage (default: .yo-rc.json)

309

*/

310

readonly config: Storage;

311

312

/**

313

* Package.json Storage resolved to destinationPath('package.json')

314

*/

315

readonly packageJson: Storage;

316

317

/**

318

* Generator-specific configuration (namespaced by generator name)

319

*/

320

readonly generatorConfig?: Storage;

321

322

/**

323

* Instance-specific configuration (namespaced by generator + instance)

324

*/

325

readonly instanceConfig?: Storage;

326

```

327

328

**Usage Example:**

329

330

```typescript

331

export default class MyGenerator extends Generator {

332

configuring() {

333

// Main config (shared across all generators in project)

334

this.config.set('projectType', 'library');

335

336

// Generator-specific config (only for this generator type)

337

this.generatorConfig?.set('templateVersion', '2.1.0');

338

339

// Instance-specific config (for this specific generator run)

340

this.instanceConfig?.set('runId', Date.now());

341

342

// Package.json manipulation

343

this.packageJson.set('name', this.answers.name);

344

}

345

}

346

```

347

348

### Storage Options

349

350

Configuration options for storage behavior.

351

352

```typescript { .api }

353

interface StorageOptions {

354

name?: string;

355

lodashPath?: boolean;

356

disableCache?: boolean;

357

disableCacheByFile?: boolean;

358

sorted?: boolean;

359

}

360

```

361

362

**Usage Example:**

363

364

```typescript

365

export default class MyGenerator extends Generator {

366

constructor(args, opts) {

367

super(args, opts);

368

369

// Storage with custom options

370

this.sortedConfig = this.createStorage('sorted-config.json', {

371

name: 'sortedConfig',

372

sorted: true, // Sort keys alphabetically

373

lodashPath: true, // Enable lodash path access

374

disableCache: false // Enable caching (default)

375

});

376

}

377

378

configuring() {

379

// Keys will be sorted when saved

380

this.sortedConfig.set('z-last', 'value');

381

this.sortedConfig.set('a-first', 'value');

382

383

// Can use lodash paths

384

this.sortedConfig.setPath('nested.deep.property', 'value');

385

}

386

}

387

```

388

389

## Types

390

391

```typescript { .api }

392

// Valid JSON storage values

393

type StorageValue = string | number | boolean | null | undefined | StorageValue[] | StorageRecord;

394

395

// Storage record (key-value object)

396

type StorageRecord = Record<string, StorageValue>;

397

398

// Storage configuration options

399

interface StorageOptions {

400

name?: string;

401

lodashPath?: boolean;

402

disableCache?: boolean;

403

disableCacheByFile?: boolean;

404

sorted?: boolean;

405

}

406

```