yeoman-generator 8.0.2 → 8.1.0

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/dist/generator.js CHANGED
@@ -97,6 +97,7 @@ export class BaseGenerator extends EventEmitter {
97
97
  else if (typeof args === 'object' && !Array.isArray(args)) {
98
98
  actualArgs = [];
99
99
  actualOptions = args;
100
+ actualFeatures = options;
100
101
  }
101
102
  else {
102
103
  actualArgs = args ?? [];
@@ -611,7 +612,11 @@ export class BaseGenerator extends EventEmitter {
611
612
  options = rootName;
612
613
  rootName = this.rootGeneratorName();
613
614
  }
614
- return this.createStorage('.yo-rc.json', { ...options, name: rootName });
615
+ return this.createStorage('.yo-rc.json', {
616
+ transform: this.#features.configTransform,
617
+ ...options,
618
+ name: rootName,
619
+ });
615
620
  }
616
621
  /**
617
622
  * Setup a globalConfig storage instance.
@@ -622,7 +627,7 @@ export class BaseGenerator extends EventEmitter {
622
627
  const globalStorageDir = this.options.localConfigOnly ? this.destinationRoot() : os.homedir();
623
628
  const storePath = path.join(globalStorageDir, '.yo-rc-global.json');
624
629
  const storeName = `${this.rootGeneratorName()}:${this.rootGeneratorVersion()}`;
625
- return this.createStorage(storePath, { name: storeName });
630
+ return this.createStorage(storePath, { transform: this.#features.configTransform, name: storeName });
626
631
  }
627
632
  /**
628
633
  * Change the generator destination root directory.
package/dist/types.d.ts CHANGED
@@ -105,6 +105,9 @@ export type BaseFeatures = FeaturesApi & {
105
105
 
106
106
  /** Inherit tasks from parent prototypes, implies tasksMatchingPriority */
107
107
  inheritTasks?: boolean;
108
+
109
+ /** Transform the configuration before reading. */
110
+ configTransform?: (config: any) => any;
108
111
  };
109
112
 
110
113
  export type BaseOptions = OptionsApi & {
@@ -167,7 +170,7 @@ export type CliOptionSpec = {
167
170
  hide?: boolean;
168
171
 
169
172
  /** The storage to persist the option */
170
- storage?: string | Storage;
173
+ storage?: string | Storage<any>;
171
174
  };
172
175
 
173
176
  export type ComposeOptions<G extends BaseGenerator = BaseGenerator> = EnvironmentComposeOptions<G> & {
@@ -7,7 +7,7 @@ import type Storage from './storage.js';
7
7
  * @param questions Original prompt questions
8
8
  * @return Prompt questions array with prefilled values.
9
9
  */
10
- export declare const prefillQuestions: <A extends PromptAnswers = PromptAnswers>(store: Storage, questions: Array<PromptQuestion<A>> | PromptQuestion<A>) => PromptQuestion<A>[];
10
+ export declare const prefillQuestions: <A extends PromptAnswers = PromptAnswers>(store: Storage<any>, questions: Array<PromptQuestion<A>> | PromptQuestion<A>) => PromptQuestion<A>[];
11
11
  /**
12
12
  * Store the answers in the global store
13
13
  *
@@ -16,4 +16,4 @@ export declare const prefillQuestions: <A extends PromptAnswers = PromptAnswers>
16
16
  * @param answers The inquirer answers
17
17
  * @param storeAll Should store default values
18
18
  */
19
- export declare const storeAnswers: (store: Storage, questions: any, answers: PromptAnswers, storeAll: boolean) => void;
19
+ export declare const storeAnswers: (store: Storage<any>, questions: any, answers: PromptAnswers, storeAll: boolean) => void;
@@ -1,7 +1,7 @@
1
1
  import type { Get } from 'type-fest';
2
2
  import type { MemFsEditor } from 'mem-fs-editor';
3
3
  import type { StorageValue } from '../types.js';
4
- export type StorageOptions = {
4
+ export type StorageOptions<StorageRecord extends Record<string, any> = Record<string, any>> = {
5
5
  name?: string;
6
6
  /**
7
7
  * Set true to treat name as a lodash path.
@@ -19,6 +19,10 @@ export type StorageOptions = {
19
19
  * Set true to write sorted json.
20
20
  */
21
21
  sorted?: boolean;
22
+ /**
23
+ * Transform the content of the storage when reading it. This can be used to sanitize or modify the data before it is returned.
24
+ */
25
+ transform?: (content: StorageRecord) => StorageRecord;
22
26
  };
23
27
  /**
24
28
  * Storage instances handle a json file where Generator authors can store data.
@@ -46,10 +50,11 @@ declare class Storage<StorageRecord extends Record<string, any> = Record<string,
46
50
  disableCache: boolean;
47
51
  disableCacheByFile: boolean;
48
52
  sorted: boolean;
53
+ transform?: (content: StorageRecord) => StorageRecord;
49
54
  existed: boolean;
50
55
  _cachedStore?: StorageRecord;
51
- constructor(name: string | undefined, fs: MemFsEditor, configPath: string, options?: StorageOptions);
52
- constructor(fs: MemFsEditor, configPath: string, options?: StorageOptions);
56
+ constructor(name: string | undefined, fs: MemFsEditor, configPath: string, options?: StorageOptions<StorageRecord>);
57
+ constructor(fs: MemFsEditor, configPath: string, options?: StorageOptions<StorageRecord>);
53
58
  /**
54
59
  * @protected
55
60
  * @return the store content
@@ -138,5 +143,6 @@ declare class Storage<StorageRecord extends Record<string, any> = Record<string,
138
143
  * @return proxy.
139
144
  */
140
145
  createProxy(): StorageRecord;
146
+ private transformedStore;
141
147
  }
142
148
  export default Storage;
@@ -55,6 +55,7 @@ class Storage {
55
55
  disableCache;
56
56
  disableCacheByFile;
57
57
  sorted;
58
+ transform;
58
59
  existed;
59
60
  _cachedStore;
60
61
  constructor(name, fs, configPath, options = {}) {
@@ -92,6 +93,7 @@ class Storage {
92
93
  this.disableCache = actualOptions.disableCache ?? false;
93
94
  this.disableCacheByFile = actualOptions.disableCacheByFile ?? false;
94
95
  this.sorted = actualOptions.sorted ?? false;
96
+ this.transform = actualOptions.transform;
95
97
  this.existed = Object.keys(this._store).length > 0;
96
98
  this.fs.store.on('change', filename => {
97
99
  // At mem-fs 1.1.3 filename is not passed to the event.
@@ -170,7 +172,7 @@ class Storage {
170
172
  * @return The stored value. Any JSON valid type could be returned
171
173
  */
172
174
  get(key) {
173
- return this._store[key];
175
+ return this.transformedStore()[key];
174
176
  }
175
177
  /**
176
178
  * Get a stored value from a lodash path
@@ -178,14 +180,14 @@ class Storage {
178
180
  * @return The stored value. Any JSON valid type could be returned
179
181
  */
180
182
  getPath(path) {
181
- return get(this._store, path);
183
+ return get(this.transformedStore(), path);
182
184
  }
183
185
  /**
184
186
  * Get all the stored values
185
187
  * @return key-value object
186
188
  */
187
189
  getAll() {
188
- return cloneDeep(this._store);
190
+ return this.transformedStore({ forceClone: true });
189
191
  }
190
192
  set(key, value) {
191
193
  const store = this._store;
@@ -249,7 +251,7 @@ class Storage {
249
251
  }
250
252
  createStorage(path) {
251
253
  const childName = this.name ? `${this.name}.${path}` : path;
252
- return new Storage(childName, this.fs, this.path, { lodashPath: true });
254
+ return new Storage(childName, this.fs, this.path, { lodashPath: true, transform: this.transform });
253
255
  }
254
256
  /**
255
257
  * Creates a proxy object.
@@ -258,5 +260,14 @@ class Storage {
258
260
  createProxy() {
259
261
  return new Proxy(this, proxyHandler);
260
262
  }
263
+ transformedStore({ forceClone = false } = {}) {
264
+ if (this.transform) {
265
+ return this.transform(cloneDeep(this._store));
266
+ }
267
+ if (forceClone) {
268
+ return cloneDeep(this._store);
269
+ }
270
+ return this._store;
271
+ }
261
272
  }
262
273
  export default Storage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeoman-generator",
3
- "version": "8.0.2",
3
+ "version": "8.1.0",
4
4
  "description": "Rails-inspired generator system that provides scaffolding for your apps",
5
5
  "keywords": [
6
6
  "development",
@@ -82,7 +82,7 @@
82
82
  "@yeoman/transform": "^2.1.0",
83
83
  "@yeoman/types": "^1.10.3",
84
84
  "cpy-cli": "^7.0.0",
85
- "ejs": "^4.0.1",
85
+ "ejs": "^5.0.1",
86
86
  "eslint": "9.39.3",
87
87
  "jsdoc": "^4.0.5",
88
88
  "prettier": "3.8.1",