Files
mpcfill-pdf/card.js
orion kindel ae5193700a init
2025-11-06 15:16:08 -06:00

80 lines
1.8 KiB
JavaScript

import * as Log from './log.js'
import * as Cache from './cache.js'
import * as Drive from './drive'
import * as Mpc from './mpcfill.js'
import Sharp from 'sharp'
/**
* @typedef {{ pixels: number, inches: number, pt: number }} Dim
*/
/**
* @typedef
* {{
* id: string,
* mpc: Mpc.Card,
* dump: Mpc.XMLDumpCard,
* width: Dim,
* height: Dim,
* type: 'jpg' | 'png'
* }}
* Card
*/
/**
* @param {{ id: string, driveAuth: string, dump: import('./mpcfill.js').XMLDumpCard }}
* @returns {Promise<Card>}
*/
const get = async ({id, driveAuth, dump}) => {
try {
const file = await Cache.tryGetJson('drive-' + id, () => Drive.info(driveAuth, id))
const bytes = await Cache.tryGet(id, () => Drive.download(driveAuth, id))
const mpc = await Cache.tryGetJson('mpcfill-' + id, async () => (await Mpc.cards(id))[id])
if (!mpc) throw `Not an MPCFill id: ${id}`
const image = Sharp(bytes)
const {width, height} = await image.metadata()
const widthInch = width / mpc.dpi
const heightInch = height / mpc.dpi
const type =
file.mimeType === 'image/jpeg'
? 'jpg'
: file.mimeType === 'image/png'
? 'png'
: (() => {
throw `Unsupported MIME type ${file.mimeType}`
})();
return {
id,
mpc,
dump,
width: {
pixels: width,
inches: widthInch,
pt: widthInch * 72
},
type,
height: {
pixels: height,
inches: heightInch,
pt: heightInch * 72
}
}
} catch (e) {
Log.error(`card with id=${id} ${e.toString()}`)
return undefined
}
}
/**
* @param {{ id: string, driveAuth: string }}
* @returns {Promise<ArrayBuffer>}
*/
const image =
({id, driveAuth}) => Cache.tryGet(id, () => Drive.download(driveAuth, id))
export { get, image }