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:
48
packages/libs/libs/alpha_composite.js
Normal file
48
packages/libs/libs/alpha_composite.js
Normal 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()
|
||||
}
|
||||
7
packages/libs/libs/env.js
Normal file
7
packages/libs/libs/env.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export function generate(values) {
|
||||
return values
|
||||
.map((value) => {
|
||||
return `VITE_${value.key.toUpperCase()}=${value.value}`
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
43
packages/libs/libs/env_parser.js
Normal file
43
packages/libs/libs/env_parser.js
Normal 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
|
||||
}
|
||||
}
|
||||
6
packages/libs/libs/error.js
Normal file
6
packages/libs/libs/error.js
Normal 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
166
packages/libs/libs/file.js
Normal 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
|
||||
19
packages/libs/libs/yaml.js
Normal file
19
packages/libs/libs/yaml.js
Normal 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],
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user