feat: setup barrelsby for automatic barrel file generation
Add barrelsby as a dev dependency with a `generate-barrels` npm script and a `barrelesby.json` config targeting `./src`. This automates creation of barrel/index files to simplify imports across the project.
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory": "./src"
|
||||
}
|
||||
+3
-1
@@ -7,7 +7,8 @@
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
"lint:fix": "eslint --fix",
|
||||
"generate-barrels": "barrelsby --delete"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "16.2.7",
|
||||
@@ -19,6 +20,7 @@
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"barrelsby": "^2.8.1",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.2.7",
|
||||
"tailwindcss": "^4",
|
||||
|
||||
Generated
+284
@@ -30,6 +30,9 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: ^19
|
||||
version: 19.2.3(@types/react@19.2.16)
|
||||
barrelsby:
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1
|
||||
eslint:
|
||||
specifier: ^9
|
||||
version: 9.39.4(jiti@2.7.0)
|
||||
@@ -553,6 +556,12 @@ packages:
|
||||
'@types/react@19.2.16':
|
||||
resolution: {integrity: sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==}
|
||||
|
||||
'@types/yargs-parser@21.0.3':
|
||||
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
|
||||
|
||||
'@types/yargs@17.0.35':
|
||||
resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.60.1':
|
||||
resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@@ -745,6 +754,14 @@ packages:
|
||||
ajv@6.15.0:
|
||||
resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@3.2.1:
|
||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -814,6 +831,11 @@ packages:
|
||||
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
barrelsby@2.8.1:
|
||||
resolution: {integrity: sha512-barN2MVKqUVwmjRy3JLSMYufrBDcdWUc2pjlR0V9P8S3aMvvJ4StFz1GJMzEi5GBoQlnBIWOcCxBDzI2xfaaGw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
baseline-browser-mapping@2.10.33:
|
||||
resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@@ -854,6 +876,10 @@ packages:
|
||||
caniuse-lite@1.0.30001793:
|
||||
resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==}
|
||||
|
||||
chalk@2.4.2:
|
||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -861,10 +887,20 @@ packages:
|
||||
client-only@0.0.1:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
color-convert@1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.3:
|
||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
@@ -939,6 +975,9 @@ packages:
|
||||
electron-to-chromium@1.5.368:
|
||||
resolution: {integrity: sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
@@ -946,6 +985,9 @@ packages:
|
||||
resolution: {integrity: sha512-0rxICaFZ7NQho/sHely2bvOPRP0Eu2B0NZ9zM54YvRvWMn7jfz3DmnOZDR9LlXDdDcqntAVc6Hfy4gr/tdH/Ag==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
error-ex@1.3.4:
|
||||
resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
|
||||
|
||||
es-abstract@1.24.2:
|
||||
resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -982,6 +1024,10 @@ packages:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1131,6 +1177,10 @@ packages:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
figures@2.0.0:
|
||||
resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
file-entry-cache@8.0.0:
|
||||
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
@@ -1139,6 +1189,10 @@ packages:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
find-up@2.1.0:
|
||||
resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
find-up@5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1172,6 +1226,10 @@ packages:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1218,6 +1276,10 @@ packages:
|
||||
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-flag@3.0.0:
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1271,6 +1333,9 @@ packages:
|
||||
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
|
||||
is-async-function@2.1.1:
|
||||
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1310,6 +1375,10 @@ packages:
|
||||
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-generator-function@1.1.2:
|
||||
resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1399,6 +1468,9 @@ packages:
|
||||
json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
|
||||
json-parse-better-errors@1.0.2:
|
||||
resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
|
||||
|
||||
json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
|
||||
@@ -1506,6 +1578,14 @@ packages:
|
||||
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
||||
load-json-file@4.0.0:
|
||||
resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
locate-path@2.0.0:
|
||||
resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
locate-path@6.0.0:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1630,18 +1710,38 @@ packages:
|
||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
p-limit@1.3.0:
|
||||
resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-locate@2.0.0:
|
||||
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
p-locate@5.0.0:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-try@1.0.0:
|
||||
resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
parse-json@4.0.0:
|
||||
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
path-exists@3.0.0:
|
||||
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1664,6 +1764,14 @@ packages:
|
||||
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
pify@3.0.0:
|
||||
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pkg-conf@2.1.0:
|
||||
resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1710,6 +1818,10 @@ packages:
|
||||
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -1793,6 +1905,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
signale@1.4.0:
|
||||
resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -1804,6 +1920,10 @@ packages:
|
||||
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string.prototype.includes@2.0.1:
|
||||
resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1827,6 +1947,10 @@ packages:
|
||||
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-bom@3.0.0:
|
||||
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -1848,6 +1972,10 @@ packages:
|
||||
babel-plugin-macros:
|
||||
optional: true
|
||||
|
||||
supports-color@5.5.0:
|
||||
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1959,9 +2087,25 @@ packages:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2422,6 +2566,12 @@ snapshots:
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
|
||||
'@types/yargs-parser@21.0.3': {}
|
||||
|
||||
'@types/yargs@17.0.35':
|
||||
dependencies:
|
||||
'@types/yargs-parser': 21.0.3
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
@@ -2596,6 +2746,12 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-styles@3.2.1:
|
||||
dependencies:
|
||||
color-convert: 1.9.3
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
@@ -2687,6 +2843,12 @@ snapshots:
|
||||
|
||||
balanced-match@4.0.4: {}
|
||||
|
||||
barrelsby@2.8.1:
|
||||
dependencies:
|
||||
'@types/yargs': 17.0.35
|
||||
signale: 1.4.0
|
||||
yargs: 17.7.2
|
||||
|
||||
baseline-browser-mapping@2.10.33: {}
|
||||
|
||||
brace-expansion@1.1.15:
|
||||
@@ -2731,6 +2893,12 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001793: {}
|
||||
|
||||
chalk@2.4.2:
|
||||
dependencies:
|
||||
ansi-styles: 3.2.1
|
||||
escape-string-regexp: 1.0.5
|
||||
supports-color: 5.5.0
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@@ -2738,10 +2906,22 @@ snapshots:
|
||||
|
||||
client-only@0.0.1: {}
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
color-convert@1.9.3:
|
||||
dependencies:
|
||||
color-name: 1.1.3
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.3: {}
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@@ -2812,6 +2992,8 @@ snapshots:
|
||||
|
||||
electron-to-chromium@1.5.368: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
enhanced-resolve@5.22.2:
|
||||
@@ -2819,6 +3001,10 @@ snapshots:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.3.3
|
||||
|
||||
error-ex@1.3.4:
|
||||
dependencies:
|
||||
is-arrayish: 0.2.1
|
||||
|
||||
es-abstract@1.24.2:
|
||||
dependencies:
|
||||
array-buffer-byte-length: 1.0.2
|
||||
@@ -2922,6 +3108,8 @@ snapshots:
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-string-regexp@1.0.5: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-next@16.2.7(@typescript-eslint/parser@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3):
|
||||
@@ -3151,6 +3339,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.4
|
||||
|
||||
figures@2.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp: 1.0.5
|
||||
|
||||
file-entry-cache@8.0.0:
|
||||
dependencies:
|
||||
flat-cache: 4.0.1
|
||||
@@ -3159,6 +3351,10 @@ snapshots:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
find-up@2.1.0:
|
||||
dependencies:
|
||||
locate-path: 2.0.0
|
||||
|
||||
find-up@5.0.0:
|
||||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
@@ -3192,6 +3388,8 @@ snapshots:
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@@ -3243,6 +3441,8 @@ snapshots:
|
||||
|
||||
has-bigints@1.1.0: {}
|
||||
|
||||
has-flag@3.0.0: {}
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
@@ -3292,6 +3492,8 @@ snapshots:
|
||||
call-bound: 1.0.4
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
is-arrayish@0.2.1: {}
|
||||
|
||||
is-async-function@2.1.1:
|
||||
dependencies:
|
||||
async-function: 1.0.0
|
||||
@@ -3336,6 +3538,8 @@ snapshots:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
is-generator-function@1.1.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
@@ -3423,6 +3627,8 @@ snapshots:
|
||||
|
||||
json-buffer@3.0.1: {}
|
||||
|
||||
json-parse-better-errors@1.0.2: {}
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||
@@ -3504,6 +3710,18 @@ snapshots:
|
||||
lightningcss-win32-arm64-msvc: 1.32.0
|
||||
lightningcss-win32-x64-msvc: 1.32.0
|
||||
|
||||
load-json-file@4.0.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
parse-json: 4.0.0
|
||||
pify: 3.0.0
|
||||
strip-bom: 3.0.0
|
||||
|
||||
locate-path@2.0.0:
|
||||
dependencies:
|
||||
p-locate: 2.0.0
|
||||
path-exists: 3.0.0
|
||||
|
||||
locate-path@6.0.0:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
@@ -3639,18 +3857,35 @@ snapshots:
|
||||
object-keys: 1.1.1
|
||||
safe-push-apply: 1.0.0
|
||||
|
||||
p-limit@1.3.0:
|
||||
dependencies:
|
||||
p-try: 1.0.0
|
||||
|
||||
p-limit@3.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
|
||||
p-locate@2.0.0:
|
||||
dependencies:
|
||||
p-limit: 1.3.0
|
||||
|
||||
p-locate@5.0.0:
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
p-try@1.0.0: {}
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
|
||||
parse-json@4.0.0:
|
||||
dependencies:
|
||||
error-ex: 1.3.4
|
||||
json-parse-better-errors: 1.0.2
|
||||
|
||||
path-exists@3.0.0: {}
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
@@ -3663,6 +3898,13 @@ snapshots:
|
||||
|
||||
picomatch@4.0.4: {}
|
||||
|
||||
pify@3.0.0: {}
|
||||
|
||||
pkg-conf@2.1.0:
|
||||
dependencies:
|
||||
find-up: 2.1.0
|
||||
load-json-file: 4.0.0
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
postcss@8.4.31:
|
||||
@@ -3718,6 +3960,8 @@ snapshots:
|
||||
gopd: 1.2.0
|
||||
set-function-name: 2.0.2
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
@@ -3850,6 +4094,12 @@ snapshots:
|
||||
side-channel-map: 1.0.1
|
||||
side-channel-weakmap: 1.0.2
|
||||
|
||||
signale@1.4.0:
|
||||
dependencies:
|
||||
chalk: 2.4.2
|
||||
figures: 2.0.0
|
||||
pkg-conf: 2.1.0
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
stable-hash@0.0.5: {}
|
||||
@@ -3859,6 +4109,12 @@ snapshots:
|
||||
es-errors: 1.3.0
|
||||
internal-slot: 1.1.0
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string.prototype.includes@2.0.1:
|
||||
dependencies:
|
||||
call-bind: 1.0.9
|
||||
@@ -3909,6 +4165,10 @@ snapshots:
|
||||
define-properties: 1.2.1
|
||||
es-object-atoms: 1.1.2
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-bom@3.0.0: {}
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
@@ -3920,6 +4180,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@babel/core': 7.29.7
|
||||
|
||||
supports-color@5.5.0:
|
||||
dependencies:
|
||||
has-flag: 3.0.0
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
@@ -4095,8 +4359,28 @@ snapshots:
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod-validation-error@4.0.2(zod@4.4.3):
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Apple 登录请求
|
||||
* 原始 Dart: AppleLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class AppleLoginRequest {
|
||||
readonly identityToken: string;
|
||||
readonly platform: string;
|
||||
|
||||
constructor(params: { identityToken: string; platform: string }) {
|
||||
this.identityToken = params.identityToken;
|
||||
this.platform = params.platform;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
identityToken: this.identityToken,
|
||||
platform: this.platform,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AppleLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`AppleLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new AppleLoginRequest({
|
||||
identityToken: requireString("identityToken"),
|
||||
platform: requireString("platform"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Facebook 登录请求
|
||||
* 原始 Dart: FacebookLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class FacebookLoginRequest {
|
||||
readonly accessToken: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
accessToken: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.accessToken = params.accessToken;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
accessToken: this.accessToken,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): FacebookLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`FacebookLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new FacebookLoginRequest({
|
||||
accessToken: requireString("accessToken"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Facebook ID 登录请求
|
||||
* 原始 Dart: FbIdLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `avatarUrl` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class FbIdLoginRequest {
|
||||
readonly fbId: string;
|
||||
readonly avatarUrl: string;
|
||||
|
||||
constructor(params: { fbId: string; avatarUrl?: string }) {
|
||||
this.fbId = params.fbId;
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
fbId: this.fbId,
|
||||
avatarUrl: this.avatarUrl,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): FbIdLoginRequest {
|
||||
const fbId = json.fbId;
|
||||
if (typeof fbId !== "string") {
|
||||
throw new Error(
|
||||
"FbIdLoginRequest.fbId is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new FbIdLoginRequest({
|
||||
fbId,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Google 登录请求
|
||||
* 原始 Dart: GoogleLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class GoogleLoginRequest {
|
||||
readonly idToken: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
idToken: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.idToken = params.idToken;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
idToken: this.idToken,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GoogleLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`GoogleLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new GoogleLoginRequest({
|
||||
idToken: requireString("idToken"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 游客登录请求
|
||||
* 原始 Dart: GuestLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class GuestLoginRequest {
|
||||
readonly deviceId: string;
|
||||
|
||||
constructor(params: { deviceId: string }) {
|
||||
this.deviceId = params.deviceId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { deviceId: this.deviceId };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestLoginRequest {
|
||||
const deviceId = json.deviceId;
|
||||
if (typeof deviceId !== "string") {
|
||||
throw new Error(
|
||||
"GuestLoginRequest.deviceId is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new GuestLoginRequest({ deviceId });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 游客登录响应
|
||||
* 原始 Dart: GuestLoginResponse (lib/data/models/auth/auth_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `user` 为 `User?`,按"全部非空"约定兜底为默认 User 实例
|
||||
* (id/username 为空串,使用方可通过 user.id === "" 判定无用户数据)。
|
||||
*/
|
||||
import { User } from "../user/user";
|
||||
|
||||
export class GuestLoginResponse {
|
||||
readonly token: string;
|
||||
readonly deviceId: string;
|
||||
readonly userId: string;
|
||||
readonly isDeviceUser: boolean;
|
||||
readonly expiresIn: number;
|
||||
readonly user: User;
|
||||
|
||||
constructor(params: {
|
||||
token: string;
|
||||
deviceId: string;
|
||||
userId: string;
|
||||
isDeviceUser?: boolean;
|
||||
expiresIn?: number;
|
||||
user?: User;
|
||||
}) {
|
||||
this.token = params.token;
|
||||
this.deviceId = params.deviceId;
|
||||
this.userId = params.userId;
|
||||
this.isDeviceUser = params.isDeviceUser ?? true;
|
||||
this.expiresIn = params.expiresIn ?? 2592000;
|
||||
this.user = params.user ?? new User({ id: "", username: "" });
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
token: this.token,
|
||||
deviceId: this.deviceId,
|
||||
userId: this.userId,
|
||||
isDeviceUser: this.isDeviceUser,
|
||||
expiresIn: this.expiresIn,
|
||||
user: this.user.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestLoginResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`GuestLoginResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const userJson = json.user;
|
||||
const user: User =
|
||||
typeof userJson === "object" && userJson !== null
|
||||
? User.fromJson(userJson as Record<string, unknown>)
|
||||
: new User({ id: "", username: "" });
|
||||
return new GuestLoginResponse({
|
||||
token: requireString("token"),
|
||||
deviceId: requireString("deviceId"),
|
||||
userId: requireString("userId"),
|
||||
isDeviceUser:
|
||||
typeof json.isDeviceUser === "boolean"
|
||||
? json.isDeviceUser
|
||||
: undefined,
|
||||
expiresIn: typeof json.expiresIn === "number" ? json.expiresIn : undefined,
|
||||
user,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// auth 子目录 barrel export
|
||||
export { AppleLoginRequest } from "./apple_login_request";
|
||||
export { FbIdLoginRequest } from "./fb_id_login_request";
|
||||
export { FacebookLoginRequest } from "./facebook_login_request";
|
||||
export { GoogleLoginRequest } from "./google_login_request";
|
||||
export { GuestLoginRequest } from "./guest_login_request";
|
||||
export { GuestLoginResponse } from "./guest_login_response";
|
||||
export { LoginRequest } from "./login_request";
|
||||
export { LoginResponse } from "./login_response";
|
||||
export { LogoutResponse } from "./logout_response";
|
||||
export { RefreshTokenRequest } from "./refresh_token_request";
|
||||
export { RefreshTokenResponse } from "./refresh_token_response";
|
||||
export { RegisterRequest } from "./register_request";
|
||||
export { SendCodeRequest } from "./send_code_request";
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 登录请求 - 支持用户名或邮箱登录
|
||||
* 原始 Dart: LoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `email`/`username`/`guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
* 后端校验 email 与 username 至少传入一个。
|
||||
*/
|
||||
export class LoginRequest {
|
||||
readonly email: string;
|
||||
readonly username: string;
|
||||
readonly password: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
email?: string;
|
||||
username?: string;
|
||||
password: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.email = params.email ?? "";
|
||||
this.username = params.username ?? "";
|
||||
this.password = params.password;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
email: this.email,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`LoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new LoginRequest({
|
||||
email: typeof json.email === "string" ? json.email : undefined,
|
||||
username: typeof json.username === "string" ? json.username : undefined,
|
||||
password: requireString("password"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 登录响应
|
||||
* 原始 Dart: LoginResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
import { User } from "../user/user";
|
||||
|
||||
export class LoginResponse {
|
||||
readonly user: User;
|
||||
readonly token: string;
|
||||
readonly refreshToken: string;
|
||||
|
||||
constructor(params: { user: User; token: string; refreshToken?: string }) {
|
||||
this.user = params.user;
|
||||
this.token = params.token;
|
||||
this.refreshToken = params.refreshToken ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
user: this.user.toJson(),
|
||||
token: this.token,
|
||||
refreshToken: this.refreshToken,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LoginResponse {
|
||||
const token = json.token;
|
||||
if (typeof token !== "string") {
|
||||
throw new Error("LoginResponse.token is required and must be a string");
|
||||
}
|
||||
const userJson = json.user;
|
||||
if (typeof userJson !== "object" || userJson === null) {
|
||||
throw new Error("LoginResponse.user is required and must be an object");
|
||||
}
|
||||
return new LoginResponse({
|
||||
user: User.fromJson(userJson as Record<string, unknown>),
|
||||
token,
|
||||
refreshToken:
|
||||
typeof json.refreshToken === "string" ? json.refreshToken : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 退出登录响应
|
||||
* 原始 Dart: LogoutResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
export class LogoutResponse {
|
||||
readonly success: boolean;
|
||||
|
||||
constructor(params: { success?: boolean }) {
|
||||
this.success = params.success ?? true;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { success: this.success };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LogoutResponse {
|
||||
return new LogoutResponse({
|
||||
success: typeof json.success === "boolean" ? json.success : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 刷新 Token 请求
|
||||
* 原始 Dart: RefreshTokenRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class RefreshTokenRequest {
|
||||
readonly refreshToken: string;
|
||||
|
||||
constructor(params: { refreshToken: string }) {
|
||||
this.refreshToken = params.refreshToken;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { refreshToken: this.refreshToken };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RefreshTokenRequest {
|
||||
const refreshToken = json.refreshToken;
|
||||
if (typeof refreshToken !== "string") {
|
||||
throw new Error(
|
||||
"RefreshTokenRequest.refreshToken is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new RefreshTokenRequest({ refreshToken });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 刷新 Token 响应
|
||||
* 原始 Dart: RefreshTokenResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
export class RefreshTokenResponse {
|
||||
readonly token: string;
|
||||
readonly refreshToken: string;
|
||||
readonly userId: string;
|
||||
|
||||
constructor(params: {
|
||||
token: string;
|
||||
refreshToken: string;
|
||||
userId: string;
|
||||
}) {
|
||||
this.token = params.token;
|
||||
this.refreshToken = params.refreshToken;
|
||||
this.userId = params.userId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
token: this.token,
|
||||
refreshToken: this.refreshToken,
|
||||
userId: this.userId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RefreshTokenResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RefreshTokenResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new RefreshTokenResponse({
|
||||
token: requireString("token"),
|
||||
refreshToken: requireString("refreshToken"),
|
||||
userId: requireString("userId"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 注册请求
|
||||
* 原始 Dart: RegisterRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class RegisterRequest {
|
||||
readonly username: string;
|
||||
readonly email: string;
|
||||
readonly password: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.username = params.username;
|
||||
this.email = params.email;
|
||||
this.password = params.password;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RegisterRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RegisterRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new RegisterRequest({
|
||||
username: requireString("username"),
|
||||
email: requireString("email"),
|
||||
password: requireString("password"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 发送验证码请求
|
||||
* 原始 Dart: SendCodeRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class SendCodeRequest {
|
||||
readonly email: string;
|
||||
|
||||
constructor(params: { email: string }) {
|
||||
this.email = params.email;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { email: this.email };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SendCodeRequest {
|
||||
const email = json.email;
|
||||
if (typeof email !== "string") {
|
||||
throw new Error(
|
||||
"SendCodeRequest.email is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new SendCodeRequest({ email });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 聊天历史响应
|
||||
* 原始 Dart: ChatHistoryResponse (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `total` 为 `int?`,按"全部非空"约定兜底为 0。
|
||||
*/
|
||||
import { ChatMessage } from "./chat_message";
|
||||
|
||||
export class ChatHistoryResponse {
|
||||
readonly messages: ChatMessage[];
|
||||
readonly total: number;
|
||||
readonly limit: number;
|
||||
readonly offset: number;
|
||||
|
||||
constructor(params: {
|
||||
messages: ChatMessage[];
|
||||
total?: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}) {
|
||||
this.messages = params.messages;
|
||||
this.total = params.total ?? 0;
|
||||
this.limit = params.limit;
|
||||
this.offset = params.offset;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
messages: this.messages.map((m) => m.toJson()),
|
||||
total: this.total,
|
||||
limit: this.limit,
|
||||
offset: this.offset,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatHistoryResponse {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ChatHistoryResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawMessages = json.messages;
|
||||
const messages: ChatMessage[] = Array.isArray(rawMessages)
|
||||
? (rawMessages as Record<string, unknown>[]).map((m) =>
|
||||
ChatMessage.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new ChatHistoryResponse({
|
||||
messages,
|
||||
total: typeof json.total === "number" ? json.total : undefined,
|
||||
limit: requireNumber("limit"),
|
||||
offset: requireNumber("offset"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 聊天历史中的单条消息
|
||||
* 原始 Dart: ChatMessage (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `id`/`createdAt` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class ChatMessage {
|
||||
readonly role: string;
|
||||
readonly content: string;
|
||||
readonly id: string;
|
||||
readonly createdAt: string;
|
||||
|
||||
constructor(params: {
|
||||
role: string;
|
||||
content: string;
|
||||
id?: string;
|
||||
createdAt?: string;
|
||||
}) {
|
||||
this.role = params.role;
|
||||
this.content = params.content;
|
||||
this.id = params.id ?? "";
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
role: this.role,
|
||||
content: this.content,
|
||||
id: this.id,
|
||||
createdAt: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatMessage {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ChatMessage.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatMessage({
|
||||
role: requireString("role"),
|
||||
content: requireString("content"),
|
||||
id: typeof json.id === "string" ? json.id : undefined,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 发送消息响应
|
||||
* 原始 Dart: ChatSendResponse (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `mode`/`currentMood`/`isGuest` 为可空字段,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - bool → false
|
||||
* - int → 0
|
||||
*/
|
||||
export class ChatSendResponse {
|
||||
readonly mode: string;
|
||||
readonly reply: string;
|
||||
readonly voiceUrl: string;
|
||||
readonly audioUrl: string;
|
||||
readonly intimacyChange: number;
|
||||
readonly newIntimacy: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly currentMood: string;
|
||||
readonly messageId: string;
|
||||
readonly isGuest: boolean;
|
||||
readonly timestamp: number;
|
||||
|
||||
constructor(params: {
|
||||
mode?: string;
|
||||
reply: string;
|
||||
voiceUrl?: string;
|
||||
audioUrl?: string;
|
||||
intimacyChange?: number;
|
||||
newIntimacy?: number;
|
||||
relationshipStage: string;
|
||||
currentMood?: string;
|
||||
messageId: string;
|
||||
isGuest?: boolean;
|
||||
timestamp?: number;
|
||||
}) {
|
||||
this.mode = params.mode ?? "";
|
||||
this.reply = params.reply;
|
||||
this.voiceUrl = params.voiceUrl ?? "";
|
||||
this.audioUrl = params.audioUrl ?? "";
|
||||
this.intimacyChange = params.intimacyChange ?? 0;
|
||||
this.newIntimacy = params.newIntimacy ?? 0;
|
||||
this.relationshipStage = params.relationshipStage;
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
this.messageId = params.messageId;
|
||||
this.isGuest = params.isGuest ?? false;
|
||||
this.timestamp = params.timestamp ?? 0;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
mode: this.mode,
|
||||
reply: this.reply,
|
||||
voiceUrl: this.voiceUrl,
|
||||
audioUrl: this.audioUrl,
|
||||
intimacyChange: this.intimacyChange,
|
||||
newIntimacy: this.newIntimacy,
|
||||
relationshipStage: this.relationshipStage,
|
||||
currentMood: this.currentMood,
|
||||
messageId: this.messageId,
|
||||
isGuest: this.isGuest,
|
||||
timestamp: this.timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSendResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ChatSendResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatSendResponse({
|
||||
mode: typeof json.mode === "string" ? json.mode : undefined,
|
||||
reply: requireString("reply"),
|
||||
voiceUrl:
|
||||
typeof json.voiceUrl === "string" ? json.voiceUrl : undefined,
|
||||
audioUrl:
|
||||
typeof json.audioUrl === "string" ? json.audioUrl : undefined,
|
||||
intimacyChange:
|
||||
typeof json.intimacyChange === "number"
|
||||
? json.intimacyChange
|
||||
: undefined,
|
||||
newIntimacy:
|
||||
typeof json.newIntimacy === "number" ? json.newIntimacy : undefined,
|
||||
relationshipStage: requireString("relationshipStage"),
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
messageId: requireString("messageId"),
|
||||
isGuest: typeof json.isGuest === "boolean" ? json.isGuest : undefined,
|
||||
timestamp:
|
||||
typeof json.timestamp === "number" ? json.timestamp : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 消息同步响应
|
||||
* 原始 Dart: ChatSyncData (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
export class ChatSyncData {
|
||||
readonly syncedCount: number;
|
||||
readonly totalHistory: number;
|
||||
|
||||
constructor(params: { syncedCount: number; totalHistory: number }) {
|
||||
this.syncedCount = params.syncedCount;
|
||||
this.totalHistory = params.totalHistory;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
syncedCount: this.syncedCount,
|
||||
totalHistory: this.totalHistory,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSyncData {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ChatSyncData.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatSyncData({
|
||||
syncedCount: requireNumber("syncedCount"),
|
||||
totalHistory: requireNumber("totalHistory"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 消息同步请求
|
||||
* 原始 Dart: ChatSyncRequest (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
import { SyncMessage } from "./sync_message";
|
||||
|
||||
export class ChatSyncRequest {
|
||||
readonly messages: SyncMessage[];
|
||||
|
||||
constructor(params: { messages: SyncMessage[] }) {
|
||||
this.messages = params.messages;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { messages: this.messages.map((m) => m.toJson()) };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSyncRequest {
|
||||
const rawMessages = json.messages;
|
||||
const messages: SyncMessage[] = Array.isArray(rawMessages)
|
||||
? (rawMessages as Record<string, unknown>[]).map((m) =>
|
||||
SyncMessage.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new ChatSyncRequest({ messages });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 游客每日聊天配额数据
|
||||
* 原始 Dart: GuestChatQuota (lib/data/models/chat/guest_chat_quota.dart)
|
||||
*
|
||||
* 注:原始 Dart 中的静态常量与运行时环境判断方法(isDevelopment)已迁移为
|
||||
* 静态成员。环境检测逻辑(threshold / totalQuotaDefault 等)保留为方法,
|
||||
* 内部使用 `process.env.NODE_ENV` 替代 Dart 中的 `AppEnvUtil.isDevelopment`。
|
||||
* `initial()` 工厂方法已迁移为静态方法;`needReset` getter 保留为实例方法。
|
||||
*
|
||||
* Dart 中 `initial()` 依赖 `app_date.DateUtils.todayString()`,
|
||||
* 在 TS 中由调用方通过 `date` 字段传入。
|
||||
*/
|
||||
export class GuestChatQuota {
|
||||
readonly remaining: number;
|
||||
readonly date: string;
|
||||
|
||||
// 静态常量
|
||||
static readonly maxQuotaPerDay = 40;
|
||||
static readonly maxQuotaPerDayTest = 4;
|
||||
static readonly quotaWarningThreshold = 20;
|
||||
static readonly quotaWarningThresholdTest = 2;
|
||||
static readonly defaultTotalQuota = 50;
|
||||
static readonly defaultTotalQuotaDev = 5;
|
||||
static readonly quotaExhausted = 0;
|
||||
|
||||
constructor(params: { remaining: number; date: string }) {
|
||||
this.remaining = params.remaining;
|
||||
this.date = params.date;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配额耗尽状态值(便捷引用)
|
||||
*/
|
||||
static get exhausted(): number {
|
||||
return GuestChatQuota.quotaExhausted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否处于开发环境
|
||||
* 通过 `process.env.NODE_ENV` 判断,替代 Dart 中的 `AppEnvUtil.isDevelopment`
|
||||
*/
|
||||
static get isDevelopment(): boolean {
|
||||
return process.env.NODE_ENV !== "production";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的配额警告阈值
|
||||
*/
|
||||
static get warningThreshold(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.quotaWarningThresholdTest
|
||||
: GuestChatQuota.quotaWarningThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的每日最大配额
|
||||
*/
|
||||
static get threshold(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.maxQuotaPerDayTest
|
||||
: GuestChatQuota.maxQuotaPerDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的总配额默认值
|
||||
*/
|
||||
static get totalQuotaDefault(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.defaultTotalQuotaDev
|
||||
: GuestChatQuota.defaultTotalQuota;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建初始配额实例
|
||||
* @param todayString 当天日期字符串(YYYY-MM-DD),由调用方提供
|
||||
*/
|
||||
static initial(todayString: string): GuestChatQuota {
|
||||
return new GuestChatQuota({
|
||||
remaining: GuestChatQuota.threshold,
|
||||
date: todayString,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要重置(跨天)
|
||||
* @param todayString 当天日期字符串(YYYY-MM-DD),由调用方提供
|
||||
*/
|
||||
needsReset(todayString: string): boolean {
|
||||
return this.date !== todayString;
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
remaining: this.remaining,
|
||||
date: this.date,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestChatQuota {
|
||||
const remaining = json.remaining;
|
||||
const date = json.date;
|
||||
if (typeof remaining !== "number") {
|
||||
throw new Error(
|
||||
"GuestChatQuota.remaining is required and must be a number"
|
||||
);
|
||||
}
|
||||
if (typeof date !== "string") {
|
||||
throw new Error("GuestChatQuota.date is required and must be a string");
|
||||
}
|
||||
return new GuestChatQuota({ remaining, date });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 图片上传响应
|
||||
* 原始 Dart: ImageUploadResponse (lib/data/models/chat/image_upload_response.dart)
|
||||
*/
|
||||
export class ImageUploadResponse {
|
||||
readonly success: boolean;
|
||||
readonly imageId: string;
|
||||
readonly thumbUrl: string;
|
||||
readonly mediumUrl: string;
|
||||
readonly originalUrl: string;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly bytes: number;
|
||||
|
||||
constructor(params: {
|
||||
success?: boolean;
|
||||
imageId: string;
|
||||
thumbUrl: string;
|
||||
mediumUrl: string;
|
||||
originalUrl: string;
|
||||
width: number;
|
||||
height: number;
|
||||
bytes: number;
|
||||
}) {
|
||||
this.success = params.success ?? true;
|
||||
this.imageId = params.imageId;
|
||||
this.thumbUrl = params.thumbUrl;
|
||||
this.mediumUrl = params.mediumUrl;
|
||||
this.originalUrl = params.originalUrl;
|
||||
this.width = params.width;
|
||||
this.height = params.height;
|
||||
this.bytes = params.bytes;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
success: this.success,
|
||||
imageId: this.imageId,
|
||||
thumbUrl: this.thumbUrl,
|
||||
mediumUrl: this.mediumUrl,
|
||||
originalUrl: this.originalUrl,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
bytes: this.bytes,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ImageUploadResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ImageUploadResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ImageUploadResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ImageUploadResponse({
|
||||
success: typeof json.success === "boolean" ? json.success : undefined,
|
||||
imageId: requireString("imageId"),
|
||||
thumbUrl: requireString("thumbUrl"),
|
||||
mediumUrl: requireString("mediumUrl"),
|
||||
originalUrl: requireString("originalUrl"),
|
||||
width: requireNumber("width"),
|
||||
height: requireNumber("height"),
|
||||
bytes: requireNumber("bytes"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// chat 子目录 barrel export
|
||||
export { ChatHistoryResponse } from "./chat_history_response";
|
||||
export { ChatMessage } from "./chat_message";
|
||||
export { ChatSendResponse } from "./chat_send_response";
|
||||
export { ChatSyncData } from "./chat_sync_data";
|
||||
export { ChatSyncRequest } from "./chat_sync_request";
|
||||
export { GuestChatQuota } from "./guest_chat_quota";
|
||||
export { ImageUploadResponse } from "./image_upload_response";
|
||||
export { SendMessageRequest } from "./send_message_request";
|
||||
export { SttData } from "./stt_data";
|
||||
export { SyncMessage } from "./sync_message";
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 发送消息请求 - 用于 /api/chat/send 接口
|
||||
* 原始 Dart: SendMessageRequest (lib/data/models/chat/send_message_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中所有图片相关字段为可空,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - 数字 → 0
|
||||
*/
|
||||
export class SendMessageRequest {
|
||||
readonly message: string;
|
||||
readonly image: string;
|
||||
readonly imageId: string;
|
||||
readonly imageThumbUrl: string;
|
||||
readonly imageMediumUrl: string;
|
||||
readonly imageOriginalUrl: string;
|
||||
readonly imageWidth: number;
|
||||
readonly imageHeight: number;
|
||||
readonly useWebSocket: boolean;
|
||||
|
||||
constructor(params: {
|
||||
message?: string;
|
||||
image?: string;
|
||||
imageId?: string;
|
||||
imageThumbUrl?: string;
|
||||
imageMediumUrl?: string;
|
||||
imageOriginalUrl?: string;
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
useWebSocket?: boolean;
|
||||
}) {
|
||||
this.message = params.message ?? "";
|
||||
this.image = params.image ?? "";
|
||||
this.imageId = params.imageId ?? "";
|
||||
this.imageThumbUrl = params.imageThumbUrl ?? "";
|
||||
this.imageMediumUrl = params.imageMediumUrl ?? "";
|
||||
this.imageOriginalUrl = params.imageOriginalUrl ?? "";
|
||||
this.imageWidth = params.imageWidth ?? 0;
|
||||
this.imageHeight = params.imageHeight ?? 0;
|
||||
this.useWebSocket = params.useWebSocket ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
message: this.message,
|
||||
image: this.image,
|
||||
imageId: this.imageId,
|
||||
imageThumbUrl: this.imageThumbUrl,
|
||||
imageMediumUrl: this.imageMediumUrl,
|
||||
imageOriginalUrl: this.imageOriginalUrl,
|
||||
imageWidth: this.imageWidth,
|
||||
imageHeight: this.imageHeight,
|
||||
useWebSocket: this.useWebSocket,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SendMessageRequest {
|
||||
return new SendMessageRequest({
|
||||
message: typeof json.message === "string" ? json.message : undefined,
|
||||
image: typeof json.image === "string" ? json.image : undefined,
|
||||
imageId: typeof json.imageId === "string" ? json.imageId : undefined,
|
||||
imageThumbUrl:
|
||||
typeof json.imageThumbUrl === "string"
|
||||
? json.imageThumbUrl
|
||||
: undefined,
|
||||
imageMediumUrl:
|
||||
typeof json.imageMediumUrl === "string"
|
||||
? json.imageMediumUrl
|
||||
: undefined,
|
||||
imageOriginalUrl:
|
||||
typeof json.imageOriginalUrl === "string"
|
||||
? json.imageOriginalUrl
|
||||
: undefined,
|
||||
imageWidth:
|
||||
typeof json.imageWidth === "number" ? json.imageWidth : undefined,
|
||||
imageHeight:
|
||||
typeof json.imageHeight === "number" ? json.imageHeight : undefined,
|
||||
useWebSocket:
|
||||
typeof json.useWebSocket === "boolean" ? json.useWebSocket : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* STT(语音转文字)响应
|
||||
* 原始 Dart: SttData (lib/data/models/chat/stt_response.dart)
|
||||
*/
|
||||
export class SttData {
|
||||
readonly text: string;
|
||||
|
||||
constructor(params: { text: string }) {
|
||||
this.text = params.text;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { text: this.text };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SttData {
|
||||
const text = json.text;
|
||||
if (typeof text !== "string") {
|
||||
throw new Error("SttData.text is required and must be a string");
|
||||
}
|
||||
return new SttData({ text });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 待同步的单条消息
|
||||
* 原始 Dart: SyncMessage (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
export class SyncMessage {
|
||||
readonly role: string;
|
||||
readonly content: string;
|
||||
readonly timestamp: string;
|
||||
|
||||
constructor(params: { role: string; content: string; timestamp: string }) {
|
||||
this.role = params.role;
|
||||
this.content = params.content;
|
||||
this.timestamp = params.timestamp;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
role: this.role,
|
||||
content: this.content,
|
||||
timestamp: this.timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SyncMessage {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`SyncMessage.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new SyncMessage({
|
||||
role: requireString("role"),
|
||||
content: requireString("content"),
|
||||
timestamp: requireString("timestamp"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// models 顶层 barrel export - 集中导出所有分类
|
||||
export * from "./auth";
|
||||
export * from "./chat";
|
||||
export * from "./metrics";
|
||||
export * from "./user";
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 应用事件上报请求 - 用于 /api/data/report-user-info 接口
|
||||
* 原始 Dart: AppEvent (lib/data/models/metrics/app_event.dart)
|
||||
*/
|
||||
export class AppEvent {
|
||||
readonly userId: string;
|
||||
readonly browser: string;
|
||||
readonly userAgent: string;
|
||||
|
||||
constructor(params: { userId: string; browser: string; userAgent: string }) {
|
||||
this.userId = params.userId;
|
||||
this.browser = params.browser;
|
||||
this.userAgent = params.userAgent;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
browser: this.browser,
|
||||
userAgent: this.userAgent,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AppEvent {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`AppEvent.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new AppEvent({
|
||||
userId: requireString("userId"),
|
||||
browser: requireString("browser"),
|
||||
userAgent: requireString("userAgent"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// metrics 子目录 barrel export
|
||||
export { AppEvent } from "./app_event";
|
||||
export { PwaEvent } from "./pwa_event";
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* PWA 事件上报请求 - 用于 /api/metrics/pwa/event 接口
|
||||
* 原始 Dart: PwaEvent (lib/data/models/metrics/pwa_event.dart)
|
||||
*/
|
||||
export class PwaEvent {
|
||||
readonly deviceId: string;
|
||||
readonly deviceType: string;
|
||||
readonly timestamp: number;
|
||||
readonly pwaInstalled: boolean;
|
||||
readonly pwaSupported: boolean;
|
||||
|
||||
constructor(params: {
|
||||
deviceId: string;
|
||||
deviceType: string;
|
||||
timestamp: number;
|
||||
pwaInstalled?: boolean;
|
||||
pwaSupported?: boolean;
|
||||
}) {
|
||||
this.deviceId = params.deviceId;
|
||||
this.deviceType = params.deviceType;
|
||||
this.timestamp = params.timestamp;
|
||||
this.pwaInstalled = params.pwaInstalled ?? false;
|
||||
this.pwaSupported = params.pwaSupported ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
deviceId: this.deviceId,
|
||||
deviceType: this.deviceType,
|
||||
timestamp: this.timestamp,
|
||||
pwaInstalled: this.pwaInstalled,
|
||||
pwaSupported: this.pwaSupported,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): PwaEvent {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`PwaEvent.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(`PwaEvent.${key} is required and must be a number`);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new PwaEvent({
|
||||
deviceId: requireString("deviceId"),
|
||||
deviceType: requireString("deviceType"),
|
||||
timestamp: requireNumber("timestamp"),
|
||||
pwaInstalled:
|
||||
typeof json.pwaInstalled === "boolean"
|
||||
? json.pwaInstalled
|
||||
: undefined,
|
||||
pwaSupported:
|
||||
typeof json.pwaSupported === "boolean"
|
||||
? json.pwaSupported
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 头像数据模型 - 对应后端 AvatarData schema
|
||||
* 原始 Dart: AvatarData (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `avatarUrl` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class AvatarData {
|
||||
readonly avatarUrl: string;
|
||||
readonly userId: string;
|
||||
|
||||
constructor(params: { avatarUrl?: string; userId: string }) {
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
this.userId = params.userId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
avatarUrl: this.avatarUrl,
|
||||
userId: this.userId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AvatarData {
|
||||
const userId = json.userId;
|
||||
if (typeof userId !== "string") {
|
||||
throw new Error("AvatarData.userId is required and must be a string");
|
||||
}
|
||||
return new AvatarData({
|
||||
userId,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 积分数据模型 - 对应后端 CreditsData schema
|
||||
* 原始 Dart: CreditsData (lib/data/models/user/user.dart)
|
||||
*/
|
||||
export class CreditsData {
|
||||
readonly userId: string;
|
||||
readonly dolBalance: number;
|
||||
|
||||
constructor(params: { userId: string; dolBalance: number }) {
|
||||
this.userId = params.userId;
|
||||
this.dolBalance = params.dolBalance;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
dolBalance: this.dolBalance,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): CreditsData {
|
||||
const userId = json.userId;
|
||||
const dolBalance = json.dolBalance;
|
||||
if (typeof userId !== "string") {
|
||||
throw new Error("CreditsData.userId is required and must be a string");
|
||||
}
|
||||
if (typeof dolBalance !== "number") {
|
||||
throw new Error(
|
||||
"CreditsData.dolBalance is required and must be a number"
|
||||
);
|
||||
}
|
||||
return new CreditsData({ userId, dolBalance });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 积分历史记录模型 - 对应后端 CreditsHistoryData schema
|
||||
* 原始 Dart: CreditsHistoryData (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `records` 为 `List<Map<String, dynamic>>`,
|
||||
* 迁移为 `Record<string, unknown>[]`。
|
||||
*/
|
||||
export class CreditsHistoryData {
|
||||
readonly records: Record<string, unknown>[];
|
||||
readonly total: number;
|
||||
readonly limit: number;
|
||||
readonly offset: number;
|
||||
|
||||
constructor(params: {
|
||||
records: Record<string, unknown>[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}) {
|
||||
this.records = params.records;
|
||||
this.total = params.total;
|
||||
this.limit = params.limit;
|
||||
this.offset = params.offset;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
records: this.records,
|
||||
total: this.total,
|
||||
limit: this.limit,
|
||||
offset: this.offset,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): CreditsHistoryData {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`CreditsHistoryData.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawRecords = json.records;
|
||||
const records: Record<string, unknown>[] = Array.isArray(rawRecords)
|
||||
? (rawRecords as Record<string, unknown>[])
|
||||
: [];
|
||||
return new CreditsHistoryData({
|
||||
records,
|
||||
total: requireNumber("total"),
|
||||
limit: requireNumber("limit"),
|
||||
offset: requireNumber("offset"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// user 子目录 barrel export
|
||||
export { AvatarData } from "./avatar_data";
|
||||
export { CreditsData } from "./credits_data";
|
||||
export { CreditsHistoryData } from "./credits_history_data";
|
||||
export { PersonalityTraits } from "./personality_traits";
|
||||
export { RecentMemory } from "./recent_memory";
|
||||
export { UpdateProfileRequest } from "./update_profile_request";
|
||||
export { User } from "./user";
|
||||
export { UserStatsResponse } from "./user_stats_response";
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 个性特征模型
|
||||
* 原始 Dart: PersonalityTraits (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:所有 double 字段在 Dart 中使用 @Default(0.5)。
|
||||
*/
|
||||
export class PersonalityTraits {
|
||||
readonly cheerful: number;
|
||||
readonly caring: number;
|
||||
readonly playful: number;
|
||||
readonly serious: number;
|
||||
readonly romantic: number;
|
||||
|
||||
constructor(params: {
|
||||
cheerful?: number;
|
||||
caring?: number;
|
||||
playful?: number;
|
||||
serious?: number;
|
||||
romantic?: number;
|
||||
}) {
|
||||
this.cheerful = params.cheerful ?? 0.5;
|
||||
this.caring = params.caring ?? 0.5;
|
||||
this.playful = params.playful ?? 0.5;
|
||||
this.serious = params.serious ?? 0.5;
|
||||
this.romantic = params.romantic ?? 0.5;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
cheerful: this.cheerful,
|
||||
caring: this.caring,
|
||||
playful: this.playful,
|
||||
serious: this.serious,
|
||||
romantic: this.romantic,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): PersonalityTraits {
|
||||
return new PersonalityTraits({
|
||||
cheerful: typeof json.cheerful === "number" ? json.cheerful : undefined,
|
||||
caring: typeof json.caring === "number" ? json.caring : undefined,
|
||||
playful: typeof json.playful === "number" ? json.playful : undefined,
|
||||
serious: typeof json.serious === "number" ? json.serious : undefined,
|
||||
romantic: typeof json.romantic === "number" ? json.romantic : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 最近记忆模型
|
||||
* 原始 Dart: RecentMemory (lib/data/models/user/recent_memory.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `createdAt` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class RecentMemory {
|
||||
readonly type: string;
|
||||
readonly content: string;
|
||||
readonly importance: number;
|
||||
readonly createdAt: string;
|
||||
|
||||
constructor(params: {
|
||||
type: string;
|
||||
content: string;
|
||||
importance: number;
|
||||
createdAt?: string;
|
||||
}) {
|
||||
this.type = params.type;
|
||||
this.content = params.content;
|
||||
this.importance = params.importance;
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
type: this.type,
|
||||
content: this.content,
|
||||
importance: this.importance,
|
||||
createdAt: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RecentMemory {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RecentMemory.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const importance = json.importance;
|
||||
if (typeof importance !== "number") {
|
||||
throw new Error(
|
||||
"RecentMemory.importance is required and must be a number"
|
||||
);
|
||||
}
|
||||
return new RecentMemory({
|
||||
type: requireString("type"),
|
||||
content: requireString("content"),
|
||||
importance,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 更新个人资料请求
|
||||
* 原始 Dart: UpdateProfileRequest (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中所有字段为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class UpdateProfileRequest {
|
||||
readonly username: string;
|
||||
readonly nickname: string;
|
||||
readonly preferredLanguage: string;
|
||||
readonly currentMood: string;
|
||||
|
||||
constructor(params: {
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
preferredLanguage?: string;
|
||||
currentMood?: string;
|
||||
}) {
|
||||
this.username = params.username ?? "";
|
||||
this.nickname = params.nickname ?? "";
|
||||
this.preferredLanguage = params.preferredLanguage ?? "";
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
username: this.username,
|
||||
nickname: this.nickname,
|
||||
preferredLanguage: this.preferredLanguage,
|
||||
currentMood: this.currentMood,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): UpdateProfileRequest {
|
||||
return new UpdateProfileRequest({
|
||||
username: typeof json.username === "string" ? json.username : undefined,
|
||||
nickname: typeof json.nickname === "string" ? json.nickname : undefined,
|
||||
preferredLanguage:
|
||||
typeof json.preferredLanguage === "string"
|
||||
? json.preferredLanguage
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 用户模型 - 对应后端 UserData schema
|
||||
* 原始 Dart: User (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `email`/`personalityTraits`/`preferredLanguage`/`createdAt`/
|
||||
* `lastMessageAt`/`avatarUrl` 为可空字段,按"全部非空"约定统一兜底:
|
||||
* - 字符串字段 → 空串 ""
|
||||
* - PersonalityTraits → 默认实例(全 0.5)
|
||||
*/
|
||||
import { PersonalityTraits } from "./personality_traits";
|
||||
|
||||
export class User {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly email: string;
|
||||
readonly platform: string;
|
||||
readonly intimacy: number;
|
||||
readonly dolBalance: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly currentMood: string;
|
||||
readonly personalityTraits: PersonalityTraits;
|
||||
readonly preferredLanguage: string;
|
||||
readonly createdAt: string;
|
||||
readonly lastMessageAt: string;
|
||||
readonly avatarUrl: string;
|
||||
readonly loginProvider: string;
|
||||
readonly isGuest: boolean;
|
||||
|
||||
constructor(params: {
|
||||
id: string;
|
||||
username: string;
|
||||
email?: string;
|
||||
platform?: string;
|
||||
intimacy?: number;
|
||||
dolBalance?: number;
|
||||
relationshipStage?: string;
|
||||
currentMood?: string;
|
||||
personalityTraits?: PersonalityTraits;
|
||||
preferredLanguage?: string;
|
||||
createdAt?: string;
|
||||
lastMessageAt?: string;
|
||||
avatarUrl?: string;
|
||||
loginProvider?: string;
|
||||
isGuest?: boolean;
|
||||
}) {
|
||||
this.id = params.id;
|
||||
this.username = params.username;
|
||||
this.email = params.email ?? "";
|
||||
this.platform = params.platform ?? "web";
|
||||
this.intimacy = params.intimacy ?? 0;
|
||||
this.dolBalance = params.dolBalance ?? 0;
|
||||
this.relationshipStage = params.relationshipStage ?? "密友";
|
||||
this.currentMood = params.currentMood ?? "happy";
|
||||
this.personalityTraits = params.personalityTraits ?? new PersonalityTraits({});
|
||||
this.preferredLanguage = params.preferredLanguage ?? "";
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
this.lastMessageAt = params.lastMessageAt ?? "";
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
this.loginProvider = params.loginProvider ?? "email";
|
||||
this.isGuest = params.isGuest ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
id: this.id,
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
platform: this.platform,
|
||||
intimacy: this.intimacy,
|
||||
dolBalance: this.dolBalance,
|
||||
relationshipStage: this.relationshipStage,
|
||||
currentMood: this.currentMood,
|
||||
personalityTraits: this.personalityTraits.toJson(),
|
||||
preferredLanguage: this.preferredLanguage,
|
||||
createdAt: this.createdAt,
|
||||
lastMessageAt: this.lastMessageAt,
|
||||
avatarUrl: this.avatarUrl,
|
||||
loginProvider: this.loginProvider,
|
||||
isGuest: this.isGuest,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): User {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(`User.${key} is required and must be a string`);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new User({
|
||||
id: requireString("id"),
|
||||
username: requireString("username"),
|
||||
email: typeof json.email === "string" ? json.email : undefined,
|
||||
platform: typeof json.platform === "string" ? json.platform : undefined,
|
||||
intimacy: typeof json.intimacy === "number" ? json.intimacy : undefined,
|
||||
dolBalance:
|
||||
typeof json.dolBalance === "number" ? json.dolBalance : undefined,
|
||||
relationshipStage:
|
||||
typeof json.relationshipStage === "string"
|
||||
? json.relationshipStage
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
personalityTraits: json.personalityTraits
|
||||
? PersonalityTraits.fromJson(
|
||||
json.personalityTraits as Record<string, unknown>
|
||||
)
|
||||
: undefined,
|
||||
preferredLanguage:
|
||||
typeof json.preferredLanguage === "string"
|
||||
? json.preferredLanguage
|
||||
: undefined,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
lastMessageAt:
|
||||
typeof json.lastMessageAt === "string" ? json.lastMessageAt : undefined,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
loginProvider:
|
||||
typeof json.loginProvider === "string"
|
||||
? json.loginProvider
|
||||
: undefined,
|
||||
isGuest: typeof json.isGuest === "boolean" ? json.isGuest : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* 用户统计响应
|
||||
* 原始 Dart: UserStatsResponse (lib/data/models/user/user_stats_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `lastMessageAt`/`accountCreatedAt`/`currentMood` 为 `String?`,
|
||||
* `personalityTraits` 为 `PersonalityTraits?`,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - PersonalityTraits → 默认实例
|
||||
* - recentMemories 缺失或 null 时使用 []
|
||||
*/
|
||||
import { PersonalityTraits } from "./personality_traits";
|
||||
import { RecentMemory } from "./recent_memory";
|
||||
|
||||
export class UserStatsResponse {
|
||||
readonly userId: string;
|
||||
readonly username: string;
|
||||
readonly platform: string;
|
||||
readonly intimacy: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly dolBalance: number;
|
||||
readonly totalMessages: number;
|
||||
readonly lastMessageAt: string;
|
||||
readonly accountCreatedAt: string;
|
||||
readonly currentMood: string;
|
||||
readonly personalityTraits: PersonalityTraits;
|
||||
readonly recentMemories: RecentMemory[];
|
||||
readonly promptTokensTotal: number;
|
||||
readonly completionTokensTotal: number;
|
||||
readonly cacheHitTokensTotal: number;
|
||||
readonly tokensTotal: number;
|
||||
|
||||
constructor(params: {
|
||||
userId: string;
|
||||
username: string;
|
||||
platform: string;
|
||||
intimacy: number;
|
||||
relationshipStage: string;
|
||||
dolBalance: number;
|
||||
totalMessages: number;
|
||||
lastMessageAt?: string;
|
||||
accountCreatedAt?: string;
|
||||
currentMood?: string;
|
||||
personalityTraits?: PersonalityTraits;
|
||||
recentMemories?: RecentMemory[];
|
||||
promptTokensTotal?: number;
|
||||
completionTokensTotal?: number;
|
||||
cacheHitTokensTotal?: number;
|
||||
tokensTotal?: number;
|
||||
}) {
|
||||
this.userId = params.userId;
|
||||
this.username = params.username;
|
||||
this.platform = params.platform;
|
||||
this.intimacy = params.intimacy;
|
||||
this.relationshipStage = params.relationshipStage;
|
||||
this.dolBalance = params.dolBalance;
|
||||
this.totalMessages = params.totalMessages;
|
||||
this.lastMessageAt = params.lastMessageAt ?? "";
|
||||
this.accountCreatedAt = params.accountCreatedAt ?? "";
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
this.personalityTraits =
|
||||
params.personalityTraits ?? new PersonalityTraits({});
|
||||
this.recentMemories = params.recentMemories ?? [];
|
||||
this.promptTokensTotal = params.promptTokensTotal ?? 0;
|
||||
this.completionTokensTotal = params.completionTokensTotal ?? 0;
|
||||
this.cacheHitTokensTotal = params.cacheHitTokensTotal ?? 0;
|
||||
this.tokensTotal = params.tokensTotal ?? 0;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
username: this.username,
|
||||
platform: this.platform,
|
||||
intimacy: this.intimacy,
|
||||
relationshipStage: this.relationshipStage,
|
||||
dolBalance: this.dolBalance,
|
||||
totalMessages: this.totalMessages,
|
||||
lastMessageAt: this.lastMessageAt,
|
||||
accountCreatedAt: this.accountCreatedAt,
|
||||
currentMood: this.currentMood,
|
||||
personalityTraits: this.personalityTraits.toJson(),
|
||||
recentMemories: this.recentMemories.map((m) => m.toJson()),
|
||||
promptTokensTotal: this.promptTokensTotal,
|
||||
completionTokensTotal: this.completionTokensTotal,
|
||||
cacheHitTokensTotal: this.cacheHitTokensTotal,
|
||||
tokensTotal: this.tokensTotal,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): UserStatsResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawMemories = json.recentMemories;
|
||||
const recentMemories: RecentMemory[] = Array.isArray(rawMemories)
|
||||
? (rawMemories as Record<string, unknown>[]).map((m) =>
|
||||
RecentMemory.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new UserStatsResponse({
|
||||
userId: requireString("userId"),
|
||||
username: requireString("username"),
|
||||
platform: requireString("platform"),
|
||||
intimacy: requireNumber("intimacy"),
|
||||
relationshipStage: requireString("relationshipStage"),
|
||||
dolBalance: requireNumber("dolBalance"),
|
||||
totalMessages: requireNumber("totalMessages"),
|
||||
lastMessageAt:
|
||||
typeof json.lastMessageAt === "string"
|
||||
? json.lastMessageAt
|
||||
: undefined,
|
||||
accountCreatedAt:
|
||||
typeof json.accountCreatedAt === "string"
|
||||
? json.accountCreatedAt
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
personalityTraits: json.personalityTraits
|
||||
? PersonalityTraits.fromJson(
|
||||
json.personalityTraits as Record<string, unknown>
|
||||
)
|
||||
: undefined,
|
||||
recentMemories,
|
||||
promptTokensTotal:
|
||||
typeof json.promptTokensTotal === "number"
|
||||
? json.promptTokensTotal
|
||||
: undefined,
|
||||
completionTokensTotal:
|
||||
typeof json.completionTokensTotal === "number"
|
||||
? json.completionTokensTotal
|
||||
: undefined,
|
||||
cacheHitTokensTotal:
|
||||
typeof json.cacheHitTokensTotal === "number"
|
||||
? json.cacheHitTokensTotal
|
||||
: undefined,
|
||||
tokensTotal:
|
||||
typeof json.tokensTotal === "number" ? json.tokensTotal : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user