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 result = runSpawnSync('npm', args, {
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(`npm ${args.join(' ')} failed: ${result.error.message}`);
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(`npm ${args.join(' ')} failed with exit code ${result.status ?? 'unknown'}`);
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.89",
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": {