packagepurge 1.0.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/LICENSE +21 -0
- package/README.md +125 -0
- package/core/Cargo.lock +1093 -0
- package/core/Cargo.toml +22 -0
- package/core/src/arc_lfu.rs +91 -0
- package/core/src/cache.rs +205 -0
- package/core/src/lockfiles.rs +112 -0
- package/core/src/main.rs +125 -0
- package/core/src/ml.rs +188 -0
- package/core/src/optimization.rs +314 -0
- package/core/src/safety.rs +103 -0
- package/core/src/scanner.rs +136 -0
- package/core/src/symlink.rs +223 -0
- package/core/src/types.rs +87 -0
- package/core/src/usage_tracker.rs +107 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +249 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/bindings.d.ts +33 -0
- package/dist/core/bindings.d.ts.map +1 -0
- package/dist/core/bindings.js +172 -0
- package/dist/core/bindings.js.map +1 -0
- package/dist/managers/base-manager.d.ts +33 -0
- package/dist/managers/base-manager.d.ts.map +1 -0
- package/dist/managers/base-manager.js +122 -0
- package/dist/managers/base-manager.js.map +1 -0
- package/dist/managers/index.d.ts +12 -0
- package/dist/managers/index.d.ts.map +1 -0
- package/dist/managers/index.js +37 -0
- package/dist/managers/index.js.map +1 -0
- package/dist/managers/npm-manager.d.ts +14 -0
- package/dist/managers/npm-manager.d.ts.map +1 -0
- package/dist/managers/npm-manager.js +128 -0
- package/dist/managers/npm-manager.js.map +1 -0
- package/dist/managers/pnpm-manager.d.ts +14 -0
- package/dist/managers/pnpm-manager.d.ts.map +1 -0
- package/dist/managers/pnpm-manager.js +137 -0
- package/dist/managers/pnpm-manager.js.map +1 -0
- package/dist/managers/yarn-manager.d.ts +14 -0
- package/dist/managers/yarn-manager.d.ts.map +1 -0
- package/dist/managers/yarn-manager.js +141 -0
- package/dist/managers/yarn-manager.js.map +1 -0
- package/dist/types/index.d.ts +85 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +18 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +64 -0
- package/src/cli/index.ts +212 -0
- package/src/core/bindings.ts +157 -0
- package/src/managers/base-manager.ts +117 -0
- package/src/managers/index.ts +32 -0
- package/src/managers/npm-manager.ts +96 -0
- package/src/managers/pnpm-manager.ts +107 -0
- package/src/managers/yarn-manager.ts +112 -0
- package/src/types/index.ts +97 -0
- package/src/utils/logger.ts +50 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm package manager integration
|
|
3
|
+
*/
|
|
4
|
+
import { BasePackageManager } from './base-manager';
|
|
5
|
+
import { PackageManager, PackageInfo } from '../types';
|
|
6
|
+
import * as os from 'os';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as fs from 'fs-extra';
|
|
9
|
+
|
|
10
|
+
export class NpmManager extends BasePackageManager {
|
|
11
|
+
readonly manager = PackageManager.NPM;
|
|
12
|
+
readonly lockFileName = 'package-lock.json';
|
|
13
|
+
|
|
14
|
+
async getCachePath(): Promise<string> {
|
|
15
|
+
// npm cache path: ~/.npm on Unix, %AppData%/npm-cache on Windows
|
|
16
|
+
if (process.platform === 'win32') {
|
|
17
|
+
return path.join(os.homedir(), 'AppData', 'Roaming', 'npm-cache');
|
|
18
|
+
}
|
|
19
|
+
return path.join(os.homedir(), '.npm');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async parseLockFile(lockFilePath: string): Promise<Map<string, string>> {
|
|
23
|
+
const dependencies = new Map<string, string>();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const lockFile = await fs.readJson(lockFilePath);
|
|
27
|
+
|
|
28
|
+
// Parse package-lock.json structure
|
|
29
|
+
function extractDependencies(obj: any, prefix: string = ''): void {
|
|
30
|
+
if (obj.dependencies) {
|
|
31
|
+
for (const [name, dep] of Object.entries(obj.dependencies as Record<string, any>)) {
|
|
32
|
+
const fullName = prefix ? `${prefix}/${name}` : name;
|
|
33
|
+
if (dep.version) {
|
|
34
|
+
dependencies.set(fullName, dep.version);
|
|
35
|
+
}
|
|
36
|
+
if (dep.dependencies) {
|
|
37
|
+
extractDependencies(dep, fullName);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
extractDependencies(lockFile);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// If lock file parsing fails, return empty map
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return dependencies;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected async analyzePackage(packagePath: string): Promise<PackageInfo | null> {
|
|
52
|
+
try {
|
|
53
|
+
const stat = await fs.stat(packagePath);
|
|
54
|
+
const packageJsonPath = path.join(packagePath, 'package.json');
|
|
55
|
+
|
|
56
|
+
if (!(await fs.pathExists(packageJsonPath))) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
61
|
+
const size = await this.calculateDirectorySize(packagePath);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
name: packageJson.name || path.basename(packagePath),
|
|
65
|
+
version: packageJson.version || 'unknown',
|
|
66
|
+
path: packagePath,
|
|
67
|
+
lastAccessed: stat.atime,
|
|
68
|
+
size,
|
|
69
|
+
manager: this.manager,
|
|
70
|
+
projectPaths: [],
|
|
71
|
+
};
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private async calculateDirectorySize(dirPath: string): Promise<number> {
|
|
78
|
+
let size = 0;
|
|
79
|
+
try {
|
|
80
|
+
const entries = await fs.readdir(dirPath);
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
const entryPath = path.join(dirPath, entry);
|
|
83
|
+
const stat = await fs.stat(entryPath);
|
|
84
|
+
if (stat.isDirectory()) {
|
|
85
|
+
size += await this.calculateDirectorySize(entryPath);
|
|
86
|
+
} else {
|
|
87
|
+
size += stat.size;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
// Ignore errors
|
|
92
|
+
}
|
|
93
|
+
return size;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pnpm package manager integration
|
|
3
|
+
*/
|
|
4
|
+
import { BasePackageManager } from './base-manager';
|
|
5
|
+
import { PackageManager, PackageInfo } from '../types';
|
|
6
|
+
import * as os from 'os';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as fs from 'fs-extra';
|
|
9
|
+
|
|
10
|
+
export class PnpmManager extends BasePackageManager {
|
|
11
|
+
readonly manager = PackageManager.PNPM;
|
|
12
|
+
readonly lockFileName = 'pnpm-lock.yaml';
|
|
13
|
+
|
|
14
|
+
async getCachePath(): Promise<string> {
|
|
15
|
+
// pnpm store path: ~/.pnpm-store on Unix, %LOCALAPPDATA%/pnpm/store on Windows
|
|
16
|
+
if (process.platform === 'win32') {
|
|
17
|
+
return path.join(os.homedir(), 'AppData', 'Local', 'pnpm', 'store');
|
|
18
|
+
}
|
|
19
|
+
return path.join(os.homedir(), '.pnpm-store');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async parseLockFile(lockFilePath: string): Promise<Map<string, string>> {
|
|
23
|
+
const dependencies = new Map<string, string>();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const lockFileContent = await fs.readFile(lockFilePath, 'utf-8');
|
|
27
|
+
|
|
28
|
+
// Parse pnpm-lock.yaml format (YAML)
|
|
29
|
+
const lines = lockFileContent.split('\n');
|
|
30
|
+
let currentPackage: string | null = null;
|
|
31
|
+
let currentVersion: string | null = null;
|
|
32
|
+
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
const trimmed = line.trim();
|
|
35
|
+
|
|
36
|
+
// Package entry: "package-name:"
|
|
37
|
+
if (trimmed.endsWith(':') && !trimmed.startsWith(' ') && !trimmed.startsWith('#')) {
|
|
38
|
+
const match = trimmed.match(/^(.+?):$/);
|
|
39
|
+
if (match && !match[1].startsWith('lockfile')) {
|
|
40
|
+
currentPackage = match[1];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Version field
|
|
45
|
+
if (trimmed.startsWith('version:') && currentPackage) {
|
|
46
|
+
const match = trimmed.match(/version:\s*(.+?)$/);
|
|
47
|
+
if (match) {
|
|
48
|
+
currentVersion = match[1].replace(/["']/g, '');
|
|
49
|
+
dependencies.set(currentPackage, currentVersion);
|
|
50
|
+
currentPackage = null;
|
|
51
|
+
currentVersion = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// If lock file parsing fails, return empty map
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return dependencies;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected async analyzePackage(packagePath: string): Promise<PackageInfo | null> {
|
|
63
|
+
try {
|
|
64
|
+
const stat = await fs.stat(packagePath);
|
|
65
|
+
const packageJsonPath = path.join(packagePath, 'package.json');
|
|
66
|
+
|
|
67
|
+
if (!(await fs.pathExists(packageJsonPath))) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
72
|
+
const size = await this.calculateDirectorySize(packagePath);
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
name: packageJson.name || path.basename(packagePath),
|
|
76
|
+
version: packageJson.version || 'unknown',
|
|
77
|
+
path: packagePath,
|
|
78
|
+
lastAccessed: stat.atime,
|
|
79
|
+
size,
|
|
80
|
+
manager: this.manager,
|
|
81
|
+
projectPaths: [],
|
|
82
|
+
};
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private async calculateDirectorySize(dirPath: string): Promise<number> {
|
|
89
|
+
let size = 0;
|
|
90
|
+
try {
|
|
91
|
+
const entries = await fs.readdir(dirPath);
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
const entryPath = path.join(dirPath, entry);
|
|
94
|
+
const stat = await fs.stat(entryPath);
|
|
95
|
+
if (stat.isDirectory()) {
|
|
96
|
+
size += await this.calculateDirectorySize(entryPath);
|
|
97
|
+
} else {
|
|
98
|
+
size += stat.size;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch {
|
|
102
|
+
// Ignore errors
|
|
103
|
+
}
|
|
104
|
+
return size;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* yarn package manager integration
|
|
3
|
+
*/
|
|
4
|
+
import { BasePackageManager } from './base-manager';
|
|
5
|
+
import { PackageManager, PackageInfo } from '../types';
|
|
6
|
+
import * as os from 'os';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as fs from 'fs-extra';
|
|
9
|
+
|
|
10
|
+
export class YarnManager extends BasePackageManager {
|
|
11
|
+
readonly manager = PackageManager.YARN;
|
|
12
|
+
readonly lockFileName = 'yarn.lock';
|
|
13
|
+
|
|
14
|
+
async getCachePath(): Promise<string> {
|
|
15
|
+
// yarn cache path: ~/.yarn/cache on Unix, %LOCALAPPDATA%/Yarn/Cache on Windows
|
|
16
|
+
if (process.platform === 'win32') {
|
|
17
|
+
return path.join(os.homedir(), 'AppData', 'Local', 'Yarn', 'Cache');
|
|
18
|
+
}
|
|
19
|
+
return path.join(os.homedir(), '.yarn', 'cache');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async parseLockFile(lockFilePath: string): Promise<Map<string, string>> {
|
|
23
|
+
const dependencies = new Map<string, string>();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const lockFileContent = await fs.readFile(lockFilePath, 'utf-8');
|
|
27
|
+
|
|
28
|
+
// Parse yarn.lock format (YAML-like format)
|
|
29
|
+
const lines = lockFileContent.split('\n');
|
|
30
|
+
let currentPackage: string | null = null;
|
|
31
|
+
let currentVersion: string | null = null;
|
|
32
|
+
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
const trimmed = line.trim();
|
|
35
|
+
|
|
36
|
+
// Package declaration: "package-name@version:"
|
|
37
|
+
if (trimmed.endsWith(':') && !trimmed.startsWith(' ')) {
|
|
38
|
+
const match = trimmed.match(/^"?(.+?)@(.+?)"?:$/);
|
|
39
|
+
if (match) {
|
|
40
|
+
currentPackage = match[1];
|
|
41
|
+
currentVersion = match[2];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Version field
|
|
46
|
+
if (trimmed.startsWith('version') && currentPackage) {
|
|
47
|
+
const match = trimmed.match(/version\s+"?(.+?)"?$/);
|
|
48
|
+
if (match) {
|
|
49
|
+
currentVersion = match[1];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Store dependency
|
|
54
|
+
if (currentPackage && currentVersion && trimmed.startsWith('resolved')) {
|
|
55
|
+
dependencies.set(currentPackage, currentVersion);
|
|
56
|
+
currentPackage = null;
|
|
57
|
+
currentVersion = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
} catch (error) {
|
|
61
|
+
// If lock file parsing fails, return empty map
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return dependencies;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected async analyzePackage(packagePath: string): Promise<PackageInfo | null> {
|
|
68
|
+
try {
|
|
69
|
+
const stat = await fs.stat(packagePath);
|
|
70
|
+
const packageJsonPath = path.join(packagePath, 'package.json');
|
|
71
|
+
|
|
72
|
+
if (!(await fs.pathExists(packageJsonPath))) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
77
|
+
const size = await this.calculateDirectorySize(packagePath);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
name: packageJson.name || path.basename(packagePath),
|
|
81
|
+
version: packageJson.version || 'unknown',
|
|
82
|
+
path: packagePath,
|
|
83
|
+
lastAccessed: stat.atime,
|
|
84
|
+
size,
|
|
85
|
+
manager: this.manager,
|
|
86
|
+
projectPaths: [],
|
|
87
|
+
};
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private async calculateDirectorySize(dirPath: string): Promise<number> {
|
|
94
|
+
let size = 0;
|
|
95
|
+
try {
|
|
96
|
+
const entries = await fs.readdir(dirPath);
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
const entryPath = path.join(dirPath, entry);
|
|
99
|
+
const stat = await fs.stat(entryPath);
|
|
100
|
+
if (stat.isDirectory()) {
|
|
101
|
+
size += await this.calculateDirectorySize(entryPath);
|
|
102
|
+
} else {
|
|
103
|
+
size += stat.size;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} catch {
|
|
107
|
+
// Ignore errors
|
|
108
|
+
}
|
|
109
|
+
return size;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for PackagePurge service
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export enum PackageManager {
|
|
6
|
+
NPM = 'npm',
|
|
7
|
+
YARN = 'yarn',
|
|
8
|
+
PNPM = 'pnpm',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface PackageInfo {
|
|
12
|
+
name: string;
|
|
13
|
+
version: string;
|
|
14
|
+
path: string;
|
|
15
|
+
lastAccessed: Date;
|
|
16
|
+
size: number; // in bytes
|
|
17
|
+
manager: PackageManager;
|
|
18
|
+
projectPaths: string[]; // projects that use this package
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProjectInfo {
|
|
22
|
+
path: string;
|
|
23
|
+
manager: PackageManager;
|
|
24
|
+
dependencies: Map<string, string>; // package -> version
|
|
25
|
+
lastModified: Date;
|
|
26
|
+
lockFilePath?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CleanupStrategy {
|
|
30
|
+
name: string;
|
|
31
|
+
rules: CleanupRule[];
|
|
32
|
+
mlEnabled: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CleanupRule {
|
|
36
|
+
name: string;
|
|
37
|
+
condition: (packageInfo: PackageInfo) => boolean;
|
|
38
|
+
priority: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CleanupResult {
|
|
42
|
+
packagesDeleted: PackageInfo[];
|
|
43
|
+
spaceSaved: number; // in bytes
|
|
44
|
+
rollbackId?: string;
|
|
45
|
+
timestamp: Date;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface BackupInfo {
|
|
49
|
+
id: string;
|
|
50
|
+
timestamp: Date;
|
|
51
|
+
packages: PackageInfo[];
|
|
52
|
+
totalSize: number;
|
|
53
|
+
archivePath: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface Analytics {
|
|
57
|
+
totalSpaceSaved: number; // in bytes
|
|
58
|
+
totalRollbacks: number;
|
|
59
|
+
totalReinstalls: number;
|
|
60
|
+
savingsToRiskRatio: number;
|
|
61
|
+
cacheHitRate: number;
|
|
62
|
+
projectsAnalyzed: number;
|
|
63
|
+
lastCleanup: Date | null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface OptimizationConfig {
|
|
67
|
+
preserveDays: number;
|
|
68
|
+
keepVersions: number;
|
|
69
|
+
enableML: boolean;
|
|
70
|
+
enableSymlinking: boolean;
|
|
71
|
+
backupEnabled: boolean;
|
|
72
|
+
managers: PackageManager[];
|
|
73
|
+
dryRun: boolean;
|
|
74
|
+
lruMaxPackages?: number;
|
|
75
|
+
lruMaxSizeBytes?: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface OptimizeResult {
|
|
79
|
+
items: Array<{
|
|
80
|
+
target_path: string;
|
|
81
|
+
estimated_size_bytes: number;
|
|
82
|
+
reason: string;
|
|
83
|
+
}>;
|
|
84
|
+
total_estimated_bytes: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface SymlinkResult {
|
|
88
|
+
status: string;
|
|
89
|
+
symlinked_count: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface DependencyGraph {
|
|
93
|
+
nodes: Map<string, PackageInfo>;
|
|
94
|
+
edges: Map<string, string[]>; // package -> dependencies
|
|
95
|
+
rootProjects: ProjectInfo[];
|
|
96
|
+
}
|
|
97
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for PackagePurge
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
export enum LogLevel {
|
|
7
|
+
DEBUG = 0,
|
|
8
|
+
INFO = 1,
|
|
9
|
+
WARN = 2,
|
|
10
|
+
ERROR = 3,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class Logger {
|
|
14
|
+
private level: LogLevel = LogLevel.INFO;
|
|
15
|
+
|
|
16
|
+
setLevel(level: LogLevel): void {
|
|
17
|
+
this.level = level;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
debug(message: string, ...args: any[]): void {
|
|
21
|
+
if (this.level <= LogLevel.DEBUG) {
|
|
22
|
+
console.log(chalk.gray(`[DEBUG] ${message}`), ...args);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
info(message: string, ...args: any[]): void {
|
|
27
|
+
if (this.level <= LogLevel.INFO) {
|
|
28
|
+
console.log(chalk.blue(`[INFO] ${message}`), ...args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
warn(message: string, ...args: any[]): void {
|
|
33
|
+
if (this.level <= LogLevel.WARN) {
|
|
34
|
+
console.warn(chalk.yellow(`[WARN] ${message}`), ...args);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
error(message: string, ...args: any[]): void {
|
|
39
|
+
if (this.level <= LogLevel.ERROR) {
|
|
40
|
+
console.error(chalk.red(`[ERROR] ${message}`), ...args);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
success(message: string, ...args: any[]): void {
|
|
45
|
+
console.log(chalk.green(`[SUCCESS] ${message}`), ...args);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const logger = new Logger();
|
|
50
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
"moduleResolution": "node",
|
|
17
|
+
"types": ["node", "jest"]
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*"],
|
|
20
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
21
|
+
}
|
|
22
|
+
|