Skip to content

Commit ce2c933

Browse files
committed
fix(deps): update dependency jiti to v2 #13
1 parent 4d74007 commit ce2c933

File tree

9 files changed

+199
-121
lines changed

9 files changed

+199
-121
lines changed

core/README.md

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Auto Config Loader
99

1010
Find and load configuration from a `package.json` property, `rc` file, or `CommonJS` module. It has smart default based on traditional expectations in the JavaScript ecosystem. But it's also flexible enough to search anywhere you want and load whatever you want.
1111

12+
[V1 To V2 Migration](#v1-to-v2-migration)
13+
1214
## Features
1315

1416
- Support [JSON](https://www.json.org), [JSONC](https://github.com/microsoft/node-jsonc-parser), [JSON5](https://json5.org/), [YAML](https://yaml.org/), [TOML](https://toml.io), [INI](https://en.wikipedia.org/wiki/INI_file), [CJS](http://www.commonjs.org), [Typescript](https://www.typescriptlang.org/), and ESM config load.
@@ -43,7 +45,7 @@ import { autoConf } from 'auto-config-loader';
4345
// process.cwd() + 'namespace.config.cjs'
4446
// process.cwd() + 'namespace.config.js'
4547
// ........
46-
const data = autoConf('namespace', {
48+
const data = await autoConf('namespace', {
4749
default: {
4850
testItem2: 'some value'
4951
}
@@ -68,22 +70,22 @@ interface Config {
6870
name: string;
6971
}
7072

71-
const result = loadConf<Config>('./app/app.config.js');
73+
const result = await loadConf<Config>('./app/app.config.js');
7274
// => { name: 'app' }
7375
```
7476

7577
## Option
7678

7779
```ts
7880
import { LoadConfOption } from 'auto-config-loader';
79-
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T;
81+
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T | Promise<T>;
8082
export type Loader<T> = Record<string, LoaderFunc<T>>;
8183
export interface AutoConfOption<T> {
8284
searchPlaces?: string[];
8385
/** An object that maps extensions to the loader functions responsible for loading and parsing files with those extensions. */
8486
loaders?: Loader<T>;
8587
/** Specify default configuration. It has the lowest priority and is applied after extending config. */
86-
defaluts?: T;
88+
default?: T;
8789
/** Resolve configuration from this working directory. The default is `process.cwd()` */
8890
cwd?: string;
8991
/** Default transform js configuration */
@@ -92,12 +94,14 @@ export interface AutoConfOption<T> {
9294
ignoreLog?: boolean;
9395
mustExist?: boolean;
9496
}
97+
export declare const getConfigPath: () => string;
9598
/**
9699
* Find and load configuration from a `package.json` property, `rc` file, or `CommonJS` module.
97100
* @param namespace {string} Configuration base name. The default is `autoconf`.
98-
* @param option
101+
* @param option
99102
*/
100-
export default function autoConf<T>(namespace?: string, option?: AutoConfOption<T>): {} & T;
103+
export declare function autoConf<T>(namespace?: string, option?: AutoConfOption<T>): Promise<{} & T>;
104+
export default autoConf;
101105
```
102106

103107
Discover configurations in the specified directory order. When configuring a tool, you can use multiple file formats and put these in multiple places. Usually, a tool would mention this in its own README file, but by default, these are the following places, where `${moduleName}` represents the name of the tool:
@@ -187,7 +191,7 @@ function loadJS(filepath, content) {
187191
});
188192
}
189193
190-
const data = load('namespace', {
194+
const data = await load('namespace', {
191195
loaders: {
192196
'.js': loadJS,
193197
'.ts': loadJS,
@@ -276,7 +280,7 @@ function loadYaml(filepath, content) {
276280
return yaml.parse(content);
277281
}
278282

279-
const data = load('namespace', {
283+
const data = await load('namespace', {
280284
searchPlaces: [
281285
'.namespacerc.yaml',
282286
'.namespacerc.yml',
@@ -298,9 +302,9 @@ const data = load('namespace', {
298302
```ts
299303
export declare const merge: {
300304
<TObject, TSource>(object: TObject, source: TSource): TObject & TSource;
301-
<TObject_1, TSource1, TSource2>(object: TObject_1, source1: TSource1, source2: TSource2): TObject_1 & TSource1 & TSource2;
302-
<TObject_2, TSource1_1, TSource2_1, TSource3>(object: TObject_2, source1: TSource1_1, source2: TSource2_1, source3: TSource3): TObject_2 & TSource1_1 & TSource2_1 & TSource3;
303-
<TObject_3, TSource1_2, TSource2_2, TSource3_1, TSource4>(object: TObject_3, source1: TSource1_2, source2: TSource2_2, source3: TSource3_1, source4: TSource4): TObject_3 & TSource1_2 & TSource2_2 & TSource3_1 & TSource4;
305+
<TObject, TSource1, TSource2>(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2;
306+
<TObject, TSource1, TSource2, TSource3>(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3;
307+
<TObject, TSource1, TSource2, TSource3, TSource4>(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4;
304308
(object: any, ...otherArgs: any[]): any;
305309
};
306310
```
@@ -327,6 +331,59 @@ const configPath = getConfigPath();
327331
// => /.autoconfrc.js
328332
```
329333

334+
## V1 To V2 Migration
335+
336+
This guide provides the steps to migrate to the latest version of the configuration loader API.
337+
338+
### Key Changes
339+
340+
1. **Loader Functions Support Async**
341+
- `LoaderFunc<T>` now supports returning `T` or `Promise<T>`.
342+
- Update custom loaders to handle asynchronous operations if needed.
343+
344+
**Example:**
345+
```ts
346+
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T | Promise<T>;
347+
```
348+
349+
2. **`autoConf` Returns a Promise**
350+
- The `autoConf` function now returns a `Promise` instead of a synchronous result.
351+
- Update your code to handle asynchronous calls.
352+
353+
**Example:**
354+
```ts
355+
export declare function autoConf<T>(namespace?: string, option?: AutoConfOption<T>): Promise<{} & T>;
356+
```
357+
358+
### Migration Steps
359+
360+
#### 1. Update Custom Loader Functions
361+
362+
If you have custom loaders, update their return types to support asynchronous operations:
363+
364+
**Example:**
365+
366+
```ts
367+
const jsonLoader: LoaderFunc<MyConfig> = async (filepath, content) => JSON.parse(content);
368+
```
369+
370+
#### 2. Handle Asynchronous `autoConf` Calls
371+
372+
Update all calls to `autoConf` to use `await` or `.then` to handle Promises:
373+
374+
**Example Using `await`:**
375+
```ts
376+
const config = await autoConf('myNamespace', options);
377+
console.log(config);
378+
```
379+
380+
**Example Using `.then`:**
381+
```ts
382+
autoConf('myNamespace', options).then(config => {
383+
console.log(config);
384+
});
385+
```
386+
330387
## Related
331388

332389
- [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig) Find and load configuration from a package.json property, rc file, or CommonJS module

core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@
6060
},
6161
"dependencies": {
6262
"ini": "^5.0.0",
63-
"jiti": "^1.18.2",
63+
"jiti": "^2.4.1",
6464
"jsonc-eslint-parser": "^2.3.0",
6565
"lodash.merge": "^4.6.2",
66-
"sucrase": "^3.32.0",
66+
"sucrase": "^3.35.0",
6767
"toml-eslint-parser": "^0.10.0",
6868
"yaml-eslint-parser": "^1.2.2"
6969
},

core/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export * from './loader/ini';
1717

1818
export const merge = mergeFun;
1919

20-
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T;
20+
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T | Promise<T>;
2121
export type Loader<T> = Record<string, LoaderFunc<T>>;
2222
export interface AutoConfOption<T> {
2323
searchPlaces?: string[];
@@ -43,7 +43,7 @@ export const getConfigPath = () => configPath;
4343
* @param namespace {string} Configuration base name. The default is `autoconf`.
4444
* @param option
4545
*/
46-
export function autoConf<T>(namespace: string = 'autoconf', option: AutoConfOption<T> = {}) {
46+
export async function autoConf<T>(namespace: string = 'autoconf', option: AutoConfOption<T> = {}) {
4747
const {
4848
searchPlaces = [],
4949
default: defaultValue = {},
@@ -89,7 +89,7 @@ export function autoConf<T>(namespace: string = 'autoconf', option: AutoConfOpti
8989
}
9090

9191
if (content && loaderFunc) {
92-
resultData = loaderFunc(configPath, content, jsOption);
92+
resultData = await loaderFunc(configPath, content, jsOption);
9393
if (typeof resultData === 'function') {
9494
return merge(defaultValue, resultData, { default: resultData });
9595
}

core/src/loader/js.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import jitiFactory from 'jiti';
2-
import type { JITIOptions } from 'jiti/dist/types';
1+
import { createJiti } from 'jiti';
2+
import type jiti from 'jiti';
33
import { transform, Options } from 'sucrase';
44

5-
let jiti: ReturnType<typeof jitiFactory> | null = null;
5+
type Jiti = ReturnType<typeof jiti>;
6+
type JITIOptions = Jiti['options'];
7+
8+
let jitiInstance: ReturnType<typeof jiti> | null = null;
69
function lazyJiti(option: JITIOptions = {}, transformOpt = {} as Options) {
710
return (
8-
jiti ??
9-
(jiti = jitiFactory(__filename, {
11+
jitiInstance ??
12+
(jitiInstance = createJiti(__filename, {
1013
interopDefault: true,
1114
...option,
1215
transform: (opts) => {
@@ -25,22 +28,28 @@ export interface LoadConfOption {
2528
transformOption?: Options;
2629
}
2730

28-
export function loadConf<T>(path: string, option: LoadConfOption = {}): T {
31+
export async function loadConf<T>(path: string, option: LoadConfOption = {}): Promise<T> {
2932
const { jiti = true, jitiOptions, transformOption } = option;
30-
let config = (function () {
33+
let config = await (async function () {
3134
try {
3235
if (jiti) {
33-
return path ? lazyJiti(jitiOptions, transformOption)(path) : {};
36+
return path ? await lazyJiti(jitiOptions, transformOption).import(path) : {};
3437
} else {
3538
return path ? require(path) : {};
3639
}
3740
} catch {
38-
return lazyJiti(jitiOptions, transformOption)(path);
41+
return await lazyJiti(jitiOptions, transformOption).import(path);
3942
}
4043
})();
41-
return config.default ?? config;
44+
45+
// Ensure both default export and named exports are handled
46+
if (config.default) {
47+
config = { ...config.default, ...config };
48+
}
49+
50+
return config;
4251
}
4352

44-
export function jsLoader<T>(filepath: string, content: string, option: LoadConfOption = {}): T {
45-
return loadConf<T>(filepath, option);
53+
export async function jsLoader<T>(filepath: string, content: string, option: LoadConfOption = {}): Promise<T> {
54+
return await loadConf<T>(filepath, option);
4655
}

0 commit comments

Comments
 (0)