@primestyleai/tryon 5.10.177 → 5.10.178

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.
@@ -34,6 +34,20 @@ export interface TryOnContext {
34
34
  modelImageId?: string;
35
35
  }
36
36
  export type TryOnCategory = "apparel" | "shoe" | "bag" | "hat" | "sunglasses" | "earring" | "necklace" | "bracelet" | "ring" | "belt" | "watch" | "accessory";
37
+ export interface TryOnFeedbackInput {
38
+ jobId?: string;
39
+ historyEntryId?: string;
40
+ rating?: number;
41
+ note?: string;
42
+ productId?: string;
43
+ productTitle?: string;
44
+ productUrl?: string;
45
+ recommendedSize?: string;
46
+ profileLoggedIn?: boolean;
47
+ profileId?: string;
48
+ profileName?: string;
49
+ profileAccessToken?: string;
50
+ }
37
51
  export declare class ApiClient {
38
52
  private apiKey?;
39
53
  private baseUrl;
@@ -41,6 +55,9 @@ export declare class ApiClient {
41
55
  private get headers();
42
56
  submitTryOn(modelImage: string, garmentImage: string, fitInfo?: FitAreaInfo[], category?: TryOnCategory, context?: TryOnContext): Promise<TryOnResponse>;
43
57
  getStatus(jobId: string): Promise<TryOnStatus>;
58
+ submitTryOnFeedback(input: TryOnFeedbackInput): Promise<{
59
+ ok: true;
60
+ }>;
44
61
  getStreamUrl(): string;
45
62
  }
46
63
  export declare function jsonHeaders(apiKey?: string): Record<string, string>;
@@ -1,26 +1,26 @@
1
1
  "use client";
2
- const g = "ps_session";
3
- const E = "ps_mem_";
4
- let f = null;
5
- function y() {
2
+ const y = "ps_session";
3
+ const P = "ps_mem_";
4
+ let S = null;
5
+ function E() {
6
6
  try {
7
7
  return typeof window < "u" && typeof window.localStorage < "u";
8
8
  } catch {
9
9
  return !1;
10
10
  }
11
11
  }
12
- function b() {
12
+ function A() {
13
13
  if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
14
14
  return crypto.randomUUID();
15
15
  const t = "0123456789abcdef";
16
- let e = E;
16
+ let e = P;
17
17
  for (let o = 0; o < 32; o++) e += t[Math.floor(Math.random() * 16)];
18
18
  return e;
19
19
  }
20
- function P() {
21
- if (!y()) return f;
20
+ function T() {
21
+ if (!E()) return S;
22
22
  try {
23
- const t = window.localStorage.getItem(g);
23
+ const t = window.localStorage.getItem(y);
24
24
  if (!t) return null;
25
25
  const e = JSON.parse(t);
26
26
  return typeof e.id != "string" || typeof e.issuedAt != "number" ? null : {
@@ -33,20 +33,20 @@ function P() {
33
33
  }
34
34
  }
35
35
  function p(t) {
36
- if (f = t, !!y())
36
+ if (S = t, !!E())
37
37
  try {
38
- window.localStorage.setItem(g, JSON.stringify(t));
38
+ window.localStorage.setItem(y, JSON.stringify(t));
39
39
  } catch {
40
40
  }
41
41
  }
42
- function A() {
43
- const t = Date.now(), e = P();
42
+ function g() {
43
+ const t = Date.now(), e = T();
44
44
  if (e && t - e.lastSeenAt < 2592e6)
45
45
  return t - e.lastSeenAt > 5 * 60 * 1e3 && p({ ...e, lastSeenAt: t }), e.id;
46
- const o = { id: b(), issuedAt: t, lastSeenAt: t };
46
+ const o = { id: A(), issuedAt: t, lastSeenAt: t };
47
47
  return p(o), o.id;
48
48
  }
49
- function T() {
49
+ function f() {
50
50
  if (typeof navigator > "u") return null;
51
51
  const t = (navigator.userAgent || "").toLowerCase();
52
52
  return /ipad|tablet|(android(?!.*mobile))/.test(t) ? "tablet" : /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(t) ? "mobile" : "desktop";
@@ -65,8 +65,8 @@ class W {
65
65
  // Attribution fields — backend logs these into the TryOnEvent collection
66
66
  // so non-technical operators can answer "which products are being tried on
67
67
  // and by how many customers". Safe fallbacks when absent.
68
- sessionId: A(),
69
- deviceHint: T()
68
+ sessionId: g(),
69
+ deviceHint: f()
70
70
  };
71
71
  if (r?.modelImageId && (i.modelImageId = r.modelImageId), e && (i.modelImage = e), a && a.length > 0 && (i.fitInfo = a), s && s !== "apparel" && (i.category = s), r?.productId && (i.productId = r.productId), r?.productTitle && (i.productTitle = r.productTitle), r?.productFitType && (i.productFitType = r.productFitType), r?.productType && (i.productType = r.productType), r?.productTags?.length && (i.productTags = r.productTags), r?.productDescription && (i.productDescription = r.productDescription), r?.productMaterial && (i.productMaterial = r.productMaterial), r?.silhouetteContext && (i.silhouetteContext = r.silhouetteContext), r?.editFromPrevious && (i.editFromPrevious = !0), a && a.length > 0)
72
72
  for (const n of a) {
@@ -83,10 +83,10 @@ class W {
83
83
  });
84
84
  if (!d.ok) {
85
85
  const n = await d.json().catch(() => ({}));
86
- throw d.status === 402 ? new c(
86
+ throw d.status === 402 ? new h(
87
87
  n.message || "Insufficient try-ons",
88
88
  "INSUFFICIENT_BALANCE"
89
- ) : new c(
89
+ ) : new h(
90
90
  n.message || "Failed to submit try-on",
91
91
  "API_ERROR"
92
92
  );
@@ -99,13 +99,32 @@ class W {
99
99
  });
100
100
  if (!o.ok) {
101
101
  const a = await o.json().catch(() => ({}));
102
- throw new c(
102
+ throw new h(
103
103
  a.message || "Failed to get status",
104
104
  "API_ERROR"
105
105
  );
106
106
  }
107
107
  return o.json();
108
108
  }
109
+ async submitTryOnFeedback(e) {
110
+ const o = await fetch(`${this.baseUrl}/api/v1/tryon/feedback`, {
111
+ method: "POST",
112
+ headers: this.headers,
113
+ body: JSON.stringify({
114
+ ...e,
115
+ sessionId: g(),
116
+ deviceHint: f()
117
+ })
118
+ });
119
+ if (!o.ok) {
120
+ const a = await o.json().catch(() => ({}));
121
+ throw new h(
122
+ a.message || "Failed to submit try-on feedback",
123
+ "API_ERROR"
124
+ );
125
+ }
126
+ return o.json();
127
+ }
109
128
  getStreamUrl() {
110
129
  const e = `${this.baseUrl}/api/v1/tryon/stream`;
111
130
  return this.apiKey ? `${e}?key=${encodeURIComponent(this.apiKey)}` : e;
@@ -115,7 +134,7 @@ function v(t) {
115
134
  const e = { "Content-Type": "application/json" };
116
135
  return t && (e.Authorization = `Bearer ${t}`), e;
117
136
  }
118
- class c extends Error {
137
+ class h extends Error {
119
138
  constructor(e, o) {
120
139
  super(e), this.name = "PrimeStyleError", this.code = o;
121
140
  }
@@ -189,8 +208,8 @@ function U(t, e = {}) {
189
208
  return;
190
209
  }
191
210
  m.drawImage(d, 0, 0, l, u);
192
- const S = n.toDataURL("image/jpeg", a);
193
- s(S);
211
+ const b = n.toDataURL("image/jpeg", a);
212
+ s(b);
194
213
  } catch (n) {
195
214
  r(n);
196
215
  }
@@ -201,7 +220,7 @@ function U(t, e = {}) {
201
220
  function F(t) {
202
221
  return ["image/jpeg", "image/png", "image/webp", "image/avif"].includes(t.type);
203
222
  }
204
- async function K(t, e, o) {
223
+ async function j(t, e, o) {
205
224
  try {
206
225
  const a = typeof t == "string" ? t : await U(t, { maxDimension: 384, quality: 0.6 }), s = await fetch(`${e}/api/v1/sizing/age-check`, {
207
226
  method: "POST",
@@ -225,13 +244,13 @@ async function K(t, e, o) {
225
244
  return { isAdult: !0, confidence: "low" };
226
245
  }
227
246
  }
228
- const h = {};
247
+ const c = {};
229
248
  function z(t, e) {
230
- h[t] = { ...h[t] || {}, ...e };
249
+ c[t] = { ...c[t] || {}, ...e };
231
250
  }
232
- function j(t) {
251
+ function K(t) {
233
252
  const e = t?.toLowerCase().split("-")[0] || "en";
234
- return (o) => e === "en" || !h[e] ? o : h[e][o] ?? o;
253
+ return (o) => e === "en" || !c[e] ? o : c[e][o] ?? o;
235
254
  }
236
255
  function V() {
237
256
  return typeof navigator > "u" ? "en" : (navigator.language || navigator.userLanguage || "en").split("-")[0].toLowerCase();
@@ -1980,7 +1999,7 @@ const J = [
1980
1999
  // ── Photo step — profile photo preload pill ──
1981
2000
  "Loaded from profile": "プロフィールから読み込み",
1982
2001
  Clear: "クリア"
1983
- }, L = {
2002
+ }, k = {
1984
2003
  "Virtual Try-On": "虚拟试穿",
1985
2004
  "Find Your Size & See It On You": "找到你的尺码并试穿",
1986
2005
  "See Your Fit": "查看合身效果",
@@ -2236,7 +2255,7 @@ const J = [
2236
2255
  // ── Photo step — profile photo preload pill ──
2237
2256
  "Loaded from profile": "已从个人资料加载",
2238
2257
  Clear: "清除"
2239
- }, k = {
2258
+ }, L = {
2240
2259
  "Virtual Try-On": "가상 피팅",
2241
2260
  "Find Your Size & See It On You": "사이즈를 찾고 입어보세요",
2242
2261
  "See Your Fit": "핏 확인하기",
@@ -2755,8 +2774,8 @@ const J = [
2755
2774
  it: B,
2756
2775
  pt: H,
2757
2776
  ja: R,
2758
- zh: L,
2759
- ko: k,
2777
+ zh: k,
2778
+ ko: L,
2760
2779
  ar: G
2761
2780
  };
2762
2781
  for (const [t, e] of Object.entries(O))
@@ -2764,17 +2783,18 @@ for (const [t, e] of Object.entries(O))
2764
2783
  export {
2765
2784
  W as A,
2766
2785
  q as L,
2767
- c as P,
2786
+ h as P,
2768
2787
  Y as S,
2769
2788
  x as T,
2770
2789
  U as a,
2771
2790
  J as b,
2772
- j as c,
2773
- K as d,
2791
+ K as c,
2792
+ j as d,
2774
2793
  V as e,
2775
- A as g,
2794
+ f,
2795
+ g,
2776
2796
  F as i,
2777
2797
  v as j,
2778
2798
  z as r
2779
2799
  };
2780
- //# sourceMappingURL=index-D4yjnBvO.js.map
2800
+ //# sourceMappingURL=index-CYT0nGWX.js.map