XuqmGroup-RNSDK/packages/update/scripts/release-package.mjs

99 行
3.5 KiB
JavaScript

import { createHash } from 'node:crypto'
import { readFileSync } from 'node:fs'
import { strFromU8, unzipSync } from 'fflate'
function requiredString(manifest, key) {
const value = manifest?.[key]
if (typeof value !== 'string' || value.trim() === '') {
throw new Error(`plugin package manifest ${key} is missing`)
}
return value
}
/**
* 发布身份只能来自即将上传的 ZIP不能根据环境变量或缓存再次推导这样 Bundle
* Source Map 和服务端登记始终使用同一个构建产生的精确身份
*/
export function readReleasePackageIdentity(packageFile, expected) {
const archive = unzipSync(new Uint8Array(readFileSync(packageFile)))
const manifestBytes = archive['rn-manifest.json']
if (!manifestBytes) throw new Error('plugin package manifest is missing')
let manifest
try {
manifest = JSON.parse(strFromU8(manifestBytes))
} catch {
throw new Error('plugin package manifest is invalid JSON')
}
const moduleId = requiredString(manifest, 'moduleId')
const platform = requiredString(manifest, 'platform')
const moduleVersion = requiredString(manifest, 'version')
const appVersion = requiredString(manifest, 'appVersion')
const buildId = requiredString(manifest, 'buildId')
const bundleFile = requiredString(manifest, 'bundleFile')
const bundleHash = requiredString(manifest, 'bundleSha256')
const bundleFormat = requiredString(manifest, 'bundleFormat')
const nativeBaselineId = requiredString(manifest, 'builtAgainstNativeBaselineId')
const appVersionRange = requiredString(manifest, 'appVersionRange')
const minNativeApiLevel = manifest.minNativeApiLevel
if (buildId === 'development') {
throw new Error('plugin package was built without a release buildId; rebuild before publishing')
}
if (expected.moduleId !== moduleId) {
throw new Error(
`plugin package moduleId mismatch: expected ${expected.moduleId}, got ${moduleId}`,
)
}
if (expected.platform !== platform) {
throw new Error(
`plugin package platform mismatch: expected ${expected.platform}, got ${platform}`,
)
}
if (expected.moduleVersion !== moduleVersion) {
throw new Error(
`plugin package version mismatch: expected ${expected.moduleVersion}, got ${moduleVersion}`,
)
}
if (expected.appVersion !== appVersion) {
throw new Error(
`plugin package appVersion mismatch: expected ${expected.appVersion}, got ${appVersion}`,
)
}
if (!/^[a-f0-9]{64}$/i.test(bundleHash)) {
throw new Error('plugin package bundleSha256 is invalid')
}
if (!Number.isInteger(minNativeApiLevel) || minNativeApiLevel < 1) {
throw new Error('plugin package minNativeApiLevel is invalid')
}
if (
manifest.commonVersionRange !== undefined &&
(typeof manifest.commonVersionRange !== 'string' || !manifest.commonVersionRange.trim())
) {
throw new Error('plugin package commonVersionRange is invalid')
}
const bundleBytes = archive[bundleFile]
if (!bundleBytes) throw new Error(`plugin package bundle is missing: ${bundleFile}`)
const actualBundleHash = createHash('sha256').update(bundleBytes).digest('hex')
if (actualBundleHash !== bundleHash.toLowerCase()) {
throw new Error('plugin package bundleSha256 does not match bundle content')
}
return {
manifest,
moduleId,
platform,
moduleVersion,
appVersion,
buildId,
bundleHash: actualBundleHash,
bundleFormat,
nativeBaselineId,
appVersionRange,
commonVersionRange: manifest.commonVersionRange,
minNativeApiLevel,
}
}