feat: migrated packages to ts
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -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: '^_' },
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -7,17 +7,26 @@ import operators, {
|
||||
getOperatorAlternativeId,
|
||||
OPERATOR_SOURCE_FOLDER,
|
||||
} from '@aklive2d/operator'
|
||||
import type {
|
||||
Region,
|
||||
CharwordTableJson,
|
||||
OperatorCharwordTable,
|
||||
CharwordTable,
|
||||
VoiceRegionObject,
|
||||
InfoRegionObject,
|
||||
} from './types.ts'
|
||||
|
||||
// zh_TW uses an older version of charword_table.json
|
||||
// zh_TW is removed
|
||||
const REGIONS = ['zh_CN', 'en_US', 'ja_JP', 'ko_KR']
|
||||
const REGIONS: Region[] = ['zh_CN', 'en_US', 'ja_JP', 'ko_KR']
|
||||
|
||||
const REGION_URLS = {
|
||||
zh_CN: 'Kengxxiao/ArknightsGameData',
|
||||
en_US: 'Kengxxiao/ArknightsGameData_YoStar',
|
||||
ja_JP: 'Kengxxiao/ArknightsGameData_YoStar',
|
||||
ko_KR: 'Kengxxiao/ArknightsGameData_YoStar',
|
||||
}
|
||||
const DEFAULT_REGION = REGIONS[0]
|
||||
const DEFAULT_REGION: Region = REGIONS[0]
|
||||
export const defaultRegion = DEFAULT_REGION.replace('_', '-')
|
||||
const NICKNAME = {
|
||||
zh_CN: '博士',
|
||||
@@ -34,22 +43,18 @@ const AUTO_UPDATE_FOLDER = path.resolve(
|
||||
import.meta.dirname,
|
||||
config.dir_name.auto_update
|
||||
)
|
||||
const CHARWORD_TABLE_FILE = path.resolve(
|
||||
AUTO_UPDATE_FOLDER,
|
||||
config.module.charword_table.charword_table_json
|
||||
)
|
||||
const CHARWORD_TABLE = JSON.parse(file.readSync(CHARWORD_TABLE_FILE)) || {}
|
||||
|
||||
const DIST_DIR = path.resolve(import.meta.dirname, config.dir_name.dist)
|
||||
|
||||
export const lookup = (operatorName) => {
|
||||
const lookup = (operatorName: string, charwordTable: CharwordTable) => {
|
||||
const operatorId = getOperatorId(operators[operatorName].filename)
|
||||
const operatorBlock = CHARWORD_TABLE[operatorId]
|
||||
const operatorBlock = charwordTable[operatorId]
|
||||
return operatorBlock.ref
|
||||
? CHARWORD_TABLE[operatorBlock.alternativeId]
|
||||
? charwordTable[operatorBlock.alternativeId]
|
||||
: operatorBlock
|
||||
}
|
||||
|
||||
const getDistDir = (name) => {
|
||||
const getDistDir = (name: string) => {
|
||||
return path.join(
|
||||
DIST_DIR,
|
||||
name,
|
||||
@@ -57,27 +62,37 @@ const getDistDir = (name) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const getLangs = (name, voiceJson = null) => {
|
||||
voiceJson = voiceJson
|
||||
? voiceJson
|
||||
: JSON.parse(file.readSync(getDistDir(name)))
|
||||
const voiceLangs = Object.keys(voiceJson.voiceLangs['zh-CN'])
|
||||
const subtitleLangs = Object.keys(voiceJson.subtitleLangs)
|
||||
export const getLangs = (
|
||||
name: string,
|
||||
voiceJson: OperatorCharwordTable | null = null
|
||||
) => {
|
||||
let data: OperatorCharwordTable
|
||||
if (!voiceJson) {
|
||||
const text = file.readSync(getDistDir(name))
|
||||
if (!text) throw new Error(`File not found: ${getDistDir(name)}`)
|
||||
data = JSON.parse(text)
|
||||
} else {
|
||||
data = voiceJson
|
||||
}
|
||||
const voiceLangs = Object.keys(data.voiceLangs['zh-CN'])
|
||||
const subtitleLangs = Object.keys(data.subtitleLangs)
|
||||
return { voiceLangs, subtitleLangs }
|
||||
}
|
||||
|
||||
export const build = async (namesToBuild) => {
|
||||
const err = []
|
||||
export const build = async (namesToBuild: string[]) => {
|
||||
const err: string[] = []
|
||||
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
||||
console.log('Generating charword_table for', names.length, 'operators')
|
||||
await updateFn(true)
|
||||
const charwordTable = await updateFn(true)
|
||||
for (const name of names) {
|
||||
const charwordTableLookup = lookup(name)
|
||||
const voiceJson = {}
|
||||
const charwordTableLookup = lookup(name, charwordTable)
|
||||
const voiceJson = {} as OperatorCharwordTable
|
||||
voiceJson.voiceLangs = {}
|
||||
voiceJson.subtitleLangs = {}
|
||||
const subtitleInfo = Object.keys(charwordTableLookup.info)
|
||||
let voiceList = {}
|
||||
const subtitleInfo = Object.keys(charwordTableLookup.info) as Region[]
|
||||
const voiceList = {} as {
|
||||
[key: string]: string[]
|
||||
}
|
||||
subtitleInfo.forEach((item) => {
|
||||
if (Object.keys(charwordTableLookup.info[item]).length > 0) {
|
||||
const key = item.replace('_', '-')
|
||||
@@ -104,7 +119,7 @@ export const build = async (namesToBuild) => {
|
||||
)
|
||||
}
|
||||
})
|
||||
let voiceLangs = []
|
||||
let voiceLangs = [] as string[]
|
||||
try {
|
||||
voiceLangs = getLangs(name, voiceJson).voiceLangs
|
||||
|
||||
@@ -161,36 +176,57 @@ const updateFn = async (isLocalOnly = false) => {
|
||||
(acc, cur) => ({ ...acc, [cur]: {} }),
|
||||
{}
|
||||
)
|
||||
const charwordTable = {} as CharwordTable
|
||||
OPERATOR_IDS.forEach((id) => {
|
||||
CHARWORD_TABLE[id] = {
|
||||
charwordTable[id] = {
|
||||
alternativeId: getOperatorAlternativeId(id),
|
||||
voice: structuredClone(regionObject),
|
||||
info: structuredClone(regionObject),
|
||||
voice: structuredClone(regionObject) as VoiceRegionObject,
|
||||
info: structuredClone(regionObject) as InfoRegionObject,
|
||||
infile: false,
|
||||
ref: false,
|
||||
}
|
||||
})
|
||||
await load(DEFAULT_REGION, isLocalOnly)
|
||||
await load(DEFAULT_REGION, charwordTable, isLocalOnly)
|
||||
await Promise.all(
|
||||
REGIONS.slice(1).map(async (region) => {
|
||||
await load(region, isLocalOnly)
|
||||
await load(region, charwordTable, isLocalOnly)
|
||||
})
|
||||
)
|
||||
return charwordTable
|
||||
}
|
||||
|
||||
const load = async (region, isLocalOnly = false) => {
|
||||
const load = async (
|
||||
region: Region,
|
||||
charwordTable: CharwordTable,
|
||||
isLocalOnly = false
|
||||
) => {
|
||||
const basename = `charword_table_${region}`
|
||||
const filename = file
|
||||
.readdirSync(AUTO_UPDATE_FOLDER)
|
||||
.filter((item) => item.startsWith(`charword_table_${region}`))[0]
|
||||
const localFilePath = path.join(AUTO_UPDATE_FOLDER, filename)
|
||||
const data = isLocalOnly
|
||||
? JSON.parse(file.readSync(localFilePath))
|
||||
: await download(
|
||||
region,
|
||||
path.join(path.dirname(localFilePath), `${basename}.json`)
|
||||
)
|
||||
let data: CharwordTableJson
|
||||
|
||||
const getOnlineData = async () => {
|
||||
return await download(
|
||||
region,
|
||||
path.join(path.dirname(localFilePath), `${basename}.json`)
|
||||
)
|
||||
}
|
||||
|
||||
if (isLocalOnly) {
|
||||
const text = file.readSync(localFilePath)
|
||||
if (!text) {
|
||||
data = await getOnlineData()
|
||||
} else {
|
||||
data = JSON.parse(text)
|
||||
}
|
||||
} else {
|
||||
data = await getOnlineData()
|
||||
}
|
||||
|
||||
// put voice actor info into charword_table
|
||||
for (const [id, element] of Object.entries(CHARWORD_TABLE)) {
|
||||
for (const [id, element] of Object.entries(charwordTable)) {
|
||||
let operatorId = id
|
||||
let useAlternativeId = false
|
||||
if (typeof data.voiceLangDict[operatorId] === 'undefined') {
|
||||
@@ -236,7 +272,7 @@ const load = async (region, isLocalOnly = false) => {
|
||||
|
||||
// put voice lines into charword_table
|
||||
Object.values(data.charWords).forEach((item) => {
|
||||
const operatorInfo = Object.values(CHARWORD_TABLE).filter(
|
||||
const operatorInfo = Object.values(charwordTable).filter(
|
||||
(element) => element.info[region][item.wordKey]
|
||||
)
|
||||
if (operatorInfo.length > 0) {
|
||||
@@ -256,9 +292,14 @@ const load = async (region, isLocalOnly = false) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return charwordTable
|
||||
}
|
||||
|
||||
const download = async (region, targetFilePath) => {
|
||||
const download = async (
|
||||
region: keyof typeof REGION_URLS,
|
||||
targetFilePath: string
|
||||
) => {
|
||||
return await githubDownload(
|
||||
`https://api.github.com/repos/${REGION_URLS[region]}/commits?path=${region}/gamedata/excel/charword_table.json`,
|
||||
`https://raw.githubusercontent.com/${REGION_URLS[region]}/master/${region}/gamedata/excel/charword_table.json`,
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@aklive2d/charword-table",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"main": "index.js",
|
||||
"main": "index.ts",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@aklive2d/libs": "workspace:*",
|
||||
@@ -12,10 +12,15 @@
|
||||
"@aklive2d/eslint-config": "workspace:*",
|
||||
"@aklive2d/prettier-config": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"globals": ">=16.0.0",
|
||||
"typescript-eslint": ">=8.31.1",
|
||||
"typescript": ">=5.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"update": "mode=update node runner.js",
|
||||
"build": "mode=build node runner.js",
|
||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
||||
"update": "mode=update bun runner.ts",
|
||||
"build": "mode=build bun runner.ts",
|
||||
"lint": "eslint && prettier --check .",
|
||||
"build:cleanup": "rm -rf ./dist"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { build, update } from './index.js'
|
||||
import { build, update } from './index.ts'
|
||||
import { envParser, error } from '@aklive2d/libs'
|
||||
|
||||
async function main() {
|
||||
let err = []
|
||||
let err: string[] = []
|
||||
const { mode, name } = envParser.parse({
|
||||
mode: {
|
||||
type: 'string',
|
||||
@@ -17,7 +17,7 @@ async function main() {
|
||||
})
|
||||
switch (mode) {
|
||||
case 'build':
|
||||
err = await build(name)
|
||||
err = await build(name as string[])
|
||||
break
|
||||
case 'update':
|
||||
await update()
|
||||
25
packages/charword-table/tsconfig.json
Normal file
25
packages/charword-table/tsconfig.json
Normal 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/**/*"]
|
||||
}
|
||||
139
packages/charword-table/types.ts
Normal file
139
packages/charword-table/types.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
export type Region = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR'
|
||||
|
||||
interface CharWordBase {
|
||||
wordKey: string
|
||||
charId: string
|
||||
voiceId: string
|
||||
voiceText: string
|
||||
}
|
||||
|
||||
interface CharWord extends CharWordBase {
|
||||
charWordId: string
|
||||
voiceTitle: string
|
||||
voiceIndex: number
|
||||
voiceType: string
|
||||
unlockType: string
|
||||
unlockParam: unknown
|
||||
lockDescription: string
|
||||
placeType: string
|
||||
voiceAsset: string
|
||||
}
|
||||
|
||||
type VoiceLangInfo = {
|
||||
wordkey: string
|
||||
voiceLangType: string
|
||||
cvName: string[]
|
||||
voicePath: string | null
|
||||
}
|
||||
|
||||
type CharVoiceLangDict = {
|
||||
wordkeys: string[]
|
||||
charId: string
|
||||
dict: Record<string, VoiceLangInfo>
|
||||
}
|
||||
|
||||
type VoiceLangType = {
|
||||
name: string
|
||||
groupType: string
|
||||
}
|
||||
|
||||
type VoiceLangGroupType = {
|
||||
name: string
|
||||
members: string[]
|
||||
}
|
||||
|
||||
type TimestampCharSet = {
|
||||
timestamp: number
|
||||
charSet: string[]
|
||||
}
|
||||
|
||||
type TimeData = {
|
||||
timeType: string
|
||||
interval: {
|
||||
startTs: number
|
||||
endTs: number
|
||||
}
|
||||
}
|
||||
|
||||
type FesVoiceData = {
|
||||
showType: string
|
||||
timeData: TimeData[]
|
||||
}
|
||||
|
||||
type FesVoiceWeight = {
|
||||
showType: string
|
||||
weight: number
|
||||
priority: number
|
||||
}
|
||||
|
||||
type ExtraVoiceConfig = {
|
||||
voiceId: string
|
||||
validVoiceLang: string[]
|
||||
}
|
||||
|
||||
export type CharwordTableJson = {
|
||||
charWords: Record<string, CharWord>
|
||||
charExtraWords: Record<string, CharWordBase>
|
||||
voiceLangDict: Record<string, CharVoiceLangDict>
|
||||
defaultLangType: string
|
||||
newTagList: string[]
|
||||
voiceLangTypeDict: Record<string, VoiceLangType>
|
||||
voiceLangGroupTypeDict: Record<string, VoiceLangGroupType>
|
||||
charDefaultTypeDict: Record<string, string>
|
||||
startTimeWithTypeDict: Record<string, TimestampCharSet[]>
|
||||
displayGroupTypeList: string[]
|
||||
displayTypeList: string[]
|
||||
playVoiceRange: string
|
||||
fesVoiceData: Record<string, FesVoiceData>
|
||||
fesVoiceWeight: Record<string, FesVoiceWeight>
|
||||
extraVoiceConfigData: Record<string, ExtraVoiceConfig>
|
||||
}
|
||||
|
||||
export type OperatorCharwordTable = {
|
||||
voiceLangs: {
|
||||
[languageCode: string]: {
|
||||
[voiceLangType: string]: string[]
|
||||
}
|
||||
}
|
||||
subtitleLangs: {
|
||||
[languageCode: string]: {
|
||||
[voiceKey: 'default' | string]: {
|
||||
[voiceId: string]: {
|
||||
title: string
|
||||
text: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type VoiceRegionObject = {
|
||||
// eslint-disable-next-line
|
||||
[region in Region]: {
|
||||
[wordkey: string]: {
|
||||
[voiceId: string]: {
|
||||
title: string
|
||||
text: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type InfoRegionObject = {
|
||||
// eslint-disable-next-line
|
||||
[region in Region]: {
|
||||
[wordkey: string]: {
|
||||
[voiceLangType: string]: string[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type CharwordTable = {
|
||||
[name: string]: {
|
||||
alternativeId: string
|
||||
voice: VoiceRegionObject
|
||||
info: InfoRegionObject
|
||||
infile: boolean
|
||||
ref: boolean
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user