mirror of
https://github.com/RSSNext/Folo.git
synced 2026-10-26 02:18:12 +08:00
Store copy for 12 listing locales, plus the tooling that captures the apps with a demo account and renders the App Store, Google Play and Microsoft Store screenshots and the README banner. Raw captures and rendered images stay out of the repository (store-assets/.gitignore). store-assets is a private workspace package, so playwright, sharp, pathe and the other script dependencies are declared instead of resolved through hoisting, and turbo typechecks it. The lockfile only gains its importer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
// Checks the rendered store images: every deck has one file per slide for
|
|
// every store locale, at the store size and without an alpha channel.
|
|
// tsx store-assets/scripts/check-output.ts
|
|
import { readdir } from "node:fs/promises"
|
|
|
|
import { join } from "pathe"
|
|
import sharp from "sharp"
|
|
|
|
import { decks } from "../src/decks"
|
|
import { listingLocales } from "../src/locales"
|
|
|
|
const root = join(import.meta.dirname, "..", "output")
|
|
const problems: string[] = []
|
|
let files = 0
|
|
|
|
const check = async (path: string, width: number, height: number) => {
|
|
const meta = await sharp(path)
|
|
.metadata()
|
|
.catch(() => null)
|
|
if (!meta) {
|
|
problems.push(`${path}: missing`)
|
|
return
|
|
}
|
|
files++
|
|
if (meta.width !== width || meta.height !== height || meta.hasAlpha) {
|
|
problems.push(`${path}: ${meta.width}x${meta.height}${meta.hasAlpha ? " with alpha" : ""}`)
|
|
}
|
|
}
|
|
|
|
for (const deck of decks) {
|
|
const { width, height } = deck.outputs[0]!
|
|
for (const locale of listingLocales) {
|
|
const storeLocales =
|
|
deck.store === "app-store"
|
|
? locale.appStore
|
|
: deck.store === "google-play"
|
|
? locale.googlePlay
|
|
: locale.microsoftStore
|
|
for (const storeLocale of storeLocales) {
|
|
const dir = join(root, deck.id, storeLocale)
|
|
const list = (await readdir(dir).catch(() => [])).filter((f) => f.endsWith(".png"))
|
|
if (list.length !== deck.slides.length) {
|
|
problems.push(`${deck.id}/${storeLocale}: ${list.length} of ${deck.slides.length} slides`)
|
|
}
|
|
for (const file of list) await check(join(dir, file), width, height)
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const locale of listingLocales) {
|
|
for (const storeLocale of locale.googlePlay) {
|
|
await check(
|
|
join(root, "google-play/feature-graphic", storeLocale, "feature-graphic.png"),
|
|
1024,
|
|
500,
|
|
)
|
|
}
|
|
}
|
|
await check(join(root, "microsoft-store/extras/super-hero-art.png"), 3840, 2160)
|
|
await check(join(root, "microsoft-store/extras/store-logo-300.png"), 300, 300)
|
|
|
|
for (const problem of problems) console.log(problem)
|
|
console.log(`${files} images checked, ${problems.length} problems`)
|
|
process.exitCode = problems.length > 0 ? 1 : 0
|