feat: migrated packages to ts

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

View File

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

View File

@@ -1,15 +1,22 @@
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 config from '@aklive2d/config'
import operators, { OPERATOR_SOURCE_FOLDER } from '@aklive2d/operator'
import { files as backgrounds } from '@aklive2d/background'
import { mapping as musics } from '@aklive2d/music'
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)
export const build = (namesToBuild) => {
export const build = (namesToBuild: string[]) => {
const err = []
const names = !namesToBuild.length ? Object.keys(operators) : namesToBuild
console.log('Generating assets for', names.length, 'operators')
@@ -43,15 +50,15 @@ export const build = (namesToBuild) => {
return err
}
const getDistDir = (name) => {
const getDistDir = (name: string) => {
return path.join(DIST_DIR, name)
}
const getDefaultPath = (name) => {
const getDefaultPath = (name: string) => {
return path.join(OPERATOR_SOURCE_FOLDER, name)
}
const getPath = (name) => {
const getPath = (name: string) => {
// if exists, do not use the template
const defaultPath = path.join(
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 {
...data,
description: template.description,
@@ -79,12 +94,14 @@ const process = ({ name, data, template }) => {
...getProperties(template),
},
},
}
} as ProjectJSON
}
const getProperties = (template) => {
const getProperties = (template: TemplateYAML) => {
const properties = template.properties
const output = {}
const output = {} as {
[key: string]: ProjectJSONProperty
}
for (let i = 0; i < properties.length; i++) {
output[properties[i].key] = {
index: i,
@@ -95,13 +112,15 @@ const getProperties = (template) => {
return output
}
const load = async (name, assets) => {
const load = async (name: string, assets: Assets) => {
// 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], {
...assets,
...(() => {
const output = {}
const output = {} as {
[key: string]: { label: string; value: string }[]
}
for (const [key, value] of Object.entries(assets)) {
output[`${key}Options`] = value.map((b) => {
return {
@@ -114,20 +133,21 @@ const load = async (name, assets) => {
})(),
})
const match = {
identify: (value) => value.startsWith('!match'),
identify: (value: unknown) =>
typeof value === 'string' && value.startsWith('!match'),
tag: '!match',
resolve(str) {
resolve(str: string) {
matcher.content = str
return matcher.result
},
}
} as ScalarTag
const template = yaml.read(
path.resolve(
import.meta.dirname,
config.module.project_json.template_yaml
),
[match]
)
) as TemplateYAML
data = process({
name,
data,

View File

@@ -1,11 +1,20 @@
import type { OperatorConfig, Codename } from '@aklive2d/operator/types'
import type { Assets } from '../types.ts'
export default class Matcher {
#start
#end
#reExp
#config
#assets
content: string = ''
constructor(start, end, config, assets) {
constructor(
start: string,
end: string,
config: OperatorConfig,
assets: Assets
) {
this.#start = start
this.#end = end
this.#reExp = new RegExp(`${start}.+?${end}`, 'g')
@@ -40,27 +49,50 @@ class Evalable {
#config
#assets
constructor(config, assets) {
constructor(config: OperatorConfig, assets: Assets) {
this.#config = config
this.#assets = assets
}
split(location, varName, separator) {
return this.#step(location, varName).split(separator)
split(location: 'config' | 'assets', varName: string, separator: string) {
return (this.#step(location, varName) as string).split(separator)
}
var(location, varName) {
var(location: 'config' | 'assets', varName: string) {
return this.#step(location, varName)
}
#step(location, varName) {
let content = this.#config
#step(
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
varName.split('->').forEach((item) => {
try {
content = content[item]
} catch (e) {
throw new Error(`Cannot step ${varName}.`, e)
if (location === 'config') {
content = (content as OperatorConfig)[
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

View File

@@ -1,7 +1,7 @@
{
"name": "@aklive2d/project-json",
"version": "0.0.0",
"main": "index.js",
"main": "index.ts",
"type": "module",
"license": "MIT",
"dependencies": {
@@ -14,8 +14,13 @@
"@aklive2d/music": "workspace:*",
"@aklive2d/prettier-config": "workspace:*"
},
"peerDependencies": {
"globals": ">=16.0.0",
"typescript-eslint": ">=8.31.1",
"typescript": ">=5.8.2"
},
"scripts": {
"build": "mode=build node runner.js",
"lint": "eslint \"*.js\" \"**/*.js\" && prettier --check ."
"build": "mode=build bun runner.ts",
"lint": "eslint && prettier --check ."
}
}

View File

@@ -14,7 +14,7 @@ async function main() {
multiple: true,
default: [],
},
})
}) as { mode: string; name: string[] }
switch (mode) {
case 'build':
err = build(name)

View File

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

View File

@@ -0,0 +1,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
}