stackkit 0.3.3 → 0.3.4

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.
@@ -66,30 +66,62 @@ async function detectPackageManager(cwd) {
66
66
  async function installDependencies(cwd, pm, maxRetries = 2) {
67
67
  const args = ["install"];
68
68
  const stdio = "pipe";
69
+ const packageInstallTimeout = Number(process.env.STACKKIT_INSTALL_TIMEOUT_MS) || constants_1.TIMEOUTS.PACKAGE_INSTALL;
70
+ const envFallback = process.env.STACKKIT_FALLBACK_PMS
71
+ ? process.env.STACKKIT_FALLBACK_PMS.split(",")
72
+ .map((s) => s.trim())
73
+ .filter(Boolean)
74
+ : [];
75
+ const defaultOrder = ["pnpm", "npm", "yarn", "bun"];
76
+ const preferredOrder = Array.from(new Set([pm, ...envFallback, ...defaultOrder].map((s) => s)));
69
77
  let lastError = null;
70
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
78
+ async function isAvailable(pmCheck) {
71
79
  try {
72
- if (attempt > 0) {
73
- logger_1.logger.debug(`Retry attempt ${attempt} for installing dependencies`);
74
- await new Promise((resolve) => setTimeout(resolve, constants_1.TIMEOUTS.RETRY_DELAY_BASE * attempt));
75
- }
76
- await (0, execa_1.default)(pm, args, { cwd, stdio, timeout: constants_1.TIMEOUTS.PACKAGE_INSTALL });
77
- return;
80
+ await (0, execa_1.default)(pmCheck, ["--version"], { cwd, stdio: "pipe", timeout: 2000 });
81
+ return true;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ for (const pmCandidate of preferredOrder) {
88
+ if (!["pnpm", "npm", "yarn", "bun"].includes(pmCandidate))
89
+ continue;
90
+ const available = await isAvailable(pmCandidate);
91
+ if (!available) {
92
+ logger_1.logger.debug(`${pmCandidate} not found on PATH, skipping`);
93
+ continue;
78
94
  }
79
- catch (error) {
80
- lastError = error;
81
- logger_1.logger.debug(`Installation attempt ${attempt + 1} failed: ${lastError.message}`);
82
- const err = error;
83
- const errorMsg = err.message || "";
84
- if (errorMsg.includes("ECONNRESET") ||
85
- errorMsg.includes("ETIMEDOUT") ||
86
- errorMsg.includes("ENOTFOUND")) {
87
- continue;
95
+ logger_1.logger.debug(`Attempting install with ${pmCandidate}`);
96
+ let succeeded = false;
97
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
98
+ try {
99
+ if (attempt > 0) {
100
+ logger_1.logger.debug(`Retry attempt ${attempt} for ${pmCandidate}`);
101
+ await new Promise((resolve) => setTimeout(resolve, constants_1.TIMEOUTS.RETRY_DELAY_BASE * attempt));
102
+ }
103
+ await (0, execa_1.default)(pmCandidate, args, { cwd, stdio, timeout: packageInstallTimeout });
104
+ succeeded = true;
105
+ break;
106
+ }
107
+ catch (error) {
108
+ lastError = error;
109
+ logger_1.logger.debug(`Installation attempt ${attempt + 1} with ${pmCandidate} failed: ${lastError.message}`);
110
+ const err = error;
111
+ const errorMsg = err.message || "";
112
+ if (errorMsg.includes("ECONNRESET") ||
113
+ errorMsg.includes("ETIMEDOUT") ||
114
+ errorMsg.includes("ENOTFOUND")) {
115
+ continue;
116
+ }
117
+ break;
88
118
  }
89
- throw error;
90
119
  }
120
+ if (succeeded)
121
+ return;
122
+ logger_1.logger.debug(`${pmCandidate} failed after retries, trying next fallback`);
91
123
  }
92
- throw new Error(`Failed to install dependencies after ${maxRetries + 1} attempts: ${lastError?.message || "Unknown error"}`);
124
+ throw new Error(`Failed to install dependencies after trying fallback package managers: ${lastError?.message || "Unknown error"}`);
93
125
  }
94
126
  async function addDependencies(cwd, pm, packages, dev = false) {
95
127
  if (packages.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stackkit",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Production-ready CLI to create and extend JavaScript or TypeScript apps with modular stacks.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {