sa2kit 1.2.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/{UniversalFileService-C1rUWWU-.d.ts → UniversalFileService-BuHN-jrR.d.ts} +46 -2
  2. package/dist/{UniversalFileService-DrCK0-NL.d.mts → UniversalFileService-CGGzYeeF.d.mts} +46 -2
  3. package/dist/{chunk-3XG5OHFD.mjs → chunk-CIVO4R6N.mjs} +2 -2
  4. package/dist/{chunk-3XG5OHFD.mjs.map → chunk-CIVO4R6N.mjs.map} +1 -1
  5. package/dist/chunk-EV6BCVOQ.mjs +204 -0
  6. package/dist/chunk-EV6BCVOQ.mjs.map +1 -0
  7. package/dist/chunk-W35VTQAW.js +211 -0
  8. package/dist/chunk-W35VTQAW.js.map +1 -0
  9. package/dist/{chunk-HWJ34NL6.js → chunk-ZRAW3HXA.js} +2 -2
  10. package/dist/{chunk-HWJ34NL6.js.map → chunk-ZRAW3HXA.js.map} +1 -1
  11. package/dist/drizzle-schema-BNhqj2AZ.d.mts +1114 -0
  12. package/dist/drizzle-schema-BNhqj2AZ.d.ts +1114 -0
  13. package/dist/mmd/admin/index.d.mts +8 -1115
  14. package/dist/mmd/admin/index.d.ts +8 -1115
  15. package/dist/mmd/admin/index.js +98 -248
  16. package/dist/mmd/admin/index.js.map +1 -1
  17. package/dist/mmd/admin/index.mjs +75 -244
  18. package/dist/mmd/admin/index.mjs.map +1 -1
  19. package/dist/mmd/index.d.mts +265 -3
  20. package/dist/mmd/index.d.ts +265 -3
  21. package/dist/mmd/index.js +1266 -15
  22. package/dist/mmd/index.js.map +1 -1
  23. package/dist/mmd/index.mjs +1261 -16
  24. package/dist/mmd/index.mjs.map +1 -1
  25. package/dist/mmd/server/index.d.mts +138 -0
  26. package/dist/mmd/server/index.d.ts +138 -0
  27. package/dist/mmd/server/index.js +245 -0
  28. package/dist/mmd/server/index.js.map +1 -0
  29. package/dist/mmd/server/index.mjs +207 -0
  30. package/dist/mmd/server/index.mjs.map +1 -0
  31. package/dist/testYourself/index.d.mts +145 -0
  32. package/dist/testYourself/index.d.ts +145 -0
  33. package/dist/testYourself/index.js +1004 -0
  34. package/dist/testYourself/index.js.map +1 -0
  35. package/dist/testYourself/index.mjs +993 -0
  36. package/dist/testYourself/index.mjs.map +1 -0
  37. package/dist/{types-C2ale3d9.d.mts → types-Bc_p-zAR.d.mts} +1 -1
  38. package/dist/{types-C2ale3d9.d.ts → types-Bc_p-zAR.d.ts} +1 -1
  39. package/dist/{types-Dg-U_chI.d.mts → types-CK4We_aI.d.mts} +13 -1
  40. package/dist/{types-Dg-U_chI.d.ts → types-CK4We_aI.d.ts} +13 -1
  41. package/dist/universalFile/index.d.mts +3 -3
  42. package/dist/universalFile/index.d.ts +3 -3
  43. package/dist/universalFile/index.js +48 -10
  44. package/dist/universalFile/index.js.map +1 -1
  45. package/dist/universalFile/index.mjs +43 -5
  46. package/dist/universalFile/index.mjs.map +1 -1
  47. package/dist/universalFile/server/index.d.mts +3 -3
  48. package/dist/universalFile/server/index.d.ts +3 -3
  49. package/dist/universalFile/server/index.js +239 -7
  50. package/dist/universalFile/server/index.js.map +1 -1
  51. package/dist/universalFile/server/index.mjs +234 -2
  52. package/dist/universalFile/server/index.mjs.map +1 -1
  53. package/package.json +19 -1
@@ -1,16 +1,17 @@
1
+ export { mmdPlaylistNodes, mmdPlaylistNodesRelations, mmdPlaylists, mmdPlaylistsRelations, mmdPresetItems, mmdResourceOptions } from '../../chunk-EV6BCVOQ.mjs';
1
2
  import '../../chunk-BJTO5JO5.mjs';
2
3
  import React2, { useState, useCallback, useEffect } from 'react';
3
- import { Upload, CheckCircle2, X, Loader2, Search, Save, Settings, ChevronUp, ChevronDown, Plus, GripVertical, Trash2, List, Database, BarChart3, FileText, Music, Film } from 'lucide-react';
4
- import { relations } from 'drizzle-orm';
5
- import { pgTable, timestamp, varchar, json, integer, uuid, boolean, text, index } from 'drizzle-orm/pg-core';
4
+ import { Upload, CheckCircle2, X, Loader2, AlertTriangle, Search, Save, Settings, ChevronUp, ChevronDown, Plus, GripVertical, Trash2, List, Database, BarChart3, FileText, Music, Film } from 'lucide-react';
5
+ import JSZip from 'jszip';
6
6
 
7
7
  // src/mmd/admin/types.ts
8
8
  var MMD_RESOURCE_TYPE_CONFIGS = {
9
9
  model: {
10
10
  moduleId: "mmd-models",
11
- acceptedTypes: [".pmx", ".pmd"],
12
- maxFileSize: 50,
13
- description: "MMD\u6A21\u578B\u6587\u4EF6"
11
+ acceptedTypes: [".zip"],
12
+ maxFileSize: 150,
13
+ description: "MMD\u6A21\u578B\u538B\u7F29\u5305 (ZIP)",
14
+ hint: "\u8BF7\u4E0A\u4F20\u5305\u542B PMX/\u8D34\u56FE\u7B49\u5B8C\u6574\u76EE\u5F55\u7684 ZIP \u538B\u7F29\u5305\uFF0C\u4FDD\u6301\u539F\u59CB\u6587\u4EF6\u7ED3\u6784"
14
15
  },
15
16
  motion: {
16
17
  moduleId: "mmd-motions",
@@ -32,9 +33,10 @@ var MMD_RESOURCE_TYPE_CONFIGS = {
32
33
  },
33
34
  stage: {
34
35
  moduleId: "mmd-stages",
35
- acceptedTypes: [".pmx", ".pmd", ".x"],
36
- maxFileSize: 100,
37
- description: "MMD\u821E\u53F0/\u573A\u666F\u6A21\u578B"
36
+ acceptedTypes: [".zip"],
37
+ maxFileSize: 200,
38
+ description: "\u821E\u53F0/\u573A\u666F\u538B\u7F29\u5305 (ZIP)",
39
+ hint: "\u9700\u5C06\u821E\u53F0\u6A21\u578B\u4E0E\u4F9D\u8D56\u8D34\u56FE\u4E00\u8D77\u6253\u5305 ZIP\uFF0C\u5E76\u4FDD\u6301\u76EE\u5F55\u7ED3\u6784"
38
40
  },
39
41
  thumbnail: {
40
42
  moduleId: "mmd-thumbnails",
@@ -60,6 +62,7 @@ var MmdResourceSelector = ({
60
62
  const [uploading, setUploading] = useState(false);
61
63
  const [searchTerm, setSearchTerm] = useState("");
62
64
  const [showUploader, setShowUploader] = useState(false);
65
+ const [zipValidationError, setZipValidationError] = useState(null);
63
66
  const config = MMD_RESOURCE_TYPE_CONFIGS[resourceType];
64
67
  if (!config) {
65
68
  return /* @__PURE__ */ React2.createElement("div", { className: "p-4 bg-red-50 text-red-600 rounded-lg" }, "\u672A\u627E\u5230\u8D44\u6E90\u7C7B\u578B\u914D\u7F6E\uFF1A", resourceType);
@@ -111,10 +114,32 @@ var MmdResourceSelector = ({
111
114
  setSelectedFile(file);
112
115
  fileService.getFileUrl(file.id).then((url) => onChange(file.id, url)).catch((error) => console.error("\u83B7\u53D6\u6587\u4EF6URL\u5931\u8D25:", error));
113
116
  };
117
+ const validateZipContents = async (buffer, type) => {
118
+ const zip = await JSZip.loadAsync(buffer);
119
+ const entries = Object.keys(zip.files);
120
+ if (!entries.length) {
121
+ throw new Error("\u538B\u7F29\u5305\u4E3A\u7A7A\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u5185\u5BB9");
122
+ }
123
+ const hasModel = entries.some((name) => /\.[pP][mM][xX]$/.test(name)) || type === "stage" && entries.some((name) => /\.[pP][mM][dD]$/.test(name));
124
+ const hasAssets = entries.some(
125
+ (name) => /\.(png|jpg|jpeg|bmp|tga|dds|spa|sph)$/i.test(name)
126
+ );
127
+ if (!hasModel) {
128
+ throw new Error(type === "stage" ? "\u538B\u7F29\u5305\u4E2D\u672A\u627E\u5230 PMX/PMD \u821E\u53F0\u6A21\u578B\u6587\u4EF6" : "\u538B\u7F29\u5305\u4E2D\u672A\u627E\u5230 PMX \u6A21\u578B\u6587\u4EF6");
129
+ }
130
+ if (!hasAssets) {
131
+ throw new Error("\u538B\u7F29\u5305\u4E2D\u672A\u53D1\u73B0\u8D34\u56FE\u6587\u4EF6\uFF0C\u8BF7\u786E\u8BA4\u662F\u5426\u5305\u542B texture \u76EE\u5F55");
132
+ }
133
+ };
114
134
  const handleFileUpload = async (file) => {
115
135
  if (!fileService) return;
116
136
  setUploading(true);
137
+ setZipValidationError(null);
117
138
  try {
139
+ if (resourceType === "model" || resourceType === "stage") {
140
+ const arrayBuffer = await file.arrayBuffer();
141
+ await validateZipContents(arrayBuffer, resourceType);
142
+ }
118
143
  const fileMetadata = await fileService.uploadFile({
119
144
  file,
120
145
  moduleId: config.moduleId,
@@ -126,7 +151,9 @@ var MmdResourceSelector = ({
126
151
  setShowUploader(false);
127
152
  } catch (error) {
128
153
  console.error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25:", error);
129
- alert(`\u4E0A\u4F20\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`);
154
+ const message = error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF";
155
+ setZipValidationError(message);
156
+ alert(`\u4E0A\u4F20\u5931\u8D25: ${message}`);
130
157
  } finally {
131
158
  setUploading(false);
132
159
  }
@@ -153,7 +180,7 @@ var MmdResourceSelector = ({
153
180
  className: "p-1 hover:bg-white/50 dark:hover:bg-black/20 rounded transition-colors"
154
181
  },
155
182
  /* @__PURE__ */ React2.createElement(X, { className: "w-4 h-4" })
156
- )), showUploader && /* @__PURE__ */ React2.createElement("div", { className: "p-4 bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg" }, /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3" }, "\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ", config.acceptedTypes.join(", "), /* @__PURE__ */ React2.createElement("br", null), "\u6700\u5927\u6587\u4EF6\u5927\u5C0F: ", config.maxFileSize, "MB"), /* @__PURE__ */ React2.createElement(
183
+ )), showUploader && /* @__PURE__ */ React2.createElement("div", { className: "p-4 bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg" }, /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3 space-y-1" }, /* @__PURE__ */ React2.createElement("p", null, "\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ", config.acceptedTypes.join(", ")), /* @__PURE__ */ React2.createElement("p", null, "\u6700\u5927\u6587\u4EF6\u5927\u5C0F: ", config.maxFileSize, "MB"), config.hint && /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-amber-600 dark:text-amber-400" }, config.hint)), /* @__PURE__ */ React2.createElement(
157
184
  "input",
158
185
  {
159
186
  type: "file",
@@ -171,7 +198,7 @@ var MmdResourceSelector = ({
171
198
  disabled: uploading,
172
199
  className: "w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 disabled:opacity-50"
173
200
  }
174
- ), uploading && /* @__PURE__ */ React2.createElement("div", { className: "mt-3 flex items-center gap-2 text-sm text-blue-600" }, /* @__PURE__ */ React2.createElement(Loader2, { className: "w-4 h-4 animate-spin" }), "\u4E0A\u4F20\u4E2D...")), /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" }), /* @__PURE__ */ React2.createElement(
201
+ ), uploading && /* @__PURE__ */ React2.createElement("div", { className: "mt-3 flex items-center gap-2 text-sm text-blue-600" }, /* @__PURE__ */ React2.createElement(Loader2, { className: "w-4 h-4 animate-spin" }), "\u4E0A\u4F20\u4E2D..."), zipValidationError && /* @__PURE__ */ React2.createElement("div", { className: "mt-3 flex items-center gap-2 text-sm text-amber-600 dark:text-amber-400" }, /* @__PURE__ */ React2.createElement(AlertTriangle, { className: "w-4 h-4" }), zipValidationError)), /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" }), /* @__PURE__ */ React2.createElement(
175
202
  "input",
176
203
  {
177
204
  type: "text",
@@ -219,50 +246,50 @@ var MmdPlaylistEditor = ({
219
246
  setNodes([...nodes, newNode]);
220
247
  setExpandedNodes(/* @__PURE__ */ new Set([...expandedNodes, nodes.length]));
221
248
  };
222
- const removeNode = (index2) => {
223
- const newNodes = nodes.filter((_, i) => i !== index2);
249
+ const removeNode = (index) => {
250
+ const newNodes = nodes.filter((_, i) => i !== index);
224
251
  newNodes.forEach((node, i) => {
225
252
  node.sortOrder = i;
226
253
  });
227
254
  setNodes(newNodes);
228
255
  const newExpanded = /* @__PURE__ */ new Set();
229
256
  expandedNodes.forEach((i) => {
230
- if (i < index2) newExpanded.add(i);
231
- else if (i > index2) newExpanded.add(i - 1);
257
+ if (i < index) newExpanded.add(i);
258
+ else if (i > index) newExpanded.add(i - 1);
232
259
  });
233
260
  setExpandedNodes(newExpanded);
234
261
  };
235
- const moveNode = (index2, direction) => {
262
+ const moveNode = (index, direction) => {
236
263
  const newNodes = [...nodes];
237
- const targetIndex = direction === "up" ? index2 - 1 : index2 + 1;
264
+ const targetIndex = direction === "up" ? index - 1 : index + 1;
238
265
  if (targetIndex < 0 || targetIndex >= newNodes.length) return;
239
- if (!newNodes[index2] || !newNodes[targetIndex]) return;
240
- [newNodes[index2], newNodes[targetIndex]] = [newNodes[targetIndex], newNodes[index2]];
266
+ if (!newNodes[index] || !newNodes[targetIndex]) return;
267
+ [newNodes[index], newNodes[targetIndex]] = [newNodes[targetIndex], newNodes[index]];
241
268
  newNodes.forEach((node, i) => {
242
269
  node.sortOrder = i;
243
270
  });
244
271
  setNodes(newNodes);
245
272
  const newExpanded = /* @__PURE__ */ new Set();
246
273
  expandedNodes.forEach((i) => {
247
- if (i === index2) newExpanded.add(targetIndex);
248
- else if (i === targetIndex) newExpanded.add(index2);
274
+ if (i === index) newExpanded.add(targetIndex);
275
+ else if (i === targetIndex) newExpanded.add(index);
249
276
  else newExpanded.add(i);
250
277
  });
251
278
  setExpandedNodes(newExpanded);
252
279
  };
253
- const toggleNode = (index2) => {
280
+ const toggleNode = (index) => {
254
281
  const newExpanded = new Set(expandedNodes);
255
- if (newExpanded.has(index2)) {
256
- newExpanded.delete(index2);
282
+ if (newExpanded.has(index)) {
283
+ newExpanded.delete(index);
257
284
  } else {
258
- newExpanded.add(index2);
285
+ newExpanded.add(index);
259
286
  }
260
287
  setExpandedNodes(newExpanded);
261
288
  };
262
- const updateNode = (index2, updates) => {
289
+ const updateNode = (index, updates) => {
263
290
  const newNodes = [...nodes];
264
- if (!newNodes[index2]) return;
265
- newNodes[index2] = { ...newNodes[index2], ...updates };
291
+ if (!newNodes[index]) return;
292
+ newNodes[index] = { ...newNodes[index], ...updates };
266
293
  setNodes(newNodes);
267
294
  };
268
295
  const validateForm = () => {
@@ -386,10 +413,10 @@ var MmdPlaylistEditor = ({
386
413
  },
387
414
  /* @__PURE__ */ React2.createElement(Plus, { className: "w-4 h-4" }),
388
415
  "\u6DFB\u52A0\u8282\u70B9"
389
- )), nodes.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "p-8 text-center text-gray-500 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg" }, '\u6682\u65E0\u8282\u70B9\uFF0C\u8BF7\u70B9\u51FB"\u6DFB\u52A0\u8282\u70B9"\u6309\u94AE\u5F00\u59CB') : nodes.map((node, index2) => /* @__PURE__ */ React2.createElement(
416
+ )), nodes.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "p-8 text-center text-gray-500 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg" }, '\u6682\u65E0\u8282\u70B9\uFF0C\u8BF7\u70B9\u51FB"\u6DFB\u52A0\u8282\u70B9"\u6309\u94AE\u5F00\u59CB') : nodes.map((node, index) => /* @__PURE__ */ React2.createElement(
390
417
  "div",
391
418
  {
392
- key: index2,
419
+ key: index,
393
420
  className: "border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden"
394
421
  },
395
422
  /* @__PURE__ */ React2.createElement("div", { className: "flex items-center gap-3 p-4 bg-gray-50 dark:bg-gray-800" }, /* @__PURE__ */ React2.createElement(
@@ -402,16 +429,16 @@ var MmdPlaylistEditor = ({
402
429
  ), /* @__PURE__ */ React2.createElement(
403
430
  "button",
404
431
  {
405
- onClick: () => toggleNode(index2),
432
+ onClick: () => toggleNode(index),
406
433
  className: "flex-1 flex items-center justify-between text-left"
407
434
  },
408
- /* @__PURE__ */ React2.createElement("span", { className: "font-medium text-gray-900 dark:text-white" }, index2 + 1, ". ", node.name || "\u672A\u547D\u540D\u8282\u70B9"),
409
- expandedNodes.has(index2) ? /* @__PURE__ */ React2.createElement(ChevronUp, { className: "w-5 h-5 text-gray-400" }) : /* @__PURE__ */ React2.createElement(ChevronDown, { className: "w-5 h-5 text-gray-400" })
435
+ /* @__PURE__ */ React2.createElement("span", { className: "font-medium text-gray-900 dark:text-white" }, index + 1, ". ", node.name || "\u672A\u547D\u540D\u8282\u70B9"),
436
+ expandedNodes.has(index) ? /* @__PURE__ */ React2.createElement(ChevronUp, { className: "w-5 h-5 text-gray-400" }) : /* @__PURE__ */ React2.createElement(ChevronDown, { className: "w-5 h-5 text-gray-400" })
410
437
  ), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React2.createElement(
411
438
  "button",
412
439
  {
413
- onClick: () => moveNode(index2, "up"),
414
- disabled: index2 === 0,
440
+ onClick: () => moveNode(index, "up"),
441
+ disabled: index === 0,
415
442
  className: "p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 disabled:opacity-30",
416
443
  title: "\u4E0A\u79FB"
417
444
  },
@@ -419,8 +446,8 @@ var MmdPlaylistEditor = ({
419
446
  ), /* @__PURE__ */ React2.createElement(
420
447
  "button",
421
448
  {
422
- onClick: () => moveNode(index2, "down"),
423
- disabled: index2 === nodes.length - 1,
449
+ onClick: () => moveNode(index, "down"),
450
+ disabled: index === nodes.length - 1,
424
451
  className: "p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 disabled:opacity-30",
425
452
  title: "\u4E0B\u79FB"
426
453
  },
@@ -428,18 +455,18 @@ var MmdPlaylistEditor = ({
428
455
  ), /* @__PURE__ */ React2.createElement(
429
456
  "button",
430
457
  {
431
- onClick: () => removeNode(index2),
458
+ onClick: () => removeNode(index),
432
459
  className: "p-1 text-red-400 hover:text-red-600 dark:hover:text-red-300",
433
460
  title: "\u5220\u9664"
434
461
  },
435
462
  /* @__PURE__ */ React2.createElement(Trash2, { className: "w-5 h-5" })
436
463
  ))),
437
- expandedNodes.has(index2) && /* @__PURE__ */ React2.createElement("div", { className: "p-6 space-y-6 bg-white dark:bg-gray-900" }, /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" }, "\u8282\u70B9\u540D\u79F0 ", /* @__PURE__ */ React2.createElement("span", { className: "text-red-500" }, "*")), /* @__PURE__ */ React2.createElement(
464
+ expandedNodes.has(index) && /* @__PURE__ */ React2.createElement("div", { className: "p-6 space-y-6 bg-white dark:bg-gray-900" }, /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" }, "\u8282\u70B9\u540D\u79F0 ", /* @__PURE__ */ React2.createElement("span", { className: "text-red-500" }, "*")), /* @__PURE__ */ React2.createElement(
438
465
  "input",
439
466
  {
440
467
  type: "text",
441
468
  value: node.name,
442
- onChange: (e) => updateNode(index2, { name: e.target.value }),
469
+ onChange: (e) => updateNode(index, { name: e.target.value }),
443
470
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
444
471
  }
445
472
  )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" }, "\u65F6\u957F\uFF08\u79D2\uFF09"), /* @__PURE__ */ React2.createElement(
@@ -447,14 +474,14 @@ var MmdPlaylistEditor = ({
447
474
  {
448
475
  type: "number",
449
476
  value: node.duration || "",
450
- onChange: (e) => updateNode(index2, { duration: parseInt(e.target.value) || void 0 }),
477
+ onChange: (e) => updateNode(index, { duration: parseInt(e.target.value) || void 0 }),
451
478
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
452
479
  }
453
480
  ))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" }, "\u63CF\u8FF0"), /* @__PURE__ */ React2.createElement(
454
481
  "textarea",
455
482
  {
456
483
  value: node.description || "",
457
- onChange: (e) => updateNode(index2, { description: e.target.value }),
484
+ onChange: (e) => updateNode(index, { description: e.target.value }),
458
485
  rows: 2,
459
486
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
460
487
  }
@@ -463,7 +490,7 @@ var MmdPlaylistEditor = ({
463
490
  {
464
491
  type: "checkbox",
465
492
  checked: node.loop,
466
- onChange: (e) => updateNode(index2, { loop: e.target.checked }),
493
+ onChange: (e) => updateNode(index, { loop: e.target.checked }),
467
494
  className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
468
495
  }
469
496
  ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-gray-700 dark:text-gray-300" }, "\u5355\u66F2\u5FAA\u73AF")), /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-1 gap-6 pt-4 border-t border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React2.createElement(
@@ -473,7 +500,7 @@ var MmdPlaylistEditor = ({
473
500
  fileService,
474
501
  userId,
475
502
  value: node.modelFileId,
476
- onChange: (fileId) => updateNode(index2, { modelFileId: fileId }),
503
+ onChange: (fileId) => updateNode(index, { modelFileId: fileId }),
477
504
  required: true
478
505
  }
479
506
  ), /* @__PURE__ */ React2.createElement(
@@ -483,7 +510,7 @@ var MmdPlaylistEditor = ({
483
510
  fileService,
484
511
  userId,
485
512
  value: node.motionFileId,
486
- onChange: (fileId) => updateNode(index2, { motionFileId: fileId })
513
+ onChange: (fileId) => updateNode(index, { motionFileId: fileId })
487
514
  }
488
515
  ), /* @__PURE__ */ React2.createElement(
489
516
  MmdResourceSelector,
@@ -492,7 +519,7 @@ var MmdPlaylistEditor = ({
492
519
  fileService,
493
520
  userId,
494
521
  value: node.audioFileId,
495
- onChange: (fileId) => updateNode(index2, { audioFileId: fileId })
522
+ onChange: (fileId) => updateNode(index, { audioFileId: fileId })
496
523
  }
497
524
  )))
498
525
  ))));
@@ -789,203 +816,7 @@ function extractPathsFromMmdResources(resources) {
789
816
  if (resources.additionalMotions) paths.push(...resources.additionalMotions);
790
817
  return paths;
791
818
  }
792
- var mmdPlaylists = pgTable(
793
- "mmd_playlists",
794
- {
795
- /** 主键ID */
796
- id: uuid("id").primaryKey().defaultRandom(),
797
- /** 播放列表名称 */
798
- name: varchar("name", { length: 255 }).notNull(),
799
- /** 播放列表描述 */
800
- description: text("description"),
801
- /** 是否启用列表循环 */
802
- loop: boolean("loop").notNull().default(false),
803
- /** 预加载策略: none, next, all */
804
- preloadStrategy: varchar("preload_strategy", { length: 20 }).notNull().default("none"),
805
- /** 是否自动播放 */
806
- autoPlay: boolean("auto_play").notNull().default(false),
807
- /** 播放列表缩略图文件ID (关联 file_metadata.id) */
808
- thumbnailFileId: uuid("thumbnail_file_id"),
809
- /** 播放列表状态: draft, published, archived */
810
- status: varchar("status", { length: 20 }).notNull().default("draft"),
811
- /** 显示顺序 */
812
- sortOrder: integer("sort_order").notNull().default(0),
813
- /** 额外配置(JSON格式,存储舞台配置等) */
814
- config: json("config"),
815
- /** 创建者ID */
816
- createdBy: varchar("created_by", { length: 255 }).notNull(),
817
- /** 创建时间 */
818
- createdAt: timestamp("created_at").defaultNow().notNull(),
819
- /** 更新时间 */
820
- updatedAt: timestamp("updated_at").defaultNow().notNull(),
821
- /** 删除时间(软删除) */
822
- deletedAt: timestamp("deleted_at")
823
- },
824
- (table) => ({
825
- /** 按状态查询的索引 */
826
- statusIndex: index("mmd_playlists_status_idx").on(table.status),
827
- /** 按创建者查询的索引 */
828
- createdByIndex: index("mmd_playlists_created_by_idx").on(table.createdBy),
829
- /** 按删除状态查询的索引 */
830
- deletedAtIndex: index("mmd_playlists_deleted_at_idx").on(table.deletedAt),
831
- /** 按排序查询的索引 */
832
- sortOrderIndex: index("mmd_playlists_sort_order_idx").on(table.sortOrder)
833
- })
834
- );
835
- var mmdPlaylistNodes = pgTable(
836
- "mmd_playlist_nodes",
837
- {
838
- /** 主键ID */
839
- id: uuid("id").primaryKey().defaultRandom(),
840
- /** 所属播放列表ID */
841
- playlistId: uuid("playlist_id").references(() => mmdPlaylists.id, { onDelete: "cascade" }).notNull(),
842
- /** 节点名称 */
843
- name: varchar("name", { length: 255 }).notNull(),
844
- /** 节点描述 */
845
- description: text("description"),
846
- /** 是否启用节点循环 */
847
- loop: boolean("loop").notNull().default(false),
848
- /** 预计时长(秒) */
849
- duration: integer("duration"),
850
- /** 节点缩略图文件ID */
851
- thumbnailFileId: uuid("thumbnail_file_id"),
852
- /** 显示顺序 */
853
- sortOrder: integer("sort_order").notNull().default(0),
854
- /** 模型文件ID (关联 file_metadata.id) */
855
- modelFileId: uuid("model_file_id").notNull(),
856
- /** 动作文件ID */
857
- motionFileId: uuid("motion_file_id"),
858
- /** 相机动画文件ID */
859
- cameraFileId: uuid("camera_file_id"),
860
- /** 音频文件ID */
861
- audioFileId: uuid("audio_file_id"),
862
- /** 舞台模型文件ID */
863
- stageModelFileId: uuid("stage_model_file_id"),
864
- /** 附加动作文件ID列表(JSON数组) */
865
- additionalMotionFileIds: json("additional_motion_file_ids").$type(),
866
- /** 额外配置(JSON格式) */
867
- config: json("config"),
868
- /** 创建时间 */
869
- createdAt: timestamp("created_at").defaultNow().notNull(),
870
- /** 更新时间 */
871
- updatedAt: timestamp("updated_at").defaultNow().notNull()
872
- },
873
- (table) => ({
874
- /** 按播放列表查询的索引 */
875
- playlistIndex: index("mmd_playlist_nodes_playlist_idx").on(table.playlistId),
876
- /** 按排序查询的索引 */
877
- sortOrderIndex: index("mmd_playlist_nodes_sort_order_idx").on(table.sortOrder),
878
- /** 按模型文件查询的索引 */
879
- modelFileIndex: index("mmd_playlist_nodes_model_file_idx").on(table.modelFileId),
880
- /** 组合索引:播放列表+排序 */
881
- playlistSortIndex: index("mmd_playlist_nodes_playlist_sort_idx").on(
882
- table.playlistId,
883
- table.sortOrder
884
- )
885
- })
886
- );
887
- var mmdResourceOptions = pgTable(
888
- "mmd_resource_options",
889
- {
890
- /** 主键ID */
891
- id: uuid("id").primaryKey().defaultRandom(),
892
- /** 资源名称 */
893
- name: varchar("name", { length: 255 }).notNull(),
894
- /** 资源描述 */
895
- description: text("description"),
896
- /** 资源类型: model, motion, camera, audio, stage */
897
- resourceType: varchar("resource_type", { length: 20 }).notNull(),
898
- /** 文件ID (关联 file_metadata.id) */
899
- fileId: uuid("file_id").notNull(),
900
- /** 缩略图文件ID */
901
- thumbnailFileId: uuid("thumbnail_file_id"),
902
- /** 资源标签(JSON数组,用于分类和筛选) */
903
- tags: json("tags").$type(),
904
- /** 显示顺序 */
905
- sortOrder: integer("sort_order").notNull().default(0),
906
- /** 是否启用 */
907
- isActive: boolean("is_active").notNull().default(true),
908
- /** 创建者ID */
909
- createdBy: varchar("created_by", { length: 255 }).notNull(),
910
- /** 创建时间 */
911
- createdAt: timestamp("created_at").defaultNow().notNull(),
912
- /** 更新时间 */
913
- updatedAt: timestamp("updated_at").defaultNow().notNull()
914
- },
915
- (table) => ({
916
- /** 按资源类型查询的索引 */
917
- resourceTypeIndex: index("mmd_resource_options_resource_type_idx").on(table.resourceType),
918
- /** 按文件ID查询的索引 */
919
- fileIdIndex: index("mmd_resource_options_file_id_idx").on(table.fileId),
920
- /** 按活跃状态查询的索引 */
921
- isActiveIndex: index("mmd_resource_options_is_active_idx").on(table.isActive),
922
- /** 按创建者查询的索引 */
923
- createdByIndex: index("mmd_resource_options_created_by_idx").on(table.createdBy),
924
- /** 组合索引:资源类型+活跃状态+排序 */
925
- typeActiveSortIndex: index("mmd_resource_options_type_active_sort_idx").on(
926
- table.resourceType,
927
- table.isActive,
928
- table.sortOrder
929
- )
930
- })
931
- );
932
- var mmdPresetItems = pgTable(
933
- "mmd_preset_items",
934
- {
935
- /** 主键ID */
936
- id: uuid("id").primaryKey().defaultRandom(),
937
- /** 预设名称 */
938
- name: varchar("name", { length: 255 }).notNull(),
939
- /** 预设描述 */
940
- description: text("description"),
941
- /** 缩略图文件ID */
942
- thumbnailFileId: uuid("thumbnail_file_id"),
943
- /** 模型文件ID */
944
- modelFileId: uuid("model_file_id").notNull(),
945
- /** 动作文件ID */
946
- motionFileId: uuid("motion_file_id"),
947
- /** 相机动画文件ID */
948
- cameraFileId: uuid("camera_file_id"),
949
- /** 音频文件ID */
950
- audioFileId: uuid("audio_file_id"),
951
- /** 舞台模型文件ID */
952
- stageModelFileId: uuid("stage_model_file_id"),
953
- /** 附加动作文件ID列表(JSON数组) */
954
- additionalMotionFileIds: json("additional_motion_file_ids").$type(),
955
- /** 显示顺序 */
956
- sortOrder: integer("sort_order").notNull().default(0),
957
- /** 是否启用 */
958
- isActive: boolean("is_active").notNull().default(true),
959
- /** 预设标签(JSON数组) */
960
- tags: json("tags").$type(),
961
- /** 创建者ID */
962
- createdBy: varchar("created_by", { length: 255 }).notNull(),
963
- /** 创建时间 */
964
- createdAt: timestamp("created_at").defaultNow().notNull(),
965
- /** 更新时间 */
966
- updatedAt: timestamp("updated_at").defaultNow().notNull()
967
- },
968
- (table) => ({
969
- /** 按活跃状态查询的索引 */
970
- isActiveIndex: index("mmd_preset_items_is_active_idx").on(table.isActive),
971
- /** 按排序查询的索引 */
972
- sortOrderIndex: index("mmd_preset_items_sort_order_idx").on(table.sortOrder),
973
- /** 按创建者查询的索引 */
974
- createdByIndex: index("mmd_preset_items_created_by_idx").on(table.createdBy),
975
- /** 按模型文件查询的索引 */
976
- modelFileIndex: index("mmd_preset_items_model_file_idx").on(table.modelFileId)
977
- })
978
- );
979
- var mmdPlaylistsRelations = relations(mmdPlaylists, ({ many }) => ({
980
- nodes: many(mmdPlaylistNodes)
981
- }));
982
- var mmdPlaylistNodesRelations = relations(mmdPlaylistNodes, ({ one }) => ({
983
- playlist: one(mmdPlaylists, {
984
- fields: [mmdPlaylistNodes.playlistId],
985
- references: [mmdPlaylists.id]
986
- })
987
- }));
988
819
 
989
- export { MMD_RESOURCE_TYPE_CONFIGS, MmdAdminPanel, MmdPlaylistEditor, MmdResourceSelector, convertNodeToMmdFormat, convertPlaylistNodeToFrontend, convertPlaylistToFrontend, convertPlaylistToMmdConfig, convertPresetItemToFrontend, convertPresetItemToMmdResource, convertResourceOptionToFrontend, convertResourceOptionsToMmdFormat, extractFileIdsFromPlaylist, extractFileIdsFromPresetItem, extractFileIdsFromResourceOptions, extractPathsFromMmdResources, generateMockFileUrls, mergeFileUrlMaps, mmdPlaylistNodes, mmdPlaylistNodesRelations, mmdPlaylists, mmdPlaylistsRelations, mmdPresetItems, mmdResourceOptions, validateFileUrls };
820
+ export { MMD_RESOURCE_TYPE_CONFIGS, MmdAdminPanel, MmdPlaylistEditor, MmdResourceSelector, convertNodeToMmdFormat, convertPlaylistNodeToFrontend, convertPlaylistToFrontend, convertPlaylistToMmdConfig, convertPresetItemToFrontend, convertPresetItemToMmdResource, convertResourceOptionToFrontend, convertResourceOptionsToMmdFormat, extractFileIdsFromPlaylist, extractFileIdsFromPresetItem, extractFileIdsFromResourceOptions, extractPathsFromMmdResources, generateMockFileUrls, mergeFileUrlMaps, validateFileUrls };
990
821
  //# sourceMappingURL=index.mjs.map
991
822
  //# sourceMappingURL=index.mjs.map