kayto_ts 0.1.0 → 0.1.2
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/README.md +2 -0
- package/package.json +4 -2
- package/publish.sh +10 -0
- package/scripts/postinstall.mjs +1 -145
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kayto_ts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Type-safe HTTP client and CLI wrapper for generating and using schemas with kayto.",
|
|
5
|
+
"repository": "https://github.com/vladislav-yemelyanov/kayto_ts",
|
|
6
|
+
"homepage": "https://www.npmjs.com/package/kayto_ts",
|
|
5
7
|
"module": "src/index.ts",
|
|
6
8
|
"type": "module",
|
|
7
9
|
"bin": {
|
|
8
10
|
"kayto": "./bin/kayto.mjs"
|
|
9
11
|
},
|
|
10
12
|
"scripts": {
|
|
11
|
-
"postinstall": "
|
|
13
|
+
"postinstall": "node ./scripts/postinstall.mjs",
|
|
12
14
|
"test": "bun test"
|
|
13
15
|
},
|
|
14
16
|
"devDependencies": {
|
package/publish.sh
ADDED
package/scripts/postinstall.mjs
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
rmSync,
|
|
10
10
|
writeFileSync,
|
|
11
11
|
} from "node:fs";
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
12
|
import { arch, platform } from "node:os";
|
|
14
13
|
import { dirname, join } from "node:path";
|
|
15
14
|
import { fileURLToPath } from "node:url";
|
|
@@ -61,17 +60,6 @@ function validateInputs() {
|
|
|
61
60
|
],
|
|
62
61
|
);
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
const checksum = process.env.KAYTO_SHA256?.trim();
|
|
66
|
-
if (checksum && !/^[a-fA-F0-9]{64}$/.test(checksum)) {
|
|
67
|
-
throw userError(
|
|
68
|
-
"KAYTO_SHA256 must be a 64-character hex SHA-256 string.",
|
|
69
|
-
[
|
|
70
|
-
"Use checksum format like: e3b0c44298fc1c149afbf4c8996fb924...",
|
|
71
|
-
"Unset KAYTO_SHA256 to auto-resolve checksum from release files.",
|
|
72
|
-
],
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
63
|
}
|
|
76
64
|
|
|
77
65
|
function getTarget() {
|
|
@@ -168,33 +156,6 @@ function findBinaryRecursive(startDir, binaryName) {
|
|
|
168
156
|
return null;
|
|
169
157
|
}
|
|
170
158
|
|
|
171
|
-
async function fetchText(url) {
|
|
172
|
-
let response;
|
|
173
|
-
try {
|
|
174
|
-
response = await fetch(url, {
|
|
175
|
-
headers: {
|
|
176
|
-
"User-Agent": "kayto_ts-postinstall",
|
|
177
|
-
Accept: "application/json, text/plain, application/octet-stream",
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
} catch (error) {
|
|
181
|
-
throw userError(`Network error while requesting ${url}.`, [
|
|
182
|
-
"Check internet access and DNS settings.",
|
|
183
|
-
"If you are behind proxy, configure proxy for Node.js/npm.",
|
|
184
|
-
`Original error: ${error instanceof Error ? error.message : String(error)}`,
|
|
185
|
-
]);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!response.ok) {
|
|
189
|
-
throw userError(`Request failed (${response.status}) ${url}`, [
|
|
190
|
-
"Verify repository/tag/checksum file exists in GitHub release.",
|
|
191
|
-
"If GitHub is rate-limited, retry later or use authenticated network.",
|
|
192
|
-
]);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return response.text();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
159
|
async function resolveVersionInput() {
|
|
199
160
|
if (versionInputRaw) {
|
|
200
161
|
return versionInputRaw;
|
|
@@ -264,110 +225,6 @@ async function downloadFile(url, outFile) {
|
|
|
264
225
|
writeFileSync(outFile, Buffer.from(arrayBuffer));
|
|
265
226
|
}
|
|
266
227
|
|
|
267
|
-
function sha256Hex(filePath) {
|
|
268
|
-
return createHash("sha256").update(readFileSync(filePath)).digest("hex");
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
function parseSha256Text(text, archiveName) {
|
|
272
|
-
const normalized = text.trim().toLowerCase();
|
|
273
|
-
const direct = normalized.match(/^[a-f0-9]{64}$/);
|
|
274
|
-
if (direct) {
|
|
275
|
-
return direct[0];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const lines = text.split(/\r?\n/);
|
|
279
|
-
for (const line of lines) {
|
|
280
|
-
const match = line.trim().match(/^([a-fA-F0-9]{64})\s+\*?(.+)$/);
|
|
281
|
-
if (!match) {
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const fileName = match[2].trim();
|
|
286
|
-
if (fileName === archiveName) {
|
|
287
|
-
return match[1].toLowerCase();
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return null;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
async function resolveExpectedSha256(repoName, tag, archiveName) {
|
|
295
|
-
const base = `https://github.com/${repoName}/releases/download/${tag}`;
|
|
296
|
-
const directCandidates = [
|
|
297
|
-
`${base}/${archiveName}.sha256`,
|
|
298
|
-
`${base}/${archiveName}.sha256.txt`,
|
|
299
|
-
];
|
|
300
|
-
|
|
301
|
-
for (const url of directCandidates) {
|
|
302
|
-
try {
|
|
303
|
-
const text = await fetchText(url);
|
|
304
|
-
const value = parseSha256Text(text, archiveName);
|
|
305
|
-
if (value) {
|
|
306
|
-
return { value, source: url };
|
|
307
|
-
}
|
|
308
|
-
} catch {
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const checksumFileCandidates = [
|
|
313
|
-
"checksums.txt",
|
|
314
|
-
"sha256sums.txt",
|
|
315
|
-
"SHA256SUMS",
|
|
316
|
-
"SHA256SUMS.txt",
|
|
317
|
-
];
|
|
318
|
-
|
|
319
|
-
for (const fileName of checksumFileCandidates) {
|
|
320
|
-
const url = `${base}/${fileName}`;
|
|
321
|
-
try {
|
|
322
|
-
const text = await fetchText(url);
|
|
323
|
-
const value = parseSha256Text(text, archiveName);
|
|
324
|
-
if (value) {
|
|
325
|
-
return { value, source: url };
|
|
326
|
-
}
|
|
327
|
-
} catch {
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return null;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
async function verifyArchiveChecksum(archivePath, archiveName, resolvedTag) {
|
|
335
|
-
if (process.env.KAYTO_SKIP_CHECKSUM === "1") {
|
|
336
|
-
console.warn("[kayto_ts] checksum verification is disabled via KAYTO_SKIP_CHECKSUM=1");
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const expectedFromEnv = process.env.KAYTO_SHA256?.trim().toLowerCase();
|
|
341
|
-
let expected = expectedFromEnv;
|
|
342
|
-
let source = "KAYTO_SHA256";
|
|
343
|
-
|
|
344
|
-
if (!expected) {
|
|
345
|
-
const resolved = await resolveExpectedSha256(repo, resolvedTag, archiveName);
|
|
346
|
-
if (!resolved) {
|
|
347
|
-
throw userError(`Could not resolve SHA-256 for ${archiveName}.`, [
|
|
348
|
-
`Publish checksum files in release ${resolvedTag} (e.g. checksums.txt).`,
|
|
349
|
-
"Or provide checksum explicitly via KAYTO_SHA256.",
|
|
350
|
-
"Or set KAYTO_SKIP_CHECKSUM=1 to bypass verification (not recommended).",
|
|
351
|
-
]);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
expected = resolved.value;
|
|
355
|
-
source = resolved.source;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const actual = sha256Hex(archivePath);
|
|
359
|
-
if (actual !== expected) {
|
|
360
|
-
throw userError(`Checksum mismatch for ${archiveName}.`, [
|
|
361
|
-
`Expected: ${expected} (${source})`,
|
|
362
|
-
`Actual: ${actual}`,
|
|
363
|
-
"Re-run install with KAYTO_FORCE_INSTALL=1 to re-download archive.",
|
|
364
|
-
"If mismatch persists, verify release integrity and network/proxy behavior.",
|
|
365
|
-
]);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
console.log(`[kayto_ts] verified SHA-256 for ${archiveName} (${source})`);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
228
|
function extractArchive(archivePath, outDir, ext) {
|
|
372
229
|
if (ext === "tar.gz") {
|
|
373
230
|
const tar = spawnSync("tar", ["-xzf", archivePath, "-C", outDir], {
|
|
@@ -502,10 +359,9 @@ async function main() {
|
|
|
502
359
|
);
|
|
503
360
|
|
|
504
361
|
console.log(
|
|
505
|
-
`[kayto_ts] downloaded
|
|
362
|
+
`[kayto_ts] downloaded ${archiveName} (tag ${resolvedTag})`,
|
|
506
363
|
);
|
|
507
364
|
|
|
508
|
-
await verifyArchiveChecksum(archivePath, archiveName, resolvedTag);
|
|
509
365
|
extractArchive(archivePath, tmpDir, ext);
|
|
510
366
|
|
|
511
367
|
const extractedBinary = findBinaryRecursive(tmpDir, binaryName);
|