@james-pre/config 1.0.2 → 1.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/manager.d.ts CHANGED
@@ -58,7 +58,7 @@ export interface ManagerOptions {
58
58
  /**
59
59
  * Manager for configuration files
60
60
  */
61
- export declare class Manager<LoadOpts extends LoadOptions = LoadOptions, Shape extends Readonly<Record<string, z.ZodType>> = Readonly<Record<string, z.ZodType>>, out In extends z.input<z.ZodObject<Shape>> = z.input<z.ZodObject<Shape>>, out FileData = z.output<ReturnType<typeof z.deepPartial<z.ZodObject<Shape>>>>> extends EventEmitter<{
61
+ export declare class Manager<Schema extends z.ZodObject, LoadOpts extends LoadOptions = LoadOptions, out In extends z.input<Schema> = z.input<Schema>, out FileData = z.output<ReturnType<typeof z.deepPartial<Schema>>>> extends EventEmitter<{
62
62
  load: [path: string, config: FileData, options: Partial<LoadOpts>];
63
63
  post_load: [path: string, config: FileData, options: Partial<LoadOpts>];
64
64
  load_error: [path: string, stage: 'read' | 'create' | 'parse', error: Error];
@@ -67,19 +67,26 @@ export declare class Manager<LoadOpts extends LoadOptions = LoadOptions, Shape e
67
67
  write: [path: string, data: FileData];
68
68
  reload: [];
69
69
  }> {
70
+ readonly schema: Schema;
70
71
  protected options: ManagerOptions;
71
- readonly schema: z.ZodObject<Shape>;
72
- readonly fileSchema: ReturnType<typeof z.deepPartial<z.ZodObject<Shape>>>;
73
- protected readonly files: Map<string, File<FileData>>;
72
+ readonly fileSchema: ReturnType<typeof z.deepPartial<Schema>>;
73
+ protected readonly _files: Map<string, File<FileData, LoadOpts>>;
74
74
  get filePaths(): MapIterator<string>;
75
- readonly data: z.output<z.ZodObject<Shape>>;
76
- constructor(shape: Shape, options?: ManagerOptions);
75
+ get files(): IteratorObject<Readonly<File<FileData, LoadOpts>>>;
76
+ configAt(path: string): Readonly<FileData> | undefined;
77
+ readonly data: z.output<Schema>;
78
+ constructor(schema: Schema, options?: ManagerOptions);
79
+ /**
80
+ * Narrow the type of this manager's load options
81
+ */
82
+ $loadOptions<O extends object>(): Manager<Schema, LoadOpts & O, In, FileData>;
83
+ $assertLoadOptions<O extends object>(): asserts this is Manager<Schema, LoadOpts & O, In, FileData>;
77
84
  /**
78
85
  * A fresh config with only the schema's defaults applied.
79
86
  */
80
- get defaults(): z.output<z.ZodObject<Shape>> & In;
81
- get<const K extends string | number = FlattenKeys<z.output<z.ZodObject<Shape>>>>(key: K): GetByString<z.output<z.ZodObject<Shape>>, K>;
82
- set<const K extends string | number = FlattenKeys<z.output<z.ZodObject<Shape>>>, V = GetByString<z.output<z.ZodObject<Shape>>, K>>(key: K, value: V): void;
87
+ get defaults(): z.output<Schema> & In;
88
+ get<const K extends string | number = FlattenKeys<z.output<Schema>>>(key: K): GetByString<z.output<Schema>, K>;
89
+ set<const K extends string | number = FlattenKeys<z.output<Schema>>, V = GetByString<z.output<Schema>, K>>(key: K, value: V): void;
83
90
  /**
84
91
  * Deeply merge `config` into the current config. Arrays are replaced rather than combined.
85
92
  */
@@ -88,8 +95,8 @@ export declare class Manager<LoadOpts extends LoadOptions = LoadOptions, Shape e
88
95
  replace(config: In): void;
89
96
  loadFile(path: string, options: Partial<LoadOpts>): void;
90
97
  /** Get the entry for `path`, adding one for a file that has not been loaded */
91
- protected fileAt(path: string): File<FileData>;
92
- protected writeFile(file: File<FileData>): void;
98
+ protected fileAt(path: string): File<FileData, LoadOpts>;
99
+ protected writeFile(file: File<FileData, LoadOpts>): void;
93
100
  /**
94
101
  * Replace the contents of the config file at `path` and write it,
95
102
  * then rebuild the current config from the defaults and all loaded files.
package/dist/manager.js CHANGED
@@ -145,21 +145,35 @@ let Manager = (() => {
145
145
  __esDecorate(this, null, _get_defaultPaths_decorators, { kind: "getter", name: "defaultPaths", static: false, private: false, access: { has: obj => "defaultPaths" in obj, get: obj => obj.defaultPaths }, metadata: _metadata }, null, _instanceExtraInitializers);
146
146
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
147
147
  }
148
- options = __runInitializers(this, _instanceExtraInitializers);
149
- schema;
148
+ schema = __runInitializers(this, _instanceExtraInitializers);
149
+ options;
150
150
  fileSchema;
151
- files = new Map();
151
+ _files = new Map();
152
152
  get filePaths() {
153
- return this.files.keys();
153
+ return this._files.keys();
154
+ }
155
+ get files() {
156
+ return this._files.values().map(f => structuredClone(f));
157
+ }
158
+ configAt(path) {
159
+ return structuredClone(this._files.get(path)?.data);
154
160
  }
155
161
  data;
156
- constructor(shape, options = {}) {
162
+ constructor(schema, options = {}) {
157
163
  super({ captureRejections: true });
164
+ this.schema = schema;
158
165
  this.options = options;
159
- this.schema = z.object(shape);
160
- this.fileSchema = z.deepPartial(stripDefaults(z.object(options.enableIncludes ? { ...shape, include } : shape)));
166
+ this.fileSchema = z.deepPartial(stripDefaults(z.object(options.enableIncludes ? { ...schema.shape, include } : schema.shape)));
161
167
  this.data = this.schema.parse(this.defaults);
162
168
  }
169
+ /**
170
+ * Narrow the type of this manager's load options
171
+ */
172
+ $loadOptions() {
173
+ this.$assertLoadOptions();
174
+ return this;
175
+ }
176
+ $assertLoadOptions() { }
163
177
  /**
164
178
  * A fresh config with only the schema's defaults applied.
165
179
  */
@@ -187,7 +201,7 @@ let Manager = (() => {
187
201
  this.emit('change');
188
202
  }
189
203
  loadFile(path, options) {
190
- if (this.files.has(path))
204
+ if (this._files.has(path))
191
205
  return;
192
206
  let json;
193
207
  try {
@@ -223,7 +237,7 @@ let Manager = (() => {
223
237
  this.emit('load_error', path, 'parse', e);
224
238
  file = json;
225
239
  }
226
- this.files.set(path, {
240
+ this._files.set(path, {
227
241
  auto: false,
228
242
  wasIncluded: false,
229
243
  type: typeFromPath(path),
@@ -247,7 +261,7 @@ let Manager = (() => {
247
261
  }
248
262
  /** Get the entry for `path`, adding one for a file that has not been loaded */
249
263
  fileAt(path) {
250
- const existing = this.files.get(path);
264
+ const existing = this._files.get(path);
251
265
  if (existing)
252
266
  return existing;
253
267
  const file = {
@@ -258,7 +272,7 @@ let Manager = (() => {
258
272
  wasIncluded: false,
259
273
  options: {},
260
274
  };
261
- this.files.set(path, file);
275
+ this._files.set(path, file);
262
276
  return file;
263
277
  }
264
278
  writeFile(file) {
@@ -275,7 +289,7 @@ let Manager = (() => {
275
289
  file.data = this.fileSchema.parse(config);
276
290
  this.writeFile(file);
277
291
  this.replace(this.defaults);
278
- for (const file of this.files.values())
292
+ for (const file of this._files.values())
279
293
  this.merge(file.data);
280
294
  }
281
295
  /**
@@ -313,7 +327,7 @@ let Manager = (() => {
313
327
  * the most recently loaded file of that type, or the path `loadDefaults` would use for it.
314
328
  */
315
329
  findPath(type) {
316
- const loaded = this.files
330
+ const loaded = this._files
317
331
  .values()
318
332
  .filter(file => (!type || file.type == type) && !file.wasIncluded)
319
333
  .map(file => file.path)
@@ -332,11 +346,11 @@ let Manager = (() => {
332
346
  this.updateFile(this.findPath(type), config);
333
347
  }
334
348
  reloadFiles(options = {}) {
335
- const files = this.files
349
+ const files = this._files
336
350
  .values()
337
351
  .filter(file => !file.wasIncluded)
338
352
  .toArray();
339
- this.files.clear();
353
+ this._files.clear();
340
354
  this.replace(this.defaults);
341
355
  for (const file of files) {
342
356
  this.loadFile(file.path, { ...options, [kInit]: { type: file.type, auto: file.auto } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@james-pre/config",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Manage configuration files",
5
5
  "funding": {
6
6
  "type": "individual",