check-github-open-graph-image.mjs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { dirname, resolve } from 'node:path'
  2. import { spawnSync } from 'node:child_process'
  3. import { fileURLToPath } from 'node:url'
  4. const scriptDir = dirname(fileURLToPath(import.meta.url))
  5. const sourceRoot = resolve(scriptDir, '..')
  6. const args = process.argv.slice(2)
  7. const optionValue = (name, fallback) => {
  8. const prefix = `${name}=`
  9. const match = args.find(arg => arg.startsWith(prefix))
  10. return match ? match.slice(prefix.length) : fallback
  11. }
  12. const owner = optionValue('--owner', 'flyfish-dev')
  13. const name = optionValue('--repo', 'file-viewer')
  14. const result = spawnSync(
  15. 'gh',
  16. [
  17. 'api',
  18. 'graphql',
  19. '-F',
  20. `owner=${owner}`,
  21. '-F',
  22. `name=${name}`,
  23. '-f',
  24. 'query=query($owner:String!, $name:String!) { repository(owner:$owner, name:$name) { openGraphImageUrl usesCustomOpenGraphImage } }'
  25. ],
  26. {
  27. cwd: sourceRoot,
  28. encoding: 'utf8',
  29. stdio: 'pipe'
  30. }
  31. )
  32. if (result.status !== 0) {
  33. const details = [result.stderr, result.stdout].filter(Boolean).join('\n')
  34. throw new Error(`Failed to read GitHub Open Graph URL.${details ? `\n${details}` : ''}`)
  35. }
  36. const payload = JSON.parse(result.stdout || '{}')
  37. const repository = payload.data?.repository
  38. const url = repository?.openGraphImageUrl
  39. const usesCustomOpenGraphImage = Boolean(repository?.usesCustomOpenGraphImage)
  40. if (!url) {
  41. throw new Error('GitHub did not return an Open Graph image URL.')
  42. }
  43. const response = await fetch(url)
  44. if (!response.ok) {
  45. throw new Error(`Failed to fetch Open Graph image: ${response.status} ${response.statusText}`)
  46. }
  47. const bytes = Buffer.from(await response.arrayBuffer())
  48. let width = null
  49. let height = null
  50. let type = 'unknown'
  51. if (bytes.subarray(0, 8).toString('hex') === '89504e470d0a1a0a') {
  52. type = 'png'
  53. width = bytes.readUInt32BE(16)
  54. height = bytes.readUInt32BE(20)
  55. }
  56. console.log(`Repository: ${owner}/${name}`)
  57. console.log(`Open Graph URL: ${url}`)
  58. console.log(`Uses custom Open Graph image: ${usesCustomOpenGraphImage ? 'yes' : 'no'}`)
  59. console.log(`Image type: ${type}`)
  60. console.log(`Image size: ${width && height ? `${width}x${height}` : 'unknown'}`)
  61. if (usesCustomOpenGraphImage) {
  62. console.log('Status: GitHub reports a custom social preview image is configured.')
  63. } else {
  64. console.log('Status: GitHub reports no custom social preview image. Upload .github/social-preview.png in Settings -> Social preview.')
  65. }