@dk/hipp 0.1.8 → 0.1.12

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.
Files changed (3) hide show
  1. package/README.md +27 -4
  2. package/hipp.js +66 -20
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -148,20 +148,43 @@ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
148
148
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
149
149
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
150
150
  PERFORMANCE OF THIS SOFTWARE.
151
+
152
+
151
153
  ```json
152
154
  {
153
155
  "origin": "git@github.com:dmytri/hipp.git",
154
- "tag": "v0.1.8"
156
+ "tag": "v0.1.10"
155
157
  }
156
158
  ```
157
159
 
158
- ```npx @dk/hipp @dk/hipp@0.1.8```
160
+ ```npx @dk/hipp @dk/hipp@0.1.10
161
+ ```
162
+
163
+ <!-- HIPP-META -->
164
+ ```json
165
+ {
166
+ "origin": "git@github.com:dmytri/hipp.git",
167
+ "tag": "v0.1.11"
168
+ }
169
+ ```
170
+
171
+ ```npx @dk/hipp @dk/hipp@0.1.11
172
+ ```
173
+ <!-- /HIPP-META -->
174
+
175
+ ```json
176
+ {
177
+ "origin": "git@github.com:dmytri/hipp.git",
178
+ "tag": "v0.1.12"
179
+ }
180
+ ```
159
181
 
182
+ ```npx @dk/hipp @dk/hipp@0.1.12```
160
183
  <!-- HIPP-MANIFEST -->
161
184
  ```json
162
185
  {
163
- "hash": "57d56d76a120bbc755700c3aa1f91f756e2cda09076dc0df522beb6a22018dca",
164
- "signature": "eclO/AvbMfQMGS7g/vwX1DbB3dbm4XxWvlMFjo06KpE+d3w7KagtIv9klyjTazls74yGy3qcHhoy3i6/zWmZAg=="
186
+ "hash": "9213a0bc269441f5dc3dc07fe07eba4d127815ae78f0d7e07474547bb342ce1b",
187
+ "signature": "Bg5/in81S3ia4x4W2C1WzvXeZPxspCdXEcSHCyLT3aUaEF5JrSANcIerZXrgbAvDyrxsf9O2wDJ/0cZNI4KOAA=="
165
188
  }
166
189
  ```
167
190
  <!-- /HIPP-MANIFEST -->
package/hipp.js CHANGED
@@ -372,6 +372,19 @@ function getTrackedFiles() {
372
372
  .filter(Boolean);
373
373
  }
374
374
 
375
+ function getTrackedFilesFromDir(repoDir) {
376
+ const out = execFileSync('git', ['ls-files', '-z'], {
377
+ encoding: 'buffer',
378
+ stdio: ['pipe', 'pipe', 'pipe'],
379
+ cwd: repoDir,
380
+ });
381
+
382
+ return out
383
+ .toString('utf8')
384
+ .split('\0')
385
+ .filter(Boolean);
386
+ }
387
+
375
388
  function copyTrackedFiles(stageDir, files) {
376
389
  const repoRoot = process.cwd();
377
390
 
@@ -393,6 +406,25 @@ function copyTrackedFiles(stageDir, files) {
393
406
  }
394
407
  }
395
408
 
409
+ function copyTrackedFilesFromDir(stageDir, repoDir, files) {
410
+ for (const rel of files) {
411
+ const src = path.join(repoDir, rel);
412
+ const dest = path.join(stageDir, rel);
413
+ const stat = fs.lstatSync(src);
414
+
415
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
416
+
417
+ if (stat.isSymbolicLink()) {
418
+ const target = fs.readlinkSync(src);
419
+ fs.symlinkSync(target, dest);
420
+ } else if (stat.isDirectory()) {
421
+ fs.mkdirSync(dest, { recursive: true });
422
+ } else if (stat.isFile()) {
423
+ fs.copyFileSync(src, dest);
424
+ }
425
+ }
426
+ }
427
+
396
428
  async function runVerify(packageSpec) {
397
429
  let pkgName, pkgVersion;
398
430
  if (packageSpec.startsWith('@')) {
@@ -462,45 +494,55 @@ async function runVerify(packageSpec) {
462
494
  fail(`❌ JSON meta (origin/tag) not found in README`);
463
495
  }
464
496
 
465
- const manifestBase64 = extractManifestFromReadme(stagedReadme);
466
- if (!manifestBase64) {
497
+ const manifestStr = extractManifestFromReadme(stagedReadme);
498
+ if (!manifestStr) {
467
499
  fail(`❌ Manifest not found in README`);
468
500
  }
469
501
 
470
- const manifest = parseManifest(manifestBase64);
502
+ const manifest = parseManifest(manifestStr);
471
503
  if (!manifest || !manifest.hash || !manifest.signature) {
472
504
  fail(`❌ Invalid manifest format`);
473
505
  }
474
506
 
507
+ const originUrl = jsonMeta.origin;
508
+ const tag = jsonMeta.tag;
509
+
475
510
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), `hipp-verify-git-`));
511
+ const stageDir = fs.mkdtempSync(path.join(os.tmpdir(), `hipp-verify-stage-`));
512
+
476
513
  try {
477
- log.info(`🌿 Fetching from git origin...`);
514
+ log.info(`🌿 Fetching from git origin at tag ${tag}...`);
515
+ git(['clone', '--branch', tag, '--depth', '1', originUrl, tmpDir], { stdio: 'pipe' });
478
516
 
479
- const originUrl = jsonMeta.origin;
480
- const tag = jsonMeta.tag;
517
+ const publicKeyPath = path.join(tmpDir, 'hipp.pub');
518
+ if (!fs.existsSync(publicKeyPath)) {
519
+ fail(`❌ hipp.pub not found in git at tag ${tag}`);
520
+ }
481
521
 
482
- git(['clone', '--branch', tag, '--depth', '1', originUrl, tmpDir], { stdio: 'pipe' });
522
+ const publicKey = fs.readFileSync(publicKeyPath, 'utf8');
523
+
524
+ log.info(`🏗️ Staging git files...`);
525
+ const trackedFiles = getTrackedFilesFromDir(tmpDir);
526
+ copyTrackedFilesFromDir(stageDir, tmpDir, trackedFiles);
483
527
 
484
- const clonedReadmePath = path.join(tmpDir, 'README.md');
485
- if (!fs.existsSync(clonedReadmePath)) {
528
+ const stagedReadmePath = path.join(stageDir, 'README.md');
529
+ if (!fs.existsSync(stagedReadmePath)) {
486
530
  fail(`❌ README.md not found in git at tag ${tag}`);
487
531
  }
488
532
 
489
- const clonedReadme = fs.readFileSync(clonedReadmePath, 'utf8');
490
- const clonedHash = computeReadmeHash(clonedReadme);
533
+ let stagedReadme = fs.readFileSync(stagedReadmePath, 'utf8');
534
+ const verifyBlock = '```npx @dk/hipp ' + pkgName + '@' + tag + '```';
535
+ const jsonMetaStr = '```json\n{\n "origin": "' + originUrl + '",\n "tag": "' + tag + '"\n}\n```';
536
+ stagedReadme = stagedReadme.trimEnd() + '\n\n' + jsonMetaStr + '\n\n' + verifyBlock + '\n';
537
+
538
+ const stagedHash = computeReadmeHash(stagedReadme);
491
539
 
492
- if (clonedHash !== manifest.hash) {
540
+ if (stagedHash !== manifest.hash) {
493
541
  fail(`❌ Hash mismatch: git content does not match npm manifest`);
494
542
  }
495
543
 
496
544
  log.success(`🔒 Content hash verified: ${manifest.hash.slice(0, 12)}...`);
497
545
 
498
- const publicKeyPath = path.join(tmpDir, 'hipp.pub');
499
- if (!fs.existsSync(publicKeyPath)) {
500
- fail(`❌ hipp.pub not found in git at tag ${tag}`);
501
- }
502
-
503
- const publicKey = fs.readFileSync(publicKeyPath, 'utf8');
504
546
  const signData = buildSignData(manifest.hash, originUrl, tag);
505
547
  const signatureValid = verifySignature(signData, manifest.signature, publicKey);
506
548
 
@@ -514,6 +556,7 @@ async function runVerify(packageSpec) {
514
556
  log.info(`📍 Tag: ${tag}`);
515
557
  } finally {
516
558
  fs.rmSync(tmpDir, { recursive: true, force: true });
559
+ fs.rmSync(stageDir, { recursive: true, force: true });
517
560
  }
518
561
  } finally {
519
562
  fs.rmSync(tarballPath, { recursive: true, force: true });
@@ -565,9 +608,10 @@ async function run() {
565
608
  log.success('📝 hipp.pub committed.');
566
609
  }
567
610
 
611
+ const { rawTag, version } = getVersionFromExactTagOnHead();
612
+
568
613
  ensureCleanRepo(pkg);
569
614
 
570
- const { rawTag, version } = getVersionFromExactTagOnHead();
571
615
  const refInfo = ensureMutableRefPolicy();
572
616
  const provenance = ensureRemoteProvenance(rawTag, refInfo.head);
573
617
  const lockInfo = ensureLockIntegrity(pkg);
@@ -608,7 +652,9 @@ async function run() {
608
652
  stagedReadme = fs.readFileSync(stagedReadmePath, 'utf8');
609
653
  }
610
654
 
611
- stagedReadme += '\n```json\n{\n "origin": "' + provenance.remoteUrl + '",\n "tag": "' + rawTag + '"\n}\n```\n\n```npx @dk/hipp ' + pkg.name + '@' + version + '```\n\n';
655
+ const verifyBlock = '```npx @dk/hipp ' + pkg.name + '@' + version + '```';
656
+ const jsonMetaStr = '```json\n{\n "origin": "' + provenance.remoteUrl + '",\n "tag": "' + rawTag + '"\n}\n```';
657
+ stagedReadme = stagedReadme.trimEnd() + '\n\n' + jsonMetaStr + '\n\n' + verifyBlock + '\n';
612
658
 
613
659
  const readmeHash = computeReadmeHash(stagedReadme);
614
660
  const dataToSign = buildSignData(readmeHash, provenance.remoteUrl, rawTag);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dk/hipp",
3
- "version": "0.1.8",
3
+ "version": "0.1.12",
4
4
  "description": "High Integrity Package Publisher",
5
5
  "main": "hipp.js",
6
6
  "bin": {