feat: migrate to turbo (#22)

* feat: migrate top turbo

* ci: ci test

* fix: fix codeql issues

* feat: ci test

* chore: lint

* chore: misc changes

* feat: rename vite helpers

* feat: use fetch to handle assets

* feat: update directory

* feat: fetch charword table

* feat: migrate download game data and detect missing voice files

* feat: symlink relative path

* feat: finish wrangler upload

* feat: migrate wrangler download

* feat: finish

* chore: auto update

* ci: update ci

* ci: update ci

---------

Co-authored-by: Halyul <Halyul@users.noreply.github.com>
This commit is contained in:
Haoyu Xu
2025-02-22 15:11:30 +08:00
committed by GitHub
parent 17c61ce5d4
commit d6e7bc20d3
352 changed files with 12911 additions and 9411 deletions

View File

@@ -0,0 +1,48 @@
import sharp from 'sharp'
import path from 'path'
export const process = async (filename, maskFilename, extractedDir) => {
const image = sharp(path.join(extractedDir, filename)).removeAlpha()
const imageMeta = await image.metadata()
const imageBuffer = await image.toBuffer()
const mask = await sharp(path.join(extractedDir, maskFilename))
.extractChannel('blue')
.resize(imageMeta.width, imageMeta.height)
.toBuffer()
return sharp(imageBuffer).joinChannel(mask).toBuffer()
}
export const crop = async (buffer, rect) => {
const left = rect.y
const top = rect.x
const width = rect.h
const height = rect.w
const rotate = rect.rotate === 0 ? -90 : 0
const newImage = await sharp(buffer)
.rotate(90)
.extract({ left: left, top: top, width: width, height: height })
.resize(width, height)
.extract({ left: 0, top: 0, width: width, height: height })
.toBuffer()
return await sharp(newImage).rotate(rotate).toBuffer()
}
export const toBuffer = async (filename, extractedDir) => {
const file = path.join(extractedDir, filename)
const { data, info } = await sharp(file)
.raw()
.toBuffer({ resolveWithObject: true })
const { width, height, channels } = info
const pixelArray = new Uint8ClampedArray(data.buffer)
for (let i = 0; i < pixelArray.length; i += 4) {
let alpha = pixelArray[i + 3] / 255
pixelArray[i + 0] = pixelArray[i + 0] * alpha
pixelArray[i + 1] = pixelArray[i + 1] * alpha
pixelArray[i + 2] = pixelArray[i + 2] * alpha
}
return await sharp(pixelArray, { raw: { width, height, channels } })
.png()
.toBuffer()
}

View File

@@ -0,0 +1,7 @@
export function generate(values) {
return values
.map((value) => {
return `VITE_${value.key.toUpperCase()}=${value.value}`
})
.join('\n')
}

View File

@@ -0,0 +1,43 @@
import process from 'node:process'
export const parse = (args) => {
const envVars = process.env
const argKeys = Object.keys(args)
const values = {}
argKeys.map((key) => {
let noInput = false
let value,
type = args[key].type || 'string',
defaultVal = args[key].default,
multiple = args[key].multiple || false,
short = args[key].short
value = envVars[key] || envVars[short]
if (!value) noInput = true
value = noInput ? defaultVal : value
if (noInput) {
values[key] = value
} else {
value = multiple ? value.split(',') : value
if (multiple) {
values[key] = []
value.map((item) => {
values[key].push(typeCast(type, item))
})
} else {
values[key] = typeCast(type, value)
}
}
})
return values
}
const typeCast = (type, value) => {
switch (type) {
case 'number':
return Number(value)
case 'boolean':
return Boolean(value)
default:
return value
}
}

View File

@@ -0,0 +1,6 @@
export const handle = (err) => {
if (err.length > 0) {
const str = `${err.length} error${err.length > 1 ? 's were' : ' was'} found:\n${err.join('\n')}`
throw new Error(str)
}
}

166
packages/libs/libs/file.js Normal file
View File

@@ -0,0 +1,166 @@
import fs, { promises as fsP } from 'fs'
import path from 'path'
import yauzl from 'yauzl-promise'
import yazl from 'yazl'
export async function write(content, filePath) {
mkdir(path.dirname(filePath))
return await fsP.writeFile(filePath, content, { flag: 'w' })
}
export function writeSync(content, filePath) {
mkdir(path.dirname(filePath))
return fs.writeFileSync(filePath, content, { flag: 'w' })
}
export async function read(filePath, encoding = 'utf8') {
return await fsP.readFile(filePath, encoding, { flag: 'r' })
}
export function readSync(filePath, encoding = 'utf8') {
if (exists(filePath)) {
return fs.readFileSync(filePath, encoding, { flag: 'r' })
}
return null
}
export function exists(filePath) {
return fs.existsSync(filePath)
}
export function rmdir(dir) {
if (exists(dir)) {
fs.rmSync(dir, { recursive: true })
}
}
export function rm(dir) {
if (exists(dir)) {
fs.rmSync(dir, { recursive: true })
}
}
export function mkdir(dir) {
if (!exists(dir)) {
fs.mkdirSync(dir, { recursive: true })
}
}
export async function copy(
sourcePath,
targetPath,
mode = fs.constants.COPYFILE_FICLONE
) {
if (!exists(sourcePath)) {
console.warn(`Source file ${sourcePath} does not exist.`)
return
}
mkdir(path.dirname(targetPath))
return await fsP.copyFile(sourcePath, targetPath, mode)
}
export async function copyDir(
sourcePath,
targetPath,
mode = fs.constants.COPYFILE_FICLONE
) {
if (!exists(sourcePath)) {
console.warn(`Source file ${sourcePath} does not exist.`)
return
}
mkdir(targetPath)
return await fsP.cp(sourcePath, targetPath, { recursive: true, mode })
}
export function appendSync(content, filePath) {
return fs.appendFileSync(filePath, content, 'utf8')
}
export function readdirSync(dir) {
if (!exists(dir)) {
console.warn(`Source ${dir} does not exist.`)
return []
}
return fs.readdirSync(dir)
}
export function fileTypeSync(dir) {
if (!exists(dir)) {
console.warn(`Source ${dir} does not exist.`)
return null
}
return fs.statSync(dir).isDirectory() ? 'dir' : 'file'
}
export const symlink = (source, target) => {
if (!exists(source)) {
console.warn(`Source ${source} does not exist.`)
return
}
if (exists(target)) {
fs.unlinkSync(target)
}
mkdir(path.dirname(target))
const relative = path.relative(path.dirname(target), source)
fs.symlinkSync(relative, target)
}
export const symlinkAll = (source, target) => {
const files = readdirSync(source)
files.map((file) => {
symlink(path.join(source, file), path.join(target, file))
})
}
export const mv = (source, target) => {
if (!exists(source)) {
console.warn(`Source file ${source} does not exist.`)
return
}
if (exists(target)) {
rmdir(target)
}
mkdir(target)
fs.renameSync(source, target)
}
export const cpSync = (
source,
target,
opts = {
dereference: false,
}
) => {
if (!exists(source)) {
console.warn(`Source file ${source} does not exist.`)
return
}
if (fs.statSync(source).isFile()) {
mkdir(path.dirname(target))
} else {
mkdir(target)
}
fs.cpSync(source, target, {
recursive: true,
dereference: opts.dereference,
})
}
export const relative = (source, target) => {
if (!exists(source)) {
console.warn(`Source file ${source} does not exist.`)
return
}
return path.relative(source, target)
}
export const size = (source) => {
if (!exists(source)) {
console.warn(`Source file ${source} does not exist.`)
return
}
return fs.statSync(source).size
}
export const unzip = yauzl
export const zip = yazl

View File

@@ -0,0 +1,19 @@
import fs from 'fs'
import path from 'path'
import { parse } from 'yaml'
export function read(file_dir, customTags = []) {
const include = {
identify: (value) => value.startsWith('!include'),
tag: '!include',
resolve(str) {
const dir = path.resolve(path.dirname(file_dir), str)
const data = read(dir)
return data
},
}
const file = fs.readFileSync(file_dir, 'utf8')
return parse(file, {
customTags: [include, ...customTags],
})
}