/* eslint-disable import/no-dynamic-require,global-require */ import { execSync } from 'node:child_process'; import { copyFileSync, readFileSync, writeFileSync } from 'node:fs'; import { resolve } from 'node:path'; const options = process.argv.slice(2).reduce((args, arg) => { const [key, value] = arg.split('='); args[key.substring(2)] = value ?? true; return args; }, {} as any); function copy(filename: string, from: string, to: string): void { copyFileSync(resolve(from, filename), resolve(to, filename)); } function rewrite(path: string, replacer: (from: string) => string): void { try { const file = readFileSync(path).toString(); const replaced = replacer(file); writeFileSync(path, replaced); } catch { // not found } } let rootVersion: string; function getRootVersion(bump = true): string { if (rootVersion) { return rootVersion; } rootVersion = require(resolve(root, './lerna.json')).version.replace(/^(\d+\.\d+\.\d+)-?.*$/, '$1'); if (bump) { const parts = rootVersion.split('.'); parts[2] = `${+parts[2] + 1}`; rootVersion = parts.join('.'); } return rootVersion; } /** * Checks next dev version number based on the `crawlee` meta package via `npm show`. * We always use this package, so we ensure the version is the same for each package in the monorepo. */ function getNextVersion() { const versions: string[] = []; try { const versionString = execSync(`npm show @crawlee/core versions --json`, { encoding: 'utf8', stdio: 'pipe' }); const parsed = JSON.parse(versionString) as string[]; versions.push(...parsed); } catch { // the package might not have been published yet } const version = getRootVersion(); if (versions.some((v) => v === version)) { console.error( `before-deploy: A release with version ${version} already exists. Please increment version accordingly.`, ); process.exit(1); } const preid = options.preid ?? 'alpha'; const prereleaseNumbers = versions .filter((v) => v.startsWith(`${version}-${preid}.`)) .map((v) => Number(v.match(/\.(\d+)$/)?.[1])); const lastPrereleaseNumber = Math.max(-1, ...prereleaseNumbers); return `${version}-${preid}.${lastPrereleaseNumber + 1}`; } // as we publish only the dist folder, we need to copy some meta files inside (readme/license/package.json) // also changes paths inside the copied `package.json` (`dist/index.js` -> `index.js`) const root = resolve(__dirname, '..'); const target = resolve(process.cwd(), 'dist'); const pkgPath = resolve(process.cwd(), 'package.json'); if (options.canary) { const pkgJson = require(pkgPath); const nextVersion = getNextVersion(); pkgJson.version = nextVersion; for (const dep of Object.keys(pkgJson.dependencies)) { if (dep.startsWith('@crawlee/') || dep === 'crawlee') { const prefix = pkgJson.dependencies[dep].startsWith('^') ? '^' : ''; pkgJson.dependencies[dep] = prefix + nextVersion; } } console.info(`canary: setting version to ${nextVersion}`); writeFileSync(pkgPath, `${JSON.stringify(pkgJson, null, 4)}\n`); } if (options['pin-versions']) { const pkgJson = require(pkgPath); const version = getRootVersion(false); for (const dep of Object.keys(pkgJson.dependencies ?? {})) { if (dep.startsWith('@crawlee/') || dep === 'crawlee') { pkgJson.dependencies[dep] = version; } } console.info(`pin-versions: version ${version}`, pkgJson.dependencies); writeFileSync(pkgPath, `${JSON.stringify(pkgJson, null, 4)}\n`); } copy('README.md', root, target); copy('LICENSE.md', root, target); copy('package.json', process.cwd(), target); rewrite(resolve(target, 'package.json'), (pkg) => { return pkg.replace(/dist\//g, '').replace(/src\/(.*)\.ts/g, '$1.js'); }); rewrite(resolve(target, 'utils.js'), (pkg) => pkg.replace('../package.json', './package.json'));