@primestyleai/tryon 5.10.86 → 5.10.87
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.
- package/dist/api-client.d.ts +7 -0
- package/dist/{index-Z44A-Ydq.js → index-YDYXhM8c.js} +51 -51
- package/dist/index-YDYXhM8c.js.map +1 -0
- package/dist/primestyle-tryon.js +2 -2
- package/dist/react/PrimeStyleTryonInner.d.ts +1 -1
- package/dist/react/index.js +4062 -4056
- package/dist/react/index.js.map +1 -1
- package/dist/react/types.d.ts +7 -0
- package/dist/storefront/primestyle-tryon.js +8 -0
- package/package.json +1 -1
- package/dist/index-Z44A-Ydq.js.map +0 -1
package/dist/api-client.d.ts
CHANGED
|
@@ -3,6 +3,13 @@ export interface TryOnContext {
|
|
|
3
3
|
/** Storefront product the customer is currently viewing — shown in analytics. */
|
|
4
4
|
productId?: string;
|
|
5
5
|
productTitle?: string;
|
|
6
|
+
/** Free-text product description forwarded to the try-on prompt so Gemini
|
|
7
|
+
* knows the garment context (e.g. "Brown slip maxi dress, spaghetti straps"). */
|
|
8
|
+
productDescription?: string;
|
|
9
|
+
/** Material / fabric composition (e.g. "100% Cotton", "60% Polyester / 40% Polyester")
|
|
10
|
+
* — forwarded to the prompt so Gemini drapes the fabric correctly without
|
|
11
|
+
* having to guess from the image alone. */
|
|
12
|
+
productMaterial?: string;
|
|
6
13
|
/** Optional silhouette-prompt context forwarded to the backend Gemini try-on
|
|
7
14
|
* call. Enables doc-example-grade fit reasoning ("X tension at button
|
|
8
15
|
* because waist 54.4 exceeds size 50 drop"). All fields optional. */
|
|
@@ -62,7 +62,7 @@ class q {
|
|
|
62
62
|
Authorization: `Bearer ${this.apiKey}`
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
async submitTryOn(e, t,
|
|
65
|
+
async submitTryOn(e, t, r, s, i) {
|
|
66
66
|
const n = {
|
|
67
67
|
garmentImage: t,
|
|
68
68
|
// Attribution fields — backend logs these into the TryOnEvent collection
|
|
@@ -71,27 +71,27 @@ class q {
|
|
|
71
71
|
sessionId: T(),
|
|
72
72
|
deviceHint: b()
|
|
73
73
|
};
|
|
74
|
-
if (
|
|
74
|
+
if (i?.modelImageId && (n.modelImageId = i.modelImageId), e && (n.modelImage = e), r && r.length > 0 && (n.fitInfo = r), s && s !== "apparel" && (n.category = s), i?.productId && (n.productId = i.productId), i?.productTitle && (n.productTitle = i.productTitle), i?.productDescription && (n.productDescription = i.productDescription), i?.productMaterial && (n.productMaterial = i.productMaterial), i?.silhouetteContext && (n.silhouetteContext = i.silhouetteContext), i?.editFromPrevious && (n.editFromPrevious = !0), console.log("[ps-sdk:api] POST /api/v1/tryon payload", {
|
|
75
75
|
modelImageBytes: e.length,
|
|
76
76
|
garmentImageBytes: t.length,
|
|
77
77
|
category: s || "apparel",
|
|
78
|
-
fitInfo:
|
|
79
|
-
area:
|
|
80
|
-
fit:
|
|
81
|
-
userValue:
|
|
82
|
-
garmentRange:
|
|
78
|
+
fitInfo: r?.map((a) => ({
|
|
79
|
+
area: a.area,
|
|
80
|
+
fit: a.fit,
|
|
81
|
+
userValue: a.userValue,
|
|
82
|
+
garmentRange: a.garmentRange
|
|
83
83
|
})) || null,
|
|
84
|
-
silhouetteContext:
|
|
85
|
-
}),
|
|
84
|
+
silhouetteContext: i?.silhouetteContext || null
|
|
85
|
+
}), r && r.length > 0) {
|
|
86
86
|
console.log("[ps-sdk:api] Body vs Garment (what Gemini will see):");
|
|
87
|
-
for (const
|
|
88
|
-
const l = (
|
|
87
|
+
for (const a of r) {
|
|
88
|
+
const l = (a.garmentRange || "").replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((h) => !isNaN(h));
|
|
89
89
|
let u = "";
|
|
90
|
-
if (l.length &&
|
|
91
|
-
const h = (Math.min(...l) + Math.max(...l)) / 2, g = Math.round((
|
|
90
|
+
if (l.length && a.userValue != null) {
|
|
91
|
+
const h = (Math.min(...l) + Math.max(...l)) / 2, g = Math.round((a.userValue - h) * 10) / 10;
|
|
92
92
|
u = g > 0 ? `garment ${g} smaller` : g < 0 ? `garment ${Math.abs(g)} larger` : "matched";
|
|
93
93
|
}
|
|
94
|
-
console.log(`[ps-sdk:api] ${
|
|
94
|
+
console.log(`[ps-sdk:api] ${a.area.padEnd(10)} body=${a.userValue ?? "?"} garment=${a.garmentRange ?? "?"} → ${u}`);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
const d = await fetch(`${this.baseUrl}/api/v1/tryon`, {
|
|
@@ -100,12 +100,12 @@ class q {
|
|
|
100
100
|
body: JSON.stringify(n)
|
|
101
101
|
});
|
|
102
102
|
if (!d.ok) {
|
|
103
|
-
const
|
|
103
|
+
const a = await d.json().catch(() => ({}));
|
|
104
104
|
throw d.status === 402 ? new y(
|
|
105
|
-
|
|
105
|
+
a.message || "Insufficient try-ons",
|
|
106
106
|
"INSUFFICIENT_BALANCE"
|
|
107
107
|
) : new y(
|
|
108
|
-
|
|
108
|
+
a.message || "Failed to submit try-on",
|
|
109
109
|
"API_ERROR"
|
|
110
110
|
);
|
|
111
111
|
}
|
|
@@ -116,9 +116,9 @@ class q {
|
|
|
116
116
|
headers: this.headers
|
|
117
117
|
});
|
|
118
118
|
if (!t.ok) {
|
|
119
|
-
const
|
|
119
|
+
const r = await t.json().catch(() => ({}));
|
|
120
120
|
throw new y(
|
|
121
|
-
|
|
121
|
+
r.message || "Failed to get status",
|
|
122
122
|
"API_ERROR"
|
|
123
123
|
);
|
|
124
124
|
}
|
|
@@ -159,13 +159,13 @@ class _ {
|
|
|
159
159
|
}
|
|
160
160
|
onJob(e, t) {
|
|
161
161
|
return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), this.eventSource || this.connect(), () => {
|
|
162
|
-
const
|
|
163
|
-
|
|
162
|
+
const r = this.listeners.get(e);
|
|
163
|
+
r && (r.delete(t), r.size === 0 && this.listeners.delete(e)), this.listeners.size === 0 && this.disconnect();
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
emit(e, t) {
|
|
167
|
-
const
|
|
168
|
-
|
|
167
|
+
const r = this.listeners.get(e);
|
|
168
|
+
r && r.forEach((s) => s(t));
|
|
169
169
|
}
|
|
170
170
|
disconnect() {
|
|
171
171
|
this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.eventSource && (this.eventSource.close(), this.eventSource = null), this.listeners.clear(), this.reconnectAttempts = 0;
|
|
@@ -173,29 +173,29 @@ class _ {
|
|
|
173
173
|
}
|
|
174
174
|
const z = 512, A = 0.65;
|
|
175
175
|
function M(o, e = {}) {
|
|
176
|
-
const t = e.maxDimension ?? z,
|
|
177
|
-
return new Promise((s,
|
|
176
|
+
const t = e.maxDimension ?? z, r = e.quality ?? A;
|
|
177
|
+
return new Promise((s, i) => {
|
|
178
178
|
const n = new FileReader();
|
|
179
179
|
n.onload = () => {
|
|
180
180
|
const d = new Image();
|
|
181
181
|
d.onload = () => {
|
|
182
182
|
try {
|
|
183
|
-
const
|
|
183
|
+
const a = document.createElement("canvas");
|
|
184
184
|
let { width: l, height: u } = d;
|
|
185
|
-
(l > t || u > t) && (l > u ? (u = Math.round(u * t / l), l = t) : (l = Math.round(l * t / u), u = t)),
|
|
186
|
-
const h =
|
|
185
|
+
(l > t || u > t) && (l > u ? (u = Math.round(u * t / l), l = t) : (l = Math.round(l * t / u), u = t)), a.width = l, a.height = u;
|
|
186
|
+
const h = a.getContext("2d");
|
|
187
187
|
if (!h) {
|
|
188
|
-
|
|
188
|
+
i(new Error("Canvas context not available"));
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
h.drawImage(d, 0, 0, l, u);
|
|
192
|
-
const g =
|
|
192
|
+
const g = a.toDataURL("image/jpeg", r);
|
|
193
193
|
s(g);
|
|
194
|
-
} catch (
|
|
195
|
-
a
|
|
194
|
+
} catch (a) {
|
|
195
|
+
i(a);
|
|
196
196
|
}
|
|
197
|
-
}, d.onerror = () =>
|
|
198
|
-
}, n.onerror = () =>
|
|
197
|
+
}, d.onerror = () => i(new Error("Failed to load image")), d.src = n.result;
|
|
198
|
+
}, n.onerror = () => i(new Error("Failed to read file")), n.readAsDataURL(o);
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
function $(o) {
|
|
@@ -203,25 +203,25 @@ function $(o) {
|
|
|
203
203
|
}
|
|
204
204
|
async function X(o, e, t) {
|
|
205
205
|
try {
|
|
206
|
-
const
|
|
206
|
+
const r = typeof o == "string" ? o : await M(o, { maxDimension: 384, quality: 0.6 }), s = await fetch(`${e}/api/v1/sizing/age-check`, {
|
|
207
207
|
method: "POST",
|
|
208
208
|
headers: {
|
|
209
209
|
"Content-Type": "application/json",
|
|
210
210
|
Authorization: `Bearer ${t}`
|
|
211
211
|
},
|
|
212
|
-
body: JSON.stringify({ bodyImage:
|
|
212
|
+
body: JSON.stringify({ bodyImage: r })
|
|
213
213
|
});
|
|
214
214
|
if (!s.ok)
|
|
215
215
|
return console.warn(`[PS-SDK:AgeCheck] HTTP ${s.status} — failing open`), { isAdult: !0, confidence: "low" };
|
|
216
|
-
const
|
|
216
|
+
const i = await s.json();
|
|
217
217
|
return {
|
|
218
|
-
isAdult:
|
|
218
|
+
isAdult: i?.isAdult !== !1,
|
|
219
219
|
// anything other than explicit false → allow
|
|
220
|
-
confidence:
|
|
221
|
-
reasoning: typeof
|
|
220
|
+
confidence: i?.confidence === "high" ? "high" : "low",
|
|
221
|
+
reasoning: typeof i?.reasoning == "string" ? i.reasoning : void 0
|
|
222
222
|
};
|
|
223
|
-
} catch (
|
|
224
|
-
return console.warn("[PS-SDK:AgeCheck] error — failing open:",
|
|
223
|
+
} catch (r) {
|
|
224
|
+
return console.warn("[PS-SDK:AgeCheck] error — failing open:", r), { isAdult: !0, confidence: "low" };
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
const m = {};
|
|
@@ -629,7 +629,7 @@ const te = [
|
|
|
629
629
|
"Your Weight": "체중",
|
|
630
630
|
"Drag or scroll to set your height": "드래그 또는 스크롤하여 키를 설정하세요",
|
|
631
631
|
"Drag or scroll to set your weight": "드래그 또는 스크롤하여 체중을 설정하세요"
|
|
632
|
-
},
|
|
632
|
+
}, D = {
|
|
633
633
|
"Virtual Try-On": "虚拟试穿",
|
|
634
634
|
"Find Your Size & See It On You": "找到你的尺码并试穿",
|
|
635
635
|
"Get the perfect fit, then try it on virtually": "找到最佳合身度,然后虚拟试穿",
|
|
@@ -746,7 +746,7 @@ const te = [
|
|
|
746
746
|
"Your Weight": "你的体重",
|
|
747
747
|
"Drag or scroll to set your height": "拖动或滚动设置身高",
|
|
748
748
|
"Drag or scroll to set your weight": "拖动或滚动设置体重"
|
|
749
|
-
},
|
|
749
|
+
}, U = {
|
|
750
750
|
"Virtual Try-On": "Probador Virtual",
|
|
751
751
|
"Find Your Size & See It On You": "Encuentra tu talla y pruébatelo",
|
|
752
752
|
"Get the perfect fit, then try it on virtually": "Encuentra el ajuste perfecto y pruébatelo virtualmente",
|
|
@@ -2501,7 +2501,7 @@ const te = [
|
|
|
2501
2501
|
"Your Weight": "น้ำหนักของคุณ",
|
|
2502
2502
|
"Drag or scroll to set your height": "ลากหรือเลื่อนเพื่อตั้งค่าส่วนสูง",
|
|
2503
2503
|
"Drag or scroll to set your weight": "ลากหรือเลื่อนเพื่อตั้งค่าน้ำหนัก"
|
|
2504
|
-
},
|
|
2504
|
+
}, Z = {
|
|
2505
2505
|
"Virtual Try-On": "Thử Đồ Ảo",
|
|
2506
2506
|
"Find Your Size & See It On You": "Tìm cỡ của bạn và thử mặc",
|
|
2507
2507
|
"Get the perfect fit, then try it on virtually": "Tìm size phù hợp nhất rồi thử mặc ảo",
|
|
@@ -2618,11 +2618,11 @@ const te = [
|
|
|
2618
2618
|
"Your Weight": "Cân Nặng",
|
|
2619
2619
|
"Drag or scroll to set your height": "Kéo hoặc cuộn để đặt chiều cao",
|
|
2620
2620
|
"Drag or scroll to set your weight": "Kéo hoặc cuộn để đặt cân nặng"
|
|
2621
|
-
},
|
|
2621
|
+
}, x = {
|
|
2622
2622
|
ja: I,
|
|
2623
2623
|
ko: G,
|
|
2624
|
-
zh:
|
|
2625
|
-
es:
|
|
2624
|
+
zh: D,
|
|
2625
|
+
es: U,
|
|
2626
2626
|
fr: w,
|
|
2627
2627
|
de: H,
|
|
2628
2628
|
it: C,
|
|
@@ -2637,9 +2637,9 @@ const te = [
|
|
|
2637
2637
|
nb: j,
|
|
2638
2638
|
fi: V,
|
|
2639
2639
|
th: J,
|
|
2640
|
-
vi:
|
|
2640
|
+
vi: Z
|
|
2641
2641
|
};
|
|
2642
|
-
for (const [o, e] of Object.entries(
|
|
2642
|
+
for (const [o, e] of Object.entries(x))
|
|
2643
2643
|
N(o, e);
|
|
2644
2644
|
export {
|
|
2645
2645
|
q as A,
|
|
@@ -2655,4 +2655,4 @@ export {
|
|
|
2655
2655
|
$ as i,
|
|
2656
2656
|
N as r
|
|
2657
2657
|
};
|
|
2658
|
-
//# sourceMappingURL=index-
|
|
2658
|
+
//# sourceMappingURL=index-YDYXhM8c.js.map
|