mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
57 lines
2.5 KiB
TypeScript
57 lines
2.5 KiB
TypeScript
/**
|
||
* Turns an export of first-party custom avatar items into a D1 migration that seeds the
|
||
* `custom_avatar_item` table with them, the way `apps/rooms/migrations/0002_import_rooms.sql`
|
||
* seeds the rooms.
|
||
*
|
||
* bun apps/api/scripts/import-custom-avatar-items.ts <export.json> <NNNN>
|
||
*
|
||
* `export.json` is a JSON array of `CustomAvatarItem` records as the official service serves
|
||
* them (a `{ Results: [...] }` page or a single record are accepted too). `NNNN` is the
|
||
* migration number; the file is written to `apps/api/migrations/NNNN_import_custom_avatar_items.sql`.
|
||
*
|
||
* For a load that needs no migration and no deploy — the usual case — use
|
||
* `just admin cai-load` instead, which runs the same statements straight against a database.
|
||
* The statements come from src/custom-avatar-items-load.ts either way: each record stored as
|
||
* the row's JSON minus `PurchaseInfo`, with `CreatorAccountId` forced to the Coach account (1)
|
||
* and each save's `ThumbnailFileName` put under `avatar/`, an existing id REPLACED, nothing
|
||
* deleted.
|
||
*
|
||
* The export's `Price` is mostly 0; run `price-custom-avatar-items.ts` against it first to fill
|
||
* in prices from the storefront dump.
|
||
*
|
||
* The saves name assetbundles by bare filename; the migration does nothing about those files,
|
||
* which have to be served from wherever the client fetches them.
|
||
*/
|
||
|
||
import { readFileSync, writeFileSync } from 'node:fs'
|
||
|
||
import {
|
||
customAvatarItemUpsertStatements,
|
||
readCustomAvatarItemExport,
|
||
} from '../src/custom-avatar-items-load'
|
||
|
||
const [input, number] = process.argv.slice(2)
|
||
if (!input || !number || !/^\d{4}$/.test(number)) {
|
||
console.error('usage: bun apps/api/scripts/import-custom-avatar-items.ts <export.json> <NNNN>')
|
||
process.exit(2)
|
||
}
|
||
|
||
// Tolerate the BOM a .NET export carries (`JSON.parse` rejects U+FEFF).
|
||
const records = readCustomAvatarItemExport(
|
||
JSON.parse(readFileSync(input, 'utf8').replace(/^/, ''))
|
||
)
|
||
const lines = [
|
||
`-- Seed first-party custom avatar items (${records.length} records) from ${input.split('/').pop()}.`,
|
||
'-- Generated by apps/api/scripts/import-custom-avatar-items.ts — do not edit by hand.',
|
||
'-- Each record is the official `CustomAvatarItem`, filed under the Coach account (CreatorAccountId 1);',
|
||
'-- an existing id is replaced.',
|
||
'',
|
||
...customAvatarItemUpsertStatements(records),
|
||
]
|
||
|
||
const out = decodeURIComponent(
|
||
new URL(`../migrations/${number}_import_custom_avatar_items.sql`, import.meta.url).pathname
|
||
)
|
||
writeFileSync(out, lines.join('\n') + '\n')
|
||
console.log(`wrote ${records.length} records to ${out}`)
|