pumuki 6.3.89 → 6.3.90
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.
|
@@ -1,21 +1,173 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
1
3
|
import { spawnSync as runSpawnSync } from 'node:child_process';
|
|
2
4
|
|
|
3
5
|
export interface ILifecycleNpmService {
|
|
4
6
|
runNpm(args: ReadonlyArray<string>, cwd: string): void;
|
|
5
7
|
}
|
|
6
8
|
|
|
9
|
+
type LifecyclePackageManager = 'npm' | 'pnpm' | 'yarn';
|
|
10
|
+
|
|
11
|
+
type PackageManagerManifest = {
|
|
12
|
+
packageManager?: string;
|
|
13
|
+
workspaces?: unknown;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const resolvePackageManagerFromManifest = (cwd: string): LifecyclePackageManager | undefined => {
|
|
17
|
+
const packageJsonPath = join(cwd, 'package.json');
|
|
18
|
+
if (!existsSync(packageJsonPath)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const raw = readFileSync(packageJsonPath, 'utf8');
|
|
24
|
+
const manifest = JSON.parse(raw) as PackageManagerManifest;
|
|
25
|
+
const packageManager = manifest.packageManager?.trim().toLowerCase();
|
|
26
|
+
if (!packageManager) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
if (packageManager.startsWith('pnpm@')) {
|
|
30
|
+
return 'pnpm';
|
|
31
|
+
}
|
|
32
|
+
if (packageManager.startsWith('yarn@')) {
|
|
33
|
+
return 'yarn';
|
|
34
|
+
}
|
|
35
|
+
if (packageManager.startsWith('npm@')) {
|
|
36
|
+
return 'npm';
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return undefined;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const resolveLifecyclePackageManager = (cwd: string): LifecyclePackageManager => {
|
|
46
|
+
const fromManifest = resolvePackageManagerFromManifest(cwd);
|
|
47
|
+
if (fromManifest) {
|
|
48
|
+
return fromManifest;
|
|
49
|
+
}
|
|
50
|
+
if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {
|
|
51
|
+
return 'pnpm';
|
|
52
|
+
}
|
|
53
|
+
if (existsSync(join(cwd, 'yarn.lock'))) {
|
|
54
|
+
return 'yarn';
|
|
55
|
+
}
|
|
56
|
+
return 'npm';
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const isWorkspaceRoot = (cwd: string): boolean => {
|
|
60
|
+
if (existsSync(join(cwd, 'pnpm-workspace.yaml'))) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const packageJsonPath = join(cwd, 'package.json');
|
|
64
|
+
if (!existsSync(packageJsonPath)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const raw = readFileSync(packageJsonPath, 'utf8');
|
|
69
|
+
const manifest = JSON.parse(raw) as PackageManagerManifest;
|
|
70
|
+
return Array.isArray(manifest.workspaces) || typeof manifest.workspaces === 'object';
|
|
71
|
+
} catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const translateInstallLikeArgs = (
|
|
77
|
+
packageManager: Exclude<LifecyclePackageManager, 'npm'>,
|
|
78
|
+
args: ReadonlyArray<string>,
|
|
79
|
+
cwd: string
|
|
80
|
+
): ReadonlyArray<string> => {
|
|
81
|
+
const packageSpecs = args.filter((arg) => !arg.startsWith('-')).slice(1);
|
|
82
|
+
if (packageSpecs.length === 0) {
|
|
83
|
+
return args;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const useExact = args.includes('--save-exact');
|
|
87
|
+
const useDev = args.includes('--save-dev');
|
|
88
|
+
|
|
89
|
+
if (packageManager === 'pnpm') {
|
|
90
|
+
return [
|
|
91
|
+
'add',
|
|
92
|
+
...(isWorkspaceRoot(cwd) ? ['-w'] : []),
|
|
93
|
+
...(useDev ? ['-D'] : []),
|
|
94
|
+
...(useExact ? ['-E'] : []),
|
|
95
|
+
...packageSpecs,
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [
|
|
100
|
+
'add',
|
|
101
|
+
...(useDev ? ['--dev'] : []),
|
|
102
|
+
...(useExact ? ['--exact'] : []),
|
|
103
|
+
...packageSpecs,
|
|
104
|
+
];
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const translateUninstallLikeArgs = (
|
|
108
|
+
packageManager: Exclude<LifecyclePackageManager, 'npm'>,
|
|
109
|
+
args: ReadonlyArray<string>,
|
|
110
|
+
cwd: string
|
|
111
|
+
): ReadonlyArray<string> => {
|
|
112
|
+
const packageSpecs = args.filter((arg) => !arg.startsWith('-')).slice(1);
|
|
113
|
+
if (packageSpecs.length === 0) {
|
|
114
|
+
return args;
|
|
115
|
+
}
|
|
116
|
+
if (packageManager === 'pnpm') {
|
|
117
|
+
return ['remove', ...(isWorkspaceRoot(cwd) ? ['-w'] : []), ...packageSpecs];
|
|
118
|
+
}
|
|
119
|
+
return ['remove', ...packageSpecs];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const resolveLifecyclePackageManagerCommand = (
|
|
123
|
+
args: ReadonlyArray<string>,
|
|
124
|
+
cwd: string
|
|
125
|
+
): {
|
|
126
|
+
command: LifecyclePackageManager;
|
|
127
|
+
args: ReadonlyArray<string>;
|
|
128
|
+
} => {
|
|
129
|
+
const packageManager = resolveLifecyclePackageManager(cwd);
|
|
130
|
+
if (packageManager === 'npm') {
|
|
131
|
+
return {
|
|
132
|
+
command: 'npm',
|
|
133
|
+
args,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const primaryCommand = args[0];
|
|
138
|
+
if (primaryCommand === 'install') {
|
|
139
|
+
return {
|
|
140
|
+
command: packageManager,
|
|
141
|
+
args: translateInstallLikeArgs(packageManager, args, cwd),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (primaryCommand === 'uninstall') {
|
|
145
|
+
return {
|
|
146
|
+
command: packageManager,
|
|
147
|
+
args: translateUninstallLikeArgs(packageManager, args, cwd),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
command: packageManager,
|
|
153
|
+
args,
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
|
|
7
157
|
export class LifecycleNpmService implements ILifecycleNpmService {
|
|
8
158
|
runNpm(args: ReadonlyArray<string>, cwd: string): void {
|
|
9
|
-
const
|
|
159
|
+
const execution = resolveLifecyclePackageManagerCommand(args, cwd);
|
|
160
|
+
const renderedCommand = `${execution.command} ${execution.args.join(' ')}`.trim();
|
|
161
|
+
const result = runSpawnSync(execution.command, execution.args, {
|
|
10
162
|
cwd,
|
|
11
163
|
stdio: 'inherit',
|
|
12
164
|
env: process.env,
|
|
13
165
|
});
|
|
14
166
|
if (result.error) {
|
|
15
|
-
throw new Error(
|
|
167
|
+
throw new Error(`${renderedCommand} failed: ${result.error.message}`);
|
|
16
168
|
}
|
|
17
169
|
if (typeof result.status !== 'number' || result.status !== 0) {
|
|
18
|
-
throw new Error(
|
|
170
|
+
throw new Error(`${renderedCommand} failed with exit code ${result.status ?? 'unknown'}`);
|
|
19
171
|
}
|
|
20
172
|
}
|
|
21
173
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.90",
|
|
4
4
|
"description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|