@rslsp1/fa-app-tools 1.2.9 → 1.3.1

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.
@@ -60,16 +60,23 @@ async function hfUploadProject(zipBase64, name, token) {
60
60
  const fileInfo = preData.files?.[0];
61
61
  const debugInfo = JSON.stringify({ uploadMode: fileInfo?.uploadMode, hasUploadUrl: !!fileInfo?.uploadUrl, hasVerifyUrl: !!fileInfo?.verifyUrl, headerKeys: Object.keys(fileInfo?.header || {}), verifyHeaderKeys: Object.keys(fileInfo?.verifyHeader || {}) });
62
62
  if (!fileInfo?.uploadMode) throw new Error(`HF preupload kein fileInfo: ${JSON.stringify(preData)}`);
63
- if (fileInfo.uploadMode === "lfs") {
64
- if (!fileInfo.uploadUrl) throw new Error(`HF preupload: kein uploadUrl \u2014 ${debugInfo}`);
65
- const uploadRes = await fetch(fileInfo.uploadUrl, {
66
- method: "PUT",
67
- headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
68
- body: bytes
69
- });
70
- if (!uploadRes.ok) {
71
- const uploadErr = await uploadRes.text().catch(() => "");
72
- throw new Error(`HF LFS upload failed: ${uploadRes.status} \u2014 ${uploadErr.slice(0, 200)}`);
63
+ if (fileInfo.uploadMode === "lfs" && fileInfo.uploadUrl) {
64
+ let uploadStatus = 0;
65
+ try {
66
+ const uploadRes = await fetch(fileInfo.uploadUrl, {
67
+ method: "PUT",
68
+ redirect: "follow",
69
+ headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
70
+ body: bytes
71
+ });
72
+ uploadStatus = uploadRes.status;
73
+ if (!uploadRes.ok) {
74
+ const uploadErr = await uploadRes.text().catch(() => "");
75
+ throw new Error(`HF LFS upload failed: ${uploadRes.status} \u2014 ${uploadErr.slice(0, 300)}`);
76
+ }
77
+ } catch (e) {
78
+ if (uploadStatus === 0) throw new Error(`HF LFS upload network error (CORS/redirect?): ${e.message}`);
79
+ throw e;
73
80
  }
74
81
  if (fileInfo.verifyUrl) {
75
82
  const verifyRes = await fetch(fileInfo.verifyUrl, {
@@ -82,7 +89,6 @@ async function hfUploadProject(zipBase64, name, token) {
82
89
  throw new Error(`HF LFS verify failed: ${verifyRes.status} \u2014 ${verifyErr.slice(0, 200)}`);
83
90
  }
84
91
  }
85
- } else if (fileInfo.uploadMode === "regular") {
86
92
  }
87
93
  const commitRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
88
94
  method: "POST",
@@ -98,6 +104,24 @@ async function hfUploadProject(zipBase64, name, token) {
98
104
  }
99
105
  return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size, isLfs: true };
100
106
  }
107
+ async function hfUploadProjectForm(zipBase64, name, token) {
108
+ const filename = name.endsWith(".zip") ? name : `${name}.zip`;
109
+ const binary = atob(zipBase64);
110
+ const bytes = new Uint8Array(binary.length);
111
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
112
+ const blob = new Blob([bytes], { type: "application/zip" });
113
+ const form = new FormData();
114
+ form.append("files[]", blob, filename);
115
+ const res = await fetch(
116
+ `${HF_BASE}/api/datasets/${HF_REPO}/upload/main`,
117
+ { method: "POST", headers: { Authorization: `Bearer ${token}` }, body: form }
118
+ );
119
+ if (!res.ok) {
120
+ const err = await res.text().catch(() => "");
121
+ throw new Error(`HF FormData upload failed: ${res.status} \u2014 ${err.slice(0, 300)}`);
122
+ }
123
+ return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size: bytes.length, isLfs: true };
124
+ }
101
125
  async function hfDeleteProject(path, token) {
102
126
  const res = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
103
127
  method: "POST",
@@ -117,5 +141,6 @@ export {
117
141
  hfListProjects,
118
142
  hfDownloadProject,
119
143
  hfUploadProject,
144
+ hfUploadProjectForm,
120
145
  hfDeleteProject
121
146
  };
@@ -5,8 +5,9 @@ import {
5
5
  hfDownloadProject,
6
6
  hfListProjects,
7
7
  hfUploadProject,
8
+ hfUploadProjectForm,
8
9
  setHFToken
9
- } from "./chunk-5FBMUNEP.mjs";
10
+ } from "./chunk-4MIV2ED3.mjs";
10
11
  export {
11
12
  HF_TOKEN_KEY,
12
13
  getHFToken,
@@ -14,5 +15,6 @@ export {
14
15
  hfDownloadProject,
15
16
  hfListProjects,
16
17
  hfUploadProject,
18
+ hfUploadProjectForm,
17
19
  setHFToken
18
20
  };
package/dist/index.d.mts CHANGED
@@ -448,6 +448,6 @@ declare function buildLoopInstruction(rounds: Array<{
448
448
  declare function autoLabel(index: number): string;
449
449
  declare function buildReferenceImageMediaIds(images: SelectedLabImage[]): string[];
450
450
 
451
- declare const LIB_VERSION = "1.2.9";
451
+ declare const LIB_VERSION = "1.3.1";
452
452
 
453
453
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, groupGenerationsToLabItems, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
package/dist/index.d.ts CHANGED
@@ -448,6 +448,6 @@ declare function buildLoopInstruction(rounds: Array<{
448
448
  declare function autoLabel(index: number): string;
449
449
  declare function buildReferenceImageMediaIds(images: SelectedLabImage[]): string[];
450
450
 
451
- declare const LIB_VERSION = "1.2.9";
451
+ declare const LIB_VERSION = "1.3.1";
452
452
 
453
453
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, groupGenerationsToLabItems, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
package/dist/index.js CHANGED
@@ -268,6 +268,7 @@ __export(hfStateService_exports, {
268
268
  hfDownloadProject: () => hfDownloadProject,
269
269
  hfListProjects: () => hfListProjects,
270
270
  hfUploadProject: () => hfUploadProject,
271
+ hfUploadProjectForm: () => hfUploadProjectForm,
271
272
  setHFToken: () => setHFToken
272
273
  });
273
274
  function getHFToken() {
@@ -328,16 +329,23 @@ async function hfUploadProject(zipBase64, name, token) {
328
329
  const fileInfo = preData.files?.[0];
329
330
  const debugInfo = JSON.stringify({ uploadMode: fileInfo?.uploadMode, hasUploadUrl: !!fileInfo?.uploadUrl, hasVerifyUrl: !!fileInfo?.verifyUrl, headerKeys: Object.keys(fileInfo?.header || {}), verifyHeaderKeys: Object.keys(fileInfo?.verifyHeader || {}) });
330
331
  if (!fileInfo?.uploadMode) throw new Error(`HF preupload kein fileInfo: ${JSON.stringify(preData)}`);
331
- if (fileInfo.uploadMode === "lfs") {
332
- if (!fileInfo.uploadUrl) throw new Error(`HF preupload: kein uploadUrl \u2014 ${debugInfo}`);
333
- const uploadRes = await fetch(fileInfo.uploadUrl, {
334
- method: "PUT",
335
- headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
336
- body: bytes
337
- });
338
- if (!uploadRes.ok) {
339
- const uploadErr = await uploadRes.text().catch(() => "");
340
- throw new Error(`HF LFS upload failed: ${uploadRes.status} \u2014 ${uploadErr.slice(0, 200)}`);
332
+ if (fileInfo.uploadMode === "lfs" && fileInfo.uploadUrl) {
333
+ let uploadStatus = 0;
334
+ try {
335
+ const uploadRes = await fetch(fileInfo.uploadUrl, {
336
+ method: "PUT",
337
+ redirect: "follow",
338
+ headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
339
+ body: bytes
340
+ });
341
+ uploadStatus = uploadRes.status;
342
+ if (!uploadRes.ok) {
343
+ const uploadErr = await uploadRes.text().catch(() => "");
344
+ throw new Error(`HF LFS upload failed: ${uploadRes.status} \u2014 ${uploadErr.slice(0, 300)}`);
345
+ }
346
+ } catch (e) {
347
+ if (uploadStatus === 0) throw new Error(`HF LFS upload network error (CORS/redirect?): ${e.message}`);
348
+ throw e;
341
349
  }
342
350
  if (fileInfo.verifyUrl) {
343
351
  const verifyRes = await fetch(fileInfo.verifyUrl, {
@@ -350,7 +358,6 @@ async function hfUploadProject(zipBase64, name, token) {
350
358
  throw new Error(`HF LFS verify failed: ${verifyRes.status} \u2014 ${verifyErr.slice(0, 200)}`);
351
359
  }
352
360
  }
353
- } else if (fileInfo.uploadMode === "regular") {
354
361
  }
355
362
  const commitRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
356
363
  method: "POST",
@@ -366,6 +373,24 @@ async function hfUploadProject(zipBase64, name, token) {
366
373
  }
367
374
  return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size, isLfs: true };
368
375
  }
376
+ async function hfUploadProjectForm(zipBase64, name, token) {
377
+ const filename = name.endsWith(".zip") ? name : `${name}.zip`;
378
+ const binary = atob(zipBase64);
379
+ const bytes = new Uint8Array(binary.length);
380
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
381
+ const blob = new Blob([bytes], { type: "application/zip" });
382
+ const form = new FormData();
383
+ form.append("files[]", blob, filename);
384
+ const res = await fetch(
385
+ `${HF_BASE}/api/datasets/${HF_REPO}/upload/main`,
386
+ { method: "POST", headers: { Authorization: `Bearer ${token}` }, body: form }
387
+ );
388
+ if (!res.ok) {
389
+ const err = await res.text().catch(() => "");
390
+ throw new Error(`HF FormData upload failed: ${res.status} \u2014 ${err.slice(0, 300)}`);
391
+ }
392
+ return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size: bytes.length, isLfs: true };
393
+ }
369
394
  async function hfDeleteProject(path, token) {
370
395
  const res = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
371
396
  method: "POST",
@@ -1954,7 +1979,7 @@ var ProjectSyncTab = ({
1954
1979
  try {
1955
1980
  const base64 = await onProjectExportBase64();
1956
1981
  const name = hfSaveName.trim() || `project_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16).replace("T", "_").replace(":", "")}`;
1957
- await hfUploadProject(base64, name, hfToken);
1982
+ await hfUploadProjectForm(base64, name, hfToken);
1958
1983
  setHfSaveName("");
1959
1984
  await loadHfProjects(hfToken);
1960
1985
  } catch (e) {
@@ -4605,7 +4630,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4605
4630
  }
4606
4631
 
4607
4632
  // src/index.ts
4608
- var LIB_VERSION = "1.2.9";
4633
+ var LIB_VERSION = "1.3.1";
4609
4634
  // Annotate the CommonJS export names for ESM import in node:
4610
4635
  0 && (module.exports = {
4611
4636
  AvatarArchitectApp,
package/dist/index.mjs CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  import {
7
7
  hfDeleteProject,
8
8
  hfListProjects,
9
- hfUploadProject
10
- } from "./chunk-5FBMUNEP.mjs";
9
+ hfUploadProjectForm
10
+ } from "./chunk-4MIV2ED3.mjs";
11
11
 
12
12
  // src/hooks/useOnClickOutside.ts
13
13
  import { useEffect } from "react";
@@ -1518,7 +1518,7 @@ var ProjectSyncTab = ({
1518
1518
  try {
1519
1519
  const base64 = await onProjectExportBase64();
1520
1520
  const name = hfSaveName.trim() || `project_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16).replace("T", "_").replace(":", "")}`;
1521
- await hfUploadProject(base64, name, hfToken);
1521
+ await hfUploadProjectForm(base64, name, hfToken);
1522
1522
  setHfSaveName("");
1523
1523
  await loadHfProjects(hfToken);
1524
1524
  } catch (e) {
@@ -1547,7 +1547,7 @@ var ProjectSyncTab = ({
1547
1547
  {
1548
1548
  onClick: async () => {
1549
1549
  try {
1550
- const { hfDownloadProject } = await import("./hfStateService-PB325HBF.mjs");
1550
+ const { hfDownloadProject } = await import("./hfStateService-UKEBY3QR.mjs");
1551
1551
  const file = await hfDownloadProject(p.path, hfToken);
1552
1552
  onHfLoad(file);
1553
1553
  } catch (e) {
@@ -3507,7 +3507,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3507
3507
  onClick: async () => {
3508
3508
  setIsLoadingFromHF(true);
3509
3509
  try {
3510
- const { hfListProjects: hfListProjects2, hfDownloadProject } = await import("./hfStateService-PB325HBF.mjs");
3510
+ const { hfListProjects: hfListProjects2, hfDownloadProject } = await import("./hfStateService-UKEBY3QR.mjs");
3511
3511
  const projects = await hfListProjects2(hfToken);
3512
3512
  if (projects.length > 0) {
3513
3513
  const file = await hfDownloadProject(projects[0].path, hfToken);
@@ -4165,7 +4165,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4165
4165
  }
4166
4166
 
4167
4167
  // src/index.ts
4168
- var LIB_VERSION = "1.2.9";
4168
+ var LIB_VERSION = "1.3.1";
4169
4169
  export {
4170
4170
  AvatarArchitectApp,
4171
4171
  CollapsibleCard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "1.2.9",
3
+ "version": "1.3.1",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",