@abdokouta/react-config 1.0.0 → 1.0.2
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/LICENSE +21 -0
- package/README.md +2 -1
- package/config/config.config.ts +9 -9
- package/dist/{index.d.mts → index.d.cts} +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +28 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +55 -25
- package/.examples/01-basic-usage.ts +0 -289
- package/.examples/02-env-helper.ts +0 -282
- package/.examples/README.md +0 -285
- package/.prettierrc.js +0 -1
- package/__tests__/config.module.test.ts +0 -244
- package/__tests__/drivers/env.driver.test.ts +0 -259
- package/__tests__/services/config.service.test.ts +0 -328
- package/__tests__/setup.d.ts +0 -11
- package/__tests__/vitest.setup.ts +0 -30
- package/eslint.config.js +0 -13
- package/src/config.module.ts +0 -154
- package/src/constants/index.ts +0 -5
- package/src/constants/tokens.constant.ts +0 -38
- package/src/drivers/env.driver.ts +0 -194
- package/src/drivers/file.driver.ts +0 -81
- package/src/drivers/index.ts +0 -6
- package/src/index.ts +0 -92
- package/src/interfaces/config-driver.interface.ts +0 -30
- package/src/interfaces/config-module-options.interface.ts +0 -84
- package/src/interfaces/config-service.interface.ts +0 -71
- package/src/interfaces/index.ts +0 -8
- package/src/interfaces/vite-config-plugin-options.interface.ts +0 -56
- package/src/plugins/index.ts +0 -5
- package/src/plugins/vite.plugin.ts +0 -115
- package/src/services/config.service.ts +0 -172
- package/src/services/index.ts +0 -5
- package/src/utils/get-nested-value.util.ts +0 -56
- package/src/utils/index.ts +0 -6
- package/src/utils/load-config-file.util.ts +0 -37
- package/src/utils/scan-config-files.util.ts +0 -40
- package/tsconfig.json +0 -28
- package/tsup.config.ts +0 -105
- package/vitest.config.ts +0 -66
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vite Plugin for Config Package
|
|
3
|
-
*
|
|
4
|
-
* Simple plugin that receives env from Vite's loadEnv and injects it into the browser.
|
|
5
|
-
* Does NOT apply any business logic - that's handled by ConfigService.
|
|
6
|
-
*
|
|
7
|
-
* Responsibilities:
|
|
8
|
-
* 1. Receive environment variables from Vite's loadEnv (passed via options)
|
|
9
|
-
* 2. Inject them into window.__APP_CONFIG__ (or custom global name)
|
|
10
|
-
* 3. Optionally scan and collect .config.ts files
|
|
11
|
-
*
|
|
12
|
-
* ConfigService will then query from window.__APP_CONFIG__ and apply:
|
|
13
|
-
* - Prefix stripping
|
|
14
|
-
* - Type conversion
|
|
15
|
-
* - Validation
|
|
16
|
-
* - Defaults
|
|
17
|
-
*
|
|
18
|
-
* Usage:
|
|
19
|
-
* ```ts
|
|
20
|
-
* import { defineConfig, loadEnv } from 'vite'
|
|
21
|
-
* import { viteConfigPlugin } from '@abdokouta/config/vite-plugin'
|
|
22
|
-
*
|
|
23
|
-
* export default defineConfig(({ mode }) => {
|
|
24
|
-
* const env = loadEnv(mode, 'environments', '')
|
|
25
|
-
*
|
|
26
|
-
* return {
|
|
27
|
-
* plugins: [
|
|
28
|
-
* viteConfigPlugin({ env })
|
|
29
|
-
* ]
|
|
30
|
-
* }
|
|
31
|
-
* })
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
import path from 'path';
|
|
36
|
-
import type { Plugin } from 'vite';
|
|
37
|
-
import type { ViteConfigPluginOptions } from '@/interfaces/vite-config-plugin-options.interface';
|
|
38
|
-
import { scanConfigFiles } from '@/utils/scan-config-files.util';
|
|
39
|
-
import { loadConfigFile } from '@/utils/load-config-file.util';
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Vite plugin that injects environment variables into the browser
|
|
43
|
-
*
|
|
44
|
-
* This plugin is DUMB - it just receives env and injects it.
|
|
45
|
-
* ConfigService is SMART - it queries and applies business logic.
|
|
46
|
-
*/
|
|
47
|
-
export function viteConfigPlugin(options: ViteConfigPluginOptions = {}): Plugin {
|
|
48
|
-
const {
|
|
49
|
-
env = {},
|
|
50
|
-
includeAll = true,
|
|
51
|
-
include = [],
|
|
52
|
-
scanConfigFiles: shouldScanConfigFiles = false,
|
|
53
|
-
globalName = '__APP_CONFIG__',
|
|
54
|
-
} = options;
|
|
55
|
-
|
|
56
|
-
let collectedConfig: Record<string, any> = {};
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
name: 'vite-plugin-config',
|
|
60
|
-
|
|
61
|
-
async configResolved(config) {
|
|
62
|
-
// Scan and collect config files (optional, disabled by default)
|
|
63
|
-
if (shouldScanConfigFiles) {
|
|
64
|
-
const configFiles = await scanConfigFiles({
|
|
65
|
-
...options,
|
|
66
|
-
root: config.root,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
console.log('[vite-plugin-config] Found config files:', configFiles.length);
|
|
70
|
-
|
|
71
|
-
// Load all config files and merge them
|
|
72
|
-
for (const file of configFiles) {
|
|
73
|
-
const fileConfig = await loadConfigFile(file);
|
|
74
|
-
collectedConfig = { ...collectedConfig, ...fileConfig };
|
|
75
|
-
console.log('[vite-plugin-config] Loaded config from:', path.relative(config.root, file));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
transformIndexHtml(html) {
|
|
81
|
-
// Build the config object from provided env
|
|
82
|
-
const processEnv: Record<string, any> = {};
|
|
83
|
-
|
|
84
|
-
for (const [key, value] of Object.entries(env)) {
|
|
85
|
-
// Filter by include list if not including all
|
|
86
|
-
if (!includeAll && !include.includes(key)) {
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Just copy the value as-is (NO prefix stripping here)
|
|
91
|
-
processEnv[key] = value;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Merge with collected config from .config.ts files
|
|
95
|
-
const finalConfig = { ...processEnv, ...collectedConfig };
|
|
96
|
-
|
|
97
|
-
console.log('[vite-plugin-config] Injecting environment variables into HTML');
|
|
98
|
-
console.log('[vite-plugin-config] Total variables:', Object.keys(finalConfig).length);
|
|
99
|
-
console.log('[vite-plugin-config] Sample keys:', Object.keys(finalConfig).filter(k => k.includes('APP') || k.includes('VITE')));
|
|
100
|
-
console.log('[vite-plugin-config] Global name:', globalName);
|
|
101
|
-
|
|
102
|
-
// Inject script into HTML head
|
|
103
|
-
const script = `
|
|
104
|
-
<script>
|
|
105
|
-
window.${globalName} = ${JSON.stringify(finalConfig)};
|
|
106
|
-
// Also set process.env for backward compatibility
|
|
107
|
-
window.process = window.process || {};
|
|
108
|
-
window.process.env = window.${globalName};
|
|
109
|
-
</script>
|
|
110
|
-
`;
|
|
111
|
-
|
|
112
|
-
return html.replace('<head>', `<head>${script}`);
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { Inject, Injectable } from "@abdokouta/react-di";
|
|
2
|
-
|
|
3
|
-
import { CONFIG_DRIVER } from "@/constants/tokens.constant";
|
|
4
|
-
import type { ConfigDriver } from "@/interfaces/config-driver.interface";
|
|
5
|
-
import type { ConfigServiceInterface } from "@/interfaces/config-service.interface";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Configuration Service
|
|
9
|
-
*
|
|
10
|
-
* Provides type-safe access to configuration values with various getter methods.
|
|
11
|
-
* Similar to NestJS ConfigService.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* class MyService {
|
|
16
|
-
* constructor(private config: ConfigService) {}
|
|
17
|
-
*
|
|
18
|
-
* getDbConfig() {
|
|
19
|
-
* return {
|
|
20
|
-
* host: this.config.getString('DB_HOST', 'localhost'),
|
|
21
|
-
* port: this.config.getNumber('DB_PORT', 5432),
|
|
22
|
-
* ssl: this.config.getBool('DB_SSL', false),
|
|
23
|
-
* };
|
|
24
|
-
* }
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
@Injectable()
|
|
29
|
-
export class ConfigService implements ConfigServiceInterface {
|
|
30
|
-
constructor(
|
|
31
|
-
@Inject(CONFIG_DRIVER)
|
|
32
|
-
private driver: ConfigDriver,
|
|
33
|
-
) {}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get configuration value
|
|
37
|
-
*/
|
|
38
|
-
get<T = any>(key: string, defaultValue?: T): T | undefined {
|
|
39
|
-
return this.driver.get<T>(key, defaultValue);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Get configuration value or throw if not found
|
|
44
|
-
*/
|
|
45
|
-
getOrThrow<T = any>(key: string): T {
|
|
46
|
-
const value = this.get<T>(key);
|
|
47
|
-
if (value === undefined) {
|
|
48
|
-
throw new Error(`Configuration key "${key}" is required but not set`);
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Get string value
|
|
55
|
-
*/
|
|
56
|
-
getString(key: string, defaultValue?: string): string | undefined {
|
|
57
|
-
const value = this.get(key, defaultValue);
|
|
58
|
-
return value !== undefined ? String(value) : undefined;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Get string value or throw
|
|
63
|
-
*/
|
|
64
|
-
getStringOrThrow(key: string): string {
|
|
65
|
-
return String(this.getOrThrow(key));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get number value
|
|
70
|
-
*/
|
|
71
|
-
getNumber(key: string, defaultValue?: number): number | undefined {
|
|
72
|
-
const value = this.get(key, defaultValue);
|
|
73
|
-
if (value === undefined) {
|
|
74
|
-
return undefined;
|
|
75
|
-
}
|
|
76
|
-
const parsed = Number(value);
|
|
77
|
-
return isNaN(parsed) ? defaultValue : parsed;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get number value or throw
|
|
82
|
-
*/
|
|
83
|
-
getNumberOrThrow(key: string): number {
|
|
84
|
-
const value = this.getNumber(key);
|
|
85
|
-
if (value === undefined) {
|
|
86
|
-
throw new Error(`Configuration key "${key}" is required but not set`);
|
|
87
|
-
}
|
|
88
|
-
return value;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Get boolean value
|
|
93
|
-
* Treats 'true', '1', 'yes', 'on' as true
|
|
94
|
-
*/
|
|
95
|
-
getBool(key: string, defaultValue?: boolean): boolean | undefined {
|
|
96
|
-
const value = this.get(key, defaultValue);
|
|
97
|
-
if (value === undefined) {
|
|
98
|
-
return undefined;
|
|
99
|
-
}
|
|
100
|
-
if (typeof value === "boolean") {
|
|
101
|
-
return value;
|
|
102
|
-
}
|
|
103
|
-
return ["true", "1", "yes", "on"].includes(String(value).toLowerCase());
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get boolean value or throw
|
|
108
|
-
*/
|
|
109
|
-
getBoolOrThrow(key: string): boolean {
|
|
110
|
-
const value = this.getBool(key);
|
|
111
|
-
if (value === undefined) {
|
|
112
|
-
throw new Error(`Configuration key "${key}" is required but not set`);
|
|
113
|
-
}
|
|
114
|
-
return value;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get array value (comma-separated string or actual array)
|
|
119
|
-
*/
|
|
120
|
-
getArray(key: string, defaultValue?: string[]): string[] | undefined {
|
|
121
|
-
const value = this.get(key, defaultValue);
|
|
122
|
-
if (value === undefined) {
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
125
|
-
if (Array.isArray(value)) {
|
|
126
|
-
return value.map(String);
|
|
127
|
-
}
|
|
128
|
-
return String(value)
|
|
129
|
-
.split(",")
|
|
130
|
-
.map((v) => v.trim())
|
|
131
|
-
.filter(Boolean);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Get JSON value
|
|
136
|
-
*/
|
|
137
|
-
getJson<T = any>(key: string, defaultValue?: T): T | undefined {
|
|
138
|
-
const value = this.get(key, defaultValue);
|
|
139
|
-
if (value === undefined) {
|
|
140
|
-
return undefined;
|
|
141
|
-
}
|
|
142
|
-
if (typeof value === "object") {
|
|
143
|
-
return value as T;
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
return JSON.parse(String(value)) as T;
|
|
147
|
-
} catch {
|
|
148
|
-
return defaultValue;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Check if configuration key exists
|
|
154
|
-
*/
|
|
155
|
-
has(key: string): boolean {
|
|
156
|
-
return this.driver.has(key);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Get all configuration values
|
|
161
|
-
*/
|
|
162
|
-
all(): Record<string, any> {
|
|
163
|
-
return this.driver.all();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Clear cache (no-op since we don't cache in ConfigService)
|
|
168
|
-
*/
|
|
169
|
-
clearCache(): void {
|
|
170
|
-
// No-op - caching should be done at a higher level if needed
|
|
171
|
-
}
|
|
172
|
-
}
|
package/src/services/index.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get nested value from object using dot notation
|
|
3
|
-
*
|
|
4
|
-
* @param obj - Source object
|
|
5
|
-
* @param path - Dot-notated path (e.g., 'database.host')
|
|
6
|
-
* @param defaultValue - Default value if path not found
|
|
7
|
-
* @returns Value at path or default value
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* const config = { database: { host: 'localhost' } };
|
|
12
|
-
* getNestedValue(config, 'database.host'); // 'localhost'
|
|
13
|
-
* getNestedValue(config, 'database.port', 5432); // 5432
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
export function getNestedValue<T = any>(
|
|
17
|
-
obj: Record<string, any>,
|
|
18
|
-
path: string,
|
|
19
|
-
defaultValue?: T
|
|
20
|
-
): T | undefined {
|
|
21
|
-
const keys = path.split('.');
|
|
22
|
-
let current: any = obj;
|
|
23
|
-
|
|
24
|
-
for (const key of keys) {
|
|
25
|
-
if (current === null || current === undefined) {
|
|
26
|
-
return defaultValue;
|
|
27
|
-
}
|
|
28
|
-
current = current[key];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return current !== undefined ? current : defaultValue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Check if nested path exists in object
|
|
36
|
-
*
|
|
37
|
-
* @param obj - Source object
|
|
38
|
-
* @param path - Dot-notated path
|
|
39
|
-
* @returns True if path exists
|
|
40
|
-
*/
|
|
41
|
-
export function hasNestedValue(
|
|
42
|
-
obj: Record<string, any>,
|
|
43
|
-
path: string
|
|
44
|
-
): boolean {
|
|
45
|
-
const keys = path.split('.');
|
|
46
|
-
let current: any = obj;
|
|
47
|
-
|
|
48
|
-
for (const key of keys) {
|
|
49
|
-
if (current === null || current === undefined || !(key in current)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
current = current[key];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return true;
|
|
56
|
-
}
|
package/src/utils/index.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load Config File Utility
|
|
3
|
-
*
|
|
4
|
-
* Dynamically loads and parses a config file.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Load and parse config file
|
|
9
|
-
*
|
|
10
|
-
* @param filePath - Absolute path to the config file
|
|
11
|
-
* @returns Parsed config object
|
|
12
|
-
*/
|
|
13
|
-
export async function loadConfigFile(
|
|
14
|
-
filePath: string
|
|
15
|
-
): Promise<Record<string, any>> {
|
|
16
|
-
try {
|
|
17
|
-
// Dynamic import of the config file
|
|
18
|
-
// @ts-ignore - Dynamic import path
|
|
19
|
-
const module = await import(/* @vite-ignore */ filePath);
|
|
20
|
-
|
|
21
|
-
// Extract config object (could be default export or named export)
|
|
22
|
-
const config = module.default || module;
|
|
23
|
-
|
|
24
|
-
// If it's a function, call it
|
|
25
|
-
if (typeof config === 'function') {
|
|
26
|
-
return await config();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return config;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.warn(
|
|
32
|
-
`[vite-plugin-config] Failed to load config file: ${filePath}`,
|
|
33
|
-
error
|
|
34
|
-
);
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Scan Config Files Utility
|
|
3
|
-
*
|
|
4
|
-
* Scans and collects all .config.ts files based on the provided options.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { glob } from 'glob';
|
|
8
|
-
import type { ViteConfigPluginOptions } from '@/interfaces/vite-config-plugin-options.interface';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Scan and collect all .config.ts files
|
|
12
|
-
*
|
|
13
|
-
* @param options - Plugin options containing scan configuration
|
|
14
|
-
* @returns Array of absolute file paths to config files
|
|
15
|
-
*/
|
|
16
|
-
export async function scanConfigFiles(
|
|
17
|
-
options: ViteConfigPluginOptions
|
|
18
|
-
): Promise<string[]> {
|
|
19
|
-
const {
|
|
20
|
-
configFilePattern = 'src/**/*.config.ts',
|
|
21
|
-
excludeDirs = ['node_modules', 'dist', 'build', '.git'],
|
|
22
|
-
root = process.cwd(),
|
|
23
|
-
} = options;
|
|
24
|
-
|
|
25
|
-
const patterns = Array.isArray(configFilePattern)
|
|
26
|
-
? configFilePattern
|
|
27
|
-
: [configFilePattern];
|
|
28
|
-
const configFiles: string[] = [];
|
|
29
|
-
|
|
30
|
-
for (const pattern of patterns) {
|
|
31
|
-
const files = await glob(pattern, {
|
|
32
|
-
cwd: root,
|
|
33
|
-
absolute: true,
|
|
34
|
-
ignore: excludeDirs.map((dir) => `**/${dir}/**`),
|
|
35
|
-
});
|
|
36
|
-
configFiles.push(...files);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return configFiles;
|
|
40
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "@nesvel/typescript-config/base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "./dist",
|
|
5
|
-
"rootDir": ".",
|
|
6
|
-
/* Silence TypeScript deprecation warnings */
|
|
7
|
-
"ignoreDeprecations": "6.0",
|
|
8
|
-
/* Module resolution - Override Nesvel's NodeNext for compatibility */
|
|
9
|
-
"module": "ESNext",
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
/* Decorators - Required for DI container */
|
|
12
|
-
"experimentalDecorators": true,
|
|
13
|
-
"emitDecoratorMetadata": true,
|
|
14
|
-
/* Build options */
|
|
15
|
-
"declaration": true,
|
|
16
|
-
"declarationMap": true,
|
|
17
|
-
"sourceMap": true,
|
|
18
|
-
"jsx": "react-jsx",
|
|
19
|
-
/* Testing */
|
|
20
|
-
"types": ["vitest/globals", "node"],
|
|
21
|
-
"baseUrl": ".",
|
|
22
|
-
"paths": {
|
|
23
|
-
"@/*": ["./src/*"]
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"include": ["src/**/*", "__tests__/**/*"],
|
|
27
|
-
"exclude": ["node_modules", "dist", "config"]
|
|
28
|
-
}
|
package/tsup.config.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "tsup";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* tsup Configuration for @abdokouta/logger Package
|
|
5
|
-
*
|
|
6
|
-
* Builds the logger package with dual format output (ESM + CJS).
|
|
7
|
-
* Provides a flexible logging system with multiple transporters
|
|
8
|
-
* (console, storage, silent) and formatters (pretty, json, simple).
|
|
9
|
-
*
|
|
10
|
-
* @see https://tsup.egoist.dev/
|
|
11
|
-
*/
|
|
12
|
-
export default defineConfig({
|
|
13
|
-
/**
|
|
14
|
-
* Entry point for the build.
|
|
15
|
-
*
|
|
16
|
-
* Exports the logger service, transporters, formatters, and hooks.
|
|
17
|
-
*/
|
|
18
|
-
entry: ["src/index.ts"],
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Dual format output (ESM + CJS).
|
|
22
|
-
*
|
|
23
|
-
* - ESM: Modern module format for tree-shaking
|
|
24
|
-
* - CJS: CommonJS for Node.js compatibility
|
|
25
|
-
*/
|
|
26
|
-
format: ["esm", "cjs"],
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Generate TypeScript declaration files.
|
|
30
|
-
*
|
|
31
|
-
* Provides full type safety for consumers.
|
|
32
|
-
*/
|
|
33
|
-
dts: true,
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Generate source maps for debugging.
|
|
37
|
-
*
|
|
38
|
-
* Helps developers debug issues in production.
|
|
39
|
-
*/
|
|
40
|
-
sourcemap: true,
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Clean output directory before each build.
|
|
44
|
-
*
|
|
45
|
-
* Prevents stale files from previous builds.
|
|
46
|
-
*/
|
|
47
|
-
clean: true,
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Consumers will minify during their own build.
|
|
51
|
-
*
|
|
52
|
-
* Library code should not be pre-minified to allow
|
|
53
|
-
* better tree-shaking and debugging.
|
|
54
|
-
*/
|
|
55
|
-
minify: false,
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Target ES2020 for broad compatibility.
|
|
59
|
-
*
|
|
60
|
-
* Supports modern browsers and Node.js 14+.
|
|
61
|
-
* Includes optional chaining, nullish coalescing, and other ES2020 features.
|
|
62
|
-
*/
|
|
63
|
-
target: "es2020",
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Platform-neutral build.
|
|
67
|
-
*
|
|
68
|
-
* Works in both browser and Node.js environments.
|
|
69
|
-
*/
|
|
70
|
-
platform: "neutral",
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* External dependencies that should not be bundled.
|
|
74
|
-
*
|
|
75
|
-
* - @abdokouta/react-di: DI system (peer dependency)
|
|
76
|
-
* - react: React library (optional peer dependency for hooks)
|
|
77
|
-
*/
|
|
78
|
-
external: ["@abdokouta/react-di", "react"],
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Disable code splitting for library builds.
|
|
82
|
-
*
|
|
83
|
-
* Libraries should be single-file outputs for easier consumption.
|
|
84
|
-
*/
|
|
85
|
-
splitting: false,
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Skip node_modules from being processed.
|
|
89
|
-
*
|
|
90
|
-
* Improves build performance by not processing dependencies.
|
|
91
|
-
*/
|
|
92
|
-
skipNodeModulesBundle: true,
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Ensure proper file extensions for each format.
|
|
96
|
-
*
|
|
97
|
-
* - .mjs for ESM (explicit module format)
|
|
98
|
-
* - .js for CJS (CommonJS format)
|
|
99
|
-
*
|
|
100
|
-
* This ensures proper module resolution in all environments.
|
|
101
|
-
*/
|
|
102
|
-
outExtension({ format }) {
|
|
103
|
-
return { js: format === "esm" ? ".mjs" : ".js" };
|
|
104
|
-
},
|
|
105
|
-
});
|
package/vitest.config.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Vitest configuration for @abdokouta/react-di package
|
|
3
|
-
*
|
|
4
|
-
* This configuration sets up the testing environment for the container package,
|
|
5
|
-
* including test globals, jsdom environment, coverage reporting, and path aliases.
|
|
6
|
-
*
|
|
7
|
-
* Configuration Features:
|
|
8
|
-
* - Globals: Enables global test functions (describe, it, expect)
|
|
9
|
-
* - Environment: Uses jsdom for React component testing
|
|
10
|
-
* - Setup Files: Runs vitest.setup.ts before tests
|
|
11
|
-
* - Coverage: Configures v8 coverage provider with HTML/JSON/text reports
|
|
12
|
-
* - Path Aliases: Resolves @ to ./src for consistent imports
|
|
13
|
-
*
|
|
14
|
-
* @module @abdokouta/react-di
|
|
15
|
-
* @category Configuration
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { fileURLToPath } from "url";
|
|
19
|
-
import { resolve, dirname } from "path";
|
|
20
|
-
import { defineConfig } from "vitest/config";
|
|
21
|
-
|
|
22
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
-
const __dirname = dirname(__filename);
|
|
24
|
-
|
|
25
|
-
export default defineConfig({
|
|
26
|
-
test: {
|
|
27
|
-
// Enable global test functions (describe, it, expect, etc.)
|
|
28
|
-
globals: true,
|
|
29
|
-
|
|
30
|
-
// Use jsdom environment for React testing
|
|
31
|
-
environment: "jsdom",
|
|
32
|
-
|
|
33
|
-
// Run setup file before tests
|
|
34
|
-
setupFiles: ["./__tests__/vitest.setup.ts"],
|
|
35
|
-
|
|
36
|
-
// Only include __tests__ directory
|
|
37
|
-
include: ["__tests__/**/*.{test,spec}.{ts,tsx}"],
|
|
38
|
-
|
|
39
|
-
// Coverage configuration
|
|
40
|
-
coverage: {
|
|
41
|
-
// Use v8 coverage provider (faster than istanbul)
|
|
42
|
-
provider: "v8",
|
|
43
|
-
|
|
44
|
-
// Generate multiple report formats
|
|
45
|
-
reporter: ["text", "json", "html"],
|
|
46
|
-
|
|
47
|
-
// Exclude files from coverage
|
|
48
|
-
exclude: [
|
|
49
|
-
"node_modules/",
|
|
50
|
-
"dist/",
|
|
51
|
-
"test/",
|
|
52
|
-
"**/*.test.ts",
|
|
53
|
-
"**/*.test.tsx",
|
|
54
|
-
"**/*.config.ts",
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
// Resolve path aliases
|
|
60
|
-
resolve: {
|
|
61
|
-
alias: {
|
|
62
|
-
// Map @ to ./src for consistent imports
|
|
63
|
-
"@": resolve(__dirname, "./src"),
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
});
|