knarr 0.0.1 → 0.0.3
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 +20 -20
- package/dist/{add-ODK52RZI.mjs → add-LZ6CZTHG.mjs} +1 -1
- package/dist/bell-YD6IWNXO.mjs +0 -0
- package/dist/check-YVEJEI2G.mjs +0 -0
- package/dist/chokidar-LVDD2IK4.mjs +0 -0
- package/dist/chunk-2GDRDQA5.mjs +0 -0
- package/dist/chunk-2VCW5RWI.mjs +0 -0
- package/dist/chunk-37AAX47E.mjs +19 -0
- package/dist/chunk-3KNUBUPH.mjs +0 -0
- package/dist/{chunk-7DZPDPP6.mjs → chunk-5BZD55UB.mjs} +1 -1
- package/dist/chunk-7HVPEBK5.mjs +0 -0
- package/dist/chunk-7JG555TZ.mjs +0 -0
- package/dist/chunk-7SDPRKFT.mjs +13 -0
- package/dist/chunk-B3DZ5HVQ.mjs +0 -0
- package/dist/chunk-BS4VKVYH.mjs +0 -0
- package/dist/chunk-CTJF2EWO.mjs +3 -0
- package/dist/{chunk-HQ7NKBQW.mjs → chunk-EE2UYGFD.mjs} +2 -2
- package/dist/chunk-GO6F6AGH.mjs +3 -0
- package/dist/chunk-GQYG5FCW.mjs +5 -0
- package/dist/chunk-HEDVIVEO.mjs +14 -0
- package/dist/chunk-KOHUNKHP.mjs +3 -0
- package/dist/{chunk-U5ZZAYNU.mjs → chunk-LXGALE74.mjs} +2 -2
- package/dist/chunk-MBKCCWSD.mjs +0 -0
- package/dist/chunk-NBSJGM2X.mjs +0 -0
- package/dist/chunk-OPLSUHCD.mjs +4 -0
- package/dist/chunk-QGLOGD5G.mjs +3 -0
- package/dist/chunk-SFLWVTJC.mjs +0 -0
- package/dist/{chunk-XQVMCMO7.mjs → chunk-SN4TOUQW.mjs} +3 -3
- package/dist/chunk-SYADAYF4.mjs +0 -0
- package/dist/chunk-TEFMLGCB.mjs +0 -0
- package/dist/{chunk-2EZDTBUU.mjs → chunk-UBGMLVMB.mjs} +2 -2
- package/dist/{chunk-FU7FCNTW.mjs → chunk-XKO24LUM.mjs} +2 -2
- package/dist/chunk-XQPVRRTN.mjs +0 -0
- package/dist/{chunk-FUINO5RD.mjs → chunk-ZJEEAMB3.mjs} +2 -2
- package/dist/clean-ZD5GPGXQ.mjs +3 -0
- package/dist/cli.mjs +1 -1
- package/dist/{dev-7L35BV6M.mjs → dev-TMWMIT7W.mjs} +2 -2
- package/dist/doctor-AXP7GVBM.mjs +4 -0
- package/dist/fs-2NITBGIO.mjs +2 -0
- package/dist/{history-XUZSDCNE.mjs → history-SKKGT225.mjs} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +239 -140
- package/dist/{init-OBJFQ6OB.mjs → init-XK4B7XYG.mjs} +4 -4
- package/dist/{list-AQKUBZ2I.mjs → list-GLSA6I67.mjs} +2 -2
- package/dist/migrate-MW4BVLL2.mjs +8 -0
- package/dist/preflight-TVJFHRI2.mjs +0 -0
- package/dist/publish-TAWTHPSD.mjs +3 -0
- package/dist/{push-NHCPN6MO.mjs → push-65ZZFZJY.mjs} +2 -2
- package/dist/remove-LOBXHBMC.mjs +2 -0
- package/dist/reset-EAN5NVGM.mjs +3 -0
- package/dist/{restore-YGPO42W4.mjs → restore-YHZYT54B.mjs} +3 -3
- package/dist/rollback-U3LQTWH5.mjs +3 -0
- package/dist/{status-3VUPPR5D.mjs → status-FA6UEHEF.mjs} +3 -3
- package/dist/tailwind-source-RIWWXW2Y.mjs +5 -0
- package/dist/topo-sort-WEIVPJKN.mjs +0 -0
- package/dist/{tracker-R4ZZIDJV.mjs → tracker-JJEYXX45.mjs} +1 -1
- package/dist/update-VOUKMOLK.mjs +3 -0
- package/dist/{use-NKLXGPIZ.mjs → use-BXAZ5OP3.mjs} +1 -1
- package/dist/{vite-config-URP2SYRQ.mjs → vite-config-UWCLPTOZ.mjs} +1 -1
- package/dist/watch-orchestrator-I2623SMT.mjs +3 -0
- package/dist/watcher-PTPUN2HE.mjs +0 -0
- package/dist/{workspace-L5CGPK7U.mjs → workspace-S3TAUSS3.mjs} +1 -1
- package/dist/xxhash-wasm-DTW44IIQ.mjs +0 -0
- package/package.json +7 -4
- package/dist/chunk-23HXXAGG.mjs +0 -5
- package/dist/chunk-2QPLXLJW.mjs +0 -3
- package/dist/chunk-IM555H3S.mjs +0 -4
- package/dist/chunk-KXLQGVT2.mjs +0 -13
- package/dist/chunk-OLUZ7T7G.mjs +0 -3
- package/dist/chunk-OXI2KGCW.mjs +0 -14
- package/dist/chunk-V2ED74ZQ.mjs +0 -3
- package/dist/chunk-YZCBBQCH.mjs +0 -19
- package/dist/chunk-Z22BYXWQ.mjs +0 -3
- package/dist/clean-XMLDIZDZ.mjs +0 -3
- package/dist/doctor-4TTAYNGW.mjs +0 -4
- package/dist/fs-35635IS7.mjs +0 -2
- package/dist/migrate-7B7ACQHY.mjs +0 -8
- package/dist/publish-Q4JYQPQP.mjs +0 -3
- package/dist/remove-PDERBH66.mjs +0 -2
- package/dist/reset-3FXWAAPQ.mjs +0 -3
- package/dist/rollback-FKNGLGFC.mjs +0 -3
- package/dist/tailwind-source-ND5FE6PQ.mjs +0 -5
- package/dist/update-QPBWYDSG.mjs +0 -3
- package/dist/watch-orchestrator-F6S5WQQX.mjs +0 -3
package/dist/index.mjs
CHANGED
|
@@ -97,12 +97,12 @@ function pLimit(concurrency) {
|
|
|
97
97
|
head = 0;
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
|
-
return (fn) => new Promise((
|
|
100
|
+
return (fn) => new Promise((resolve8, reject) => {
|
|
101
101
|
const run = () => {
|
|
102
102
|
fn().then(
|
|
103
103
|
(val) => {
|
|
104
104
|
active--;
|
|
105
|
-
|
|
105
|
+
resolve8(val);
|
|
106
106
|
next();
|
|
107
107
|
},
|
|
108
108
|
(err) => {
|
|
@@ -126,19 +126,86 @@ var init_concurrency = __esm({
|
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
+
// src/utils/validators.ts
|
|
130
|
+
import { readFile } from "fs/promises";
|
|
131
|
+
import { join } from "path";
|
|
132
|
+
function validatePackageName(name) {
|
|
133
|
+
if (!name || name.length > 214 || CONTROL_CHARS_RE.test(name) || name.includes("\\") || name.includes("//") || name.split("/").some((part) => part === "." || part === "..") || !PACKAGE_NAME_RE.test(name)) {
|
|
134
|
+
throw new Error(`Invalid package name "${name}"`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function validatePackageVersion(version) {
|
|
138
|
+
if (!version || CONTROL_CHARS_RE.test(version) || version.includes("/") || version.includes("\\") || version.includes("..") || !SEMVER_RE.test(version)) {
|
|
139
|
+
throw new Error(`Invalid package version "${version}"`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function validatePackageIdentity(name, version) {
|
|
143
|
+
validatePackageName(name);
|
|
144
|
+
validatePackageVersion(version);
|
|
145
|
+
}
|
|
146
|
+
function isKnarrMeta(value) {
|
|
147
|
+
if (typeof value !== "object" || value === null) return false;
|
|
148
|
+
const v = value;
|
|
149
|
+
return typeof v.contentHash === "string" && typeof v.publishedAt === "string" && typeof v.sourcePath === "string" && (v.buildId === void 0 || typeof v.buildId === "string") && (v.schemaVersion === void 0 || typeof v.schemaVersion === "number");
|
|
150
|
+
}
|
|
151
|
+
function isLinkEntry(value) {
|
|
152
|
+
if (typeof value !== "object" || value === null) return false;
|
|
153
|
+
const v = value;
|
|
154
|
+
return typeof v.version === "string" && typeof v.contentHash === "string" && typeof v.linkedAt === "string" && typeof v.sourcePath === "string" && typeof v.backupExists === "boolean" && typeof v.packageManager === "string" && ["npm", "pnpm", "yarn", "bun"].includes(v.packageManager) && (v.buildId === void 0 || typeof v.buildId === "string");
|
|
155
|
+
}
|
|
156
|
+
function isConsumerState(value) {
|
|
157
|
+
if (typeof value !== "object" || value === null) return false;
|
|
158
|
+
const v = value;
|
|
159
|
+
if (v.version !== "1") return false;
|
|
160
|
+
if (typeof v.links !== "object" || v.links === null) return false;
|
|
161
|
+
const links = v.links;
|
|
162
|
+
for (const entry of Object.values(links)) {
|
|
163
|
+
if (!isLinkEntry(entry)) return false;
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
function isConsumersRegistry(value) {
|
|
168
|
+
if (typeof value !== "object" || value === null) return false;
|
|
169
|
+
const v = value;
|
|
170
|
+
for (const val of Object.values(v)) {
|
|
171
|
+
if (!Array.isArray(val)) return false;
|
|
172
|
+
for (const item of val) {
|
|
173
|
+
if (typeof item !== "string") return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
var PACKAGE_NAME_RE, SEMVER_RE, CONTROL_CHARS_RE;
|
|
179
|
+
var init_validators = __esm({
|
|
180
|
+
"src/utils/validators.ts"() {
|
|
181
|
+
"use strict";
|
|
182
|
+
PACKAGE_NAME_RE = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
183
|
+
SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
184
|
+
CONTROL_CHARS_RE = /[\x00-\x1F\x7F]/;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
129
188
|
// src/utils/paths.ts
|
|
130
189
|
import { homedir } from "os";
|
|
131
|
-
import { join } from "path";
|
|
190
|
+
import { isAbsolute, join as join2, relative, resolve } from "path";
|
|
191
|
+
function assertInside(root, target, label) {
|
|
192
|
+
const resolvedRoot = resolve(root);
|
|
193
|
+
const resolvedTarget = resolve(target);
|
|
194
|
+
const rel = relative(resolvedRoot, resolvedTarget);
|
|
195
|
+
if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return;
|
|
196
|
+
throw new Error(`${label} escapes expected directory: ${target}`);
|
|
197
|
+
}
|
|
132
198
|
function getKnarrHome() {
|
|
133
|
-
return process.env.KNARR_HOME ||
|
|
199
|
+
return process.env.KNARR_HOME || join2(homedir(), ".knarr");
|
|
134
200
|
}
|
|
135
201
|
function getStorePath() {
|
|
136
|
-
return
|
|
202
|
+
return join2(getKnarrHome(), "store");
|
|
137
203
|
}
|
|
138
204
|
function getConsumersPath() {
|
|
139
|
-
return
|
|
205
|
+
return join2(getKnarrHome(), "consumers.json");
|
|
140
206
|
}
|
|
141
207
|
function encodePackageName(name) {
|
|
208
|
+
validatePackageName(name);
|
|
142
209
|
return name.replace(/\//g, "+");
|
|
143
210
|
}
|
|
144
211
|
function decodePackageName(encoded) {
|
|
@@ -151,38 +218,54 @@ function decodePackageName(encoded) {
|
|
|
151
218
|
return encoded;
|
|
152
219
|
}
|
|
153
220
|
function getStoreEntryPath(name, version) {
|
|
154
|
-
|
|
221
|
+
validatePackageIdentity(name, version);
|
|
222
|
+
const root = getStorePath();
|
|
223
|
+
const target = join2(root, `${encodePackageName(name)}@${version}`);
|
|
224
|
+
assertInside(root, target, "Store entry path");
|
|
225
|
+
return target;
|
|
155
226
|
}
|
|
156
227
|
function getStorePackagePath(name, version) {
|
|
157
|
-
return
|
|
228
|
+
return join2(getStoreEntryPath(name, version), "package");
|
|
158
229
|
}
|
|
159
230
|
function getStoreMetaPath(name, version) {
|
|
160
|
-
return
|
|
231
|
+
return join2(getStoreEntryPath(name, version), ".knarr-meta.json");
|
|
161
232
|
}
|
|
162
233
|
function getStoreHistoryPath(name, version) {
|
|
163
|
-
return
|
|
234
|
+
return join2(getStoreEntryPath(name, version), "history");
|
|
164
235
|
}
|
|
165
236
|
function getHistoryEntryPath(name, version, buildId) {
|
|
166
|
-
|
|
237
|
+
if (!/^[a-f0-9]{8,64}$/i.test(buildId)) {
|
|
238
|
+
throw new Error(`Invalid build id "${buildId}"`);
|
|
239
|
+
}
|
|
240
|
+
return join2(getStoreHistoryPath(name, version), buildId);
|
|
167
241
|
}
|
|
168
242
|
function getConsumerKnarrDir(consumerPath) {
|
|
169
|
-
return
|
|
243
|
+
return join2(consumerPath, ".knarr");
|
|
170
244
|
}
|
|
171
245
|
function getConsumerStatePath(consumerPath) {
|
|
172
|
-
return
|
|
246
|
+
return join2(consumerPath, ".knarr", "state.json");
|
|
173
247
|
}
|
|
174
248
|
function getConsumerBackupPath(consumerPath, packageName) {
|
|
175
|
-
|
|
249
|
+
validatePackageName(packageName);
|
|
250
|
+
const root = join2(consumerPath, ".knarr", "backups");
|
|
251
|
+
const target = join2(root, encodePackageName(packageName));
|
|
252
|
+
assertInside(root, target, "Backup path");
|
|
253
|
+
return target;
|
|
176
254
|
}
|
|
177
255
|
function normalizePath(p) {
|
|
178
256
|
return p.replace(/\\/g, "/");
|
|
179
257
|
}
|
|
180
258
|
function getNodeModulesPackagePath(consumerPath, packageName) {
|
|
181
|
-
|
|
259
|
+
validatePackageName(packageName);
|
|
260
|
+
const root = join2(consumerPath, "node_modules");
|
|
261
|
+
const target = join2(root, packageName);
|
|
262
|
+
assertInside(root, target, "node_modules package path");
|
|
263
|
+
return target;
|
|
182
264
|
}
|
|
183
265
|
var init_paths = __esm({
|
|
184
266
|
"src/utils/paths.ts"() {
|
|
185
267
|
"use strict";
|
|
268
|
+
init_validators();
|
|
186
269
|
}
|
|
187
270
|
});
|
|
188
271
|
|
|
@@ -209,8 +292,8 @@ var init_logger = __esm({
|
|
|
209
292
|
|
|
210
293
|
// src/utils/hash.ts
|
|
211
294
|
import { createHash } from "crypto";
|
|
212
|
-
import { readFile, stat } from "fs/promises";
|
|
213
|
-
import { relative } from "path";
|
|
295
|
+
import { readFile as readFile2, stat } from "fs/promises";
|
|
296
|
+
import { relative as relative2 } from "path";
|
|
214
297
|
import { availableParallelism } from "os";
|
|
215
298
|
function getXXHash() {
|
|
216
299
|
if (!_xxhash) {
|
|
@@ -223,8 +306,8 @@ function getXXHash() {
|
|
|
223
306
|
}
|
|
224
307
|
async function computeContentHash(files, baseDir) {
|
|
225
308
|
const sorted = [...files].sort((a, b) => {
|
|
226
|
-
const relA = normalizePath(
|
|
227
|
-
const relB = normalizePath(
|
|
309
|
+
const relA = normalizePath(relative2(baseDir, a));
|
|
310
|
+
const relB = normalizePath(relative2(baseDir, b));
|
|
228
311
|
return relA.localeCompare(relB);
|
|
229
312
|
});
|
|
230
313
|
const currentFiles = new Set(sorted);
|
|
@@ -232,14 +315,14 @@ async function computeContentHash(files, baseDir) {
|
|
|
232
315
|
const contents = await Promise.all(
|
|
233
316
|
sorted.map(
|
|
234
317
|
(file) => limit(async () => {
|
|
235
|
-
const rel = normalizePath(
|
|
318
|
+
const rel = normalizePath(relative2(baseDir, file));
|
|
236
319
|
const s = await stat(file);
|
|
237
320
|
const cached = _contentCache.get(file);
|
|
238
321
|
if (cached && cached.mtimeMs === s.mtimeMs && cached.size === s.size) {
|
|
239
322
|
cacheHits++;
|
|
240
323
|
return { rel, content: cached.content };
|
|
241
324
|
}
|
|
242
|
-
const content = await
|
|
325
|
+
const content = await readFile2(file);
|
|
243
326
|
_contentCache.set(file, { mtimeMs: s.mtimeMs, size: s.size, content });
|
|
244
327
|
return { rel, content };
|
|
245
328
|
})
|
|
@@ -268,16 +351,16 @@ async function hashFile(filePath, knownSize) {
|
|
|
268
351
|
if (size > STREAM_THRESHOLD) {
|
|
269
352
|
return hashFileStream(filePath, xx);
|
|
270
353
|
}
|
|
271
|
-
const content = await
|
|
354
|
+
const content = await readFile2(filePath);
|
|
272
355
|
return xx.h64Raw(content).toString(16);
|
|
273
356
|
}
|
|
274
357
|
async function hashFileStream(filePath, xx) {
|
|
275
358
|
const { createReadStream } = await import("fs");
|
|
276
359
|
const hasher = xx.create64();
|
|
277
|
-
return new Promise((
|
|
360
|
+
return new Promise((resolve8, reject) => {
|
|
278
361
|
const stream = createReadStream(filePath);
|
|
279
362
|
stream.on("data", (chunk) => hasher.update(chunk));
|
|
280
|
-
stream.on("end", () =>
|
|
363
|
+
stream.on("end", () => resolve8(hasher.digest().toString(16)));
|
|
281
364
|
stream.on("error", reject);
|
|
282
365
|
});
|
|
283
366
|
}
|
|
@@ -330,7 +413,8 @@ function printDryRunReport() {
|
|
|
330
413
|
"bin-unlink": "Remove bin link",
|
|
331
414
|
"cache-invalidate": "Invalidate cache",
|
|
332
415
|
"lock-skip": "Skip lock",
|
|
333
|
-
"lifecycle-skip": "Skip lifecycle hook"
|
|
416
|
+
"lifecycle-skip": "Skip lifecycle hook",
|
|
417
|
+
"command-skip": "Skip command"
|
|
334
418
|
};
|
|
335
419
|
for (const [type, items] of grouped) {
|
|
336
420
|
consola.info(` ${labels[type]} (${items.length}):`);
|
|
@@ -385,7 +469,7 @@ import {
|
|
|
385
469
|
writeFile,
|
|
386
470
|
constants
|
|
387
471
|
} from "fs/promises";
|
|
388
|
-
import { join as
|
|
472
|
+
import { join as join3, dirname, relative as relative3, parse as parsePath } from "path";
|
|
389
473
|
import { availableParallelism as availableParallelism2 } from "os";
|
|
390
474
|
function isNodeError(err) {
|
|
391
475
|
return err instanceof Error && "code" in err;
|
|
@@ -424,7 +508,7 @@ async function copyWithCoW(src, dest, options) {
|
|
|
424
508
|
}
|
|
425
509
|
async function collectFiles(dir) {
|
|
426
510
|
const entries = await readdir(dir, { recursive: true, withFileTypes: true });
|
|
427
|
-
return entries.filter((e) => e.isFile()).map((e) =>
|
|
511
|
+
return entries.filter((e) => e.isFile()).map((e) => join3(e.parentPath, e.name));
|
|
428
512
|
}
|
|
429
513
|
async function incrementalCopy(srcDir, destDir, options = {}) {
|
|
430
514
|
const srcFilesPromise = collectFiles(srcDir);
|
|
@@ -439,8 +523,8 @@ async function incrementalCopy(srcDir, destDir, options = {}) {
|
|
|
439
523
|
const results = await Promise.all(
|
|
440
524
|
srcFiles.map(
|
|
441
525
|
(srcFile) => ioLimit(async () => {
|
|
442
|
-
const rel =
|
|
443
|
-
const destFile =
|
|
526
|
+
const rel = relative3(srcDir, srcFile);
|
|
527
|
+
const destFile = join3(destDir, rel);
|
|
444
528
|
let needsCopy = true;
|
|
445
529
|
let srcTimes = null;
|
|
446
530
|
if (options.force) {
|
|
@@ -494,14 +578,14 @@ async function incrementalCopy(srcDir, destDir, options = {}) {
|
|
|
494
578
|
if (r === "copied") copied++;
|
|
495
579
|
else skipped++;
|
|
496
580
|
}
|
|
497
|
-
const srcRelPaths = new Set(srcFiles.map((f) =>
|
|
581
|
+
const srcRelPaths = new Set(srcFiles.map((f) => relative3(srcDir, f)));
|
|
498
582
|
const filesToRemove = destFiles.filter(
|
|
499
|
-
(f) => !srcRelPaths.has(
|
|
583
|
+
(f) => !srcRelPaths.has(relative3(destDir, f))
|
|
500
584
|
);
|
|
501
585
|
await Promise.all(
|
|
502
586
|
filesToRemove.map(
|
|
503
587
|
(destFile) => ioLimit(async () => {
|
|
504
|
-
verbose(`[remove] ${
|
|
588
|
+
verbose(`[remove] ${relative3(destDir, destFile)} (no longer in source)`);
|
|
505
589
|
if (isDryRun()) {
|
|
506
590
|
recordMutation({ type: "remove", path: destFile });
|
|
507
591
|
} else {
|
|
@@ -584,6 +668,11 @@ async function dirSize(dir) {
|
|
|
584
668
|
}
|
|
585
669
|
}
|
|
586
670
|
async function copyDir(src, dest) {
|
|
671
|
+
if (isDryRun()) {
|
|
672
|
+
verbose(`[dry-run] would copy directory ${src} \u2192 ${dest}`);
|
|
673
|
+
recordMutation({ type: "copy", path: src, dest });
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
587
676
|
await cp(src, dest, { recursive: true });
|
|
588
677
|
}
|
|
589
678
|
var ioLimit, reflinkSupported;
|
|
@@ -601,19 +690,19 @@ var init_fs = __esm({
|
|
|
601
690
|
});
|
|
602
691
|
|
|
603
692
|
// src/utils/pack-list.ts
|
|
604
|
-
import { readFile as
|
|
605
|
-
import { join as
|
|
693
|
+
import { readFile as readFile3, readdir as readdir2, stat as stat3 } from "fs/promises";
|
|
694
|
+
import { join as join4, relative as relative4, resolve as resolve2, sep } from "path";
|
|
606
695
|
import picomatch from "picomatch";
|
|
607
696
|
async function resolvePackFiles(packageDir, pkg) {
|
|
608
697
|
const files = [];
|
|
609
|
-
const absDir =
|
|
610
|
-
files.push(
|
|
698
|
+
const absDir = resolve2(packageDir);
|
|
699
|
+
files.push(join4(absDir, "package.json"));
|
|
611
700
|
const allFiles = await collectAllFiles(absDir, absDir);
|
|
612
|
-
const allRelPaths = allFiles.map((f) => normalizePath(
|
|
701
|
+
const allRelPaths = allFiles.map((f) => normalizePath(relative4(absDir, f)));
|
|
613
702
|
if (pkg.files && pkg.files.length > 0) {
|
|
614
703
|
for (const pattern of pkg.files) {
|
|
615
|
-
const target =
|
|
616
|
-
const resolved =
|
|
704
|
+
const target = join4(absDir, pattern);
|
|
705
|
+
const resolved = resolve2(target);
|
|
617
706
|
if (!resolved.startsWith(absDir + sep) && resolved !== absDir) {
|
|
618
707
|
consola.warn(`files pattern "${pattern}" escapes package directory, skipping`);
|
|
619
708
|
continue;
|
|
@@ -622,7 +711,7 @@ async function resolvePackFiles(packageDir, pkg) {
|
|
|
622
711
|
try {
|
|
623
712
|
const s = await stat3(target);
|
|
624
713
|
if (s.isDirectory()) {
|
|
625
|
-
const prefix = normalizePath(
|
|
714
|
+
const prefix = normalizePath(relative4(absDir, target)) + "/";
|
|
626
715
|
for (let i = 0; i < allRelPaths.length; i++) {
|
|
627
716
|
if (allRelPaths[i].startsWith(prefix)) {
|
|
628
717
|
files.push(allFiles[i]);
|
|
@@ -643,7 +732,7 @@ async function resolvePackFiles(packageDir, pkg) {
|
|
|
643
732
|
let globMatched = 0;
|
|
644
733
|
for (let i = 0; i < allRelPaths.length; i++) {
|
|
645
734
|
if (isMatch(allRelPaths[i])) {
|
|
646
|
-
const absFile =
|
|
735
|
+
const absFile = resolve2(allFiles[i]);
|
|
647
736
|
if (!absFile.startsWith(absDir + sep) && absFile !== absDir) continue;
|
|
648
737
|
files.push(allFiles[i]);
|
|
649
738
|
globMatched++;
|
|
@@ -665,7 +754,7 @@ async function resolvePackFiles(packageDir, pkg) {
|
|
|
665
754
|
const fileSet = new Set(files);
|
|
666
755
|
const allFileSet = new Set(allFiles);
|
|
667
756
|
for (const name of ["README.md", "README", "LICENSE", "LICENCE", "CHANGELOG.md"]) {
|
|
668
|
-
const p =
|
|
757
|
+
const p = join4(absDir, name);
|
|
669
758
|
if (fileSet.has(p)) continue;
|
|
670
759
|
if (!allFileSet.has(p)) continue;
|
|
671
760
|
files.push(p);
|
|
@@ -691,7 +780,7 @@ function shouldIgnore(relPath, matchers) {
|
|
|
691
780
|
async function loadNpmIgnore(dir) {
|
|
692
781
|
const matchers = { literals: /* @__PURE__ */ new Set(), patterns: [], negations: [] };
|
|
693
782
|
try {
|
|
694
|
-
const content = await
|
|
783
|
+
const content = await readFile3(join4(dir, ".npmignore"), "utf-8");
|
|
695
784
|
for (const line of content.split("\n")) {
|
|
696
785
|
const trimmed = line.trim();
|
|
697
786
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -723,7 +812,7 @@ async function collectAllFiles(dir, rootDir) {
|
|
|
723
812
|
try {
|
|
724
813
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
725
814
|
for (const entry of entries) {
|
|
726
|
-
const full =
|
|
815
|
+
const full = join4(dir, entry.name);
|
|
727
816
|
if (entry.isDirectory()) {
|
|
728
817
|
if (entry.name === ".git") continue;
|
|
729
818
|
if (dir === rootDir && entry.name === "node_modules") continue;
|
|
@@ -779,47 +868,6 @@ var init_pack_list = __esm({
|
|
|
779
868
|
}
|
|
780
869
|
});
|
|
781
870
|
|
|
782
|
-
// src/utils/validators.ts
|
|
783
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
784
|
-
import { join as join4 } from "path";
|
|
785
|
-
function isKnarrMeta(value) {
|
|
786
|
-
if (typeof value !== "object" || value === null) return false;
|
|
787
|
-
const v = value;
|
|
788
|
-
return typeof v.contentHash === "string" && typeof v.publishedAt === "string" && typeof v.sourcePath === "string" && (v.buildId === void 0 || typeof v.buildId === "string") && (v.schemaVersion === void 0 || typeof v.schemaVersion === "number");
|
|
789
|
-
}
|
|
790
|
-
function isLinkEntry(value) {
|
|
791
|
-
if (typeof value !== "object" || value === null) return false;
|
|
792
|
-
const v = value;
|
|
793
|
-
return typeof v.version === "string" && typeof v.contentHash === "string" && typeof v.linkedAt === "string" && typeof v.sourcePath === "string" && typeof v.backupExists === "boolean" && typeof v.packageManager === "string" && ["npm", "pnpm", "yarn", "bun"].includes(v.packageManager) && (v.buildId === void 0 || typeof v.buildId === "string");
|
|
794
|
-
}
|
|
795
|
-
function isConsumerState(value) {
|
|
796
|
-
if (typeof value !== "object" || value === null) return false;
|
|
797
|
-
const v = value;
|
|
798
|
-
if (v.version !== "1") return false;
|
|
799
|
-
if (typeof v.links !== "object" || v.links === null) return false;
|
|
800
|
-
const links = v.links;
|
|
801
|
-
for (const entry of Object.values(links)) {
|
|
802
|
-
if (!isLinkEntry(entry)) return false;
|
|
803
|
-
}
|
|
804
|
-
return true;
|
|
805
|
-
}
|
|
806
|
-
function isConsumersRegistry(value) {
|
|
807
|
-
if (typeof value !== "object" || value === null) return false;
|
|
808
|
-
const v = value;
|
|
809
|
-
for (const val of Object.values(v)) {
|
|
810
|
-
if (!Array.isArray(val)) return false;
|
|
811
|
-
for (const item of val) {
|
|
812
|
-
if (typeof item !== "string") return false;
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
return true;
|
|
816
|
-
}
|
|
817
|
-
var init_validators = __esm({
|
|
818
|
-
"src/utils/validators.ts"() {
|
|
819
|
-
"use strict";
|
|
820
|
-
}
|
|
821
|
-
});
|
|
822
|
-
|
|
823
871
|
// src/core/store.ts
|
|
824
872
|
import { readFile as readFile4, readdir as readdir3 } from "fs/promises";
|
|
825
873
|
import "path";
|
|
@@ -991,7 +1039,7 @@ __export(history_exports, {
|
|
|
991
1039
|
resolveHistoryLimit: () => resolveHistoryLimit,
|
|
992
1040
|
restoreHistoryEntry: () => restoreHistoryEntry
|
|
993
1041
|
});
|
|
994
|
-
import { readdir as readdir4, readFile as readFile5
|
|
1042
|
+
import { readdir as readdir4, readFile as readFile5 } from "fs/promises";
|
|
995
1043
|
import { join as join6 } from "path";
|
|
996
1044
|
async function captureHistory(name, version, oldEntryDir, historyLimit) {
|
|
997
1045
|
const metaPath = join6(oldEntryDir, ".knarr-meta.json");
|
|
@@ -1021,11 +1069,11 @@ async function captureHistory(name, version, oldEntryDir, historyLimit) {
|
|
|
1021
1069
|
if (await exists(oldPkgDir)) {
|
|
1022
1070
|
await moveDir(oldPkgDir, join6(tmpHistoryEntry, "package"));
|
|
1023
1071
|
}
|
|
1024
|
-
await
|
|
1072
|
+
await atomicWriteFile(
|
|
1025
1073
|
join6(tmpHistoryEntry, ".knarr-meta.json"),
|
|
1026
1074
|
JSON.stringify(meta, null, 2)
|
|
1027
1075
|
);
|
|
1028
|
-
await
|
|
1076
|
+
await moveDir(tmpHistoryEntry, entryDir);
|
|
1029
1077
|
verbose(`[history] Captured build ${buildId} to history`);
|
|
1030
1078
|
} catch (err) {
|
|
1031
1079
|
verbose(`[history] Failed to capture history: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1086,17 +1134,54 @@ async function restoreHistoryEntry(name, version, buildId, historyLimit) {
|
|
|
1086
1134
|
const historyPkg = join6(historyEntryDir, "package");
|
|
1087
1135
|
const historyMeta = join6(historyEntryDir, ".knarr-meta.json");
|
|
1088
1136
|
const metaContent = await readFile5(historyMeta, "utf-8");
|
|
1089
|
-
if (await exists(storeEntryDir)) {
|
|
1090
|
-
await captureHistory(name, version, storeEntryDir, historyLimit);
|
|
1091
|
-
}
|
|
1092
1137
|
const storePkg = join6(storeEntryDir, "package");
|
|
1093
1138
|
const storeMeta = join6(storeEntryDir, ".knarr-meta.json");
|
|
1094
|
-
if (await exists(
|
|
1095
|
-
|
|
1139
|
+
if (!await exists(historyPkg)) {
|
|
1140
|
+
throw new Error(`History entry ${buildId} is missing its package directory`);
|
|
1141
|
+
}
|
|
1142
|
+
const currentMetaContent = await readFile5(storeMeta, "utf-8").catch(() => null);
|
|
1143
|
+
const oldEntryDir = storeEntryDir + `.restore-old-${process.pid}-${Date.now()}`;
|
|
1144
|
+
const oldPkg = join6(oldEntryDir, "package");
|
|
1145
|
+
let stagedOld = false;
|
|
1146
|
+
let historyMovedToStore = false;
|
|
1147
|
+
try {
|
|
1148
|
+
if (await exists(storePkg) || currentMetaContent) {
|
|
1149
|
+
await ensureDir(oldEntryDir);
|
|
1150
|
+
if (await exists(storePkg)) {
|
|
1151
|
+
await moveDir(storePkg, oldPkg);
|
|
1152
|
+
}
|
|
1153
|
+
if (currentMetaContent) {
|
|
1154
|
+
await atomicWriteFile(join6(oldEntryDir, ".knarr-meta.json"), currentMetaContent);
|
|
1155
|
+
}
|
|
1156
|
+
stagedOld = true;
|
|
1157
|
+
}
|
|
1096
1158
|
await moveDir(historyPkg, storePkg);
|
|
1159
|
+
historyMovedToStore = true;
|
|
1160
|
+
await atomicWriteFile(storeMeta, metaContent);
|
|
1161
|
+
await removeDir(historyEntryDir);
|
|
1162
|
+
if (stagedOld) {
|
|
1163
|
+
try {
|
|
1164
|
+
await captureHistory(name, version, oldEntryDir, historyLimit);
|
|
1165
|
+
} finally {
|
|
1166
|
+
await removeDir(oldEntryDir);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
} catch (err) {
|
|
1170
|
+
if (historyMovedToStore && await exists(storePkg)) {
|
|
1171
|
+
await ensureDir(historyEntryDir);
|
|
1172
|
+
await moveDir(storePkg, historyPkg);
|
|
1173
|
+
} else if (stagedOld && await exists(storePkg)) {
|
|
1174
|
+
await removeDir(storePkg);
|
|
1175
|
+
}
|
|
1176
|
+
if (stagedOld && await exists(oldPkg)) {
|
|
1177
|
+
await moveDir(oldPkg, storePkg);
|
|
1178
|
+
}
|
|
1179
|
+
if (currentMetaContent) {
|
|
1180
|
+
await atomicWriteFile(storeMeta, currentMetaContent);
|
|
1181
|
+
}
|
|
1182
|
+
await removeDir(oldEntryDir);
|
|
1183
|
+
throw err;
|
|
1097
1184
|
}
|
|
1098
|
-
await writeFile2(storeMeta, metaContent);
|
|
1099
|
-
await removeDir(historyEntryDir);
|
|
1100
1185
|
verbose(`[history] Restored build ${buildId} as current`);
|
|
1101
1186
|
return entry;
|
|
1102
1187
|
}
|
|
@@ -1147,7 +1232,7 @@ __export(workspace_exports, {
|
|
|
1147
1232
|
parseCatalogs: () => parseCatalogs
|
|
1148
1233
|
});
|
|
1149
1234
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
1150
|
-
import { join as join7, dirname as dirname3, resolve as
|
|
1235
|
+
import { join as join7, dirname as dirname3, resolve as resolve3, relative as relative5 } from "path";
|
|
1151
1236
|
import picomatch2 from "picomatch";
|
|
1152
1237
|
async function findWorkspaceRoot(startDir) {
|
|
1153
1238
|
let dir = startDir;
|
|
@@ -1317,14 +1402,14 @@ async function resolveWorkspaceGlobs(rootDir, patterns, negations = []) {
|
|
|
1317
1402
|
const isMatch = picomatch2(pattern);
|
|
1318
1403
|
const candidates = await collectDirs(rootDir, 8);
|
|
1319
1404
|
for (const candidate of candidates) {
|
|
1320
|
-
const rel = normalizePath(
|
|
1405
|
+
const rel = normalizePath(relative5(rootDir, candidate));
|
|
1321
1406
|
if (isMatch(rel) && await exists(join7(candidate, "package.json"))) {
|
|
1322
1407
|
results.push(candidate);
|
|
1323
1408
|
}
|
|
1324
1409
|
}
|
|
1325
1410
|
}
|
|
1326
1411
|
} else {
|
|
1327
|
-
const pkgDir =
|
|
1412
|
+
const pkgDir = resolve3(rootDir, pattern);
|
|
1328
1413
|
if (await exists(join7(pkgDir, "package.json"))) {
|
|
1329
1414
|
results.push(pkgDir);
|
|
1330
1415
|
}
|
|
@@ -1334,7 +1419,7 @@ async function resolveWorkspaceGlobs(rootDir, patterns, negations = []) {
|
|
|
1334
1419
|
if (negations.length === 0) return unique;
|
|
1335
1420
|
const isExcluded = picomatch2(negations);
|
|
1336
1421
|
return unique.filter((dir) => {
|
|
1337
|
-
const rel = normalizePath(
|
|
1422
|
+
const rel = normalizePath(relative5(rootDir, dir));
|
|
1338
1423
|
return !isExcluded(rel);
|
|
1339
1424
|
});
|
|
1340
1425
|
}
|
|
@@ -1420,8 +1505,8 @@ var init_workspace = __esm({
|
|
|
1420
1505
|
});
|
|
1421
1506
|
|
|
1422
1507
|
// src/core/publisher.ts
|
|
1423
|
-
import { readFile as readFile7,
|
|
1424
|
-
import { join as join8, relative as
|
|
1508
|
+
import { readFile as readFile7, stat as stat5 } from "fs/promises";
|
|
1509
|
+
import { join as join8, relative as relative6, dirname as dirname4, resolve as resolve4 } from "path";
|
|
1425
1510
|
import { spawn } from "child_process";
|
|
1426
1511
|
import { platform } from "os";
|
|
1427
1512
|
import { availableParallelism as availableParallelism3 } from "os";
|
|
@@ -1436,6 +1521,7 @@ async function publish(packageDir, options = {}) {
|
|
|
1436
1521
|
const pkg = JSON.parse(pkgContent);
|
|
1437
1522
|
if (!pkg.name) throw new Error("package.json missing 'name' field");
|
|
1438
1523
|
if (!pkg.version) throw new Error("package.json missing 'version' field");
|
|
1524
|
+
validatePackageIdentity(pkg.name, pkg.version);
|
|
1439
1525
|
if (pkg.private && !options.allowPrivate) {
|
|
1440
1526
|
throw new Error(
|
|
1441
1527
|
`Package "${pkg.name}" is private. Use --private flag to publish private packages.`
|
|
@@ -1447,7 +1533,7 @@ async function publish(packageDir, options = {}) {
|
|
|
1447
1533
|
}
|
|
1448
1534
|
let publishDir = packageDir;
|
|
1449
1535
|
if (pkg.publishConfig?.directory) {
|
|
1450
|
-
publishDir =
|
|
1536
|
+
publishDir = resolve4(packageDir, pkg.publishConfig.directory);
|
|
1451
1537
|
try {
|
|
1452
1538
|
const s = await stat5(publishDir);
|
|
1453
1539
|
if (!s.isDirectory()) {
|
|
@@ -1511,16 +1597,16 @@ async function publish(packageDir, options = {}) {
|
|
|
1511
1597
|
processedPkg = applyPublishConfig(processedPkg);
|
|
1512
1598
|
verbose(`[publish] Copying files to temp store...`);
|
|
1513
1599
|
const uniqueDirs = new Set(
|
|
1514
|
-
files.map((file) => dirname4(join8(tmpPackageDir,
|
|
1600
|
+
files.map((file) => dirname4(join8(tmpPackageDir, relative6(publishDir, file))))
|
|
1515
1601
|
);
|
|
1516
1602
|
await Promise.all([...uniqueDirs].map((d) => ensureDir(d)));
|
|
1517
1603
|
await Promise.all(
|
|
1518
1604
|
files.map(
|
|
1519
1605
|
(file) => copyLimit(async () => {
|
|
1520
|
-
const rel =
|
|
1606
|
+
const rel = relative6(publishDir, file);
|
|
1521
1607
|
const dest = join8(tmpPackageDir, rel);
|
|
1522
1608
|
if (rel === "package.json" && processedPkg !== pkg) {
|
|
1523
|
-
await
|
|
1609
|
+
await atomicWriteFile(dest, JSON.stringify(processedPkg, null, 2));
|
|
1524
1610
|
} else {
|
|
1525
1611
|
await copyWithCoW(file, dest, { ensureParent: false });
|
|
1526
1612
|
}
|
|
@@ -1528,7 +1614,7 @@ async function publish(packageDir, options = {}) {
|
|
|
1528
1614
|
)
|
|
1529
1615
|
);
|
|
1530
1616
|
if (publishDir !== packageDir) {
|
|
1531
|
-
await
|
|
1617
|
+
await atomicWriteFile(
|
|
1532
1618
|
join8(tmpPackageDir, "package.json"),
|
|
1533
1619
|
JSON.stringify(processedPkg, null, 2)
|
|
1534
1620
|
);
|
|
@@ -1540,15 +1626,29 @@ async function publish(packageDir, options = {}) {
|
|
|
1540
1626
|
sourcePath: packageDir,
|
|
1541
1627
|
buildId
|
|
1542
1628
|
};
|
|
1543
|
-
await
|
|
1629
|
+
await atomicWriteFile(
|
|
1544
1630
|
join8(tmpDir, ".knarr-meta.json"),
|
|
1545
1631
|
JSON.stringify(meta, null, 2)
|
|
1546
1632
|
);
|
|
1547
1633
|
const hadOld = await exists(storeEntryDir);
|
|
1548
1634
|
const oldDir = storeEntryDir + ".old-" + Date.now();
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1635
|
+
let oldMoved = false;
|
|
1636
|
+
try {
|
|
1637
|
+
if (hadOld) {
|
|
1638
|
+
await moveDir(storeEntryDir, oldDir);
|
|
1639
|
+
oldMoved = !isDryRun();
|
|
1640
|
+
}
|
|
1641
|
+
await moveDir(tmpDir, storeEntryDir);
|
|
1642
|
+
} catch (err) {
|
|
1643
|
+
if (oldMoved && await exists(oldDir)) {
|
|
1644
|
+
if (await exists(storeEntryDir)) {
|
|
1645
|
+
await removeDir(storeEntryDir);
|
|
1646
|
+
}
|
|
1647
|
+
await moveDir(oldDir, storeEntryDir);
|
|
1648
|
+
}
|
|
1649
|
+
throw err;
|
|
1650
|
+
}
|
|
1651
|
+
if (hadOld && !isDryRun()) {
|
|
1552
1652
|
try {
|
|
1553
1653
|
const { captureHistory: captureHistory2 } = await Promise.resolve().then(() => (init_history(), history_exports));
|
|
1554
1654
|
await captureHistory2(pkg.name, pkg.version, oldDir, options.historyLimit);
|
|
@@ -1595,7 +1695,7 @@ async function runLifecycleHook(packageDir, pkg, hookName) {
|
|
|
1595
1695
|
return;
|
|
1596
1696
|
}
|
|
1597
1697
|
verbose(`[lifecycle] Running ${hookName}: ${script}`);
|
|
1598
|
-
return new Promise((
|
|
1698
|
+
return new Promise((resolve8, reject) => {
|
|
1599
1699
|
const isWin = platform() === "win32";
|
|
1600
1700
|
const shell = isWin ? "cmd" : "sh";
|
|
1601
1701
|
const shellFlag = isWin ? "/c" : "-c";
|
|
@@ -1610,7 +1710,7 @@ async function runLifecycleHook(packageDir, pkg, hookName) {
|
|
|
1610
1710
|
child.on("close", (code) => {
|
|
1611
1711
|
clearTimeout(timer);
|
|
1612
1712
|
if (code === 0) {
|
|
1613
|
-
|
|
1713
|
+
resolve8();
|
|
1614
1714
|
} else {
|
|
1615
1715
|
reject(new Error(`${hookName} script failed with exit code ${code}`));
|
|
1616
1716
|
}
|
|
@@ -1769,6 +1869,7 @@ var init_publisher = __esm({
|
|
|
1769
1869
|
init_lockfile();
|
|
1770
1870
|
init_logger();
|
|
1771
1871
|
init_dry_run();
|
|
1872
|
+
init_validators();
|
|
1772
1873
|
copyLimit = pLimit(Math.max(availableParallelism3(), 8));
|
|
1773
1874
|
HOOK_TIMEOUT = parseInt(process.env.KNARR_HOOK_TIMEOUT ?? "30000", 10);
|
|
1774
1875
|
PUBLISH_CONFIG_OVERRIDES = [
|
|
@@ -1787,8 +1888,8 @@ var init_publisher = __esm({
|
|
|
1787
1888
|
});
|
|
1788
1889
|
|
|
1789
1890
|
// src/utils/bin-linker.ts
|
|
1790
|
-
import { mkdir as mkdir3, symlink, writeFile as
|
|
1791
|
-
import { join as join9, relative as
|
|
1891
|
+
import { mkdir as mkdir3, symlink, writeFile as writeFile2, chmod, rm as rm3 } from "fs/promises";
|
|
1892
|
+
import { join as join9, relative as relative7, resolve as resolve5, sep as sep2 } from "path";
|
|
1792
1893
|
import { platform as platform2 } from "os";
|
|
1793
1894
|
function resolveBinEntries(pkg) {
|
|
1794
1895
|
if (!pkg.bin) return {};
|
|
@@ -1815,12 +1916,12 @@ async function createBinLinks(consumerPath, packageName, pkg) {
|
|
|
1815
1916
|
for (const [binName, binPath] of Object.entries(entries)) {
|
|
1816
1917
|
const packageRoot = join9(consumerPath, "node_modules", packageName);
|
|
1817
1918
|
const targetAbsolute = join9(packageRoot, binPath);
|
|
1818
|
-
const resolvedTarget =
|
|
1819
|
-
if (!resolvedTarget.startsWith(
|
|
1919
|
+
const resolvedTarget = resolve5(targetAbsolute);
|
|
1920
|
+
if (!resolvedTarget.startsWith(resolve5(packageRoot) + sep2) && resolvedTarget !== resolve5(packageRoot)) {
|
|
1820
1921
|
consola.warn(`bin "${binName}" points outside package directory, skipping`);
|
|
1821
1922
|
continue;
|
|
1822
1923
|
}
|
|
1823
|
-
const targetRelative = normalizePath(
|
|
1924
|
+
const targetRelative = normalizePath(relative7(binDir, targetAbsolute));
|
|
1824
1925
|
if (isWindows) {
|
|
1825
1926
|
const cmdPath = join9(binDir, `${binName}.cmd`);
|
|
1826
1927
|
const targetWindows = targetRelative.replace(/\//g, "\\");
|
|
@@ -1831,21 +1932,21 @@ SET dp0=%~dp0\r
|
|
|
1831
1932
|
EXIT /b\r
|
|
1832
1933
|
:start\r
|
|
1833
1934
|
CALL :find_dp0\r
|
|
1834
|
-
"%dp0%\\${targetWindows}" %*\r
|
|
1935
|
+
node "%dp0%\\${targetWindows}" %*\r
|
|
1835
1936
|
`;
|
|
1836
|
-
await
|
|
1937
|
+
await writeFile2(cmdPath, cmdContent);
|
|
1837
1938
|
const ps1Path = join9(binDir, `${binName}.ps1`);
|
|
1838
1939
|
const ps1Content = `#!/usr/bin/env pwsh
|
|
1839
1940
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
1840
1941
|
& node "$basedir/${targetRelative}" $args
|
|
1841
1942
|
exit $LASTEXITCODE
|
|
1842
1943
|
`;
|
|
1843
|
-
await
|
|
1944
|
+
await writeFile2(ps1Path, ps1Content);
|
|
1844
1945
|
const shPath = join9(binDir, binName);
|
|
1845
1946
|
const shContent = `#!/bin/sh
|
|
1846
1947
|
exec node "${targetRelative}" "$@"
|
|
1847
1948
|
`;
|
|
1848
|
-
await
|
|
1949
|
+
await writeFile2(shPath, shContent);
|
|
1849
1950
|
} else {
|
|
1850
1951
|
const linkPath = join9(binDir, binName);
|
|
1851
1952
|
try {
|
|
@@ -1861,7 +1962,7 @@ exec node "${targetRelative}" "$@"
|
|
|
1861
1962
|
const shContent = `#!/bin/sh
|
|
1862
1963
|
exec node "${targetRelative}" "$@"
|
|
1863
1964
|
`;
|
|
1864
|
-
await
|
|
1965
|
+
await writeFile2(linkPath, shContent);
|
|
1865
1966
|
await chmod(linkPath, 493);
|
|
1866
1967
|
} else {
|
|
1867
1968
|
throw err;
|
|
@@ -2066,7 +2167,7 @@ var init_bundler_cache = __esm({
|
|
|
2066
2167
|
|
|
2067
2168
|
// src/core/injector.ts
|
|
2068
2169
|
import { readFile as readFile9, readdir as readdir6, realpath, stat as stat7 } from "fs/promises";
|
|
2069
|
-
import { join as join13, resolve as
|
|
2170
|
+
import { join as join13, resolve as resolve6 } from "path";
|
|
2070
2171
|
async function inject(storeEntry, consumerPath, pm, options = {}) {
|
|
2071
2172
|
const targetDir = await resolveTargetDir(
|
|
2072
2173
|
consumerPath,
|
|
@@ -2146,7 +2247,7 @@ async function resolveTargetDir(consumerPath, packageName, pm, version) {
|
|
|
2146
2247
|
}
|
|
2147
2248
|
try {
|
|
2148
2249
|
const realPath = await resolveRealPath(directPath);
|
|
2149
|
-
if (realPath !==
|
|
2250
|
+
if (realPath !== resolve6(directPath)) {
|
|
2150
2251
|
verbose(`[inject] pnpm: resolved symlink \u2192 ${realPath}`);
|
|
2151
2252
|
return realPath;
|
|
2152
2253
|
}
|
|
@@ -2194,7 +2295,7 @@ async function resolveRealPath(linkPath) {
|
|
|
2194
2295
|
return await realpath(linkPath);
|
|
2195
2296
|
} catch (err) {
|
|
2196
2297
|
if (isNodeError(err) && err.code === "ENOENT") {
|
|
2197
|
-
return
|
|
2298
|
+
return resolve6(linkPath);
|
|
2198
2299
|
}
|
|
2199
2300
|
throw err;
|
|
2200
2301
|
}
|
|
@@ -3008,7 +3109,7 @@ async function startWatcher(watchDir, options, onChange) {
|
|
|
3008
3109
|
return watcherHandle;
|
|
3009
3110
|
}
|
|
3010
3111
|
function runBuildCommand(cmd, cwd) {
|
|
3011
|
-
return new Promise((
|
|
3112
|
+
return new Promise((resolve8) => {
|
|
3012
3113
|
const isWin = platform3() === "win32";
|
|
3013
3114
|
const shell = isWin ? "cmd" : "sh";
|
|
3014
3115
|
const shellFlag = isWin ? "/c" : "-c";
|
|
@@ -3022,16 +3123,16 @@ function runBuildCommand(cmd, cwd) {
|
|
|
3022
3123
|
activeChild = null;
|
|
3023
3124
|
if (code === 0) {
|
|
3024
3125
|
consola.success("Build succeeded");
|
|
3025
|
-
|
|
3126
|
+
resolve8(true);
|
|
3026
3127
|
} else {
|
|
3027
3128
|
consola.error(`Build failed with code ${code}`);
|
|
3028
|
-
|
|
3129
|
+
resolve8(false);
|
|
3029
3130
|
}
|
|
3030
3131
|
});
|
|
3031
3132
|
child.on("error", (err) => {
|
|
3032
3133
|
activeChild = null;
|
|
3033
3134
|
consola.error(`Build error: ${err.message}`);
|
|
3034
|
-
|
|
3135
|
+
resolve8(false);
|
|
3035
3136
|
});
|
|
3036
3137
|
});
|
|
3037
3138
|
}
|
|
@@ -3117,14 +3218,14 @@ var init_watch_orchestrator = __esm({
|
|
|
3117
3218
|
},
|
|
3118
3219
|
wrappedOnChange
|
|
3119
3220
|
);
|
|
3120
|
-
this.packages.set(name, { dir, state: "idle", watcher });
|
|
3221
|
+
this.packages.set(name, { dir, buildCmd, state: "idle", watcher });
|
|
3121
3222
|
}
|
|
3122
3223
|
consola.info(`Watching ${this.packages.size} workspace packages`);
|
|
3123
|
-
await new Promise((
|
|
3224
|
+
await new Promise((resolve8) => {
|
|
3124
3225
|
const cleanup = async () => {
|
|
3125
3226
|
consola.info("Stopping watchers...");
|
|
3126
3227
|
await this.close();
|
|
3127
|
-
|
|
3228
|
+
resolve8();
|
|
3128
3229
|
};
|
|
3129
3230
|
process.once("SIGINT", cleanup);
|
|
3130
3231
|
process.once("SIGTERM", cleanup);
|
|
@@ -3155,11 +3256,9 @@ var init_watch_orchestrator = __esm({
|
|
|
3155
3256
|
entry.state = "building";
|
|
3156
3257
|
verbose(`[cascade] Rebuilding ${name}`);
|
|
3157
3258
|
try {
|
|
3158
|
-
|
|
3159
|
-
const buildCmd = config.buildCmd;
|
|
3160
|
-
if (buildCmd) {
|
|
3259
|
+
if (entry.buildCmd) {
|
|
3161
3260
|
const { runBuildCommand: runBuildCommand2 } = await Promise.resolve().then(() => (init_watcher(), watcher_exports));
|
|
3162
|
-
const success = await runBuildCommand2(buildCmd, entry.dir);
|
|
3261
|
+
const success = await runBuildCommand2(entry.buildCmd, entry.dir);
|
|
3163
3262
|
if (!success) {
|
|
3164
3263
|
consola.warn(`[cascade] Build failed for ${name}, skipping dependents`);
|
|
3165
3264
|
entry.state = "idle";
|
|
@@ -3256,7 +3355,7 @@ init_workspace();
|
|
|
3256
3355
|
// src/utils/preflight.ts
|
|
3257
3356
|
init_logger();
|
|
3258
3357
|
import { readFile as readFile14, stat as stat9 } from "fs/promises";
|
|
3259
|
-
import { join as join18, resolve as
|
|
3358
|
+
import { join as join18, resolve as resolve7 } from "path";
|
|
3260
3359
|
async function runPreflightChecks(packageDir) {
|
|
3261
3360
|
const issues = [];
|
|
3262
3361
|
let pkgContent;
|
|
@@ -3326,7 +3425,7 @@ async function fileExists(filePath) {
|
|
|
3326
3425
|
}
|
|
3327
3426
|
}
|
|
3328
3427
|
async function checkPath(packageDir, filePath, field, issues) {
|
|
3329
|
-
const resolved =
|
|
3428
|
+
const resolved = resolve7(packageDir, filePath);
|
|
3330
3429
|
if (!await fileExists(resolved)) {
|
|
3331
3430
|
issues.push({
|
|
3332
3431
|
code: "MISSING_PATH",
|
|
@@ -3339,7 +3438,7 @@ async function checkExports(packageDir, exports, issues) {
|
|
|
3339
3438
|
for (const [key, value] of Object.entries(exports)) {
|
|
3340
3439
|
if (typeof value === "string") {
|
|
3341
3440
|
if (value.startsWith(".")) {
|
|
3342
|
-
const resolved =
|
|
3441
|
+
const resolved = resolve7(packageDir, value);
|
|
3343
3442
|
if (!await fileExists(resolved)) {
|
|
3344
3443
|
issues.push({
|
|
3345
3444
|
code: "EXPORTS_PATH_MISSING",
|
|
@@ -3380,7 +3479,7 @@ async function checkExportsConditions(packageDir, exportKey, conditions, issues)
|
|
|
3380
3479
|
}
|
|
3381
3480
|
for (const [condition, value] of Object.entries(conditions)) {
|
|
3382
3481
|
if (typeof value === "string" && value.startsWith(".")) {
|
|
3383
|
-
const resolved =
|
|
3482
|
+
const resolved = resolve7(packageDir, value);
|
|
3384
3483
|
if (!await fileExists(resolved)) {
|
|
3385
3484
|
issues.push({
|
|
3386
3485
|
code: "EXPORTS_PATH_MISSING",
|