feat: migrated packages to ts

This commit is contained in:
Haoyu Xu
2025-05-02 02:27:42 +08:00
parent 0af0c785d4
commit 8f6f537c81
111 changed files with 3166 additions and 1155 deletions

View File

@@ -1,3 +1,27 @@
import baseConfig from '@aklive2d/eslint-config'
import { tsConfig } from '@aklive2d/eslint-config'
import tseslint from 'typescript-eslint'
import globals from 'globals'
/** @type {import('eslint').Config} */
export default [...baseConfig]
export default tseslint.config(
...tsConfig,
{
ignores: ['dist', 'data'],
},
{
files: ['**/*.js', '**/*.ts'],
languageOptions: {
ecmaVersion: 2022,
globals: {
...globals.node,
},
},
rules: {
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
],
},
}
)

View File

@@ -11,11 +11,18 @@ import * as showcaseDirs from '@aklive2d/showcase'
import { OPERATOR_SOURCE_FOLDER as OPERATOR_DATA_DIR } from '@aklive2d/operator'
import { DATA_DIR as MUSIC_DATA_DIR } from '@aklive2d/music'
import { BACKGROUND_DIR as BACKGROUND_DATA_DIR } from '@aklive2d/background'
import type {
GenerateDirTreeOpts,
DirTree,
LookupTable,
HashItem,
DownloadList,
} from './types.ts'
const dataDir = path.join(import.meta.dirname, config.dir_name.data)
const distDir = path.join(import.meta.dirname, config.dir_name.dist)
const getHash = (filePath) => {
const getHash = (filePath: string): Promise<string> => {
return new Promise((res) => {
const hash = crypto.createHash('md5')
const rStream = fs.createReadStream(filePath)
@@ -28,7 +35,7 @@ const getHash = (filePath) => {
})
}
const isToIgnore = (file) => {
const isToIgnore = (file: string) => {
switch (file) {
case '.DS_Store':
case 'index.json':
@@ -39,22 +46,19 @@ const isToIgnore = (file) => {
}
const generateDirTree = async (
dir,
opts = {
baseDir: null,
dir: string,
opts: GenerateDirTreeOpts = {
calculateHash: false,
lookupTable: null,
lookupDir: null,
}
) => {
): Promise<DirTree | null> => {
if (!opts.baseDir) opts.baseDir = dir
const files = fileLib.readdirSync(dir)
let tree = {
const tree = {
name: path.basename(dir),
type: 'dir',
path: fileLib.relative(opts.baseDir, dir),
children: [],
}
children: [] as DirTree[],
} as DirTree
for (const file of files) {
if (isToIgnore(file)) {
continue
@@ -63,17 +67,17 @@ const generateDirTree = async (
const relativePath = fileLib.relative(opts.baseDir, filePath)
const dirType = fileLib.fileTypeSync(filePath)
if (dirType === 'dir') {
const children = await generateDirTree(filePath, {
const children = (await generateDirTree(filePath, {
...opts,
baseDir: opts.baseDir,
})
})) as DirTree
if (children) tree.children.push(children)
} else {
const item = {
name: file,
path: relativePath,
type: 'file',
}
} as DirTree
if (opts.calculateHash) {
item.hash = await getHash(filePath)
if (
@@ -81,15 +85,15 @@ const generateDirTree = async (
opts.lookupTable &&
opts.lookupDir
) {
const children = opts.lookupTable[relativePath]
const children = opts.lookupTable[relativePath!]
if (children) {
let hashes = []
const hashes = [] as HashItem[]
await Promise.all(
children.map(async (child) => {
hashes.push({
path: child.path,
hash: await getHash(
path.join(opts.lookupDir, child.path)
path.join(opts.lookupDir!, child.path)
),
})
})
@@ -107,10 +111,13 @@ const generateDirTree = async (
return tree
}
const flattenChildren = (tree, prepend = null) => {
const flattenChildren = (
tree: DirTree,
prepend: string | null = null
): DirTree | DirTree[] => {
const head = prepend ? `${prepend}/` : ''
if (tree.type === 'dir') {
return tree.children.flatMap((child) => {
return tree.children.flatMap((child: DirTree) => {
return flattenChildren(child, `${head}${tree.name}`)
})
} else {
@@ -121,7 +128,12 @@ const flattenChildren = (tree, prepend = null) => {
}
}
const createZipFile = (name, files, sourceDir, targetDir) => {
const createZipFile = (
name: string,
files: DirTree[],
sourceDir: string,
targetDir: string
) => {
const zipfile = new fileLib.zip.ZipFile()
files.map((child) => {
zipfile.addFile(path.join(sourceDir, child.path), child.name)
@@ -132,19 +144,19 @@ const createZipFile = (name, files, sourceDir, targetDir) => {
)
}
const generateUploadDist = (item, depth = -1) => {
const generateUploadDist = (item: DirTree, depth = -1) => {
const baseDir = path.join(distDir, path.dirname(item.path))
fileLib.mkdir(baseDir)
if (item.type === 'dir' && depth === 1) {
// shall zip dir
const children = flattenChildren(item)
const children = flattenChildren(item) as DirTree[]
let count = 0,
filesToZip = [],
filesToZip = [] as DirTree[],
size = 0
const ret = {}
const ret = {} as LookupTable
for (const child of children) {
const currentsize = fileLib.size(path.join(dataDir, child.path))
if (size + currentsize >= config.total_size) {
if (size + currentsize! >= config.total_size) {
createZipFile(
`${item.name}-${count}`,
[...filesToZip],
@@ -154,10 +166,10 @@ const generateUploadDist = (item, depth = -1) => {
ret[`${item.path}-${count}.zip`] = filesToZip
count++
filesToZip = [child]
size = currentsize
size = currentsize!
} else {
filesToZip.push(child)
size += currentsize
size += currentsize!
}
}
if (filesToZip.length !== 0) {
@@ -190,7 +202,7 @@ const generateUploadDist = (item, depth = -1) => {
}
}
const wranglerDeploy = (distDir, project_name) => {
const wranglerDeploy = (distDir: string, project_name: string) => {
const wrangler = spawn('pnpm', [
'wrangler',
'pages',
@@ -211,20 +223,20 @@ const wranglerDeploy = (distDir, project_name) => {
}
export const upload = async () => {
const tree = await generateDirTree(dataDir)
const tree = (await generateDirTree(dataDir)) as DirTree
let ret = {}
if (!tree) throw new Error('No data to upload.')
tree.children
.map((child) => {
.map((child: DirTree) => {
ret = {
...ret,
...generateUploadDist(child, 3),
}
})
.filter((item) => typeof item !== 'undefined')
.filter((item) => typeof item !== 'undefined') // ?
const index = await generateDirTree(distDir, {
calculateHash: true,
lookupTable: ret,
lookupTable: ret as LookupTable,
lookupDir: dataDir,
})
fileLib.writeSync(
@@ -234,7 +246,11 @@ export const upload = async () => {
wranglerDeploy(distDir, config.akassets.project_name)
}
const generateDownloadList = (data, baseDir, baseUrl = '') => {
const generateDownloadList = (
data: DirTree,
baseDir: string,
baseUrl = ''
): DownloadList | DownloadList[] => {
if (data.type === 'dir') {
const curDir = path.join(baseDir, data.path)
fileLib.mkdir(curDir)
@@ -246,6 +262,8 @@ const generateDownloadList = (data, baseDir, baseUrl = '') => {
baseUrl + data.name + '/'
)
})
} else {
return []
}
} else {
const base = {
@@ -253,7 +271,7 @@ const generateDownloadList = (data, baseDir, baseUrl = '') => {
url: `${config.akassets.url}/${baseUrl + data.name.replace(/#/g, '%23')}`,
target: path.join(baseDir, data.path),
hash: data.hash,
}
} as DownloadList
if (data.name.endsWith('.zip') && data.hashes) {
base.children = data.hashes.map((hash) => {
return {
@@ -274,7 +292,7 @@ export const download = async () => {
const indexFile = `${config.akassets.url}/${config.module.wrangler.index_json}`
const resp = await fetch(indexFile)
const data = await resp.json()
const data = (await resp.json()) as DirTree
let list = data.children.flatMap((child) => {
return generateDownloadList(child, dataDir)
})
@@ -283,12 +301,12 @@ export const download = async () => {
interval: 500,
})
while (list.length > 0) {
const retry = []
const retry = [] as DownloadList[]
await Promise.all(
list.map(
throttle(async (file) => {
let isExists = true
let relativePath = fileLib.relative(dataDir, file.target)
const relativePath = fileLib.relative(dataDir, file.target)
if (file.name.endsWith('.zip') && file.children) {
for (
let i = 0;
@@ -315,7 +333,7 @@ export const download = async () => {
[
{
url: file.url,
name: relativePath,
name: relativePath!,
},
],
path.dirname(file.target)

View File

@@ -1,7 +1,7 @@
{
"name": "@aklive2d/wrangler",
"version": "0.0.0",
"main": "index.js",
"main": "index.ts",
"type": "module",
"license": "MIT",
"dependencies": {
@@ -15,5 +15,10 @@
"@aklive2d/operator": "workspace:*",
"@aklive2d/music": "workspace:*",
"@aklive2d/background": "workspace:*"
},
"peerDependencies": {
"globals": ">=16.0.0",
"typescript-eslint": ">=8.31.1",
"typescript": ">=5.8.2"
}
}

View File

@@ -1,5 +1,5 @@
import { envParser } from '@aklive2d/libs'
import { upload, download, deploy } from './index.js'
import { upload, download, deploy } from './index.ts'
async function main() {
const { mode } = envParser.parse({

View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "ES2024",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2024", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["**/*"],
"exclude": ["dist/**/*", "data/**/*"]
}

View File

@@ -0,0 +1,35 @@
export type GenerateDirTreeOpts = {
baseDir?: string
calculateHash?: boolean
lookupTable?: LookupTable
lookupDir?: string
}
export interface DirTree {
name: string
type: 'dir' | 'file'
path: string
children: DirTree[]
hash?: string
hashes?: HashItem[]
}
export type LookupTable = {
[key: string]: DirTree[]
}
export type HashItem = {
path: string
hash: string
}
export type DownloadList = {
name: string
url: string
target: string
hash: string
children?: {
target: string
hash: string
}[]
}