#!/usr/bin/env node import { readFileSync } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; export const PUBLIC_NPM_PACKAGE_NAME = '@kaelio/ktx'; export const PUBLIC_NPM_RELEASE_TAGS = new Set(['latest', 'next']); export const PUBLIC_NPM_BRANCH_RELEASE_TAG_PATTERN = /^branch-[a-z0-9]+(?:-[a-z0-9]+)*$/; export function publicNpmPackageTarballName(version) { return `kaelio-ktx-${version}.tgz`; } const SEMVER_PATTERN = /^(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-]+)*)?$/; const SEMVER_PARTS_PATTERN = /^(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-]+)*)?$/; function scriptRootDir() { return resolve(dirname(fileURLToPath(import.meta.url)), '..'); } export function releasePolicyPath(rootDir = scriptRootDir()) { return join(rootDir, 'release-policy.json'); } export function cliPackageJsonPath(rootDir = scriptRootDir()) { return join(rootDir, 'packages', 'cli', 'package.json'); } function readJsonSync(path) { return JSON.parse(readFileSync(path, 'utf8')); } export function assertPublicNpmPackageVersion(version) { if (typeof version !== 'string' || !SEMVER_PATTERN.test(version)) { throw new Error(`Invalid public npm package version: ${version}`); } return version; } export function publicNpmPackageVersionToPythonVersion(version) { const safeVersion = assertPublicNpmPackageVersion(version); const match = SEMVER_PARTS_PATTERN.exec(safeVersion); if (!match) { throw new Error(`Invalid public npm package version: ${version}`); } const [, major, minor, patch, prerelease, buildMetadata] = match; if (buildMetadata) { throw new Error(`Unsupported public npm build metadata for Python runtime version: ${safeVersion}`); } const baseVersion = `${major}.${minor}.${patch}`; if (!prerelease) { return baseVersion; } const rcMatch = /^rc\.([1-9]\d*|0)$/.exec(prerelease); if (!rcMatch) { throw new Error(`Unsupported public npm prerelease for Python runtime version: ${safeVersion}`); } return `${baseVersion}rc${rcMatch[1]}`; } export function assertPublicNpmReleaseTag(tag) { if (typeof tag !== 'string') { throw new Error(`Invalid public npm release tag: ${tag}`); } if (PUBLIC_NPM_RELEASE_TAGS.has(tag) || PUBLIC_NPM_BRANCH_RELEASE_TAG_PATTERN.test(tag)) { return tag; } throw new Error(`Invalid public npm release tag: ${tag}`); } function readCliPackageVersion(rootDir = scriptRootDir()) { const packageJson = readJsonSync(cliPackageJsonPath(rootDir)); return assertPublicNpmPackageVersion(packageJson.version); } export function readPublicNpmReleaseMetadata(rootDir = scriptRootDir()) { const policy = readJsonSync(releasePolicyPath(rootDir)); const tag = assertPublicNpmReleaseTag(policy.npm?.tag); return { packageName: PUBLIC_NPM_PACKAGE_NAME, version: readCliPackageVersion(rootDir), tag, }; } export function publicNpmPackageVersion(rootDir = scriptRootDir()) { return readCliPackageVersion(rootDir); } export const PUBLIC_NPM_PACKAGE_VERSION = publicNpmPackageVersion(); export function publicPythonRuntimePackageVersion(rootDir = scriptRootDir()) { return publicNpmPackageVersionToPythonVersion(publicNpmPackageVersion(rootDir)); }