feat: migrated packages to ts
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -139,3 +139,4 @@ assets/*
|
|||||||
temp/*
|
temp/*
|
||||||
.turbo
|
.turbo
|
||||||
data/*
|
data/*
|
||||||
|
release
|
||||||
|
|||||||
10
.vscode/launch.json
vendored
10
.vscode/launch.json
vendored
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Launch Chrome",
|
"name": "Launch Chrome",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
@@ -110,6 +111,15 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"command": "pnpm run deploy",
|
"command": "pnpm run deploy",
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
|
},{
|
||||||
|
"type": "bun",
|
||||||
|
"name": "Run Script: build",
|
||||||
|
"request": "launch",
|
||||||
|
"env": {
|
||||||
|
"mode": "build"
|
||||||
|
},
|
||||||
|
"program": "index.ts",
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import react from 'eslint-plugin-react'
|
|||||||
import reactHooks from 'eslint-plugin-react-hooks'
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
import baseConfig from '@aklive2d/eslint-config'
|
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} */
|
/** @type {import('eslint').Config} */
|
||||||
export default [
|
export default [
|
||||||
@@ -27,4 +30,21 @@ export default [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...tsConfig,
|
||||||
|
{
|
||||||
|
files: ['**/*.js', '**/*.ts'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{ argsIgnorePattern: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:directory": "vite --clearScreen false",
|
"dev:directory": "vite --clearScreen false",
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"preview:directory": "vite preview",
|
"preview:directory": "vite preview",
|
||||||
"lint": "eslint \"src/**/*.js\" \"src/**/*.jsx\" && stylelint \"src/**/*.css\" \"src/**/*.scss\" && prettier --check ."
|
"lint": "eslint && stylelint \"src/**/*.css\" \"src/**/*.scss\" && prettier --check ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
@@ -28,6 +28,11 @@
|
|||||||
"@aklive2d/module": "workspace:*",
|
"@aklive2d/module": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^19.0.8",
|
"@types/react": "^19.0.8",
|
||||||
"@types/react-dom": "^19.0.3",
|
"@types/react-dom": "^19.0.3",
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import { DIST_DIR } from '@aklive2d/showcase'
|
||||||
import { build as viteBuild } from 'vite'
|
import { build as viteBuild } from 'vite'
|
||||||
import { envParser } from '@aklive2d/libs'
|
import { envParser, file } from '@aklive2d/libs'
|
||||||
|
|
||||||
const build = async (namesToBuild) => {
|
const build = async (namesToBuild: string[]) => {
|
||||||
if (!namesToBuild.length) {
|
if (!namesToBuild.length) {
|
||||||
// skip as directory can only build
|
// skip as directory can only build
|
||||||
// when all operators are built
|
// when all operators are built
|
||||||
await viteBuild()
|
await viteBuild()
|
||||||
|
const releaseDir = path.resolve(DIST_DIR)
|
||||||
|
file.rmdir(releaseDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +22,7 @@ async function main() {
|
|||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
await build(name)
|
await build(name as string[])
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -192,7 +192,7 @@ export default function Home() {
|
|||||||
>
|
>
|
||||||
{officialUpdate.dates
|
{officialUpdate.dates
|
||||||
.reduce((acc, cur) => {
|
.reduce((acc, cur) => {
|
||||||
const op = officialUpdate[cur]
|
const op = officialUpdate.info[cur]
|
||||||
return [...acc, ...op]
|
return [...acc, ...op]
|
||||||
}, [])
|
}, [])
|
||||||
.slice(
|
.slice(
|
||||||
|
|||||||
25
apps/directory/tsconfig.json
Normal file
25
apps/directory/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": ["spine-ts/**/*"]
|
||||||
|
}
|
||||||
@@ -8,12 +8,12 @@ import { copyDirectoryData } from '@aklive2d/vite-helpers'
|
|||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig(async () => {
|
export default defineConfig(async () => {
|
||||||
const dataDir = path.resolve(import.meta.dirname, config.dir_name.data)
|
const dataDir = path.resolve(import.meta.dirname, config.dir_name.data)
|
||||||
const publicDir = path.resolve(showcaseDirs.DIST_DIR)
|
const releaseDir = path.resolve(showcaseDirs.DIST_DIR)
|
||||||
await copyDirectoryData({ dataDir, publicDir })
|
await copyDirectoryData({ dataDir, publicDir: releaseDir })
|
||||||
return {
|
return {
|
||||||
envDir: dataDir,
|
envDir: dataDir,
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
publicDir,
|
publicDir: releaseDir,
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve('./src'),
|
'@': path.resolve('./src'),
|
||||||
@@ -22,7 +22,12 @@ export default defineConfig(async () => {
|
|||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
outDir: publicDir,
|
outDir: path.resolve(
|
||||||
|
import.meta.dirname,
|
||||||
|
'..',
|
||||||
|
'..',
|
||||||
|
config.dir_name.dist
|
||||||
|
),
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
output: {
|
output: {
|
||||||
entryFileNames: `${config.directory.assets_dir}/[name]-[hash:8].js`,
|
entryFileNames: `${config.directory.assets_dir}/[name]-[hash:8].js`,
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
import eslint from '@eslint/js'
|
import { tsConfig } from '@aklive2d/eslint-config'
|
||||||
import tseslint from 'typescript-eslint'
|
import tseslint from 'typescript-eslint'
|
||||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
|
||||||
import globals from 'globals'
|
import globals from 'globals'
|
||||||
|
|
||||||
/** @type {import('eslint').Config} */
|
/** @type {import('eslint').Config} */
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
eslint.configs.recommended,
|
...tsConfig,
|
||||||
tseslint.configs.recommended,
|
|
||||||
eslintPluginPrettierRecommended,
|
|
||||||
{
|
{
|
||||||
ignores: ['dist', 'spine-ts'],
|
ignores: ['dist', 'spine-ts'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
files: ['**/*.{js,jsx}', '**/*.{ts,tsx}'],
|
files: ['**/*.js', '**/*.ts'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
ecmaVersion: 2022,
|
ecmaVersion: 2022,
|
||||||
globals: {
|
globals: {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import { Player } from './src/player.ts'
|
import { Player, PlayerConfig } from './src/player.ts'
|
||||||
|
|
||||||
export { Player }
|
export { Player }
|
||||||
|
export type { PlayerConfig }
|
||||||
|
|||||||
@@ -6,13 +6,15 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@aklive2d/postcss-config": "workspace:*",
|
"@aklive2d/postcss-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
"@aklive2d/stylelint-config": "workspace:*",
|
"@aklive2d/stylelint-config": "workspace:*",
|
||||||
"eslint-plugin-prettier": "^5.2.6",
|
"@aklive2d/eslint-config": "workspace:*"
|
||||||
"globals": "^16.0.0",
|
|
||||||
"typescript": "^5.8.3",
|
|
||||||
"typescript-eslint": "^8.31.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,29 @@
|
|||||||
import baseConfig from '@aklive2d/eslint-config'
|
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} */
|
/** @type {import('eslint').Config} */
|
||||||
export default [...baseConfig, { ignores: ['src/libs/*'] }]
|
export default tseslint.config(
|
||||||
|
...baseConfig,
|
||||||
|
...tsConfig,
|
||||||
|
{
|
||||||
|
ignores: ['dist', 'spine-ts'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.js', '**/*.ts'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{ argsIgnorePattern: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ export const DIST_DIR = path.resolve(
|
|||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
'..',
|
'..',
|
||||||
'..',
|
'..',
|
||||||
config.dir_name.dist
|
config.app.showcase.release
|
||||||
)
|
)
|
||||||
@@ -3,12 +3,17 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:showcase": "vite --clearScreen false",
|
"dev:showcase": "vite --clearScreen false",
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"preview:showcase": "vite preview",
|
"preview:showcase": "vite preview",
|
||||||
"lint": "eslint \"src/**/*.js\" && stylelint \"**/*.css\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^6.1.5",
|
"vite": "^6.1.5",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { envParser, file } from '@aklive2d/libs'
|
|||||||
import { copyShowcaseData, copyProjectJSON } from '@aklive2d/vite-helpers'
|
import { copyShowcaseData, copyProjectJSON } from '@aklive2d/vite-helpers'
|
||||||
import * as dirs from './index.js'
|
import * as dirs from './index.js'
|
||||||
|
|
||||||
const build = async (namesToBuild) => {
|
const build = async (namesToBuild: string[]) => {
|
||||||
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
||||||
console.log('Generating assets for', names.length, 'operators')
|
console.log('Generating assets for', names.length, 'operators')
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
@@ -32,7 +32,7 @@ async function main() {
|
|||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
await build(name)
|
await build(name as string[])
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
25
apps/showcase/tsconfig.json
Normal file
25
apps/showcase/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": ["spine-ts/**/*"]
|
||||||
|
}
|
||||||
102
bun.lock
102
bun.lock
@@ -4,12 +4,14 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "aklive2d",
|
"name": "aklive2d",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/jsdom": "^21.1.7",
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
"cz-conventional-changelog": "^3.3.0",
|
||||||
"eslint": "^9.25.1",
|
"eslint": "^9.25.1",
|
||||||
"http-server": "^14.1.1",
|
"http-server": "^14.1.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"stylelint": "^16.19.1",
|
"stylelint": "^16.19.1",
|
||||||
"turbo": "^2.5.2",
|
"turbo": "^2.5.2",
|
||||||
|
"typescript": "5.8.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"apps/directory": {
|
"apps/directory": {
|
||||||
@@ -46,18 +48,25 @@
|
|||||||
"sass": "^1.84.0",
|
"sass": "^1.84.0",
|
||||||
"vite": "^6.1.5",
|
"vite": "^6.1.5",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"apps/module": {
|
"apps/module": {
|
||||||
"name": "@aklive2d/module",
|
"name": "@aklive2d/module",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/postcss-config": "workspace:*",
|
"@aklive2d/postcss-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
"@aklive2d/stylelint-config": "workspace:*",
|
"@aklive2d/stylelint-config": "workspace:*",
|
||||||
"eslint-plugin-prettier": "^5.2.6",
|
},
|
||||||
"globals": "^16.0.0",
|
"peerDependencies": {
|
||||||
"typescript": "^5.8.3",
|
"globals": ">=16.0.0",
|
||||||
"typescript-eslint": "^8.31.1",
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"apps/showcase": {
|
"apps/showcase": {
|
||||||
@@ -76,6 +85,11 @@
|
|||||||
"@aklive2d/vite-helpers": "workspace:*",
|
"@aklive2d/vite-helpers": "workspace:*",
|
||||||
"vite": "^6.1.5",
|
"vite": "^6.1.5",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/assets": {
|
"packages/assets": {
|
||||||
"name": "@aklive2d/assets",
|
"name": "@aklive2d/assets",
|
||||||
@@ -89,6 +103,11 @@
|
|||||||
"@aklive2d/operator": "workspace:*",
|
"@aklive2d/operator": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/background": {
|
"packages/background": {
|
||||||
"name": "@aklive2d/background",
|
"name": "@aklive2d/background",
|
||||||
@@ -101,6 +120,11 @@
|
|||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/charword-table": {
|
"packages/charword-table": {
|
||||||
"name": "@aklive2d/charword-table",
|
"name": "@aklive2d/charword-table",
|
||||||
@@ -113,6 +137,11 @@
|
|||||||
"@aklive2d/operator": "workspace:*",
|
"@aklive2d/operator": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/config": {
|
"packages/config": {
|
||||||
"name": "@aklive2d/config",
|
"name": "@aklive2d/config",
|
||||||
@@ -122,6 +151,11 @@
|
|||||||
"@aklive2d/libs": "workspace:*",
|
"@aklive2d/libs": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/downloader": {
|
"packages/downloader": {
|
||||||
"name": "@aklive2d/downloader",
|
"name": "@aklive2d/downloader",
|
||||||
@@ -140,8 +174,10 @@
|
|||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.19.0",
|
||||||
"eslint": "^9.19.0",
|
"eslint": "^9.19.0",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-prettier": "^5.2.3",
|
"eslint-plugin-prettier": "^5.2.6",
|
||||||
"globals": "^15.14.0",
|
"globals": "^16.0.0",
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
"typescript-eslint": "^8.31.1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/libs": {
|
"packages/libs": {
|
||||||
@@ -155,6 +191,15 @@
|
|||||||
"yauzl-promise": "^4.0.0",
|
"yauzl-promise": "^4.0.0",
|
||||||
"yazl": "^3.3.1",
|
"yazl": "^3.3.1",
|
||||||
},
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/yauzl-promise": "^4.0.1",
|
||||||
|
"@types/yazl": "^2.4.6",
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/music": {
|
"packages/music": {
|
||||||
"name": "@aklive2d/music",
|
"name": "@aklive2d/music",
|
||||||
@@ -166,6 +211,11 @@
|
|||||||
"@aklive2d/libs": "workspace:*",
|
"@aklive2d/libs": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/official-info": {
|
"packages/official-info": {
|
||||||
"name": "@aklive2d/official-info",
|
"name": "@aklive2d/official-info",
|
||||||
@@ -177,6 +227,11 @@
|
|||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/operator": {
|
"packages/operator": {
|
||||||
"name": "@aklive2d/operator",
|
"name": "@aklive2d/operator",
|
||||||
@@ -189,6 +244,11 @@
|
|||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
"yaml": "^2.7.0",
|
"yaml": "^2.7.0",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/postcss-config": {
|
"packages/postcss-config": {
|
||||||
"name": "@aklive2d/postcss-config",
|
"name": "@aklive2d/postcss-config",
|
||||||
@@ -202,6 +262,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"prettier": ">=3.0.0",
|
"prettier": ">=3.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/project-json": {
|
"packages/project-json": {
|
||||||
@@ -217,6 +278,11 @@
|
|||||||
"@aklive2d/operator": "workspace:*",
|
"@aklive2d/operator": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/stylelint-config": {
|
"packages/stylelint-config": {
|
||||||
"name": "@aklive2d/stylelint-config",
|
"name": "@aklive2d/stylelint-config",
|
||||||
@@ -240,6 +306,11 @@
|
|||||||
"@aklive2d/operator": "workspace:*",
|
"@aklive2d/operator": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*",
|
"@aklive2d/prettier-config": "workspace:*",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/wrangler": {
|
"packages/wrangler": {
|
||||||
"name": "@aklive2d/wrangler",
|
"name": "@aklive2d/wrangler",
|
||||||
@@ -256,6 +327,11 @@
|
|||||||
"@aklive2d/showcase": "workspace:*",
|
"@aklive2d/showcase": "workspace:*",
|
||||||
"p-throttle": "^7.0.0",
|
"p-throttle": "^7.0.0",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript": ">=5.8.2",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
@@ -597,6 +673,8 @@
|
|||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
|
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
|
||||||
|
|
||||||
|
"@types/jsdom": ["@types/jsdom@21.1.7", "", { "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA=="],
|
||||||
|
|
||||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@22.15.3", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw=="],
|
"@types/node": ["@types/node@22.15.3", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw=="],
|
||||||
@@ -605,6 +683,12 @@
|
|||||||
|
|
||||||
"@types/react-dom": ["@types/react-dom@19.1.3", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg=="],
|
"@types/react-dom": ["@types/react-dom@19.1.3", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg=="],
|
||||||
|
|
||||||
|
"@types/tough-cookie": ["@types/tough-cookie@4.0.5", "", {}, "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="],
|
||||||
|
|
||||||
|
"@types/yauzl-promise": ["@types/yauzl-promise@4.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-qYEC3rJwqiJpdQ9b+bPNeuSY0c3JUM8vIuDy08qfuVN7xHm3ZDsHn2kGphUIB0ruEXrPGNXZ64nMUcu4fDjViQ=="],
|
||||||
|
|
||||||
|
"@types/yazl": ["@types/yazl@2.4.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-/ifFjQtcKaoZOjl5NNCQRR0fAKafB3Foxd7J/WvFPTMea46zekapcR30uzkwIkKAAuq5T6d0dkwz754RFH27hg=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.31.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/type-utils": "8.31.1", "@typescript-eslint/utils": "8.31.1", "@typescript-eslint/visitor-keys": "8.31.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.31.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/type-utils": "8.31.1", "@typescript-eslint/utils": "8.31.1", "@typescript-eslint/visitor-keys": "8.31.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.31.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/types": "8.31.1", "@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/visitor-keys": "8.31.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.31.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/types": "8.31.1", "@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/visitor-keys": "8.31.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q=="],
|
||||||
@@ -919,7 +1003,7 @@
|
|||||||
|
|
||||||
"global-prefix": ["global-prefix@3.0.0", "", { "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" } }, "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg=="],
|
"global-prefix": ["global-prefix@3.0.0", "", { "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" } }, "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg=="],
|
||||||
|
|
||||||
"globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="],
|
"globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
|
||||||
|
|
||||||
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
|
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
|
||||||
|
|
||||||
@@ -1443,7 +1527,7 @@
|
|||||||
|
|
||||||
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
|
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.31.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/parser": "8.31.1", "@typescript-eslint/utils": "8.31.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA=="],
|
"typescript-eslint": ["typescript-eslint@8.31.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/parser": "8.31.1", "@typescript-eslint/utils": "8.31.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA=="],
|
||||||
|
|
||||||
@@ -1509,7 +1593,7 @@
|
|||||||
|
|
||||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
"@aklive2d/module/globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
|
"@aklive2d/eslint-config/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||||
|
|
||||||
"@commitlint/config-validator/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
|
"@commitlint/config-validator/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
|
||||||
|
|
||||||
|
|||||||
75
package.json
75
package.json
@@ -1,37 +1,42 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "turbo run build",
|
"build": "turbo run build",
|
||||||
"dev:showcase": "turbo run dev:showcase --ui tui",
|
"dev:showcase": "turbo run dev:showcase --ui tui",
|
||||||
"preview:showcase": "turbo run preview:showcase --ui tui",
|
"preview:showcase": "turbo run preview:showcase --ui tui",
|
||||||
"dev:directory": "turbo run dev:directory --ui tui",
|
"dev:directory": "turbo run dev:directory --ui tui",
|
||||||
"preview:directory": "turbo run preview:directory --ui tui",
|
"preview:directory": "turbo run preview:directory --ui tui",
|
||||||
"preview": "http-server ./dist",
|
"preview": "http-server ./dist",
|
||||||
"lint": "turbo run lint",
|
"lint": "turbo run lint",
|
||||||
"update": "turbo run update",
|
"update": "turbo run update",
|
||||||
"init": "turbo run init",
|
"init": "turbo run init",
|
||||||
"download:game": "turbo run download:game",
|
"download:game": "turbo run download:game",
|
||||||
"build:cleanup": "turbo run build:cleanup"
|
"build:cleanup": "turbo run build:cleanup"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
"@types/jsdom": "^21.1.7",
|
||||||
"eslint": "^9.25.1",
|
"cz-conventional-changelog": "^3.3.0",
|
||||||
"http-server": "^14.1.1",
|
"eslint": "^9.25.1",
|
||||||
"prettier": "^3.5.3",
|
"http-server": "^14.1.1",
|
||||||
"stylelint": "^16.19.1",
|
"prettier": "^3.5.3",
|
||||||
"turbo": "^2.5.2"
|
"stylelint": "^16.19.1",
|
||||||
},
|
"turbo": "^2.5.2",
|
||||||
"name": "aklive2d",
|
"typescript": "5.8.2"
|
||||||
"type": "module",
|
},
|
||||||
"config": {
|
"name": "aklive2d",
|
||||||
"commitizen": {
|
"type": "module",
|
||||||
"path": "cz-conventional-changelog"
|
"config": {
|
||||||
}
|
"commitizen": {
|
||||||
},
|
"path": "cz-conventional-changelog"
|
||||||
"packageManager": "bun@1.2.11",
|
}
|
||||||
"workspaces": ["packages/*", "apps/*"],
|
},
|
||||||
"trustedDependencies": [
|
"packageManager": "bun@1.2.11",
|
||||||
"@parcel/watcher",
|
"workspaces": [
|
||||||
"@swc/core"
|
"packages/*",
|
||||||
]
|
"apps/*"
|
||||||
|
],
|
||||||
|
"trustedDependencies": [
|
||||||
|
"@parcel/watcher",
|
||||||
|
"@swc/core"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
import { yaml } from '@aklive2d/libs'
|
import { yaml } from '@aklive2d/libs'
|
||||||
|
import type { Config } from './types.ts'
|
||||||
|
|
||||||
export const DIST_DIR = path.resolve(import.meta.dirname, config.dir_name.dist)
|
export const DIST_DIR = path.resolve(import.meta.dirname, config.dir_name.dist)
|
||||||
export const CONFIG_PATH = path.resolve(
|
export const CONFIG_PATH = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
config.module.assets.config_yaml
|
config.module.assets.config_yaml
|
||||||
)
|
)
|
||||||
const selfConfig = yaml.read(CONFIG_PATH)
|
const selfConfig: Config = yaml.read(CONFIG_PATH)
|
||||||
|
|
||||||
export default selfConfig
|
export default selfConfig
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { file } from '@aklive2d/libs'
|
import { file } from '@aklive2d/libs'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
import { DIST_DIR } from '../index.js'
|
import { DIST_DIR } from '../index.ts'
|
||||||
|
|
||||||
export default async (packageDir) => {
|
export default async (packageDir: string) => {
|
||||||
const copyQueue = [
|
const copyQueue = [
|
||||||
{
|
{
|
||||||
fn: file.symlink,
|
fn: file.symlink,
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { file } from '@aklive2d/libs'
|
import { file } from '@aklive2d/libs'
|
||||||
import { unzipDownload } from '@aklive2d/downloader'
|
import { unzipDownload, type UnzipDownloadItem } from '@aklive2d/downloader'
|
||||||
import { getOperatorId, getOperatorAlternativeId } from '@aklive2d/operator'
|
import { getOperatorId, getOperatorAlternativeId } from '@aklive2d/operator'
|
||||||
import { mapping } from '@aklive2d/music'
|
import { mapping } from '@aklive2d/music'
|
||||||
import config from '../index.js'
|
import config from '../index.ts'
|
||||||
|
import type { UpdateList, ItemToDownload, AbInfosItem } from '../types.ts'
|
||||||
|
|
||||||
export default async (dataDir) => {
|
export default async (dataDir: string) => {
|
||||||
const pidSet = new Set()
|
const pidSet: Set<string> = new Set()
|
||||||
const versionRes = await fetch(
|
const versionRes: Response = await fetch(
|
||||||
'https://ak-conf.hypergryph.com/config/prod/official/Android/version'
|
'https://ak-conf.hypergryph.com/config/prod/official/Android/version'
|
||||||
)
|
)
|
||||||
const version = (await versionRes.json()).resVersion
|
const version: string = (await versionRes.json()).resVersion
|
||||||
const lpacksRes = await fetch(
|
const lpacksRes: Response = await fetch(
|
||||||
`https://ak.hycdn.cn/assetbundle/official/Android/assets/${version}/hot_update_list.json`
|
`https://ak.hycdn.cn/assetbundle/official/Android/assets/${version}/hot_update_list.json`
|
||||||
)
|
)
|
||||||
const updateList = await lpacksRes.json()
|
const updateList: UpdateList = await lpacksRes.json()
|
||||||
const itemToDownload = new Set(config.item_to_download)
|
const itemToDownload: Set<ItemToDownload> = new Set(config.item_to_download)
|
||||||
updateList.abInfos.map((item) => {
|
updateList.abInfos.map((item: AbInfosItem) => {
|
||||||
if (item.name.includes(config.dynchars)) {
|
if (item.name.includes(config.dynchars)) {
|
||||||
const id = getOperatorId(item.name).replace('.ab', '')
|
const id = getOperatorId(item.name).replace('.ab', '')
|
||||||
itemToDownload.add(id)
|
itemToDownload.add(id)
|
||||||
@@ -32,12 +33,12 @@ export default async (dataDir) => {
|
|||||||
const itemToDownloadRegExp = new RegExp(
|
const itemToDownloadRegExp = new RegExp(
|
||||||
`(.*)(${Array.from(itemToDownload).join('|')})(.*)`
|
`(.*)(${Array.from(itemToDownload).join('|')})(.*)`
|
||||||
)
|
)
|
||||||
updateList.abInfos.map((item) => {
|
updateList.abInfos.map((item: AbInfosItem) => {
|
||||||
if (itemToDownloadRegExp.test(item.name)) {
|
if (itemToDownloadRegExp.test(item.name)) {
|
||||||
item.pid && pidSet.add(item.pid)
|
if (item.pid) pidSet.add(item.pid)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const lpacksToDownload = []
|
const lpacksToDownload: UnzipDownloadItem[] = []
|
||||||
pidSet.forEach((item) => {
|
pidSet.forEach((item) => {
|
||||||
lpacksToDownload.push({
|
lpacksToDownload.push({
|
||||||
name: item,
|
name: item,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/assets",
|
"name": "@aklive2d/assets",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -13,10 +13,15 @@
|
|||||||
"@aklive2d/operator": "workspace:*",
|
"@aklive2d/operator": "workspace:*",
|
||||||
"@aklive2d/music": "workspace:*"
|
"@aklive2d/music": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"download:game": "mode=download node runner.js",
|
"download:game": "mode=download bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
"lint": "eslint && prettier --check .",
|
||||||
"build:cleanup": "rm -rf ./dist"
|
"build:cleanup": "rm -rf ./dist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { envParser } from '@aklive2d/libs'
|
import { envParser } from '@aklive2d/libs'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
import build from './libs/build.js'
|
import build from './libs/build.ts'
|
||||||
import download from './libs/download.js'
|
import download from './libs/download.ts'
|
||||||
|
|
||||||
const packageDir = path.resolve(import.meta.dirname, '..')
|
const packageDir = path.resolve(import.meta.dirname, '..')
|
||||||
const dataDir = path.resolve(import.meta.dirname, config.dir_name.data)
|
const dataDir = path.resolve(import.meta.dirname, config.dir_name.data)
|
||||||
25
packages/assets/tsconfig.json
Normal file
25
packages/assets/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/**/*"]
|
||||||
|
}
|
||||||
35
packages/assets/types.ts
Normal file
35
packages/assets/types.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
export type Config = {
|
||||||
|
dynchars: string
|
||||||
|
item_to_download: ItemToDownload[]
|
||||||
|
additional_regex: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ItemToDownload = string
|
||||||
|
|
||||||
|
export type UpdateList = {
|
||||||
|
versionId: string
|
||||||
|
abInfos: AbInfosItem[]
|
||||||
|
manifestName: string
|
||||||
|
manifestVersion: string
|
||||||
|
packInfos: PackInfosItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AbInfosItem = {
|
||||||
|
name: string
|
||||||
|
hash: string
|
||||||
|
md5: string
|
||||||
|
totalSize: number
|
||||||
|
abSize: number
|
||||||
|
cid: number
|
||||||
|
cat?: number
|
||||||
|
pid?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PackInfosItem = {
|
||||||
|
name: string
|
||||||
|
hash: string
|
||||||
|
md5: string
|
||||||
|
totalSize: number
|
||||||
|
abSize: number
|
||||||
|
cid: number
|
||||||
|
}
|
||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -66,12 +66,18 @@ export const build = async () => {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const composite = async (filenamePrefix, fileExt) => {
|
const composite = async (filenamePrefix: string, fileExt: string) => {
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
path.join(EXTRACTED_DIR, `${filenamePrefix}_left${fileExt}`)
|
path.join(EXTRACTED_DIR, `${filenamePrefix}_left${fileExt}`)
|
||||||
)
|
)
|
||||||
const metadata = await image.metadata()
|
const metadata = await image.metadata()
|
||||||
|
|
||||||
|
if (!metadata.width || !metadata.height) {
|
||||||
|
throw new Error(
|
||||||
|
`Width and height metadata for ${filenamePrefix}_left${fileExt} is not found.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
image
|
image
|
||||||
.resize(2 * metadata.width, metadata.height, {
|
.resize(2 * metadata.width, metadata.height, {
|
||||||
kernel: sharp.kernel.nearest,
|
kernel: sharp.kernel.nearest,
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/background",
|
"name": "@aklive2d/background",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
@@ -12,9 +12,14 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.js",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
"lint": "eslint && prettier --check .",
|
||||||
"build:cleanup": "rm -rf ./dist ./data"
|
"build:cleanup": "rm -rf ./dist ./data"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { build } from './index.js'
|
import { build } from './index.ts'
|
||||||
import { envParser, error } from '@aklive2d/libs'
|
import { envParser, error } from '@aklive2d/libs'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
25
packages/background/tsconfig.json
Normal file
25
packages/background/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/**/*"]
|
||||||
|
}
|
||||||
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} */
|
/** @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,
|
getOperatorAlternativeId,
|
||||||
OPERATOR_SOURCE_FOLDER,
|
OPERATOR_SOURCE_FOLDER,
|
||||||
} from '@aklive2d/operator'
|
} 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 uses an older version of charword_table.json
|
||||||
// zh_TW is removed
|
// 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 = {
|
const REGION_URLS = {
|
||||||
zh_CN: 'Kengxxiao/ArknightsGameData',
|
zh_CN: 'Kengxxiao/ArknightsGameData',
|
||||||
en_US: 'Kengxxiao/ArknightsGameData_YoStar',
|
en_US: 'Kengxxiao/ArknightsGameData_YoStar',
|
||||||
ja_JP: 'Kengxxiao/ArknightsGameData_YoStar',
|
ja_JP: 'Kengxxiao/ArknightsGameData_YoStar',
|
||||||
ko_KR: '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('_', '-')
|
export const defaultRegion = DEFAULT_REGION.replace('_', '-')
|
||||||
const NICKNAME = {
|
const NICKNAME = {
|
||||||
zh_CN: '博士',
|
zh_CN: '博士',
|
||||||
@@ -34,22 +43,18 @@ const AUTO_UPDATE_FOLDER = path.resolve(
|
|||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
config.dir_name.auto_update
|
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)
|
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 operatorId = getOperatorId(operators[operatorName].filename)
|
||||||
const operatorBlock = CHARWORD_TABLE[operatorId]
|
const operatorBlock = charwordTable[operatorId]
|
||||||
return operatorBlock.ref
|
return operatorBlock.ref
|
||||||
? CHARWORD_TABLE[operatorBlock.alternativeId]
|
? charwordTable[operatorBlock.alternativeId]
|
||||||
: operatorBlock
|
: operatorBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDistDir = (name) => {
|
const getDistDir = (name: string) => {
|
||||||
return path.join(
|
return path.join(
|
||||||
DIST_DIR,
|
DIST_DIR,
|
||||||
name,
|
name,
|
||||||
@@ -57,27 +62,37 @@ const getDistDir = (name) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLangs = (name, voiceJson = null) => {
|
export const getLangs = (
|
||||||
voiceJson = voiceJson
|
name: string,
|
||||||
? voiceJson
|
voiceJson: OperatorCharwordTable | null = null
|
||||||
: JSON.parse(file.readSync(getDistDir(name)))
|
) => {
|
||||||
const voiceLangs = Object.keys(voiceJson.voiceLangs['zh-CN'])
|
let data: OperatorCharwordTable
|
||||||
const subtitleLangs = Object.keys(voiceJson.subtitleLangs)
|
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 }
|
return { voiceLangs, subtitleLangs }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const build = async (namesToBuild) => {
|
export const build = async (namesToBuild: string[]) => {
|
||||||
const err = []
|
const err: string[] = []
|
||||||
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
||||||
console.log('Generating charword_table for', names.length, 'operators')
|
console.log('Generating charword_table for', names.length, 'operators')
|
||||||
await updateFn(true)
|
const charwordTable = await updateFn(true)
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
const charwordTableLookup = lookup(name)
|
const charwordTableLookup = lookup(name, charwordTable)
|
||||||
const voiceJson = {}
|
const voiceJson = {} as OperatorCharwordTable
|
||||||
voiceJson.voiceLangs = {}
|
voiceJson.voiceLangs = {}
|
||||||
voiceJson.subtitleLangs = {}
|
voiceJson.subtitleLangs = {}
|
||||||
const subtitleInfo = Object.keys(charwordTableLookup.info)
|
const subtitleInfo = Object.keys(charwordTableLookup.info) as Region[]
|
||||||
let voiceList = {}
|
const voiceList = {} as {
|
||||||
|
[key: string]: string[]
|
||||||
|
}
|
||||||
subtitleInfo.forEach((item) => {
|
subtitleInfo.forEach((item) => {
|
||||||
if (Object.keys(charwordTableLookup.info[item]).length > 0) {
|
if (Object.keys(charwordTableLookup.info[item]).length > 0) {
|
||||||
const key = item.replace('_', '-')
|
const key = item.replace('_', '-')
|
||||||
@@ -104,7 +119,7 @@ export const build = async (namesToBuild) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let voiceLangs = []
|
let voiceLangs = [] as string[]
|
||||||
try {
|
try {
|
||||||
voiceLangs = getLangs(name, voiceJson).voiceLangs
|
voiceLangs = getLangs(name, voiceJson).voiceLangs
|
||||||
|
|
||||||
@@ -161,36 +176,57 @@ const updateFn = async (isLocalOnly = false) => {
|
|||||||
(acc, cur) => ({ ...acc, [cur]: {} }),
|
(acc, cur) => ({ ...acc, [cur]: {} }),
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
const charwordTable = {} as CharwordTable
|
||||||
OPERATOR_IDS.forEach((id) => {
|
OPERATOR_IDS.forEach((id) => {
|
||||||
CHARWORD_TABLE[id] = {
|
charwordTable[id] = {
|
||||||
alternativeId: getOperatorAlternativeId(id),
|
alternativeId: getOperatorAlternativeId(id),
|
||||||
voice: structuredClone(regionObject),
|
voice: structuredClone(regionObject) as VoiceRegionObject,
|
||||||
info: structuredClone(regionObject),
|
info: structuredClone(regionObject) as InfoRegionObject,
|
||||||
|
infile: false,
|
||||||
|
ref: false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await load(DEFAULT_REGION, isLocalOnly)
|
await load(DEFAULT_REGION, charwordTable, isLocalOnly)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
REGIONS.slice(1).map(async (region) => {
|
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 basename = `charword_table_${region}`
|
||||||
const filename = file
|
const filename = file
|
||||||
.readdirSync(AUTO_UPDATE_FOLDER)
|
.readdirSync(AUTO_UPDATE_FOLDER)
|
||||||
.filter((item) => item.startsWith(`charword_table_${region}`))[0]
|
.filter((item) => item.startsWith(`charword_table_${region}`))[0]
|
||||||
const localFilePath = path.join(AUTO_UPDATE_FOLDER, filename)
|
const localFilePath = path.join(AUTO_UPDATE_FOLDER, filename)
|
||||||
const data = isLocalOnly
|
let data: CharwordTableJson
|
||||||
? JSON.parse(file.readSync(localFilePath))
|
|
||||||
: await download(
|
const getOnlineData = async () => {
|
||||||
region,
|
return await download(
|
||||||
path.join(path.dirname(localFilePath), `${basename}.json`)
|
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
|
// 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 operatorId = id
|
||||||
let useAlternativeId = false
|
let useAlternativeId = false
|
||||||
if (typeof data.voiceLangDict[operatorId] === 'undefined') {
|
if (typeof data.voiceLangDict[operatorId] === 'undefined') {
|
||||||
@@ -236,7 +272,7 @@ const load = async (region, isLocalOnly = false) => {
|
|||||||
|
|
||||||
// put voice lines into charword_table
|
// put voice lines into charword_table
|
||||||
Object.values(data.charWords).forEach((item) => {
|
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]
|
(element) => element.info[region][item.wordKey]
|
||||||
)
|
)
|
||||||
if (operatorInfo.length > 0) {
|
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(
|
return await githubDownload(
|
||||||
`https://api.github.com/repos/${REGION_URLS[region]}/commits?path=${region}/gamedata/excel/charword_table.json`,
|
`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`,
|
`https://raw.githubusercontent.com/${REGION_URLS[region]}/master/${region}/gamedata/excel/charword_table.json`,
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/charword-table",
|
"name": "@aklive2d/charword-table",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aklive2d/libs": "workspace:*",
|
"@aklive2d/libs": "workspace:*",
|
||||||
@@ -12,10 +12,15 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"update": "mode=update node runner.js",
|
"update": "mode=update bun runner.ts",
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
"lint": "eslint && prettier --check .",
|
||||||
"build:cleanup": "rm -rf ./dist"
|
"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'
|
import { envParser, error } from '@aklive2d/libs'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
let err = []
|
let err: string[] = []
|
||||||
const { mode, name } = envParser.parse({
|
const { mode, name } = envParser.parse({
|
||||||
mode: {
|
mode: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -17,7 +17,7 @@ async function main() {
|
|||||||
})
|
})
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'build':
|
case 'build':
|
||||||
err = await build(name)
|
err = await build(name as string[])
|
||||||
break
|
break
|
||||||
case 'update':
|
case 'update':
|
||||||
await 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ app:
|
|||||||
showcase:
|
showcase:
|
||||||
public: public
|
public: public
|
||||||
assets: assets
|
assets: assets
|
||||||
|
release: release
|
||||||
dir_name:
|
dir_name:
|
||||||
data: data
|
data: data
|
||||||
dist: dist
|
dist: dist
|
||||||
|
|||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import path from 'node:path'
|
|
||||||
import { yaml } from '@aklive2d/libs'
|
|
||||||
|
|
||||||
export default yaml.read(path.resolve(import.meta.dirname, 'config.yaml'))
|
|
||||||
9
packages/config/index.ts
Normal file
9
packages/config/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import { yaml } from '@aklive2d/libs'
|
||||||
|
import type { Config } from './types'
|
||||||
|
|
||||||
|
const config: Config = yaml.read(
|
||||||
|
path.resolve(import.meta.dirname, 'config.yaml')
|
||||||
|
)
|
||||||
|
|
||||||
|
export default config
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/config",
|
"name": "@aklive2d/config",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -9,7 +9,12 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
packages/config/tsconfig.json
Normal file
25
packages/config/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/**/*"]
|
||||||
|
}
|
||||||
103
packages/config/types.ts
Normal file
103
packages/config/types.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
export type Config = {
|
||||||
|
site_id: string
|
||||||
|
total_size: number
|
||||||
|
akassets: {
|
||||||
|
project_name: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
insight: {
|
||||||
|
id: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
module: {
|
||||||
|
assets: {
|
||||||
|
config_yaml: string
|
||||||
|
background: string
|
||||||
|
music: string
|
||||||
|
charword_table: string
|
||||||
|
project_json: string
|
||||||
|
}
|
||||||
|
background: {
|
||||||
|
operator_bg_png: string
|
||||||
|
}
|
||||||
|
charword_table: {
|
||||||
|
charword_table_json: string
|
||||||
|
}
|
||||||
|
music: {
|
||||||
|
music_table_json: string
|
||||||
|
display_meta_table_json: string
|
||||||
|
audio_data_json: string
|
||||||
|
}
|
||||||
|
official_info: {
|
||||||
|
official_info_json: string
|
||||||
|
}
|
||||||
|
operator: {
|
||||||
|
operator: string
|
||||||
|
config: string
|
||||||
|
template_yaml: string
|
||||||
|
config_yaml: string
|
||||||
|
portraits: string
|
||||||
|
logos_assets: string
|
||||||
|
logos: string
|
||||||
|
directory_assets: string
|
||||||
|
MonoBehaviour: string
|
||||||
|
Texture2D: string
|
||||||
|
title: {
|
||||||
|
'zh-CN': string
|
||||||
|
'en-US': string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project_json: {
|
||||||
|
project_json: string
|
||||||
|
preview_jpg: string
|
||||||
|
template_yaml: string
|
||||||
|
}
|
||||||
|
wrangler: {
|
||||||
|
index_json: string
|
||||||
|
}
|
||||||
|
vite_helpers: {
|
||||||
|
config_json: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app: {
|
||||||
|
showcase: {
|
||||||
|
public: string
|
||||||
|
assets: string
|
||||||
|
release: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir_name: {
|
||||||
|
data: string
|
||||||
|
dist: string
|
||||||
|
extracted: string
|
||||||
|
auto_update: string
|
||||||
|
voice: {
|
||||||
|
main: string
|
||||||
|
sub: {
|
||||||
|
name: string
|
||||||
|
lang: string
|
||||||
|
lookup_region: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
directory: {
|
||||||
|
assets_dir: string
|
||||||
|
title: string
|
||||||
|
voice: string
|
||||||
|
error: {
|
||||||
|
files: {
|
||||||
|
key: string
|
||||||
|
paddings: {
|
||||||
|
left: string
|
||||||
|
right: string
|
||||||
|
top: string
|
||||||
|
bottom: string
|
||||||
|
}
|
||||||
|
}[]
|
||||||
|
voice: {
|
||||||
|
file: string
|
||||||
|
target: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ import { pipeline } from 'node:stream/promises'
|
|||||||
import pThrottle from 'p-throttle'
|
import pThrottle from 'p-throttle'
|
||||||
import { file as fileLib } from '@aklive2d/libs'
|
import { file as fileLib } from '@aklive2d/libs'
|
||||||
|
|
||||||
export const githubDownload = async (history_url, raw_url, filepath) => {
|
export type UnzipDownloadItem = {
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const githubDownload = async (
|
||||||
|
history_url: string,
|
||||||
|
raw_url: string,
|
||||||
|
filepath: string
|
||||||
|
) => {
|
||||||
const historyResponse = await fetch(history_url)
|
const historyResponse = await fetch(history_url)
|
||||||
const historyData = await historyResponse.json()
|
const historyData = await historyResponse.json()
|
||||||
const lastCommit = historyData[0]
|
const lastCommit = historyData[0]
|
||||||
@@ -21,7 +30,8 @@ export const githubDownload = async (history_url, raw_url, filepath) => {
|
|||||||
|
|
||||||
if (fileLib.exists(filepath)) {
|
if (fileLib.exists(filepath)) {
|
||||||
console.log(`${basename} is the latest version.`)
|
console.log(`${basename} is the latest version.`)
|
||||||
return JSON.parse(fileLib.readSync(filepath))
|
const content = fileLib.readSync(filepath)
|
||||||
|
return content ? JSON.parse(content) : null
|
||||||
}
|
}
|
||||||
const response = await fetch(raw_url)
|
const response = await fetch(raw_url)
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
@@ -39,9 +49,12 @@ export const githubDownload = async (history_url, raw_url, filepath) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const unzipDownload = async (
|
export const unzipDownload = async (
|
||||||
filesToDownload,
|
filesToDownload: UnzipDownloadItem[],
|
||||||
targetDir,
|
targetDir: string,
|
||||||
opts = {
|
opts: {
|
||||||
|
defaultRegex: RegExp | null
|
||||||
|
matchRegExps: RegExp[]
|
||||||
|
} = {
|
||||||
defaultRegex: null,
|
defaultRegex: null,
|
||||||
matchRegExps: [],
|
matchRegExps: [],
|
||||||
}
|
}
|
||||||
@@ -52,7 +65,7 @@ export const unzipDownload = async (
|
|||||||
interval: 1000,
|
interval: 1000,
|
||||||
})
|
})
|
||||||
while (retry.length > 0) {
|
while (retry.length > 0) {
|
||||||
const newRetry = []
|
const newRetry: UnzipDownloadItem[] = []
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
retry.map(
|
retry.map(
|
||||||
throttle(async (item) => {
|
throttle(async (item) => {
|
||||||
@@ -72,7 +85,9 @@ export const unzipDownload = async (
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
return null
|
||||||
})
|
})
|
||||||
|
if (!zip) return
|
||||||
try {
|
try {
|
||||||
for await (const entry of zip) {
|
for await (const entry of zip) {
|
||||||
if (
|
if (
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/downloader",
|
"name": "@aklive2d/downloader",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
"p-throttle": "^7.0.0"
|
"p-throttle": "^7.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
packages/downloader/tsconfig.json
Normal file
25
packages/downloader/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/**/*"]
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import js from '@eslint/js'
|
import js from '@eslint/js'
|
||||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
||||||
import globals from 'globals'
|
import globals from 'globals'
|
||||||
|
import tsConfig from './ts.js'
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{ ignores: ['dist'] },
|
{ ignores: ['dist'] },
|
||||||
@@ -24,3 +25,5 @@ export default [
|
|||||||
},
|
},
|
||||||
eslintPluginPrettierRecommended,
|
eslintPluginPrettierRecommended,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export { tsConfig }
|
||||||
|
|||||||
4
packages/eslint-config/js.js
Normal file
4
packages/eslint-config/js.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import eslint from '@eslint/js'
|
||||||
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
||||||
|
|
||||||
|
export default [eslint.configs.recommended, eslintPluginPrettierRecommended]
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/eslint-config",
|
"name": "@aklive2d/eslint-config",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.19.0",
|
||||||
"eslint": "^9.19.0",
|
"eslint": "^9.19.0",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-prettier": "^5.2.3",
|
"eslint-plugin-prettier": "^5.2.6",
|
||||||
"globals": "^15.14.0"
|
"globals": "^16.0.0",
|
||||||
},
|
"typescript": "^5.8.3",
|
||||||
"publishConfig": {
|
"typescript-eslint": "^8.31.1"
|
||||||
"access": "public"
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
packages/eslint-config/ts.js
Normal file
10
packages/eslint-config/ts.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import eslint from '@eslint/js'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
||||||
|
|
||||||
|
/** @type {import('eslint').Config} */
|
||||||
|
export default tseslint.config(
|
||||||
|
eslint.configs.recommended,
|
||||||
|
tseslint.configs.recommended,
|
||||||
|
eslintPluginPrettierRecommended
|
||||||
|
)
|
||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import * as file from './libs/file.js'
|
|
||||||
import * as yaml from './libs/yaml.js'
|
|
||||||
import * as env from './libs/env.js'
|
|
||||||
import * as error from './libs/error.js'
|
|
||||||
import * as alphaComposite from './libs/alpha_composite.js'
|
|
||||||
import * as envParser from './libs/env_parser.js'
|
|
||||||
|
|
||||||
export { file }
|
|
||||||
export { yaml }
|
|
||||||
export { env }
|
|
||||||
export { error }
|
|
||||||
export { alphaComposite }
|
|
||||||
export { envParser }
|
|
||||||
13
packages/libs/index.ts
Normal file
13
packages/libs/index.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import * as file from './libs/file.ts'
|
||||||
|
import * as yaml from './libs/yaml.ts'
|
||||||
|
import * as env from './libs/env.ts'
|
||||||
|
import * as error from './libs/error.ts'
|
||||||
|
import * as alphaComposite from './libs/alpha_composite.ts'
|
||||||
|
import * as envParser from './libs/env_parser.ts'
|
||||||
|
|
||||||
|
export { file }
|
||||||
|
export { yaml }
|
||||||
|
export { env }
|
||||||
|
export { error }
|
||||||
|
export { alphaComposite }
|
||||||
|
export { envParser }
|
||||||
@@ -1,7 +1,19 @@
|
|||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
|
|
||||||
export const process = async (filename, maskFilename, extractedDir) => {
|
export type Rect = {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
w: number
|
||||||
|
h: number
|
||||||
|
rotate: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const process = async (
|
||||||
|
filename: string,
|
||||||
|
maskFilename: string,
|
||||||
|
extractedDir: string
|
||||||
|
) => {
|
||||||
const image = sharp(path.join(extractedDir, filename)).removeAlpha()
|
const image = sharp(path.join(extractedDir, filename)).removeAlpha()
|
||||||
const imageMeta = await image.metadata()
|
const imageMeta = await image.metadata()
|
||||||
const imageBuffer = await image.toBuffer()
|
const imageBuffer = await image.toBuffer()
|
||||||
@@ -13,7 +25,22 @@ export const process = async (filename, maskFilename, extractedDir) => {
|
|||||||
return sharp(imageBuffer).joinChannel(mask).toBuffer()
|
return sharp(imageBuffer).joinChannel(mask).toBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const crop = async (buffer, rect) => {
|
export const crop = async (
|
||||||
|
buffer:
|
||||||
|
| Buffer
|
||||||
|
| ArrayBuffer
|
||||||
|
| Uint8Array
|
||||||
|
| Uint8ClampedArray
|
||||||
|
| Int8Array
|
||||||
|
| Uint16Array
|
||||||
|
| Int16Array
|
||||||
|
| Uint32Array
|
||||||
|
| Int32Array
|
||||||
|
| Float32Array
|
||||||
|
| Float64Array
|
||||||
|
| string,
|
||||||
|
rect: Rect
|
||||||
|
) => {
|
||||||
const left = rect.y
|
const left = rect.y
|
||||||
const top = rect.x
|
const top = rect.x
|
||||||
const width = rect.h
|
const width = rect.h
|
||||||
@@ -28,7 +55,7 @@ export const crop = async (buffer, rect) => {
|
|||||||
return await sharp(newImage).rotate(rotate).toBuffer()
|
return await sharp(newImage).rotate(rotate).toBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const toBuffer = async (filename, extractedDir) => {
|
export const toBuffer = async (filename: string, extractedDir: string) => {
|
||||||
const file = path.join(extractedDir, filename)
|
const file = path.join(extractedDir, filename)
|
||||||
const { data, info } = await sharp(file)
|
const { data, info } = await sharp(file)
|
||||||
.raw()
|
.raw()
|
||||||
@@ -36,7 +63,7 @@ export const toBuffer = async (filename, extractedDir) => {
|
|||||||
const { width, height, channels } = info
|
const { width, height, channels } = info
|
||||||
const pixelArray = new Uint8ClampedArray(data.buffer)
|
const pixelArray = new Uint8ClampedArray(data.buffer)
|
||||||
for (let i = 0; i < pixelArray.length; i += 4) {
|
for (let i = 0; i < pixelArray.length; i += 4) {
|
||||||
let alpha = pixelArray[i + 3] / 255
|
const alpha = pixelArray[i + 3] / 255
|
||||||
pixelArray[i + 0] = pixelArray[i + 0] * alpha
|
pixelArray[i + 0] = pixelArray[i + 0] * alpha
|
||||||
pixelArray[i + 1] = pixelArray[i + 1] * alpha
|
pixelArray[i + 1] = pixelArray[i + 1] * alpha
|
||||||
pixelArray[i + 2] = pixelArray[i + 2] * alpha
|
pixelArray[i + 2] = pixelArray[i + 2] * alpha
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
export function generate(values) {
|
export function generate(
|
||||||
|
values: {
|
||||||
|
key: string
|
||||||
|
value: string
|
||||||
|
}[]
|
||||||
|
) {
|
||||||
return values
|
return values
|
||||||
.map((value) => {
|
.map((value) => {
|
||||||
return `VITE_${value.key.toUpperCase()}=${value.value}`
|
return `VITE_${value.key.toUpperCase()}=${value.value}`
|
||||||
@@ -1,28 +1,40 @@
|
|||||||
import process from 'node:process'
|
import process from 'node:process'
|
||||||
|
|
||||||
export const parse = (args) => {
|
type Args = {
|
||||||
|
[name: string]: {
|
||||||
|
type?: string
|
||||||
|
default?: unknown
|
||||||
|
multiple?: boolean
|
||||||
|
short?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parse = (args: Args) => {
|
||||||
const envVars = process.env
|
const envVars = process.env
|
||||||
const argKeys = Object.keys(args)
|
const argKeys = Object.keys(args)
|
||||||
const values = {}
|
const values: Record<string, unknown | unknown[]> = {}
|
||||||
argKeys.map((key) => {
|
argKeys.map((key) => {
|
||||||
let noInput = false
|
let noInput = false
|
||||||
let value,
|
let value: unknown
|
||||||
type = args[key].type || 'string',
|
const type = args[key].type || 'string',
|
||||||
defaultVal = args[key].default,
|
defaultVal = args[key].default,
|
||||||
multiple = args[key].multiple || false,
|
multiple = args[key].multiple || false,
|
||||||
short = args[key].short
|
short = args[key].short
|
||||||
value = envVars[key] || envVars[short]
|
value = short
|
||||||
|
? envVars[short]
|
||||||
|
? envVars[short]
|
||||||
|
: envVars[key]
|
||||||
|
: envVars[key]
|
||||||
if (!value) noInput = true
|
if (!value) noInput = true
|
||||||
value = noInput ? defaultVal : value
|
value = noInput ? defaultVal : value
|
||||||
if (noInput) {
|
if (noInput) {
|
||||||
values[key] = value
|
values[key] = value
|
||||||
} else {
|
} else {
|
||||||
value = multiple ? value.split(',') : value
|
const cValue = multiple ? (value as string).split(',') : value
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
values[key] = []
|
values[key] = (cValue as string[]).map((item: string) =>
|
||||||
value.map((item) => {
|
typeCast(type, item)
|
||||||
values[key].push(typeCast(type, item))
|
)
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
values[key] = typeCast(type, value)
|
values[key] = typeCast(type, value)
|
||||||
}
|
}
|
||||||
@@ -31,7 +43,7 @@ export const parse = (args) => {
|
|||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
const typeCast = (type, value) => {
|
const typeCast = (type: 'number' | 'boolean' | string, value: unknown) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'number':
|
case 'number':
|
||||||
return Number(value)
|
return Number(value)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export const handle = (err) => {
|
export const handle = (err: string[]) => {
|
||||||
if (err.length > 0) {
|
if (err.length > 0) {
|
||||||
const str = `${err.length} error${err.length > 1 ? 's were' : ' was'} found:\n${err.join('\n')}`
|
const str = `${err.length} error${err.length > 1 ? 's were' : ' was'} found:\n${err.join('\n')}`
|
||||||
throw new Error(str)
|
throw new Error(str)
|
||||||
@@ -3,52 +3,61 @@ import path from 'node:path'
|
|||||||
import yauzl from 'yauzl-promise'
|
import yauzl from 'yauzl-promise'
|
||||||
import yazl from 'yazl'
|
import yazl from 'yazl'
|
||||||
|
|
||||||
export async function write(content, filePath) {
|
export async function write(
|
||||||
|
content: string | NodeJS.ArrayBufferView,
|
||||||
|
filePath: string
|
||||||
|
) {
|
||||||
mkdir(path.dirname(filePath))
|
mkdir(path.dirname(filePath))
|
||||||
return await fsP.writeFile(filePath, content, { flag: 'w' })
|
return await fsP.writeFile(filePath, content, { flag: 'w' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeSync(content, filePath) {
|
export function writeSync(
|
||||||
|
content: string | NodeJS.ArrayBufferView,
|
||||||
|
filePath: string
|
||||||
|
) {
|
||||||
mkdir(path.dirname(filePath))
|
mkdir(path.dirname(filePath))
|
||||||
return fs.writeFileSync(filePath, content, { flag: 'w' })
|
return fs.writeFileSync(filePath, content, { flag: 'w' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function read(filePath, encoding = 'utf8') {
|
export async function read(
|
||||||
return await fsP.readFile(filePath, encoding, { flag: 'r' })
|
filePath: string,
|
||||||
|
encoding: BufferEncoding = 'utf8'
|
||||||
|
) {
|
||||||
|
return await fsP.readFile(filePath, { encoding, flag: 'r' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readSync(filePath, encoding = 'utf8') {
|
export function readSync(filePath: string, encoding: BufferEncoding = 'utf8') {
|
||||||
if (exists(filePath)) {
|
if (exists(filePath)) {
|
||||||
return fs.readFileSync(filePath, encoding, { flag: 'r' })
|
return fs.readFileSync(filePath, { encoding, flag: 'r' })
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
export function exists(filePath) {
|
export function exists(filePath: string) {
|
||||||
return fs.existsSync(filePath)
|
return fs.existsSync(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rmdir(dir) {
|
export function rmdir(dir: string) {
|
||||||
if (exists(dir)) {
|
if (exists(dir)) {
|
||||||
fs.rmSync(dir, { recursive: true })
|
fs.rmSync(dir, { recursive: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rm(dir) {
|
export function rm(dir: string) {
|
||||||
if (exists(dir)) {
|
if (exists(dir)) {
|
||||||
fs.rmSync(dir, { recursive: true })
|
fs.rmSync(dir, { recursive: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mkdir(dir) {
|
export function mkdir(dir: string) {
|
||||||
if (!exists(dir)) {
|
if (!exists(dir)) {
|
||||||
fs.mkdirSync(dir, { recursive: true })
|
fs.mkdirSync(dir, { recursive: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function copy(
|
export async function copy(
|
||||||
sourcePath,
|
sourcePath: string,
|
||||||
targetPath,
|
targetPath: string,
|
||||||
mode = fs.constants.COPYFILE_FICLONE
|
mode = fs.constants.COPYFILE_FICLONE
|
||||||
) {
|
) {
|
||||||
if (!exists(sourcePath)) {
|
if (!exists(sourcePath)) {
|
||||||
@@ -60,8 +69,8 @@ export async function copy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function copyDir(
|
export async function copyDir(
|
||||||
sourcePath,
|
sourcePath: string,
|
||||||
targetPath,
|
targetPath: string,
|
||||||
mode = fs.constants.COPYFILE_FICLONE
|
mode = fs.constants.COPYFILE_FICLONE
|
||||||
) {
|
) {
|
||||||
if (!exists(sourcePath)) {
|
if (!exists(sourcePath)) {
|
||||||
@@ -72,11 +81,11 @@ export async function copyDir(
|
|||||||
return await fsP.cp(sourcePath, targetPath, { recursive: true, mode })
|
return await fsP.cp(sourcePath, targetPath, { recursive: true, mode })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendSync(content, filePath) {
|
export function appendSync(content: string | Uint8Array, filePath: string) {
|
||||||
return fs.appendFileSync(filePath, content, 'utf8')
|
return fs.appendFileSync(filePath, content, 'utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readdirSync(dir) {
|
export function readdirSync(dir: string) {
|
||||||
if (!exists(dir)) {
|
if (!exists(dir)) {
|
||||||
console.warn(`Source ${dir} does not exist.`)
|
console.warn(`Source ${dir} does not exist.`)
|
||||||
return []
|
return []
|
||||||
@@ -84,7 +93,7 @@ export function readdirSync(dir) {
|
|||||||
return fs.readdirSync(dir)
|
return fs.readdirSync(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fileTypeSync(dir) {
|
export function fileTypeSync(dir: string) {
|
||||||
if (!exists(dir)) {
|
if (!exists(dir)) {
|
||||||
console.warn(`Source ${dir} does not exist.`)
|
console.warn(`Source ${dir} does not exist.`)
|
||||||
return null
|
return null
|
||||||
@@ -92,7 +101,7 @@ export function fileTypeSync(dir) {
|
|||||||
return fs.statSync(dir).isDirectory() ? 'dir' : 'file'
|
return fs.statSync(dir).isDirectory() ? 'dir' : 'file'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const symlink = (source, target) => {
|
export const symlink = (source: string, target: string) => {
|
||||||
if (!exists(source)) {
|
if (!exists(source)) {
|
||||||
console.warn(`Source ${source} does not exist.`)
|
console.warn(`Source ${source} does not exist.`)
|
||||||
return
|
return
|
||||||
@@ -105,14 +114,14 @@ export const symlink = (source, target) => {
|
|||||||
fs.symlinkSync(relative, target)
|
fs.symlinkSync(relative, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const symlinkAll = (source, target) => {
|
export const symlinkAll = (source: string, target: string) => {
|
||||||
const files = readdirSync(source)
|
const files = readdirSync(source)
|
||||||
files.map((file) => {
|
files.map((file) => {
|
||||||
symlink(path.join(source, file), path.join(target, file))
|
symlink(path.join(source, file), path.join(target, file))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mv = (source, target) => {
|
export const mv = (source: string, target: string) => {
|
||||||
if (!exists(source)) {
|
if (!exists(source)) {
|
||||||
console.warn(`Source file ${source} does not exist.`)
|
console.warn(`Source file ${source} does not exist.`)
|
||||||
return
|
return
|
||||||
@@ -125,8 +134,8 @@ export const mv = (source, target) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const cpSync = (
|
export const cpSync = (
|
||||||
source,
|
source: string,
|
||||||
target,
|
target: string,
|
||||||
opts = {
|
opts = {
|
||||||
dereference: false,
|
dereference: false,
|
||||||
}
|
}
|
||||||
@@ -146,7 +155,7 @@ export const cpSync = (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const relative = (source, target) => {
|
export const relative = (source: string, target: string) => {
|
||||||
if (!exists(source)) {
|
if (!exists(source)) {
|
||||||
console.warn(`Source file ${source} does not exist.`)
|
console.warn(`Source file ${source} does not exist.`)
|
||||||
return
|
return
|
||||||
@@ -154,7 +163,7 @@ export const relative = (source, target) => {
|
|||||||
return path.relative(source, target)
|
return path.relative(source, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const size = (source) => {
|
export const size = (source: string) => {
|
||||||
if (!exists(source)) {
|
if (!exists(source)) {
|
||||||
console.warn(`Source file ${source} does not exist.`)
|
console.warn(`Source file ${source} does not exist.`)
|
||||||
return
|
return
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { parse } from 'yaml'
|
import { parse } from 'yaml'
|
||||||
|
import type { Tags, ScalarTag, SchemaOptions, CollectionTag } from 'yaml'
|
||||||
|
|
||||||
export function read(file_dir, customTags = []) {
|
export function read(
|
||||||
const include = {
|
file_dir: string,
|
||||||
identify: (value) => value.startsWith('!include'),
|
customTags: ScalarTag[] | CollectionTag[] = []
|
||||||
|
) {
|
||||||
|
const include: ScalarTag = {
|
||||||
|
identify: (value: unknown) =>
|
||||||
|
typeof value === 'string' && value.startsWith('!include'),
|
||||||
tag: '!include',
|
tag: '!include',
|
||||||
resolve(str) {
|
resolve(str: string) {
|
||||||
const dir = path.resolve(path.dirname(file_dir), str)
|
const dir = path.resolve(path.dirname(file_dir), str)
|
||||||
const data = read(dir)
|
const data = read(dir)
|
||||||
return data
|
return data
|
||||||
@@ -15,5 +20,5 @@ export function read(file_dir, customTags = []) {
|
|||||||
const file = fs.readFileSync(file_dir, 'utf8')
|
const file = fs.readFileSync(file_dir, 'utf8')
|
||||||
return parse(file, {
|
return parse(file, {
|
||||||
customTags: [include, ...customTags],
|
customTags: [include, ...customTags],
|
||||||
})
|
} as SchemaOptions)
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/libs",
|
"name": "@aklive2d/libs",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
@@ -12,7 +12,16 @@
|
|||||||
"yauzl-promise": "^4.0.0",
|
"yauzl-promise": "^4.0.0",
|
||||||
"yazl": "^3.3.1"
|
"yazl": "^3.3.1"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/yauzl-promise": "^4.0.1",
|
||||||
|
"@types/yazl": "^2.4.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
packages/libs/tsconfig.json
Normal file
25
packages/libs/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": ["libs/**/*"],
|
||||||
|
"exclude": ["dist/**/*", "data/**/*"]
|
||||||
|
}
|
||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,6 +2,16 @@ import path from 'node:path'
|
|||||||
import { file } from '@aklive2d/libs'
|
import { file } from '@aklive2d/libs'
|
||||||
import { githubDownload } from '@aklive2d/downloader'
|
import { githubDownload } from '@aklive2d/downloader'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
|
import type {
|
||||||
|
DisplayMetaTable,
|
||||||
|
AudioDataTable,
|
||||||
|
MusicTable,
|
||||||
|
MusicFileMapping,
|
||||||
|
MusicFiles,
|
||||||
|
MusicItem,
|
||||||
|
MusicDataItem,
|
||||||
|
MusicMapping,
|
||||||
|
} from './types.ts'
|
||||||
|
|
||||||
const AUTO_UPDATE_FOLDER = path.resolve(
|
const AUTO_UPDATE_FOLDER = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
@@ -22,12 +32,12 @@ const download = async () => {
|
|||||||
AUTO_UPDATE_FOLDER,
|
AUTO_UPDATE_FOLDER,
|
||||||
config.module.music.audio_data_json
|
config.module.music.audio_data_json
|
||||||
)
|
)
|
||||||
const metaTable = await githubDownload(
|
const metaTable: DisplayMetaTable = await githubDownload(
|
||||||
`https://api.github.com/repos/Kengxxiao/ArknightsGameData/commits?path=zh_CN/gamedata/excel/display_meta_table.json`,
|
`https://api.github.com/repos/Kengxxiao/ArknightsGameData/commits?path=zh_CN/gamedata/excel/display_meta_table.json`,
|
||||||
`https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/display_meta_table.json`,
|
`https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/display_meta_table.json`,
|
||||||
display_meta_table_json
|
display_meta_table_json
|
||||||
)
|
)
|
||||||
const audioDataTable = await githubDownload(
|
const audioDataTable: AudioDataTable = await githubDownload(
|
||||||
`https://api.github.com/repos/Kengxxiao/ArknightsGameData/commits?path=zh_CN/gamedata/excel/audio_data.json`,
|
`https://api.github.com/repos/Kengxxiao/ArknightsGameData/commits?path=zh_CN/gamedata/excel/audio_data.json`,
|
||||||
`https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/audio_data.json`,
|
`https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/audio_data.json`,
|
||||||
audio_data_json
|
audio_data_json
|
||||||
@@ -40,14 +50,17 @@ const download = async () => {
|
|||||||
|
|
||||||
const generateMapping = () => {
|
const generateMapping = () => {
|
||||||
const musicFolder = DATA_DIR
|
const musicFolder = DATA_DIR
|
||||||
const musicTable = JSON.parse(file.readSync(MUSIC_TABLE_JSON))
|
const musicTableContent = file.readSync(MUSIC_TABLE_JSON)
|
||||||
const musicFileMapping = {}
|
const musicTable: MusicTable = musicTableContent
|
||||||
const musicFiles = []
|
? JSON.parse(musicTableContent)
|
||||||
|
: null
|
||||||
|
const musicFileMapping: MusicFileMapping = {}
|
||||||
|
const musicFiles: MusicFiles = []
|
||||||
|
|
||||||
if (!musicTable) return
|
if (!musicTable) throw new Error('Music table not found')
|
||||||
for (const item of musicTable) {
|
for (const item of musicTable) {
|
||||||
const key = `${item.id}.png`
|
const key = `${item.id}.png`
|
||||||
musicFileMapping[key] = {}
|
musicFileMapping[key] = {} as MusicItem
|
||||||
|
|
||||||
if (item.intro) {
|
if (item.intro) {
|
||||||
const filename = `${item.intro.split('/').pop()}.ogg`
|
const filename = `${item.intro.split('/').pop()}.ogg`
|
||||||
@@ -78,34 +91,37 @@ const generateMapping = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mapping = generateMapping()
|
export const mapping: MusicMapping = generateMapping()
|
||||||
|
|
||||||
export const update = async () => {
|
export const update = async () => {
|
||||||
const { metaTable, audioDataTable } = await download()
|
const { metaTable, audioDataTable } = await download()
|
||||||
const musicTable = audioDataTable.musics
|
const musicTable = audioDataTable.musics
|
||||||
const musicBank = audioDataTable.bgmBanks
|
const musicBank = audioDataTable.bgmBanks
|
||||||
const musicBankAlias = audioDataTable.bankAlias
|
const musicBankAlias = audioDataTable.bankAlias
|
||||||
const musicData = metaTable.homeBackgroundData.homeBgDataList.reduce(
|
const musicData: MusicDataItem[] =
|
||||||
(acc, cur) => {
|
metaTable.homeBackgroundData.homeBgDataList.reduce((acc, cur) => {
|
||||||
acc.push({
|
acc.push({
|
||||||
id: cur.bgId,
|
id: cur.bgId,
|
||||||
musicId: cur.bgMusicId,
|
musicId: cur.bgMusicId,
|
||||||
})
|
})
|
||||||
return acc
|
return acc
|
||||||
},
|
}, [] as MusicDataItem[])
|
||||||
[]
|
|
||||||
)
|
|
||||||
const list = []
|
const list = []
|
||||||
for (const item of musicData) {
|
for (const item of musicData) {
|
||||||
let bankName = musicTable.find((el) => item.musicId === el.id).bank
|
const bankItem = musicTable.find((el) => item.musicId === el.id)
|
||||||
|
if (typeof bankItem === 'undefined')
|
||||||
|
console.warn(`No music found for id ${item.musicId}`)
|
||||||
|
let bankName = bankItem!.bank
|
||||||
if (typeof musicBankAlias[bankName] !== 'undefined') {
|
if (typeof musicBankAlias[bankName] !== 'undefined') {
|
||||||
bankName = musicBankAlias[bankName]
|
bankName = musicBankAlias[bankName]
|
||||||
}
|
}
|
||||||
const obj = musicBank.find((el) => bankName === el.name)
|
const obj = musicBank.find((el) => bankName === el.name)
|
||||||
|
if (typeof obj === 'undefined')
|
||||||
|
console.warn(`No bank found for name ${bankName}`)
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
intro: obj.intro,
|
intro: obj!.intro,
|
||||||
loop: obj.loop,
|
loop: obj!.loop,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
list.push({
|
list.push({
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/music",
|
"name": "@aklive2d/music",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aklive2d/libs": "workspace:*",
|
"@aklive2d/libs": "workspace:*",
|
||||||
@@ -11,9 +11,14 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"update": "mode=update node runner.js",
|
"update": "mode=update bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
"lint": "eslint && prettier --check .",
|
||||||
"build:cleanup": "rm -rf ./data"
|
"build:cleanup": "rm -rf ./data"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { envParser } from '@aklive2d/libs'
|
import { envParser } from '@aklive2d/libs'
|
||||||
import { update } from './index.js'
|
import { update } from './index.ts'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const { mode } = envParser.parse({
|
const { mode } = envParser.parse({
|
||||||
25
packages/music/tsconfig.json
Normal file
25
packages/music/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/**/*"]
|
||||||
|
}
|
||||||
295
packages/music/types.ts
Normal file
295
packages/music/types.ts
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
export type MusicMapping = {
|
||||||
|
musicFiles: MusicFiles
|
||||||
|
musicFileMapping: MusicFileMapping
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MusicItem = {
|
||||||
|
id?: string
|
||||||
|
intro: string | null
|
||||||
|
loop: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MusicTable = MusicItem[]
|
||||||
|
|
||||||
|
export type MusicFileMapping = Record<string, MusicItem>
|
||||||
|
|
||||||
|
export type MusicFile = {
|
||||||
|
filename: string
|
||||||
|
source: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MusicFiles = MusicFile[]
|
||||||
|
|
||||||
|
export type DisplayMetaTable = {
|
||||||
|
playerAvatarData: {
|
||||||
|
defaultAvatarId: string
|
||||||
|
avatarList: {
|
||||||
|
avatarId: string
|
||||||
|
avatarType: string
|
||||||
|
avatarIdSort: number
|
||||||
|
avatarIdDesc: string
|
||||||
|
avatarItemName: string
|
||||||
|
avatarItemDesc: string
|
||||||
|
avatarItemUsage: string
|
||||||
|
obtainApproach: string
|
||||||
|
dynAvatarId: null | unknown
|
||||||
|
}[]
|
||||||
|
avatarTypeData: {
|
||||||
|
[key: string]: {
|
||||||
|
avatarType: string
|
||||||
|
typeName: string
|
||||||
|
sortId: number
|
||||||
|
avatarIdList: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
homeBackgroundData: {
|
||||||
|
defaultBackgroundId: string
|
||||||
|
defaultThemeId: string
|
||||||
|
homeBgDataList: {
|
||||||
|
bgId: string
|
||||||
|
bgSortId: number
|
||||||
|
bgStartTime: number
|
||||||
|
bgName: string
|
||||||
|
bgMusicId: string
|
||||||
|
bgDes: string
|
||||||
|
bgUsage: string
|
||||||
|
obtainApproach: string
|
||||||
|
unlockDesList: string[]
|
||||||
|
}[]
|
||||||
|
themeList: {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
sortId: number
|
||||||
|
startTime: number
|
||||||
|
tmName: string
|
||||||
|
tmDes: string
|
||||||
|
tmUsage: string
|
||||||
|
obtainApproach: string
|
||||||
|
unlockDesList: string[]
|
||||||
|
isLimitObtain: boolean
|
||||||
|
hideWhenLimit: boolean
|
||||||
|
rarity: string
|
||||||
|
}[]
|
||||||
|
backgroundLimitData: {
|
||||||
|
[key: string]: {
|
||||||
|
bgId: string
|
||||||
|
limitInfos: {
|
||||||
|
limitInfoId: string
|
||||||
|
startTime: Date
|
||||||
|
endTime: Date
|
||||||
|
invalidObtainDesc: string
|
||||||
|
displayAfterEndTime: boolean
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
themeLimitData: {
|
||||||
|
[key: string]: {
|
||||||
|
id: string
|
||||||
|
limitInfos: {
|
||||||
|
startTime: Date
|
||||||
|
endTime: Date
|
||||||
|
invalidObtainDesc: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultBgMusicId: string
|
||||||
|
themeStartTime: Date
|
||||||
|
}
|
||||||
|
nameCardV2Data: {
|
||||||
|
fixedModuleData: {
|
||||||
|
[key: string]: {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removableModuleData: {
|
||||||
|
[key: string]: {
|
||||||
|
sortId: number
|
||||||
|
subType: string
|
||||||
|
name: string
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
skinData: {
|
||||||
|
[key: string]: {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
sortId: number
|
||||||
|
isSpTheme: boolean
|
||||||
|
defaultShowDetail: boolean
|
||||||
|
themeName: string
|
||||||
|
themeEnName: string
|
||||||
|
skinStartTime: number
|
||||||
|
skinDesc: string
|
||||||
|
usageDesc: string
|
||||||
|
skinApproach: string
|
||||||
|
unlockConditionCnt: number
|
||||||
|
unlockDescList: unknown[]
|
||||||
|
fixedModuleList: string[]
|
||||||
|
rarity: string
|
||||||
|
skinTmplCnt: number
|
||||||
|
canChangeTmpl: boolean
|
||||||
|
isTimeLimit: boolean
|
||||||
|
timeLimitInfoList: unknown[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consts: {
|
||||||
|
defaultNameCardSkinId: string
|
||||||
|
canUidHide: boolean
|
||||||
|
removableModuleMaxCount: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mailArchiveData: {
|
||||||
|
mailArchiveInfoDict: {
|
||||||
|
[key: string]: {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
sortId: number
|
||||||
|
displayReceiveTs: number
|
||||||
|
year: number
|
||||||
|
dateDelta: number
|
||||||
|
senderId: string
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
rewardList: {
|
||||||
|
id: string
|
||||||
|
count: number
|
||||||
|
type: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constData: {
|
||||||
|
funcOpenTs: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mailSenderData: {
|
||||||
|
senderDict: {
|
||||||
|
[key: string]: {
|
||||||
|
senderId: string
|
||||||
|
senderName: string
|
||||||
|
avatarId: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emoticonData: {
|
||||||
|
emojiDataDict: {
|
||||||
|
[key: string]: {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
sortId: number
|
||||||
|
picId: string
|
||||||
|
desc: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emoticonThemeDataDict: { [key: string]: string[] }
|
||||||
|
}
|
||||||
|
storyVariantData: {
|
||||||
|
[key: string]: {
|
||||||
|
plotTaskId: string
|
||||||
|
spStoryId: string
|
||||||
|
storyId: string
|
||||||
|
priority: number
|
||||||
|
startTime: number
|
||||||
|
endTime: number
|
||||||
|
template: string
|
||||||
|
param: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AudioDataTable = {
|
||||||
|
bgmBanks: {
|
||||||
|
intro: string
|
||||||
|
loop: string
|
||||||
|
volume: number
|
||||||
|
crossfade: number
|
||||||
|
delay: number
|
||||||
|
fadeStyleId: null | string
|
||||||
|
name: string
|
||||||
|
}[]
|
||||||
|
soundFXBanks: {
|
||||||
|
sounds: {
|
||||||
|
asset: string
|
||||||
|
weight: number
|
||||||
|
important: boolean
|
||||||
|
is2D: boolean
|
||||||
|
delay: number
|
||||||
|
minPitch: number
|
||||||
|
maxPitch: number
|
||||||
|
minVolume: number
|
||||||
|
maxVolume: number
|
||||||
|
ignoreTimeScale: boolean
|
||||||
|
}[]
|
||||||
|
maxSoundAllowed: number
|
||||||
|
popOldest: boolean
|
||||||
|
customMixerGroup: string
|
||||||
|
loop: boolean
|
||||||
|
name: string
|
||||||
|
mixerDesc: null | string
|
||||||
|
}[]
|
||||||
|
soundFXCtrlBanks: {
|
||||||
|
targetBank: string
|
||||||
|
ctrlStop: boolean
|
||||||
|
ctrlStopFadetime: number
|
||||||
|
name: string
|
||||||
|
}[]
|
||||||
|
snapshotBanks: {
|
||||||
|
targetSnapshot: string
|
||||||
|
hookSoundFxBank: string
|
||||||
|
delay: number
|
||||||
|
duration: number
|
||||||
|
name: string
|
||||||
|
}[]
|
||||||
|
battleVoice: {
|
||||||
|
crossfade: number
|
||||||
|
minTimeDeltaForEnemyEncounter: number
|
||||||
|
minSpCostForImportantPassiveSkill: number
|
||||||
|
voiceTypeOptions: {
|
||||||
|
voiceType: string
|
||||||
|
priority: number
|
||||||
|
overlapIfSamePriority: boolean
|
||||||
|
cooldown: number
|
||||||
|
delay: number
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
musics: {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
bank: string
|
||||||
|
}[]
|
||||||
|
duckings: {
|
||||||
|
bank: string
|
||||||
|
volume: number
|
||||||
|
fadeTime: number
|
||||||
|
delay: number
|
||||||
|
fadeStyleId: null | string
|
||||||
|
}[]
|
||||||
|
fadeStyles: {
|
||||||
|
styleName: string
|
||||||
|
fadeinTime: number
|
||||||
|
fadeoutTime: number
|
||||||
|
fadeinType: string
|
||||||
|
fadeoutType: string
|
||||||
|
}[]
|
||||||
|
soundFxVoiceLang: {
|
||||||
|
[key: string]: {
|
||||||
|
[key: string]: {
|
||||||
|
JP: string
|
||||||
|
CN_MANDARIN: string
|
||||||
|
KR: string
|
||||||
|
EN?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bankAlias: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MusicDataItem = {
|
||||||
|
id: string
|
||||||
|
musicId: string
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,6 +2,13 @@ import jsdom from 'jsdom'
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { file } from '@aklive2d/libs'
|
import { file } from '@aklive2d/libs'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
|
import type {
|
||||||
|
OfficialArray,
|
||||||
|
OfficialInfo,
|
||||||
|
OfficialOperatorInfo,
|
||||||
|
OfficialInfoMapping,
|
||||||
|
OfficialInfoOperatorConfig,
|
||||||
|
} from './types'
|
||||||
|
|
||||||
const AUTO_UPDATE_FOLDER = path.resolve(
|
const AUTO_UPDATE_FOLDER = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
@@ -18,22 +25,24 @@ export const update = async () => {
|
|||||||
|
|
||||||
const dom = new jsdom.JSDOM(html_text)
|
const dom = new jsdom.JSDOM(html_text)
|
||||||
const scripts = dom.window.document.body.querySelectorAll('script')
|
const scripts = dom.window.document.body.querySelectorAll('script')
|
||||||
let data
|
let data: OfficialArray | null = null
|
||||||
scripts.forEach((e) => {
|
scripts.forEach((e) => {
|
||||||
if (e.textContent.includes('干员晋升')) {
|
if (e.textContent?.includes('干员晋升')) {
|
||||||
data = JSON.parse(
|
data = JSON.parse(
|
||||||
e.textContent
|
e.textContent
|
||||||
.replace('self.__next_f.push([1,"c:', '')
|
.replace('self.__next_f.push([1,"c:', '')
|
||||||
.replace('\\n"])', '')
|
.replace('\\n"])', '')
|
||||||
.replaceAll('\\', '')
|
.replaceAll('\\', '')
|
||||||
)
|
) as OfficialArray
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const rows = data[0][3].initialData
|
if (!data) throw new Error('No data found')
|
||||||
|
const rows = (data as OfficialArray)[0][3].initialData
|
||||||
|
|
||||||
const dict = {
|
const dict: OfficialInfo = {
|
||||||
length: rows.length,
|
length: rows.length,
|
||||||
dates: [],
|
dates: [],
|
||||||
|
info: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_displayTime = rows[0].displayTime
|
let current_displayTime = rows[0].displayTime
|
||||||
@@ -42,22 +51,22 @@ export const update = async () => {
|
|||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
const displayTime = row.displayTime
|
const displayTime = row.displayTime
|
||||||
if (displayTime !== current_displayTime) {
|
if (displayTime !== current_displayTime) {
|
||||||
dict[current_displayTime] = current_block
|
dict.info[current_displayTime] = current_block
|
||||||
dict.dates.push(current_displayTime)
|
dict.dates.push(current_displayTime)
|
||||||
current_displayTime = row.displayTime
|
current_displayTime = row.displayTime
|
||||||
current_block = []
|
current_block = []
|
||||||
}
|
}
|
||||||
current_block.push(get_row(row))
|
current_block.push(get_row(row))
|
||||||
}
|
}
|
||||||
dict[current_displayTime] = current_block
|
dict.info[current_displayTime] = current_block
|
||||||
dict.dates.push(current_displayTime)
|
dict.dates.push(current_displayTime)
|
||||||
|
|
||||||
file.writeSync(JSON.stringify(dict, null, 4), OFFICIAL_INFO_JSON)
|
file.writeSync(JSON.stringify(dict, null, 4), OFFICIAL_INFO_JSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
const get_row = (row) => {
|
const get_row = (row: OfficialOperatorInfo): OfficialInfoOperatorConfig => {
|
||||||
const type = row.type
|
const type = row.type
|
||||||
let codename_zhCN, item_type
|
let codename_zhCN, item_type: 'operator' | 'skin'
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
codename_zhCN = row.charName
|
codename_zhCN = row.charName
|
||||||
@@ -82,18 +91,18 @@ const get_row = (row) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const generateMapping = () => {
|
const generateMapping = () => {
|
||||||
const mapping = {}
|
const mapping: OfficialInfoMapping = {}
|
||||||
const data = JSON.parse(file.readSync(OFFICIAL_INFO_JSON))
|
const content = file.readSync(OFFICIAL_INFO_JSON)
|
||||||
if (!data) return
|
if (!content) throw new Error('Failed to read official info JSON')
|
||||||
Object.keys(data).forEach((key) => {
|
const data: OfficialInfo = JSON.parse(content)
|
||||||
if (typeof data[key] === 'object') {
|
if (!data) throw new Error('Failed to parse official info JSON')
|
||||||
data[key].forEach((operator) => {
|
Object.keys(data.info).forEach((date) => {
|
||||||
mapping[operator.id] = {
|
data.info[date].forEach((operator) => {
|
||||||
date: key,
|
mapping[operator.id] = {
|
||||||
...operator,
|
date,
|
||||||
}
|
...operator,
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
return mapping
|
return mapping
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/official-info",
|
"name": "@aklive2d/official-info",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
@@ -11,8 +11,13 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"update": "mode=update node runner.js",
|
"update": "mode=update bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { envParser } from '@aklive2d/libs'
|
import { envParser } from '@aklive2d/libs'
|
||||||
import { update } from './index.js'
|
import { update } from './index.ts'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const { mode } = envParser.parse({
|
const { mode } = envParser.parse({
|
||||||
25
packages/official-info/tsconfig.json
Normal file
25
packages/official-info/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/**/*"]
|
||||||
|
}
|
||||||
48
packages/official-info/types.ts
Normal file
48
packages/official-info/types.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
export type OfficialOperatorInfo = {
|
||||||
|
cid: string
|
||||||
|
charName: string
|
||||||
|
suitName: string
|
||||||
|
codename: string
|
||||||
|
type: number
|
||||||
|
displayTime: string
|
||||||
|
portraitSrc: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OfficialDataArray = [
|
||||||
|
'$',
|
||||||
|
string,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
initialData: OfficialOperatorInfo[]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
type UnrelatedDataArray = ['$', string, null, unknown]
|
||||||
|
|
||||||
|
export type OfficialArray = [OfficialDataArray, UnrelatedDataArray]
|
||||||
|
|
||||||
|
export type OfficialInfo = {
|
||||||
|
length: number
|
||||||
|
dates: string[]
|
||||||
|
info: {
|
||||||
|
[date: string]: OfficialInfoOperatorConfig[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OfficialInfoOperatorConfig {
|
||||||
|
codename: {
|
||||||
|
'zh-CN': string
|
||||||
|
'en-US': string
|
||||||
|
}
|
||||||
|
type: 'operator' | 'skin'
|
||||||
|
link: string
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperatorConfig extends OfficialInfoOperatorConfig {
|
||||||
|
date: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OfficialInfoMapping = {
|
||||||
|
[id: string]: OperatorConfig
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
dist
|
dist
|
||||||
data
|
data
|
||||||
auto_update
|
auto_update
|
||||||
|
config
|
||||||
|
config.yaml
|
||||||
|
|||||||
@@ -61,3 +61,7 @@ yu: !include config/yu.yaml
|
|||||||
logos_radiant_serenity: !include config/logos_radiant_serenity.yaml
|
logos_radiant_serenity: !include config/logos_radiant_serenity.yaml
|
||||||
muelsyse_golden_reverie: !include config/muelsyse_golden_reverie.yaml
|
muelsyse_golden_reverie: !include config/muelsyse_golden_reverie.yaml
|
||||||
ines_melodic_flutter: !include config/ines_melodic_flutter.yaml
|
ines_melodic_flutter: !include config/ines_melodic_flutter.yaml
|
||||||
|
wisadel_supernova: !include config/wisadel_supernova.yaml
|
||||||
|
archetto_glory_of_the_devout: !include config/archetto_glory_of_the_devout.yaml
|
||||||
|
kroos_moonlit_voyage: !include config/kroos_moonlit_voyage.yaml
|
||||||
|
exusiai_the_new_covenant: !include config/exusiai_the_new_covenant.yaml
|
||||||
|
|||||||
13
packages/operator/config/archetto_glory_of_the_devout.yaml
Normal file
13
packages/operator/config/archetto_glory_of_the_devout.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
filename: dyn_illust_char_332_archet_sale#14
|
||||||
|
logo: logo_Laterano
|
||||||
|
fallback_name: char_332_archet_sale#14
|
||||||
|
viewport_left: 0
|
||||||
|
viewport_right: 0
|
||||||
|
viewport_top: 0
|
||||||
|
viewport_bottom: 0
|
||||||
|
invert_filter: true
|
||||||
|
codename:
|
||||||
|
zh-CN: 至虔者荣光 · 空弦
|
||||||
|
en-US: Glory of the Devout / Archetto
|
||||||
|
use_json: false
|
||||||
|
official_id: '202504953'
|
||||||
13
packages/operator/config/exusiai_the_new_covenant.yaml
Normal file
13
packages/operator/config/exusiai_the_new_covenant.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
filename: dyn_illust_char_1041_angel2
|
||||||
|
logo: logo_penguin
|
||||||
|
fallback_name: char_1041_angel2_2
|
||||||
|
viewport_left: 0
|
||||||
|
viewport_right: 0
|
||||||
|
viewport_top: 0
|
||||||
|
viewport_bottom: 0
|
||||||
|
invert_filter: true
|
||||||
|
codename:
|
||||||
|
zh-CN: 新约能天使
|
||||||
|
en-US: Exusiai the New Covenant
|
||||||
|
use_json: false
|
||||||
|
official_id: '202504941'
|
||||||
13
packages/operator/config/kroos_moonlit_voyage.yaml
Normal file
13
packages/operator/config/kroos_moonlit_voyage.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
filename: dyn_illust_char_124_kroos_sale#14
|
||||||
|
logo: logo_reserve1
|
||||||
|
fallback_name: char_124_kroos_sale#14
|
||||||
|
viewport_left: 0
|
||||||
|
viewport_right: 0
|
||||||
|
viewport_top: 0
|
||||||
|
viewport_bottom: 0
|
||||||
|
invert_filter: true
|
||||||
|
codename:
|
||||||
|
zh-CN: 星月漂流记 · 克洛丝
|
||||||
|
en-US: Moonlit Voyage / Kroos
|
||||||
|
use_json: false
|
||||||
|
official_id: '202504992'
|
||||||
13
packages/operator/config/wisadel_supernova.yaml
Normal file
13
packages/operator/config/wisadel_supernova.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
filename: dyn_illust_char_1035_wisdel_sale#14
|
||||||
|
logo: logo_babel
|
||||||
|
fallback_name: char_1035_wisdel_sale#14
|
||||||
|
viewport_left: 0
|
||||||
|
viewport_right: 0
|
||||||
|
viewport_top: 0
|
||||||
|
viewport_bottom: 0
|
||||||
|
invert_filter: true
|
||||||
|
codename:
|
||||||
|
zh-CN: 超新星 · 维什戴尔
|
||||||
|
en-US: Supernova / Wisadel
|
||||||
|
use_json: false
|
||||||
|
official_id: '202504974'
|
||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -3,19 +3,20 @@ import { stringify } from 'yaml'
|
|||||||
import { yaml, file, alphaComposite } from '@aklive2d/libs'
|
import { yaml, file, alphaComposite } from '@aklive2d/libs'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
import { mapping as officialInfoMapping } from '@aklive2d/official-info'
|
import { mapping as officialInfoMapping } from '@aklive2d/official-info'
|
||||||
|
import type { Config, PortraitHub, PortraitJson, AssetsJson } from './types.ts'
|
||||||
|
|
||||||
export const CONFIG_PATH = path.resolve(
|
export const CONFIG_PATH = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
config.module.operator.config_yaml
|
config.module.operator.config_yaml
|
||||||
)
|
)
|
||||||
const CONFIG = yaml.read(CONFIG_PATH)
|
const CONFIG: Config = yaml.read(CONFIG_PATH)
|
||||||
export const OPERATOR_SOURCE_FOLDER = path.resolve(
|
export const OPERATOR_SOURCE_FOLDER = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
config.dir_name.data
|
config.dir_name.data
|
||||||
)
|
)
|
||||||
const DIST_DIR = path.join(import.meta.dirname, config.dir_name.dist)
|
const DIST_DIR = path.join(import.meta.dirname, config.dir_name.dist)
|
||||||
|
|
||||||
const getVoiceFolders = (name) => {
|
const getVoiceFolders = (name: string) => {
|
||||||
return config.dir_name.voice.sub.map((sub) =>
|
return config.dir_name.voice.sub.map((sub) =>
|
||||||
path.join(
|
path.join(
|
||||||
OPERATOR_SOURCE_FOLDER,
|
OPERATOR_SOURCE_FOLDER,
|
||||||
@@ -26,7 +27,7 @@ const getVoiceFolders = (name) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getExtractedFolder = (name) => {
|
const getExtractedFolder = (name: string) => {
|
||||||
return path.join(OPERATOR_SOURCE_FOLDER, name, config.dir_name.extracted)
|
return path.join(OPERATOR_SOURCE_FOLDER, name, config.dir_name.extracted)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,11 +35,11 @@ const getConfigFolder = () => {
|
|||||||
return path.join(import.meta.dirname, config.module.operator.config)
|
return path.join(import.meta.dirname, config.module.operator.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDistFolder = (name) => {
|
const getDistFolder = (name: string) => {
|
||||||
return path.join(DIST_DIR, config.module.operator.operator, name)
|
return path.join(DIST_DIR, config.module.operator.operator, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const has = (name) => {
|
export const has = (name: string) => {
|
||||||
return Object.keys(operators).includes(name)
|
return Object.keys(operators).includes(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ const generateMapping = () => {
|
|||||||
return CONFIG
|
return CONFIG
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyVoices = (name) => {
|
const copyVoices = (name: string) => {
|
||||||
file.symlinkAll(
|
file.symlinkAll(
|
||||||
path.join(OPERATOR_SOURCE_FOLDER, name, config.dir_name.voice.main),
|
path.join(OPERATOR_SOURCE_FOLDER, name, config.dir_name.voice.main),
|
||||||
path.join(DIST_DIR, config.dir_name.voice.main, name)
|
path.join(DIST_DIR, config.dir_name.voice.main, name)
|
||||||
@@ -85,15 +86,15 @@ const operators = generateMapping()
|
|||||||
|
|
||||||
export default operators
|
export default operators
|
||||||
|
|
||||||
export function getOperatorId(name, matcher = '$2$3$4') {
|
export function getOperatorId(name: string, matcher = '$2$3$4') {
|
||||||
return name.replace(/^(.*)(char_[\d]+)(_[A-Za-z0-9]+)(|_.*)$/g, matcher)
|
return name.replace(/^(.*)(char_[\d]+)(_[A-Za-z0-9]+)(|_.*)$/g, matcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getOperatorAlternativeId = (id) => {
|
export const getOperatorAlternativeId = (id: string) => {
|
||||||
return getOperatorId(id, '$2$3')
|
return getOperatorId(id, '$2$3')
|
||||||
}
|
}
|
||||||
|
|
||||||
export const build = async (namesToBuild) => {
|
export const build = async (namesToBuild: string[]) => {
|
||||||
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
||||||
console.log('Generating assets for', names.length, 'operators')
|
console.log('Generating assets for', names.length, 'operators')
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
@@ -103,7 +104,7 @@ export const build = async (namesToBuild) => {
|
|||||||
copyLogos()
|
copyLogos()
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateAssets = async (name) => {
|
const generateAssets = async (name: string) => {
|
||||||
const extractedDir = getExtractedFolder(name)
|
const extractedDir = getExtractedFolder(name)
|
||||||
const outDir = getDistFolder(name)
|
const outDir = getDistFolder(name)
|
||||||
file.rmdir(outDir)
|
file.rmdir(outDir)
|
||||||
@@ -134,31 +135,35 @@ const generateAssets = async (name) => {
|
|||||||
OPERATOR_SOURCE_FOLDER,
|
OPERATOR_SOURCE_FOLDER,
|
||||||
config.module.operator.portraits
|
config.module.operator.portraits
|
||||||
)
|
)
|
||||||
const portraitHub = JSON.parse(
|
const portraitHubContent = file.readSync(
|
||||||
file.readSync(
|
path.join(
|
||||||
path.join(
|
portraitDir,
|
||||||
portraitDir,
|
config.module.operator.MonoBehaviour,
|
||||||
config.module.operator.MonoBehaviour,
|
'portrait_hub.json'
|
||||||
'portrait_hub.json'
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if (!portraitHubContent) throw new Error('portrait_hub.json not found')
|
||||||
|
const portraitHub: PortraitHub = JSON.parse(portraitHubContent)
|
||||||
const fallback_name_lowerCase = fallback_name.toLowerCase()
|
const fallback_name_lowerCase = fallback_name.toLowerCase()
|
||||||
const portraitAtlas = portraitHub._sprites.find(
|
const portraitItem = portraitHub._sprites.find(
|
||||||
(item) => item.name.toLowerCase() === fallback_name_lowerCase
|
(item) => item.name.toLowerCase() === fallback_name_lowerCase
|
||||||
).atlas
|
)
|
||||||
const portraitJson = JSON.parse(
|
if (!portraitItem) throw new Error(`portrait ${fallback_name} not found`)
|
||||||
file.readSync(
|
const portraitAtlas = portraitItem.atlas
|
||||||
path.join(
|
const portraitJsonText = file.readSync(
|
||||||
portraitDir,
|
path.join(
|
||||||
config.module.operator.MonoBehaviour,
|
portraitDir,
|
||||||
`portraits#${portraitAtlas}.json`
|
config.module.operator.MonoBehaviour,
|
||||||
)
|
`portraits#${portraitAtlas}.json`
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if (!portraitJsonText)
|
||||||
|
throw new Error(`portrait ${fallback_name} json not found`)
|
||||||
|
const portraitJson: PortraitJson = JSON.parse(portraitJsonText)
|
||||||
const item = portraitJson._sprites.find(
|
const item = portraitJson._sprites.find(
|
||||||
(item) => item.name.toLowerCase() === fallback_name_lowerCase
|
(item) => item.name.toLowerCase() === fallback_name_lowerCase
|
||||||
)
|
)
|
||||||
|
if (!item) throw new Error(`portrait ${fallback_name} not found`)
|
||||||
const rect = {
|
const rect = {
|
||||||
...item.rect,
|
...item.rect,
|
||||||
rotate: item.rotate,
|
rotate: item.rotate,
|
||||||
@@ -186,15 +191,18 @@ const generateAssets = async (name) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const generateAssetsJson = async (
|
export const generateAssetsJson = async (
|
||||||
filename,
|
filename: string,
|
||||||
extractedDir,
|
extractedDir: string,
|
||||||
targetDir,
|
targetDir: string,
|
||||||
_opts = {
|
_opts: {
|
||||||
|
useJSON?: boolean
|
||||||
|
useSymLink?: boolean
|
||||||
|
} = {
|
||||||
useJSON: false,
|
useJSON: false,
|
||||||
useSymLink: true,
|
useSymLink: true,
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
const assetsJson = []
|
const assetsJson: AssetsJson = []
|
||||||
|
|
||||||
let skelFilename
|
let skelFilename
|
||||||
if (_opts.useJSON) {
|
if (_opts.useJSON) {
|
||||||
@@ -206,6 +214,8 @@ export const generateAssetsJson = async (
|
|||||||
const atlasPath = path.join(extractedDir, atlasFilename)
|
const atlasPath = path.join(extractedDir, atlasFilename)
|
||||||
let atlas = await file.read(atlasPath)
|
let atlas = await file.read(atlasPath)
|
||||||
const matches = atlas.match(new RegExp(/(.*).png/g))
|
const matches = atlas.match(new RegExp(/(.*).png/g))
|
||||||
|
if (!matches)
|
||||||
|
throw new Error(`No matches found in atlas file ${atlasFilename}`)
|
||||||
for (const item of matches) {
|
for (const item of matches) {
|
||||||
let buffer
|
let buffer
|
||||||
const alphaCompositeFilename = `${path.parse(item).name}[alpha].png`
|
const alphaCompositeFilename = `${path.parse(item).name}[alpha].png`
|
||||||
@@ -236,17 +246,19 @@ export const generateAssetsJson = async (
|
|||||||
const dir = path.join(targetDir, item.filename)
|
const dir = path.join(targetDir, item.filename)
|
||||||
if (item.content) {
|
if (item.content) {
|
||||||
file.writeSync(item.content, dir)
|
file.writeSync(item.content, dir)
|
||||||
} else {
|
} else if (item.path) {
|
||||||
if (_opts.useSymLink) {
|
if (_opts.useSymLink) {
|
||||||
file.symlink(item.path, dir)
|
file.symlink(item.path, dir)
|
||||||
} else {
|
} else {
|
||||||
file.cpSync(item.path, dir)
|
file.cpSync(item.path, dir)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(`Invalid asset item: ${item}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const init = (name, id) => {
|
export const init = (name: string, id: string) => {
|
||||||
const voiceFolders = getVoiceFolders(name)
|
const voiceFolders = getVoiceFolders(name)
|
||||||
const extractedFolder = getExtractedFolder(name)
|
const extractedFolder = getExtractedFolder(name)
|
||||||
const operatorConfigFolder = getConfigFolder()
|
const operatorConfigFolder = getConfigFolder()
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@aklive2d/operator",
|
"name": "@aklive2d/operator",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yaml": "^2.7.0",
|
"yaml": "^2.7.0",
|
||||||
@@ -12,10 +12,15 @@
|
|||||||
"@aklive2d/eslint-config": "workspace:*",
|
"@aklive2d/eslint-config": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"init": "mode=init node runner.js",
|
"init": "mode=init bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check .",
|
"lint": "eslint && prettier --check .",
|
||||||
"build:cleanup": "rm -rf ./dist ./data"
|
"build:cleanup": "rm -rf ./dist ./data"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { envParser } from '@aklive2d/libs'
|
import { envParser } from '@aklive2d/libs'
|
||||||
import { build, init } from './index.js'
|
import { build, init } from './index.ts'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
mode: string
|
||||||
|
name: string[]
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const { mode, name, id } = envParser.parse({
|
const { mode, name, id } = envParser.parse({
|
||||||
@@ -16,7 +22,7 @@ async function main() {
|
|||||||
id: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
})
|
}) as Args
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'build':
|
case 'build':
|
||||||
await build(name)
|
await build(name)
|
||||||
25
packages/operator/tsconfig.json
Normal file
25
packages/operator/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/**/*"]
|
||||||
|
}
|
||||||
93
packages/operator/types.ts
Normal file
93
packages/operator/types.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
export type Codename = { 'zh-CN': string; 'en-US': string }
|
||||||
|
|
||||||
|
export interface OperatorConfig {
|
||||||
|
filename: string
|
||||||
|
logo: string
|
||||||
|
fallback_name: string
|
||||||
|
viewport_left: number
|
||||||
|
viewport_right: number
|
||||||
|
viewport_top: number
|
||||||
|
viewport_bottom: number
|
||||||
|
invert_filter: boolean
|
||||||
|
codename: Codename
|
||||||
|
use_json: boolean
|
||||||
|
official_id: string
|
||||||
|
title: string
|
||||||
|
type: 'operator' | 'skin'
|
||||||
|
link: string
|
||||||
|
id: string
|
||||||
|
date: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Config = {
|
||||||
|
[name: string]: OperatorConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileIDPathID = {
|
||||||
|
m_FileID: number
|
||||||
|
m_PathID: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PortraitHub = {
|
||||||
|
m_GameObject: FileIDPathID
|
||||||
|
m_Enabled: number
|
||||||
|
m_Script: FileIDPathID
|
||||||
|
m_Name: string
|
||||||
|
_sprites: {
|
||||||
|
name: string
|
||||||
|
atlas: number
|
||||||
|
}[]
|
||||||
|
_atlases: string[]
|
||||||
|
_inputSpriteDir: string
|
||||||
|
_outputAtlasDir: string
|
||||||
|
_rootAtlasName: string
|
||||||
|
_spriteSize: {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
_cntPerAtlas: number
|
||||||
|
_maxAtlasSize: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignedItem = {
|
||||||
|
name: string
|
||||||
|
guid: string
|
||||||
|
md5: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PortraitJson = {
|
||||||
|
m_GameObject: FileIDPathID
|
||||||
|
m_Enabled: number
|
||||||
|
m_Script: FileIDPathID
|
||||||
|
m_Name: string
|
||||||
|
_sprites: {
|
||||||
|
name: string
|
||||||
|
guid: string
|
||||||
|
atlas: number
|
||||||
|
rect: {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
w: number
|
||||||
|
h: number
|
||||||
|
}
|
||||||
|
rotate: number
|
||||||
|
}[]
|
||||||
|
_atlas: {
|
||||||
|
index: number
|
||||||
|
texture: FileIDPathID
|
||||||
|
alpha: FileIDPathID
|
||||||
|
size: number
|
||||||
|
}
|
||||||
|
_index: number
|
||||||
|
_sign: {
|
||||||
|
m_sprites: SignedItem[]
|
||||||
|
m_atlases: SignedItem[]
|
||||||
|
m_alphas: SignedItem[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AssetsJson = {
|
||||||
|
filename: string
|
||||||
|
path?: string
|
||||||
|
content?: string | Buffer<ArrayBufferLike> | Buffer
|
||||||
|
}[]
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/postcss-config",
|
"name": "@aklive2d/postcss-config",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"postcss": "^8.5.1"
|
"postcss": "^8.5.1"
|
||||||
},
|
}
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
// prettier.config.js, .prettierrc.js, prettier.config.mjs, or .prettierrc.mjs
|
// prettier.config.js, .prettierrc.js, prettier.config.mjs, or .prettierrc.mjs
|
||||||
|
|
||||||
/**
|
|
||||||
* @see https://prettier.io/docs/en/configuration.html
|
|
||||||
* @type {import("prettier").Config}
|
|
||||||
*/
|
|
||||||
const config = {
|
const config = {
|
||||||
trailingComma: "es5",
|
trailingComma: 'es5',
|
||||||
tabWidth: 4,
|
tabWidth: 4,
|
||||||
semi: false,
|
semi: false,
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
export default config;
|
export default config
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/prettier-config",
|
"name": "@aklive2d/prettier-config",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"prettier": ">=3.0.0"
|
"prettier": ">=3.0.0",
|
||||||
}
|
"typescript": ">=5.8.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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} */
|
/** @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: '^_' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import Matcher from './libs/content_processor.js'
|
import Matcher from './libs/content_processor.ts'
|
||||||
import { yaml, file } from '@aklive2d/libs'
|
import { yaml, file } from '@aklive2d/libs'
|
||||||
import config from '@aklive2d/config'
|
import config from '@aklive2d/config'
|
||||||
import operators, { OPERATOR_SOURCE_FOLDER } from '@aklive2d/operator'
|
import operators, { OPERATOR_SOURCE_FOLDER } from '@aklive2d/operator'
|
||||||
import { files as backgrounds } from '@aklive2d/background'
|
import { files as backgrounds } from '@aklive2d/background'
|
||||||
import { mapping as musics } from '@aklive2d/music'
|
import { mapping as musics } from '@aklive2d/music'
|
||||||
import { getLangs } from '@aklive2d/charword-table'
|
import { getLangs } from '@aklive2d/charword-table'
|
||||||
|
import type { ScalarTag } from 'yaml'
|
||||||
|
import type {
|
||||||
|
Assets,
|
||||||
|
TemplateYAML,
|
||||||
|
ProjectJSON,
|
||||||
|
ProjectJSONProperty,
|
||||||
|
} from './types.ts'
|
||||||
|
|
||||||
const DIST_DIR = path.join(import.meta.dirname, config.dir_name.dist)
|
const DIST_DIR = path.join(import.meta.dirname, config.dir_name.dist)
|
||||||
|
|
||||||
export const build = (namesToBuild) => {
|
export const build = (namesToBuild: string[]) => {
|
||||||
const err = []
|
const err = []
|
||||||
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
|
||||||
console.log('Generating assets for', names.length, 'operators')
|
console.log('Generating assets for', names.length, 'operators')
|
||||||
@@ -43,15 +50,15 @@ export const build = (namesToBuild) => {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDistDir = (name) => {
|
const getDistDir = (name: string) => {
|
||||||
return path.join(DIST_DIR, name)
|
return path.join(DIST_DIR, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDefaultPath = (name) => {
|
const getDefaultPath = (name: string) => {
|
||||||
return path.join(OPERATOR_SOURCE_FOLDER, name)
|
return path.join(OPERATOR_SOURCE_FOLDER, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPath = (name) => {
|
const getPath = (name: string) => {
|
||||||
// if exists, do not use the template
|
// if exists, do not use the template
|
||||||
const defaultPath = path.join(
|
const defaultPath = path.join(
|
||||||
getDefaultPath(name),
|
getDefaultPath(name),
|
||||||
@@ -67,7 +74,15 @@ const getPath = (name) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const process = ({ name, data, template }) => {
|
const process = ({
|
||||||
|
name,
|
||||||
|
data,
|
||||||
|
template,
|
||||||
|
}: {
|
||||||
|
name: string
|
||||||
|
data: ProjectJSON
|
||||||
|
template: TemplateYAML
|
||||||
|
}) => {
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
description: template.description,
|
description: template.description,
|
||||||
@@ -79,12 +94,14 @@ const process = ({ name, data, template }) => {
|
|||||||
...getProperties(template),
|
...getProperties(template),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
} as ProjectJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
const getProperties = (template) => {
|
const getProperties = (template: TemplateYAML) => {
|
||||||
const properties = template.properties
|
const properties = template.properties
|
||||||
const output = {}
|
const output = {} as {
|
||||||
|
[key: string]: ProjectJSONProperty
|
||||||
|
}
|
||||||
for (let i = 0; i < properties.length; i++) {
|
for (let i = 0; i < properties.length; i++) {
|
||||||
output[properties[i].key] = {
|
output[properties[i].key] = {
|
||||||
index: i,
|
index: i,
|
||||||
@@ -95,13 +112,15 @@ const getProperties = (template) => {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
const load = async (name, assets) => {
|
const load = async (name: string, assets: Assets) => {
|
||||||
// load json from file
|
// load json from file
|
||||||
let data = JSON.parse(await file.read(getPath(name)))
|
let data = JSON.parse(await file.read(getPath(name))) as ProjectJSON
|
||||||
const matcher = new Matcher('~{', '}', operators[name], {
|
const matcher = new Matcher('~{', '}', operators[name], {
|
||||||
...assets,
|
...assets,
|
||||||
...(() => {
|
...(() => {
|
||||||
const output = {}
|
const output = {} as {
|
||||||
|
[key: string]: { label: string; value: string }[]
|
||||||
|
}
|
||||||
for (const [key, value] of Object.entries(assets)) {
|
for (const [key, value] of Object.entries(assets)) {
|
||||||
output[`${key}Options`] = value.map((b) => {
|
output[`${key}Options`] = value.map((b) => {
|
||||||
return {
|
return {
|
||||||
@@ -114,20 +133,21 @@ const load = async (name, assets) => {
|
|||||||
})(),
|
})(),
|
||||||
})
|
})
|
||||||
const match = {
|
const match = {
|
||||||
identify: (value) => value.startsWith('!match'),
|
identify: (value: unknown) =>
|
||||||
|
typeof value === 'string' && value.startsWith('!match'),
|
||||||
tag: '!match',
|
tag: '!match',
|
||||||
resolve(str) {
|
resolve(str: string) {
|
||||||
matcher.content = str
|
matcher.content = str
|
||||||
return matcher.result
|
return matcher.result
|
||||||
},
|
},
|
||||||
}
|
} as ScalarTag
|
||||||
const template = yaml.read(
|
const template = yaml.read(
|
||||||
path.resolve(
|
path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
config.module.project_json.template_yaml
|
config.module.project_json.template_yaml
|
||||||
),
|
),
|
||||||
[match]
|
[match]
|
||||||
)
|
) as TemplateYAML
|
||||||
data = process({
|
data = process({
|
||||||
name,
|
name,
|
||||||
data,
|
data,
|
||||||
@@ -1,11 +1,20 @@
|
|||||||
|
import type { OperatorConfig, Codename } from '@aklive2d/operator/types'
|
||||||
|
import type { Assets } from '../types.ts'
|
||||||
|
|
||||||
export default class Matcher {
|
export default class Matcher {
|
||||||
#start
|
#start
|
||||||
#end
|
#end
|
||||||
#reExp
|
#reExp
|
||||||
#config
|
#config
|
||||||
#assets
|
#assets
|
||||||
|
content: string = ''
|
||||||
|
|
||||||
constructor(start, end, config, assets) {
|
constructor(
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
config: OperatorConfig,
|
||||||
|
assets: Assets
|
||||||
|
) {
|
||||||
this.#start = start
|
this.#start = start
|
||||||
this.#end = end
|
this.#end = end
|
||||||
this.#reExp = new RegExp(`${start}.+?${end}`, 'g')
|
this.#reExp = new RegExp(`${start}.+?${end}`, 'g')
|
||||||
@@ -40,27 +49,50 @@ class Evalable {
|
|||||||
#config
|
#config
|
||||||
#assets
|
#assets
|
||||||
|
|
||||||
constructor(config, assets) {
|
constructor(config: OperatorConfig, assets: Assets) {
|
||||||
this.#config = config
|
this.#config = config
|
||||||
this.#assets = assets
|
this.#assets = assets
|
||||||
}
|
}
|
||||||
|
|
||||||
split(location, varName, separator) {
|
split(location: 'config' | 'assets', varName: string, separator: string) {
|
||||||
return this.#step(location, varName).split(separator)
|
return (this.#step(location, varName) as string).split(separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
var(location, varName) {
|
var(location: 'config' | 'assets', varName: string) {
|
||||||
return this.#step(location, varName)
|
return this.#step(location, varName)
|
||||||
}
|
}
|
||||||
|
|
||||||
#step(location, varName) {
|
#step(
|
||||||
let content = this.#config
|
location: 'config' | 'assets',
|
||||||
|
varName: string
|
||||||
|
):
|
||||||
|
| OperatorConfig
|
||||||
|
| Assets
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| Codename
|
||||||
|
| string[] {
|
||||||
|
let content:
|
||||||
|
| OperatorConfig
|
||||||
|
| Assets
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| Codename
|
||||||
|
| string[] = this.#config
|
||||||
if (location === 'assets') content = this.#assets
|
if (location === 'assets') content = this.#assets
|
||||||
varName.split('->').forEach((item) => {
|
varName.split('->').forEach((item) => {
|
||||||
try {
|
try {
|
||||||
content = content[item]
|
if (location === 'config') {
|
||||||
} catch (e) {
|
content = (content as OperatorConfig)[
|
||||||
throw new Error(`Cannot step ${varName}.`, e)
|
item as keyof OperatorConfig
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
content = (content as Assets)[item as keyof Assets]
|
||||||
|
}
|
||||||
|
} catch (e: unknown) {
|
||||||
|
throw new Error(`Cannot step ${varName}. ${e}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return content
|
return content
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/project-json",
|
"name": "@aklive2d/project-json",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "index.js",
|
"main": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -14,8 +14,13 @@
|
|||||||
"@aklive2d/music": "workspace:*",
|
"@aklive2d/music": "workspace:*",
|
||||||
"@aklive2d/prettier-config": "workspace:*"
|
"@aklive2d/prettier-config": "workspace:*"
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"globals": ">=16.0.0",
|
||||||
|
"typescript-eslint": ">=8.31.1",
|
||||||
|
"typescript": ">=5.8.2"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "mode=build node runner.js",
|
"build": "mode=build bun runner.ts",
|
||||||
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
|
"lint": "eslint && prettier --check ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ async function main() {
|
|||||||
multiple: true,
|
multiple: true,
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
})
|
}) as { mode: string; name: string[] }
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'build':
|
case 'build':
|
||||||
err = build(name)
|
err = build(name)
|
||||||
25
packages/project-json/tsconfig.json
Normal file
25
packages/project-json/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/**/*"]
|
||||||
|
}
|
||||||
66
packages/project-json/types.ts
Normal file
66
packages/project-json/types.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
export type Assets = {
|
||||||
|
backgrounds: string[]
|
||||||
|
voiceLangs: string[]
|
||||||
|
subtitleLangs: string[]
|
||||||
|
music: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Property {
|
||||||
|
text: string
|
||||||
|
type?: 'bool' | 'file' | 'slider' | 'combo' | 'textinput'
|
||||||
|
value?: boolean | string
|
||||||
|
condition?: string
|
||||||
|
fraction?: boolean
|
||||||
|
max?: number
|
||||||
|
min?: number
|
||||||
|
step?: number
|
||||||
|
precision?: number
|
||||||
|
options?: string[]
|
||||||
|
fileType?: 'video'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProjectJSONProperty extends Property {
|
||||||
|
index: number
|
||||||
|
order: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Template {
|
||||||
|
description: string
|
||||||
|
localization: {
|
||||||
|
'en-us': Record<string, string>
|
||||||
|
'zh-chs': Record<string, string>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TemplateYAML extends Template {
|
||||||
|
properties: {
|
||||||
|
key: string
|
||||||
|
value: Property
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TemplateJSON extends Template {
|
||||||
|
properties: {
|
||||||
|
[key: string]: ProjectJSONProperty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProjectJSONBase {
|
||||||
|
contentrating: string
|
||||||
|
description: string
|
||||||
|
file: string
|
||||||
|
preview: string
|
||||||
|
ratingsex: string
|
||||||
|
ratingviolence: string
|
||||||
|
snapshotformat: number
|
||||||
|
snapshotoverlay: string
|
||||||
|
tags: string[]
|
||||||
|
title: string
|
||||||
|
type: string
|
||||||
|
version: number
|
||||||
|
workshopid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProjectJSON extends ProjectJSONBase {
|
||||||
|
general: TemplateJSON
|
||||||
|
}
|
||||||
@@ -1,15 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@aklive2d/stylelint-config",
|
"name": "@aklive2d/stylelint-config",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"stylelint-config-standard-scss": "^14.0.0",
|
"stylelint-config-standard-scss": "^14.0.0",
|
||||||
"stylelint-prettier": "^5.0.3"
|
"stylelint-prettier": "^5.0.3"
|
||||||
},
|
}
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user