Files
pezkuwi-api/scripts/check-papi-sources.mjs
T
SatoshiQaziMuhammed e3c72817fb chore(papi): commit the sources behind the four polkadot-api packages (#15)
* chore(papi): commit the sources behind the four polkadot-api packages

papi-utils, bizinikiwi-bindings, metadata-builders and merkleize-metadata
held only dist/ builds, and no repository held their source. Every
source map in dist/ embeds the TypeScript it was compiled from; that is
now committed as src/ (59 files), and it matches upstream polkadot-api
(MIT) exactly once @polkadot-api/* imports are renamed:

  papi-utils           @polkadot-api/utils 0.2.0
  bizinikiwi-bindings  @polkadot-api/substrate-bindings 0.16.6
  metadata-builders    @polkadot-api/metadata-builders 0.13.0-0.13.2
  merkleize-metadata   @polkadot-api/merkleize-metadata 1.1.21-1.1.23

scripts/check-papi-sources.mjs, run in the lint job, fails unless the
source embedded in dist/ is exactly the committed src/. tsconfig.json
excludes these src/ trees; ESLint already skipped the packages. Each
README now states the upstream package and version.

* chore(papi): keep the upstream sources in upstream-src/

The pezkuwi-dev build treats any package with a src/ directory as its
own: it requires our license header on every file and builds it. These
are upstream files that must stay byte-identical to the source embedded
in dist/, so they live in upstream-src/ instead, which neither the build
nor the root tsconfig picks up.
2026-10-19 22:50:59 +04:00

74 lines
2.5 KiB
JavaScript

// Copyright 2017-2026 @pezkuwi/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
// papi-utils, bizinikiwi-bindings, metadata-builders and merkleize-metadata
// ship committed dist/ builds of upstream polkadot-api packages. Every source
// map in dist/ embeds the TypeScript it was compiled from; this check fails
// unless that embedded source is exactly the upstream-src/ committed beside it,
// so a published dist/ can only come from source held in this repository.
// (Not src/: the pezkuwi-dev build treats any package with src/ as its own and
// requires our license header on every file.)
import fs from 'node:fs';
import path from 'node:path';
const PACKAGES = ['papi-utils', 'bizinikiwi-bindings', 'metadata-builders', 'merkleize-metadata'];
const failures = [];
function walk (dir) {
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
const p = path.join(dir, e.name);
return e.isDirectory() ? walk(p) : [p];
});
}
for (const name of PACKAGES) {
const pkg = path.join('packages', name);
const srcDir = path.join(pkg, 'upstream-src');
const embedded = new Map();
for (const map of walk(path.join(pkg, 'dist')).filter((f) => f.endsWith('.map'))) {
const { sources = [], sourcesContent = [] } = JSON.parse(fs.readFileSync(map, 'utf8'));
sources.forEach((source, i) => {
const resolved = path.normalize(path.join(path.dirname(map), source));
const rel = path.join('upstream-src', resolved.slice(resolved.indexOf(`${path.sep}src${path.sep}`) + 5));
const content = sourcesContent[i];
if (content == null) {
failures.push(`${map}: no embedded source for ${source}`);
} else if (embedded.has(rel) && embedded.get(rel) !== content) {
failures.push(`${map}: ${rel} differs between source maps`);
} else {
embedded.set(rel, content);
}
});
}
const committed = new Set(walk(srcDir).map((f) => path.relative(pkg, f)));
for (const [rel, content] of embedded) {
const file = path.join(pkg, rel);
if (!committed.has(rel)) {
failures.push(`${file}: in dist/ source maps but not committed`);
} else if (fs.readFileSync(file, 'utf8') !== content) {
failures.push(`${file}: differs from the source embedded in dist/`);
}
committed.delete(rel);
}
for (const rel of committed) {
failures.push(`${path.join(pkg, rel)}: committed but not part of the dist/ build`);
}
console.log(`${name}: ${embedded.size} source files match dist/`);
}
if (failures.length) {
console.error(failures.join('\n'));
process.exit(1);
}