@streamoid/settings 0.7.6 → 0.7.7
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/README.md +2 -0
- package/dist/index.js +216 -61
- package/dist/index.mjs +224 -69
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -223,3 +223,5 @@ and shares light/dark canvas, card, text, divider and selection colors with the
|
|
|
223
223
|
host sidebar. Removing settings restores the host theme. Host wrappers must
|
|
224
224
|
remain transparent and use `--alias-surface-canvas` for the app floor; do not
|
|
225
225
|
paint `--alias-surface-base` behind the whole settings page.
|
|
226
|
+
|
|
227
|
+
Handled cancellations remain silent through the toast adapter. A confirmed member update or removal closes its editor before refreshing the list. The only-admin leave guard inspects retained diagnostics before selecting its authored guidance; diagnostic text is never rendered.
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,161 @@ __export(index_exports, {
|
|
|
67
67
|
});
|
|
68
68
|
module.exports = __toCommonJS(index_exports);
|
|
69
69
|
|
|
70
|
+
// src/settings-errors.ts
|
|
71
|
+
function quietErrorToast(toast) {
|
|
72
|
+
return { ...toast, error(message) {
|
|
73
|
+
if (message.trim()) toast.error(message);
|
|
74
|
+
} };
|
|
75
|
+
}
|
|
76
|
+
function isOnlyWorkspaceAdmin(failure) {
|
|
77
|
+
const seen = /* @__PURE__ */ new Set();
|
|
78
|
+
const visit = (value, depth) => {
|
|
79
|
+
if (depth > 4 || value == null || seen.has(value)) return false;
|
|
80
|
+
if (typeof value === "string") return /single admin|only admin/i.test(value);
|
|
81
|
+
if (typeof value !== "object") return false;
|
|
82
|
+
seen.add(value);
|
|
83
|
+
const error = value;
|
|
84
|
+
return [error.body, error.data, error.status, error.message, error.error, error.cause].some((child) => visit(child, depth + 1));
|
|
85
|
+
};
|
|
86
|
+
return visit(failure, 0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ../errors/index.js
|
|
90
|
+
var actions = /* @__PURE__ */ new Set(["edit_input", "sign_in", "ask_admin", "wait", "view_status", "retry", "contact_support"]);
|
|
91
|
+
var states = /* @__PURE__ */ new Set(["not_started", "failed", "partial", "in_progress", "unknown"]);
|
|
92
|
+
var isObject = (value) => value !== null && typeof value === "object";
|
|
93
|
+
var object = (value) => isObject(value) ? value : {};
|
|
94
|
+
var text = (value) => typeof value === "string" ? value : "";
|
|
95
|
+
var reference = (value) => /^[a-zA-Z0-9][a-zA-Z0-9_-]{5,127}$/.test(text(value)) ? value : void 0;
|
|
96
|
+
var technical = /https?:\/\/|<[^>]+>|\b(?:TypeError|SyntaxError|ReferenceError|ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|Traceback|SQLSTATE|MongoServerError|localhost|undefined|null|NaN|CORS|stack trace|Xvfb|node:sqlite)\b|(?:\/[^\s/]+){3,}|\bat\s+\w+\s*\(/i;
|
|
97
|
+
var publicText = (value) => {
|
|
98
|
+
const s = text(value).trim();
|
|
99
|
+
return s && s.length <= 500 && !technical.test(s) && !/[\r\n{}]/.test(s) ? s : void 0;
|
|
100
|
+
};
|
|
101
|
+
var isCancellation = (error) => object(error).name === "AbortError";
|
|
102
|
+
function parseRetryAfter(value, now = Date.now()) {
|
|
103
|
+
if (!text(value).trim()) return void 0;
|
|
104
|
+
const seconds = /^\d+$/.test(value.trim()) ? Number(value) : Math.ceil((Date.parse(value) - now) / 1e3);
|
|
105
|
+
return Number.isFinite(seconds) && seconds >= 0 && seconds <= 86400 ? seconds : void 0;
|
|
106
|
+
}
|
|
107
|
+
function validationFields(body) {
|
|
108
|
+
if (!Array.isArray(body.detail)) return [];
|
|
109
|
+
return body.detail.slice(0, 20).flatMap((issue) => {
|
|
110
|
+
if (!isObject(issue) || !Array.isArray(issue.loc)) return [];
|
|
111
|
+
const path = issue.loc.filter((part) => part !== "body" && part !== "query").filter((part) => typeof part === "string" || typeof part === "number").join(".");
|
|
112
|
+
if (!/^[a-zA-Z0-9_.-]{1,150}$/.test(path)) return [];
|
|
113
|
+
return [{ path, message: issue.type === "missing" || issue.type === "value_error.missing" ? "This field is required." : "Check this value and try again." }];
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
var known = {
|
|
117
|
+
"platform.session_expired": ["Your session has expired. Sign in to continue.", "sign_in"],
|
|
118
|
+
"platform.permission_denied": ["You don't have permission to do this. Ask a workspace admin for access.", "ask_admin"],
|
|
119
|
+
"platform.insufficient_credits": ["There aren't enough credits for this action. Ask your billing admin to add credits.", "ask_admin"],
|
|
120
|
+
"platform.invalid_input": ["Check the information you entered and correct any highlighted fields.", "edit_input"],
|
|
121
|
+
"platform.not_found": ["This item is no longer available or you don't have access to it. Check that you've opened the correct workspace.", "view_status"],
|
|
122
|
+
"platform.conflict": ["This item has changed or already exists. Check its current state before continuing.", "view_status"],
|
|
123
|
+
"platform.file_too_large": ["This file is too large. Choose a smaller file and try again.", "edit_input"],
|
|
124
|
+
"platform.unsupported_file": ["This file type isn't supported. Choose one of the accepted file types.", "edit_input"],
|
|
125
|
+
"platform.content_rejected": ["This request couldn't be completed with the current input. Review the image or description and try again.", "edit_input"],
|
|
126
|
+
"platform.rate_limited": ["This service is busy. Wait a moment before trying again.", "wait"],
|
|
127
|
+
"platform.service_unavailable": ["A service is temporarily unavailable. Try again shortly; contact support if it keeps happening.", "wait"],
|
|
128
|
+
"platform.setup_required": ["There's a setup problem on our side. Contact support so we can help.", "contact_support"],
|
|
129
|
+
"platform.network_error": ["We couldn't reach the service. Check your connection and try again shortly.", "retry"],
|
|
130
|
+
"platform.unexpected": ["We couldn't complete this action. Contact support if it keeps happening.", "contact_support"]
|
|
131
|
+
};
|
|
132
|
+
function inferCode(status, rawCode, diagnostic) {
|
|
133
|
+
if (Object.hasOwn(known, rawCode)) return rawCode;
|
|
134
|
+
const signal = `${rawCode} ${diagnostic}`;
|
|
135
|
+
if (/insufficient.?credits|credits.?unavailable|insufficient.?balance/i.test(signal)) return "platform.insufficient_credits";
|
|
136
|
+
if (/content.?policy|safety.?block|content.?reject/i.test(signal)) return "platform.content_rejected";
|
|
137
|
+
if (/rate.?limit|capacity.?limit/i.test(signal)) return "platform.rate_limited";
|
|
138
|
+
if (status === 401) return "platform.session_expired";
|
|
139
|
+
if (status === 402) return "platform.insufficient_credits";
|
|
140
|
+
if (status === 403) return "platform.permission_denied";
|
|
141
|
+
if (status === 404 || status === 410) return "platform.not_found";
|
|
142
|
+
if (status === 409 || status === 412) return "platform.conflict";
|
|
143
|
+
if (status === 413) return "platform.file_too_large";
|
|
144
|
+
if (status === 415) return "platform.unsupported_file";
|
|
145
|
+
if (status === 429) return "platform.rate_limited";
|
|
146
|
+
if (status === 400 || status === 422) return "platform.invalid_input";
|
|
147
|
+
if ([408, 502, 503, 504].includes(status)) return "platform.service_unavailable";
|
|
148
|
+
if (/ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|server misbehaving|upstream unavailable/i.test(signal)) return "platform.service_unavailable";
|
|
149
|
+
if (/failed to fetch|networkerror|network request failed|load failed/i.test(signal)) return "platform.network_error";
|
|
150
|
+
return "platform.unexpected";
|
|
151
|
+
}
|
|
152
|
+
function normalizeError(failure, options = {}) {
|
|
153
|
+
if (failure instanceof UserFacingError && Object.keys(options).length === 0) return failure.publicError;
|
|
154
|
+
const error = object(failure);
|
|
155
|
+
const body = object(options.body ?? error.body ?? error.data ?? failure);
|
|
156
|
+
const envelope = object(body.publicError ?? error.publicError);
|
|
157
|
+
const declared = envelope.version === 1 ? envelope : {};
|
|
158
|
+
const status = Number(options.status ?? error.statusCode ?? (typeof error.status === "number" ? error.status : void 0)) || 0;
|
|
159
|
+
const diagnostic = [text(error.message), text(failure), text(body.detail), text(body.error)].filter(Boolean).join(" ");
|
|
160
|
+
const rawCode = text(declared.code) || text(object(body.error).code) || text(body.code) || text(error.code);
|
|
161
|
+
const category = inferCode(status, rawCode, diagnostic);
|
|
162
|
+
const code = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/.test(text(declared.code)) ? declared.code : category;
|
|
163
|
+
const method = (options.method || text(error.method) || "UNKNOWN").toUpperCase();
|
|
164
|
+
const read = ["GET", "HEAD", "OPTIONS"].includes(method);
|
|
165
|
+
const suppliedState = object(declared.operation).state;
|
|
166
|
+
const state = states.has(suppliedState) ? suppliedState : read ? "failed" : "unknown";
|
|
167
|
+
const retryAfterSeconds = parseRetryAfter(options.retryAfter) ?? (Number.isFinite(declared.recovery?.retryAfterSeconds) && declared.recovery.retryAfterSeconds >= 0 && declared.recovery.retryAfterSeconds <= 86400 ? declared.recovery.retryAfterSeconds : void 0);
|
|
168
|
+
let [message, action] = known[category];
|
|
169
|
+
message = publicText(declared.message) || message;
|
|
170
|
+
if (actions.has(declared.recovery?.action)) action = declared.recovery.action;
|
|
171
|
+
const fieldErrors = Array.isArray(declared.fieldErrors) && declared.fieldErrors.length ? declared.fieldErrors.slice(0, 20).filter((item) => /^[a-zA-Z0-9_.-]{1,150}$/.test(text(item?.path)) && publicText(item?.message)).map((item) => ({ path: item.path, message: item.message })) : validationFields(body);
|
|
172
|
+
if (fieldErrors.length) {
|
|
173
|
+
const fields = fieldErrors.slice(0, 3).map((field) => `${field.path.replace(/_/g, " ")}: ${field.message}`).join(" ");
|
|
174
|
+
message = `${fields}${fieldErrors.length > 3 ? " Check the remaining fields too." : ""}`;
|
|
175
|
+
action = "edit_input";
|
|
176
|
+
}
|
|
177
|
+
if (category === "platform.rate_limited" && retryAfterSeconds !== void 0 && !publicText(declared.message)) {
|
|
178
|
+
const unit = retryAfterSeconds >= 3600 ? "hour" : retryAfterSeconds >= 60 ? "minute" : "second";
|
|
179
|
+
const amount = Math.ceil(retryAfterSeconds / (unit === "hour" ? 3600 : unit === "minute" ? 60 : 1));
|
|
180
|
+
message = `This service is busy. Try again in ${amount} ${unit}${amount === 1 ? "" : "s"}.`;
|
|
181
|
+
}
|
|
182
|
+
const uncertain = !read && state === "unknown" && ["platform.network_error", "platform.service_unavailable", "platform.unexpected"].includes(category);
|
|
183
|
+
if (uncertain) {
|
|
184
|
+
const uncertainty = "We couldn't confirm whether your request completed. Check its status before trying again; contact support if you're unsure.";
|
|
185
|
+
const authored = publicText(declared.message);
|
|
186
|
+
message = authored ? authored.endsWith(uncertainty) ? authored : `${authored} ${uncertainty}` : uncertainty;
|
|
187
|
+
action = "view_status";
|
|
188
|
+
}
|
|
189
|
+
const operationLabel = publicText(options.operation);
|
|
190
|
+
if (operationLabel && !message.startsWith(`We couldn't ${operationLabel}.`)) message = `We couldn't ${operationLabel}. ${message}`;
|
|
191
|
+
const errorRef = reference(options.reference) || reference(declared.reference) || reference(error.errorRef) || reference(object(body.error).ref);
|
|
192
|
+
const safeToRetry = (read || declared.safeToRetry === true && ["not_started", "failed"].includes(state)) && ["wait", "retry"].includes(action);
|
|
193
|
+
return {
|
|
194
|
+
version: 1,
|
|
195
|
+
code,
|
|
196
|
+
message,
|
|
197
|
+
recovery: { action, ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {} },
|
|
198
|
+
operation: { state, ...reference(object(declared.operation).id) ? { id: declared.operation.id } : {} },
|
|
199
|
+
safeToRetry,
|
|
200
|
+
fieldErrors,
|
|
201
|
+
...errorRef ? { reference: errorRef } : {}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
var UserFacingError = class extends Error {
|
|
205
|
+
constructor(failure, options = {}) {
|
|
206
|
+
const normalized = normalizeError(failure, options);
|
|
207
|
+
super(normalized.message, { cause: failure });
|
|
208
|
+
this.name = "UserFacingError";
|
|
209
|
+
this.publicError = normalized;
|
|
210
|
+
this.status = Number(options.status ?? object(failure).status) || 0;
|
|
211
|
+
this.statusCode = this.status;
|
|
212
|
+
this.method = (options.method || text(object(failure).method) || "UNKNOWN").toUpperCase();
|
|
213
|
+
this.code = normalized.code;
|
|
214
|
+
this.body = options.body ?? object(failure).body;
|
|
215
|
+
this.data = this.body;
|
|
216
|
+
this.errorRef = normalized.reference ?? null;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
function errorMessage(failure, options = {}) {
|
|
220
|
+
if (isCancellation(failure)) return "";
|
|
221
|
+
const normalized = normalizeError(failure, options);
|
|
222
|
+
return normalized.reference ? `${normalized.message} Reference: ${normalized.reference}` : normalized.message;
|
|
223
|
+
}
|
|
224
|
+
|
|
70
225
|
// src/managed-organization-summary.tsx
|
|
71
226
|
var import_icons = require("@streamoid/icons");
|
|
72
227
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -293,7 +448,13 @@ function SettingsAdaptersProvider({
|
|
|
293
448
|
adapters,
|
|
294
449
|
children
|
|
295
450
|
}) {
|
|
296
|
-
|
|
451
|
+
const value = (0, import_react2.useMemo)(() => {
|
|
452
|
+
const toast = quietErrorToast(adapters.toast);
|
|
453
|
+
return new Proxy(adapters, { get(target, key) {
|
|
454
|
+
return key === "toast" ? toast : Reflect.get(target, key);
|
|
455
|
+
} });
|
|
456
|
+
}, [adapters]);
|
|
457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsAdaptersContext.Provider, { value, children });
|
|
297
458
|
}
|
|
298
459
|
function useSettingsAdapters() {
|
|
299
460
|
const ctx = (0, import_react2.useContext)(SettingsAdaptersContext);
|
|
@@ -2736,7 +2897,7 @@ function ToggleSwitch({
|
|
|
2736
2897
|
}
|
|
2737
2898
|
);
|
|
2738
2899
|
}
|
|
2739
|
-
function FieldLabel2({ text }) {
|
|
2900
|
+
function FieldLabel2({ text: text2 }) {
|
|
2740
2901
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex items-center shrink-0 w-full", style: { height: 24 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2741
2902
|
"div",
|
|
2742
2903
|
{
|
|
@@ -2748,7 +2909,7 @@ function FieldLabel2({ text }) {
|
|
|
2748
2909
|
lineHeight: T6.lhSm,
|
|
2749
2910
|
color: T6.tertiary
|
|
2750
2911
|
},
|
|
2751
|
-
children:
|
|
2912
|
+
children: text2
|
|
2752
2913
|
}
|
|
2753
2914
|
) });
|
|
2754
2915
|
}
|
|
@@ -4789,7 +4950,7 @@ function TeamsContent({
|
|
|
4789
4950
|
toast.success("Invitation resent");
|
|
4790
4951
|
await fetchData();
|
|
4791
4952
|
} catch (err) {
|
|
4792
|
-
const msg = err
|
|
4953
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4793
4954
|
toast.error(msg);
|
|
4794
4955
|
}
|
|
4795
4956
|
closeModal();
|
|
@@ -4824,17 +4985,13 @@ function TeamsContent({
|
|
|
4824
4985
|
storeIds: permissions.catalogixStores || []
|
|
4825
4986
|
});
|
|
4826
4987
|
toast.success("User permissions updated");
|
|
4827
|
-
await fetchData();
|
|
4828
4988
|
} catch (err) {
|
|
4829
|
-
const msg = err
|
|
4989
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4830
4990
|
toast.error(msg);
|
|
4831
|
-
|
|
4832
|
-
(m) => m.id === modal.target?.id ? { ...m, permissions } : m
|
|
4833
|
-
);
|
|
4834
|
-
setActiveMembers(updateList);
|
|
4835
|
-
setPendingMembers(updateList);
|
|
4991
|
+
return;
|
|
4836
4992
|
}
|
|
4837
4993
|
closeModal();
|
|
4994
|
+
await fetchData();
|
|
4838
4995
|
};
|
|
4839
4996
|
const handleRemove = async () => {
|
|
4840
4997
|
if (!modal.target) {
|
|
@@ -4869,16 +5026,13 @@ function TeamsContent({
|
|
|
4869
5026
|
} else {
|
|
4870
5027
|
throw new Error("Unable to identify target to remove");
|
|
4871
5028
|
}
|
|
4872
|
-
await fetchData();
|
|
4873
5029
|
} catch (err) {
|
|
4874
|
-
const msg = err
|
|
5030
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4875
5031
|
toast.error(msg);
|
|
4876
|
-
|
|
4877
|
-
setPendingMembers(
|
|
4878
|
-
(prev) => prev.filter((m) => m.id !== modal.target?.id)
|
|
4879
|
-
);
|
|
5032
|
+
return;
|
|
4880
5033
|
}
|
|
4881
5034
|
closeModal();
|
|
5035
|
+
await fetchData();
|
|
4882
5036
|
};
|
|
4883
5037
|
const handleCancelPendingInvite = async (member) => {
|
|
4884
5038
|
if (member.kind !== "invite" || !member.invitationId) {
|
|
@@ -4904,7 +5058,7 @@ function TeamsContent({
|
|
|
4904
5058
|
toast.success("Invitation removed");
|
|
4905
5059
|
await fetchData();
|
|
4906
5060
|
} catch (err) {
|
|
4907
|
-
const msg = err
|
|
5061
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4908
5062
|
toast.error(msg);
|
|
4909
5063
|
}
|
|
4910
5064
|
};
|
|
@@ -4921,7 +5075,7 @@ function TeamsContent({
|
|
|
4921
5075
|
toast.success("Invitation resent");
|
|
4922
5076
|
await fetchData();
|
|
4923
5077
|
} catch (err) {
|
|
4924
|
-
const msg = err
|
|
5078
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4925
5079
|
toast.error(msg);
|
|
4926
5080
|
}
|
|
4927
5081
|
};
|
|
@@ -4950,7 +5104,7 @@ function TeamsContent({
|
|
|
4950
5104
|
await fetchData();
|
|
4951
5105
|
closeModal();
|
|
4952
5106
|
} catch (err) {
|
|
4953
|
-
const msg = err
|
|
5107
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4954
5108
|
toast.error(msg);
|
|
4955
5109
|
}
|
|
4956
5110
|
};
|
|
@@ -5166,7 +5320,7 @@ var T9 = {
|
|
|
5166
5320
|
r4xl: "var(--radius-4xl)",
|
|
5167
5321
|
neutral300: "var(--primitives-neutral-300)"
|
|
5168
5322
|
};
|
|
5169
|
-
function FieldLabel3({ text }) {
|
|
5323
|
+
function FieldLabel3({ text: text2 }) {
|
|
5170
5324
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center shrink-0 w-full", style: { height: 24 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5171
5325
|
"div",
|
|
5172
5326
|
{
|
|
@@ -5178,7 +5332,7 @@ function FieldLabel3({ text }) {
|
|
|
5178
5332
|
lineHeight: T9.lhSm,
|
|
5179
5333
|
color: T9.tertiary
|
|
5180
5334
|
},
|
|
5181
|
-
children:
|
|
5335
|
+
children: text2
|
|
5182
5336
|
}
|
|
5183
5337
|
) });
|
|
5184
5338
|
}
|
|
@@ -6355,9 +6509,7 @@ function OrganizationContent({
|
|
|
6355
6509
|
await workspaceAdapter.refresh?.().catch(() => void 0);
|
|
6356
6510
|
await fetchData();
|
|
6357
6511
|
} catch (err) {
|
|
6358
|
-
toast.error(
|
|
6359
|
-
err instanceof Error ? err.message : `Couldn't join ${target.name}`
|
|
6360
|
-
);
|
|
6512
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6361
6513
|
} finally {
|
|
6362
6514
|
setJoiningId(null);
|
|
6363
6515
|
}
|
|
@@ -6370,7 +6522,7 @@ function OrganizationContent({
|
|
|
6370
6522
|
toast.success("Organization updated");
|
|
6371
6523
|
return true;
|
|
6372
6524
|
} catch (err) {
|
|
6373
|
-
toast.error(err
|
|
6525
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6374
6526
|
return false;
|
|
6375
6527
|
}
|
|
6376
6528
|
};
|
|
@@ -6381,7 +6533,7 @@ function OrganizationContent({
|
|
|
6381
6533
|
toast.success("Organization deleted");
|
|
6382
6534
|
return true;
|
|
6383
6535
|
} catch (err) {
|
|
6384
|
-
toast.error(err
|
|
6536
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6385
6537
|
return false;
|
|
6386
6538
|
}
|
|
6387
6539
|
};
|
|
@@ -6413,7 +6565,7 @@ function OrganizationContent({
|
|
|
6413
6565
|
toast.success("Member updated");
|
|
6414
6566
|
await fetchData();
|
|
6415
6567
|
} catch (err) {
|
|
6416
|
-
toast.error(err
|
|
6568
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6417
6569
|
}
|
|
6418
6570
|
closeModal();
|
|
6419
6571
|
};
|
|
@@ -6443,7 +6595,7 @@ function OrganizationContent({
|
|
|
6443
6595
|
toast.success("Member removed");
|
|
6444
6596
|
await fetchData();
|
|
6445
6597
|
} catch (err) {
|
|
6446
|
-
toast.error(err
|
|
6598
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6447
6599
|
}
|
|
6448
6600
|
closeModal();
|
|
6449
6601
|
};
|
|
@@ -6455,7 +6607,7 @@ function OrganizationContent({
|
|
|
6455
6607
|
);
|
|
6456
6608
|
await fetchData();
|
|
6457
6609
|
} catch (err) {
|
|
6458
|
-
toast.error(err
|
|
6610
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6459
6611
|
}
|
|
6460
6612
|
};
|
|
6461
6613
|
const handleRejectJoinRequest = async (request) => {
|
|
@@ -6464,7 +6616,7 @@ function OrganizationContent({
|
|
|
6464
6616
|
toast.success("Request rejected");
|
|
6465
6617
|
await fetchData();
|
|
6466
6618
|
} catch (err) {
|
|
6467
|
-
toast.error(err
|
|
6619
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6468
6620
|
}
|
|
6469
6621
|
};
|
|
6470
6622
|
if (!current) {
|
|
@@ -6694,6 +6846,21 @@ function OrganizationContent({
|
|
|
6694
6846
|
) });
|
|
6695
6847
|
}
|
|
6696
6848
|
|
|
6849
|
+
// src/billing-errors.ts
|
|
6850
|
+
function isBillingWorkspaceMissing(failure) {
|
|
6851
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6852
|
+
const visit = (value, depth) => {
|
|
6853
|
+
if (depth > 4 || value == null || seen.has(value)) return false;
|
|
6854
|
+
if (typeof value === "string") return /workspace.*not found/i.test(value);
|
|
6855
|
+
if (typeof value !== "object") return false;
|
|
6856
|
+
seen.add(value);
|
|
6857
|
+
const error = value;
|
|
6858
|
+
if (error.code === "billing.workspace_not_found") return true;
|
|
6859
|
+
return [error.message, error.error, error.data, error.body, error.cause, error.publicError].some((child) => visit(child, depth + 1));
|
|
6860
|
+
};
|
|
6861
|
+
return visit(failure, 0);
|
|
6862
|
+
}
|
|
6863
|
+
|
|
6697
6864
|
// src/billing-content.tsx
|
|
6698
6865
|
var import_react15 = require("react");
|
|
6699
6866
|
var import_ui9 = require("@streamoid/ui");
|
|
@@ -8836,8 +9003,8 @@ function BillingContent({
|
|
|
8836
9003
|
toast.success("Plan update submitted");
|
|
8837
9004
|
await fetchBillingOverview();
|
|
8838
9005
|
} catch (err) {
|
|
8839
|
-
const message = err
|
|
8840
|
-
const shouldCreateWorkspace =
|
|
9006
|
+
const message = errorMessage(err, { method: "POST" });
|
|
9007
|
+
const shouldCreateWorkspace = isBillingWorkspaceMissing(err);
|
|
8841
9008
|
if (shouldCreateWorkspace) {
|
|
8842
9009
|
const created = await ensureWorkspaceOnBilling();
|
|
8843
9010
|
if (created && api.updateSubscription) {
|
|
@@ -8890,7 +9057,7 @@ function BillingContent({
|
|
|
8890
9057
|
toast.error("Unable to cancel downgrade");
|
|
8891
9058
|
}
|
|
8892
9059
|
} catch (err) {
|
|
8893
|
-
const msg = err
|
|
9060
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
8894
9061
|
toast.error(msg);
|
|
8895
9062
|
} finally {
|
|
8896
9063
|
setPlanActionInFlight(null);
|
|
@@ -9081,7 +9248,7 @@ function BillingContent({
|
|
|
9081
9248
|
setShowBuyCreditsModal(false);
|
|
9082
9249
|
await fetchBillingOverview();
|
|
9083
9250
|
} catch (err) {
|
|
9084
|
-
const message = err
|
|
9251
|
+
const message = errorMessage(err, { method: "POST" });
|
|
9085
9252
|
toast.error(message);
|
|
9086
9253
|
} finally {
|
|
9087
9254
|
setBuyCreditsInFlight(false);
|
|
@@ -9412,7 +9579,7 @@ function CreateTokenModal({ onClose, onCreated }) {
|
|
|
9412
9579
|
const data = await api.createToken({ name: name.trim(), expiry });
|
|
9413
9580
|
onCreated(data);
|
|
9414
9581
|
} catch (err) {
|
|
9415
|
-
toast.error(err
|
|
9582
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9416
9583
|
} finally {
|
|
9417
9584
|
setLoading(false);
|
|
9418
9585
|
}
|
|
@@ -9767,7 +9934,7 @@ function TokensContent({
|
|
|
9767
9934
|
setTokens((prev) => prev.filter((t) => t._id !== tokenId));
|
|
9768
9935
|
}
|
|
9769
9936
|
} catch (err) {
|
|
9770
|
-
toast.error(err
|
|
9937
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9771
9938
|
} finally {
|
|
9772
9939
|
setDeletingId(null);
|
|
9773
9940
|
}
|
|
@@ -9779,7 +9946,7 @@ function TokensContent({
|
|
|
9779
9946
|
toast.success("Token permanently deleted.");
|
|
9780
9947
|
setTokens((prev) => prev.filter((t) => t._id !== tokenId));
|
|
9781
9948
|
} catch (err) {
|
|
9782
|
-
toast.error(err
|
|
9949
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9783
9950
|
} finally {
|
|
9784
9951
|
setDeletingId(null);
|
|
9785
9952
|
}
|
|
@@ -10617,7 +10784,7 @@ function ProfileTab() {
|
|
|
10617
10784
|
await auth.refreshProfile();
|
|
10618
10785
|
toast.success("Profile updated");
|
|
10619
10786
|
} catch (err) {
|
|
10620
|
-
const msg = err
|
|
10787
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10621
10788
|
toast.error(msg);
|
|
10622
10789
|
} finally {
|
|
10623
10790
|
setSaving(false);
|
|
@@ -10650,7 +10817,7 @@ function ProfileTab() {
|
|
|
10650
10817
|
toast.success("Profile image updated");
|
|
10651
10818
|
} catch (err) {
|
|
10652
10819
|
setImagePreview(void 0);
|
|
10653
|
-
const msg = err
|
|
10820
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10654
10821
|
toast.error(msg);
|
|
10655
10822
|
} finally {
|
|
10656
10823
|
URL.revokeObjectURL(localPreviewUrl);
|
|
@@ -10670,7 +10837,7 @@ function ProfileTab() {
|
|
|
10670
10837
|
await auth.refreshProfile();
|
|
10671
10838
|
toast.success("Profile image removed");
|
|
10672
10839
|
} catch (err) {
|
|
10673
|
-
const msg = err
|
|
10840
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10674
10841
|
toast.error(msg);
|
|
10675
10842
|
} finally {
|
|
10676
10843
|
setImageSaving(false);
|
|
@@ -10961,9 +11128,9 @@ function groupWorkspaceList(workspaces, organizations = []) {
|
|
|
10961
11128
|
});
|
|
10962
11129
|
}
|
|
10963
11130
|
}
|
|
10964
|
-
const
|
|
11131
|
+
const known2 = new Set(organizations.map((org) => org._id));
|
|
10965
11132
|
const ungrouped = workspaces.filter(
|
|
10966
|
-
(ws) => !ws.organizationId || !
|
|
11133
|
+
(ws) => !ws.organizationId || !known2.has(ws.organizationId)
|
|
10967
11134
|
);
|
|
10968
11135
|
if (ungrouped.length) {
|
|
10969
11136
|
groups.push({
|
|
@@ -11514,17 +11681,6 @@ function SettingsContentInner({
|
|
|
11514
11681
|
imageRemoved
|
|
11515
11682
|
});
|
|
11516
11683
|
};
|
|
11517
|
-
const getErrorMessage = (err, fallback) => {
|
|
11518
|
-
if (err instanceof Error && err.message.trim()) return err.message;
|
|
11519
|
-
if (err && typeof err === "object" && "body" in err && err.body && typeof err.body === "object" && "status" in err.body && err.body.status && typeof err.body.status === "object" && "message" in err.body.status && typeof err.body.status.message === "string") {
|
|
11520
|
-
return err.body.status.message;
|
|
11521
|
-
}
|
|
11522
|
-
return fallback;
|
|
11523
|
-
};
|
|
11524
|
-
const isSingleAdminError = (message) => {
|
|
11525
|
-
const normalized = message.toLowerCase();
|
|
11526
|
-
return normalized.includes("single admin") || normalized.includes("only admin");
|
|
11527
|
-
};
|
|
11528
11684
|
const getSettingsPath = (nextWorkspaceId) => `/dashboard/${nextWorkspaceId}/settings`;
|
|
11529
11685
|
const getNextWorkspaceId = async (excludedWorkspaceId) => {
|
|
11530
11686
|
try {
|
|
@@ -11608,7 +11764,7 @@ function SettingsContentInner({
|
|
|
11608
11764
|
toast.success("Workspace updated");
|
|
11609
11765
|
return true;
|
|
11610
11766
|
} catch (err) {
|
|
11611
|
-
toast.error(
|
|
11767
|
+
toast.error(errorMessage(err, { method: "PATCH" }));
|
|
11612
11768
|
return false;
|
|
11613
11769
|
} finally {
|
|
11614
11770
|
setUpdatingWorkspace(false);
|
|
@@ -11676,7 +11832,7 @@ function SettingsContentInner({
|
|
|
11676
11832
|
toast.success("Workspace created");
|
|
11677
11833
|
return true;
|
|
11678
11834
|
} catch (err) {
|
|
11679
|
-
const msg = err
|
|
11835
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
11680
11836
|
toast.error(msg);
|
|
11681
11837
|
return false;
|
|
11682
11838
|
} finally {
|
|
@@ -11723,7 +11879,7 @@ function SettingsContentInner({
|
|
|
11723
11879
|
toast.success("Workspace updated");
|
|
11724
11880
|
return true;
|
|
11725
11881
|
} catch (err) {
|
|
11726
|
-
const msg = err
|
|
11882
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
11727
11883
|
toast.error(msg);
|
|
11728
11884
|
return false;
|
|
11729
11885
|
} finally {
|
|
@@ -12199,11 +12355,10 @@ function SettingsContentInner({
|
|
|
12199
12355
|
setLeavingWorkspace(null);
|
|
12200
12356
|
await completeWorkspaceRemoval(wsId, `You left ${wsName}`);
|
|
12201
12357
|
} catch (err) {
|
|
12202
|
-
|
|
12203
|
-
if (isSingleAdminError(message)) {
|
|
12358
|
+
if (isOnlyWorkspaceAdmin(err)) {
|
|
12204
12359
|
toast.error("You are the only admin. Promote another admin before leaving.");
|
|
12205
12360
|
} else {
|
|
12206
|
-
toast.error(
|
|
12361
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
12207
12362
|
}
|
|
12208
12363
|
}
|
|
12209
12364
|
},
|
|
@@ -12233,7 +12388,7 @@ function SettingsContentInner({
|
|
|
12233
12388
|
setDeletingWorkspace(null);
|
|
12234
12389
|
await completeWorkspaceRemoval(wsId, `Workspace ${wsName} deleted`);
|
|
12235
12390
|
} catch (err) {
|
|
12236
|
-
toast.error(
|
|
12391
|
+
toast.error(errorMessage(err, { method: "DELETE" }));
|
|
12237
12392
|
}
|
|
12238
12393
|
}
|
|
12239
12394
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,158 @@
|
|
|
1
|
+
// src/settings-errors.ts
|
|
2
|
+
function quietErrorToast(toast) {
|
|
3
|
+
return { ...toast, error(message) {
|
|
4
|
+
if (message.trim()) toast.error(message);
|
|
5
|
+
} };
|
|
6
|
+
}
|
|
7
|
+
function isOnlyWorkspaceAdmin(failure) {
|
|
8
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9
|
+
const visit = (value, depth) => {
|
|
10
|
+
if (depth > 4 || value == null || seen.has(value)) return false;
|
|
11
|
+
if (typeof value === "string") return /single admin|only admin/i.test(value);
|
|
12
|
+
if (typeof value !== "object") return false;
|
|
13
|
+
seen.add(value);
|
|
14
|
+
const error = value;
|
|
15
|
+
return [error.body, error.data, error.status, error.message, error.error, error.cause].some((child) => visit(child, depth + 1));
|
|
16
|
+
};
|
|
17
|
+
return visit(failure, 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ../errors/index.js
|
|
21
|
+
var actions = /* @__PURE__ */ new Set(["edit_input", "sign_in", "ask_admin", "wait", "view_status", "retry", "contact_support"]);
|
|
22
|
+
var states = /* @__PURE__ */ new Set(["not_started", "failed", "partial", "in_progress", "unknown"]);
|
|
23
|
+
var isObject = (value) => value !== null && typeof value === "object";
|
|
24
|
+
var object = (value) => isObject(value) ? value : {};
|
|
25
|
+
var text = (value) => typeof value === "string" ? value : "";
|
|
26
|
+
var reference = (value) => /^[a-zA-Z0-9][a-zA-Z0-9_-]{5,127}$/.test(text(value)) ? value : void 0;
|
|
27
|
+
var technical = /https?:\/\/|<[^>]+>|\b(?:TypeError|SyntaxError|ReferenceError|ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|Traceback|SQLSTATE|MongoServerError|localhost|undefined|null|NaN|CORS|stack trace|Xvfb|node:sqlite)\b|(?:\/[^\s/]+){3,}|\bat\s+\w+\s*\(/i;
|
|
28
|
+
var publicText = (value) => {
|
|
29
|
+
const s = text(value).trim();
|
|
30
|
+
return s && s.length <= 500 && !technical.test(s) && !/[\r\n{}]/.test(s) ? s : void 0;
|
|
31
|
+
};
|
|
32
|
+
var isCancellation = (error) => object(error).name === "AbortError";
|
|
33
|
+
function parseRetryAfter(value, now = Date.now()) {
|
|
34
|
+
if (!text(value).trim()) return void 0;
|
|
35
|
+
const seconds = /^\d+$/.test(value.trim()) ? Number(value) : Math.ceil((Date.parse(value) - now) / 1e3);
|
|
36
|
+
return Number.isFinite(seconds) && seconds >= 0 && seconds <= 86400 ? seconds : void 0;
|
|
37
|
+
}
|
|
38
|
+
function validationFields(body) {
|
|
39
|
+
if (!Array.isArray(body.detail)) return [];
|
|
40
|
+
return body.detail.slice(0, 20).flatMap((issue) => {
|
|
41
|
+
if (!isObject(issue) || !Array.isArray(issue.loc)) return [];
|
|
42
|
+
const path = issue.loc.filter((part) => part !== "body" && part !== "query").filter((part) => typeof part === "string" || typeof part === "number").join(".");
|
|
43
|
+
if (!/^[a-zA-Z0-9_.-]{1,150}$/.test(path)) return [];
|
|
44
|
+
return [{ path, message: issue.type === "missing" || issue.type === "value_error.missing" ? "This field is required." : "Check this value and try again." }];
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
var known = {
|
|
48
|
+
"platform.session_expired": ["Your session has expired. Sign in to continue.", "sign_in"],
|
|
49
|
+
"platform.permission_denied": ["You don't have permission to do this. Ask a workspace admin for access.", "ask_admin"],
|
|
50
|
+
"platform.insufficient_credits": ["There aren't enough credits for this action. Ask your billing admin to add credits.", "ask_admin"],
|
|
51
|
+
"platform.invalid_input": ["Check the information you entered and correct any highlighted fields.", "edit_input"],
|
|
52
|
+
"platform.not_found": ["This item is no longer available or you don't have access to it. Check that you've opened the correct workspace.", "view_status"],
|
|
53
|
+
"platform.conflict": ["This item has changed or already exists. Check its current state before continuing.", "view_status"],
|
|
54
|
+
"platform.file_too_large": ["This file is too large. Choose a smaller file and try again.", "edit_input"],
|
|
55
|
+
"platform.unsupported_file": ["This file type isn't supported. Choose one of the accepted file types.", "edit_input"],
|
|
56
|
+
"platform.content_rejected": ["This request couldn't be completed with the current input. Review the image or description and try again.", "edit_input"],
|
|
57
|
+
"platform.rate_limited": ["This service is busy. Wait a moment before trying again.", "wait"],
|
|
58
|
+
"platform.service_unavailable": ["A service is temporarily unavailable. Try again shortly; contact support if it keeps happening.", "wait"],
|
|
59
|
+
"platform.setup_required": ["There's a setup problem on our side. Contact support so we can help.", "contact_support"],
|
|
60
|
+
"platform.network_error": ["We couldn't reach the service. Check your connection and try again shortly.", "retry"],
|
|
61
|
+
"platform.unexpected": ["We couldn't complete this action. Contact support if it keeps happening.", "contact_support"]
|
|
62
|
+
};
|
|
63
|
+
function inferCode(status, rawCode, diagnostic) {
|
|
64
|
+
if (Object.hasOwn(known, rawCode)) return rawCode;
|
|
65
|
+
const signal = `${rawCode} ${diagnostic}`;
|
|
66
|
+
if (/insufficient.?credits|credits.?unavailable|insufficient.?balance/i.test(signal)) return "platform.insufficient_credits";
|
|
67
|
+
if (/content.?policy|safety.?block|content.?reject/i.test(signal)) return "platform.content_rejected";
|
|
68
|
+
if (/rate.?limit|capacity.?limit/i.test(signal)) return "platform.rate_limited";
|
|
69
|
+
if (status === 401) return "platform.session_expired";
|
|
70
|
+
if (status === 402) return "platform.insufficient_credits";
|
|
71
|
+
if (status === 403) return "platform.permission_denied";
|
|
72
|
+
if (status === 404 || status === 410) return "platform.not_found";
|
|
73
|
+
if (status === 409 || status === 412) return "platform.conflict";
|
|
74
|
+
if (status === 413) return "platform.file_too_large";
|
|
75
|
+
if (status === 415) return "platform.unsupported_file";
|
|
76
|
+
if (status === 429) return "platform.rate_limited";
|
|
77
|
+
if (status === 400 || status === 422) return "platform.invalid_input";
|
|
78
|
+
if ([408, 502, 503, 504].includes(status)) return "platform.service_unavailable";
|
|
79
|
+
if (/ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|server misbehaving|upstream unavailable/i.test(signal)) return "platform.service_unavailable";
|
|
80
|
+
if (/failed to fetch|networkerror|network request failed|load failed/i.test(signal)) return "platform.network_error";
|
|
81
|
+
return "platform.unexpected";
|
|
82
|
+
}
|
|
83
|
+
function normalizeError(failure, options = {}) {
|
|
84
|
+
if (failure instanceof UserFacingError && Object.keys(options).length === 0) return failure.publicError;
|
|
85
|
+
const error = object(failure);
|
|
86
|
+
const body = object(options.body ?? error.body ?? error.data ?? failure);
|
|
87
|
+
const envelope = object(body.publicError ?? error.publicError);
|
|
88
|
+
const declared = envelope.version === 1 ? envelope : {};
|
|
89
|
+
const status = Number(options.status ?? error.statusCode ?? (typeof error.status === "number" ? error.status : void 0)) || 0;
|
|
90
|
+
const diagnostic = [text(error.message), text(failure), text(body.detail), text(body.error)].filter(Boolean).join(" ");
|
|
91
|
+
const rawCode = text(declared.code) || text(object(body.error).code) || text(body.code) || text(error.code);
|
|
92
|
+
const category = inferCode(status, rawCode, diagnostic);
|
|
93
|
+
const code = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/.test(text(declared.code)) ? declared.code : category;
|
|
94
|
+
const method = (options.method || text(error.method) || "UNKNOWN").toUpperCase();
|
|
95
|
+
const read = ["GET", "HEAD", "OPTIONS"].includes(method);
|
|
96
|
+
const suppliedState = object(declared.operation).state;
|
|
97
|
+
const state = states.has(suppliedState) ? suppliedState : read ? "failed" : "unknown";
|
|
98
|
+
const retryAfterSeconds = parseRetryAfter(options.retryAfter) ?? (Number.isFinite(declared.recovery?.retryAfterSeconds) && declared.recovery.retryAfterSeconds >= 0 && declared.recovery.retryAfterSeconds <= 86400 ? declared.recovery.retryAfterSeconds : void 0);
|
|
99
|
+
let [message, action] = known[category];
|
|
100
|
+
message = publicText(declared.message) || message;
|
|
101
|
+
if (actions.has(declared.recovery?.action)) action = declared.recovery.action;
|
|
102
|
+
const fieldErrors = Array.isArray(declared.fieldErrors) && declared.fieldErrors.length ? declared.fieldErrors.slice(0, 20).filter((item) => /^[a-zA-Z0-9_.-]{1,150}$/.test(text(item?.path)) && publicText(item?.message)).map((item) => ({ path: item.path, message: item.message })) : validationFields(body);
|
|
103
|
+
if (fieldErrors.length) {
|
|
104
|
+
const fields = fieldErrors.slice(0, 3).map((field) => `${field.path.replace(/_/g, " ")}: ${field.message}`).join(" ");
|
|
105
|
+
message = `${fields}${fieldErrors.length > 3 ? " Check the remaining fields too." : ""}`;
|
|
106
|
+
action = "edit_input";
|
|
107
|
+
}
|
|
108
|
+
if (category === "platform.rate_limited" && retryAfterSeconds !== void 0 && !publicText(declared.message)) {
|
|
109
|
+
const unit = retryAfterSeconds >= 3600 ? "hour" : retryAfterSeconds >= 60 ? "minute" : "second";
|
|
110
|
+
const amount = Math.ceil(retryAfterSeconds / (unit === "hour" ? 3600 : unit === "minute" ? 60 : 1));
|
|
111
|
+
message = `This service is busy. Try again in ${amount} ${unit}${amount === 1 ? "" : "s"}.`;
|
|
112
|
+
}
|
|
113
|
+
const uncertain = !read && state === "unknown" && ["platform.network_error", "platform.service_unavailable", "platform.unexpected"].includes(category);
|
|
114
|
+
if (uncertain) {
|
|
115
|
+
const uncertainty = "We couldn't confirm whether your request completed. Check its status before trying again; contact support if you're unsure.";
|
|
116
|
+
const authored = publicText(declared.message);
|
|
117
|
+
message = authored ? authored.endsWith(uncertainty) ? authored : `${authored} ${uncertainty}` : uncertainty;
|
|
118
|
+
action = "view_status";
|
|
119
|
+
}
|
|
120
|
+
const operationLabel = publicText(options.operation);
|
|
121
|
+
if (operationLabel && !message.startsWith(`We couldn't ${operationLabel}.`)) message = `We couldn't ${operationLabel}. ${message}`;
|
|
122
|
+
const errorRef = reference(options.reference) || reference(declared.reference) || reference(error.errorRef) || reference(object(body.error).ref);
|
|
123
|
+
const safeToRetry = (read || declared.safeToRetry === true && ["not_started", "failed"].includes(state)) && ["wait", "retry"].includes(action);
|
|
124
|
+
return {
|
|
125
|
+
version: 1,
|
|
126
|
+
code,
|
|
127
|
+
message,
|
|
128
|
+
recovery: { action, ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {} },
|
|
129
|
+
operation: { state, ...reference(object(declared.operation).id) ? { id: declared.operation.id } : {} },
|
|
130
|
+
safeToRetry,
|
|
131
|
+
fieldErrors,
|
|
132
|
+
...errorRef ? { reference: errorRef } : {}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
var UserFacingError = class extends Error {
|
|
136
|
+
constructor(failure, options = {}) {
|
|
137
|
+
const normalized = normalizeError(failure, options);
|
|
138
|
+
super(normalized.message, { cause: failure });
|
|
139
|
+
this.name = "UserFacingError";
|
|
140
|
+
this.publicError = normalized;
|
|
141
|
+
this.status = Number(options.status ?? object(failure).status) || 0;
|
|
142
|
+
this.statusCode = this.status;
|
|
143
|
+
this.method = (options.method || text(object(failure).method) || "UNKNOWN").toUpperCase();
|
|
144
|
+
this.code = normalized.code;
|
|
145
|
+
this.body = options.body ?? object(failure).body;
|
|
146
|
+
this.data = this.body;
|
|
147
|
+
this.errorRef = normalized.reference ?? null;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
function errorMessage(failure, options = {}) {
|
|
151
|
+
if (isCancellation(failure)) return "";
|
|
152
|
+
const normalized = normalizeError(failure, options);
|
|
153
|
+
return normalized.reference ? `${normalized.message} Reference: ${normalized.reference}` : normalized.message;
|
|
154
|
+
}
|
|
155
|
+
|
|
1
156
|
// src/managed-organization-summary.tsx
|
|
2
157
|
import { SiconExternalLink } from "@streamoid/icons";
|
|
3
158
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -168,7 +323,7 @@ import {
|
|
|
168
323
|
useEffect as useEffect13,
|
|
169
324
|
useRef as useRef7,
|
|
170
325
|
useCallback as useCallback7,
|
|
171
|
-
useMemo as
|
|
326
|
+
useMemo as useMemo4
|
|
172
327
|
} from "react";
|
|
173
328
|
import {
|
|
174
329
|
ScSidebarMenu,
|
|
@@ -249,14 +404,20 @@ function userLanguageLabel(code) {
|
|
|
249
404
|
import { useState as useState2, useRef as useRef2, useEffect as useEffect3 } from "react";
|
|
250
405
|
|
|
251
406
|
// src/settings-adapters-context.tsx
|
|
252
|
-
import { createContext, useContext } from "react";
|
|
407
|
+
import { createContext, useContext, useMemo } from "react";
|
|
253
408
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
254
409
|
var SettingsAdaptersContext = createContext(null);
|
|
255
410
|
function SettingsAdaptersProvider({
|
|
256
411
|
adapters,
|
|
257
412
|
children
|
|
258
413
|
}) {
|
|
259
|
-
|
|
414
|
+
const value = useMemo(() => {
|
|
415
|
+
const toast = quietErrorToast(adapters.toast);
|
|
416
|
+
return new Proxy(adapters, { get(target, key) {
|
|
417
|
+
return key === "toast" ? toast : Reflect.get(target, key);
|
|
418
|
+
} });
|
|
419
|
+
}, [adapters]);
|
|
420
|
+
return /* @__PURE__ */ jsx4(SettingsAdaptersContext.Provider, { value, children });
|
|
260
421
|
}
|
|
261
422
|
function useSettingsAdapters() {
|
|
262
423
|
const ctx = useContext(SettingsAdaptersContext);
|
|
@@ -2713,7 +2874,7 @@ function ToggleSwitch({
|
|
|
2713
2874
|
}
|
|
2714
2875
|
);
|
|
2715
2876
|
}
|
|
2716
|
-
function FieldLabel2({ text }) {
|
|
2877
|
+
function FieldLabel2({ text: text2 }) {
|
|
2717
2878
|
return /* @__PURE__ */ jsx12("div", { className: "flex items-center shrink-0 w-full", style: { height: 24 }, children: /* @__PURE__ */ jsx12(
|
|
2718
2879
|
"div",
|
|
2719
2880
|
{
|
|
@@ -2725,7 +2886,7 @@ function FieldLabel2({ text }) {
|
|
|
2725
2886
|
lineHeight: T6.lhSm,
|
|
2726
2887
|
color: T6.tertiary
|
|
2727
2888
|
},
|
|
2728
|
-
children:
|
|
2889
|
+
children: text2
|
|
2729
2890
|
}
|
|
2730
2891
|
) });
|
|
2731
2892
|
}
|
|
@@ -4766,7 +4927,7 @@ function TeamsContent({
|
|
|
4766
4927
|
toast.success("Invitation resent");
|
|
4767
4928
|
await fetchData();
|
|
4768
4929
|
} catch (err) {
|
|
4769
|
-
const msg = err
|
|
4930
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4770
4931
|
toast.error(msg);
|
|
4771
4932
|
}
|
|
4772
4933
|
closeModal();
|
|
@@ -4801,17 +4962,13 @@ function TeamsContent({
|
|
|
4801
4962
|
storeIds: permissions.catalogixStores || []
|
|
4802
4963
|
});
|
|
4803
4964
|
toast.success("User permissions updated");
|
|
4804
|
-
await fetchData();
|
|
4805
4965
|
} catch (err) {
|
|
4806
|
-
const msg = err
|
|
4966
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4807
4967
|
toast.error(msg);
|
|
4808
|
-
|
|
4809
|
-
(m) => m.id === modal.target?.id ? { ...m, permissions } : m
|
|
4810
|
-
);
|
|
4811
|
-
setActiveMembers(updateList);
|
|
4812
|
-
setPendingMembers(updateList);
|
|
4968
|
+
return;
|
|
4813
4969
|
}
|
|
4814
4970
|
closeModal();
|
|
4971
|
+
await fetchData();
|
|
4815
4972
|
};
|
|
4816
4973
|
const handleRemove = async () => {
|
|
4817
4974
|
if (!modal.target) {
|
|
@@ -4846,16 +5003,13 @@ function TeamsContent({
|
|
|
4846
5003
|
} else {
|
|
4847
5004
|
throw new Error("Unable to identify target to remove");
|
|
4848
5005
|
}
|
|
4849
|
-
await fetchData();
|
|
4850
5006
|
} catch (err) {
|
|
4851
|
-
const msg = err
|
|
5007
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4852
5008
|
toast.error(msg);
|
|
4853
|
-
|
|
4854
|
-
setPendingMembers(
|
|
4855
|
-
(prev) => prev.filter((m) => m.id !== modal.target?.id)
|
|
4856
|
-
);
|
|
5009
|
+
return;
|
|
4857
5010
|
}
|
|
4858
5011
|
closeModal();
|
|
5012
|
+
await fetchData();
|
|
4859
5013
|
};
|
|
4860
5014
|
const handleCancelPendingInvite = async (member) => {
|
|
4861
5015
|
if (member.kind !== "invite" || !member.invitationId) {
|
|
@@ -4881,7 +5035,7 @@ function TeamsContent({
|
|
|
4881
5035
|
toast.success("Invitation removed");
|
|
4882
5036
|
await fetchData();
|
|
4883
5037
|
} catch (err) {
|
|
4884
|
-
const msg = err
|
|
5038
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4885
5039
|
toast.error(msg);
|
|
4886
5040
|
}
|
|
4887
5041
|
};
|
|
@@ -4898,7 +5052,7 @@ function TeamsContent({
|
|
|
4898
5052
|
toast.success("Invitation resent");
|
|
4899
5053
|
await fetchData();
|
|
4900
5054
|
} catch (err) {
|
|
4901
|
-
const msg = err
|
|
5055
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4902
5056
|
toast.error(msg);
|
|
4903
5057
|
}
|
|
4904
5058
|
};
|
|
@@ -4927,7 +5081,7 @@ function TeamsContent({
|
|
|
4927
5081
|
await fetchData();
|
|
4928
5082
|
closeModal();
|
|
4929
5083
|
} catch (err) {
|
|
4930
|
-
const msg = err
|
|
5084
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
4931
5085
|
toast.error(msg);
|
|
4932
5086
|
}
|
|
4933
5087
|
};
|
|
@@ -5143,7 +5297,7 @@ var T9 = {
|
|
|
5143
5297
|
r4xl: "var(--radius-4xl)",
|
|
5144
5298
|
neutral300: "var(--primitives-neutral-300)"
|
|
5145
5299
|
};
|
|
5146
|
-
function FieldLabel3({ text }) {
|
|
5300
|
+
function FieldLabel3({ text: text2 }) {
|
|
5147
5301
|
return /* @__PURE__ */ jsx15("div", { className: "flex items-center shrink-0 w-full", style: { height: 24 }, children: /* @__PURE__ */ jsx15(
|
|
5148
5302
|
"div",
|
|
5149
5303
|
{
|
|
@@ -5155,7 +5309,7 @@ function FieldLabel3({ text }) {
|
|
|
5155
5309
|
lineHeight: T9.lhSm,
|
|
5156
5310
|
color: T9.tertiary
|
|
5157
5311
|
},
|
|
5158
|
-
children:
|
|
5312
|
+
children: text2
|
|
5159
5313
|
}
|
|
5160
5314
|
) });
|
|
5161
5315
|
}
|
|
@@ -6332,9 +6486,7 @@ function OrganizationContent({
|
|
|
6332
6486
|
await workspaceAdapter.refresh?.().catch(() => void 0);
|
|
6333
6487
|
await fetchData();
|
|
6334
6488
|
} catch (err) {
|
|
6335
|
-
toast.error(
|
|
6336
|
-
err instanceof Error ? err.message : `Couldn't join ${target.name}`
|
|
6337
|
-
);
|
|
6489
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6338
6490
|
} finally {
|
|
6339
6491
|
setJoiningId(null);
|
|
6340
6492
|
}
|
|
@@ -6347,7 +6499,7 @@ function OrganizationContent({
|
|
|
6347
6499
|
toast.success("Organization updated");
|
|
6348
6500
|
return true;
|
|
6349
6501
|
} catch (err) {
|
|
6350
|
-
toast.error(err
|
|
6502
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6351
6503
|
return false;
|
|
6352
6504
|
}
|
|
6353
6505
|
};
|
|
@@ -6358,7 +6510,7 @@ function OrganizationContent({
|
|
|
6358
6510
|
toast.success("Organization deleted");
|
|
6359
6511
|
return true;
|
|
6360
6512
|
} catch (err) {
|
|
6361
|
-
toast.error(err
|
|
6513
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6362
6514
|
return false;
|
|
6363
6515
|
}
|
|
6364
6516
|
};
|
|
@@ -6390,7 +6542,7 @@ function OrganizationContent({
|
|
|
6390
6542
|
toast.success("Member updated");
|
|
6391
6543
|
await fetchData();
|
|
6392
6544
|
} catch (err) {
|
|
6393
|
-
toast.error(err
|
|
6545
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6394
6546
|
}
|
|
6395
6547
|
closeModal();
|
|
6396
6548
|
};
|
|
@@ -6420,7 +6572,7 @@ function OrganizationContent({
|
|
|
6420
6572
|
toast.success("Member removed");
|
|
6421
6573
|
await fetchData();
|
|
6422
6574
|
} catch (err) {
|
|
6423
|
-
toast.error(err
|
|
6575
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6424
6576
|
}
|
|
6425
6577
|
closeModal();
|
|
6426
6578
|
};
|
|
@@ -6432,7 +6584,7 @@ function OrganizationContent({
|
|
|
6432
6584
|
);
|
|
6433
6585
|
await fetchData();
|
|
6434
6586
|
} catch (err) {
|
|
6435
|
-
toast.error(err
|
|
6587
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6436
6588
|
}
|
|
6437
6589
|
};
|
|
6438
6590
|
const handleRejectJoinRequest = async (request) => {
|
|
@@ -6441,7 +6593,7 @@ function OrganizationContent({
|
|
|
6441
6593
|
toast.success("Request rejected");
|
|
6442
6594
|
await fetchData();
|
|
6443
6595
|
} catch (err) {
|
|
6444
|
-
toast.error(err
|
|
6596
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
6445
6597
|
}
|
|
6446
6598
|
};
|
|
6447
6599
|
if (!current) {
|
|
@@ -6671,12 +6823,27 @@ function OrganizationContent({
|
|
|
6671
6823
|
) });
|
|
6672
6824
|
}
|
|
6673
6825
|
|
|
6826
|
+
// src/billing-errors.ts
|
|
6827
|
+
function isBillingWorkspaceMissing(failure) {
|
|
6828
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6829
|
+
const visit = (value, depth) => {
|
|
6830
|
+
if (depth > 4 || value == null || seen.has(value)) return false;
|
|
6831
|
+
if (typeof value === "string") return /workspace.*not found/i.test(value);
|
|
6832
|
+
if (typeof value !== "object") return false;
|
|
6833
|
+
seen.add(value);
|
|
6834
|
+
const error = value;
|
|
6835
|
+
if (error.code === "billing.workspace_not_found") return true;
|
|
6836
|
+
return [error.message, error.error, error.data, error.body, error.cause, error.publicError].some((child) => visit(child, depth + 1));
|
|
6837
|
+
};
|
|
6838
|
+
return visit(failure, 0);
|
|
6839
|
+
}
|
|
6840
|
+
|
|
6674
6841
|
// src/billing-content.tsx
|
|
6675
6842
|
import {
|
|
6676
6843
|
useState as useState13,
|
|
6677
6844
|
useEffect as useEffect11,
|
|
6678
6845
|
useCallback as useCallback5,
|
|
6679
|
-
useMemo as
|
|
6846
|
+
useMemo as useMemo3,
|
|
6680
6847
|
useRef as useRef6
|
|
6681
6848
|
} from "react";
|
|
6682
6849
|
import {
|
|
@@ -6782,7 +6949,7 @@ var PLAN_TAGLINES = {
|
|
|
6782
6949
|
};
|
|
6783
6950
|
|
|
6784
6951
|
// src/export-date-modal.tsx
|
|
6785
|
-
import { useState as useState11, useMemo, useCallback as useCallback4 } from "react";
|
|
6952
|
+
import { useState as useState11, useMemo as useMemo2, useCallback as useCallback4 } from "react";
|
|
6786
6953
|
import { SiconClose as SiconClose4, SiconLeft, SiconRight } from "@streamoid/icons";
|
|
6787
6954
|
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6788
6955
|
var PRIMARY_COLOR = "var(--alias-text---icons-primary)";
|
|
@@ -6837,7 +7004,7 @@ function ExportDateModal({
|
|
|
6837
7004
|
const [rangeEnd, setRangeEnd] = useState11(null);
|
|
6838
7005
|
const isFuture = (date) => date.getTime() > today.getTime();
|
|
6839
7006
|
const isCurrentMonthView = viewMonth === now.getMonth() && viewYear === now.getFullYear();
|
|
6840
|
-
const cells =
|
|
7007
|
+
const cells = useMemo2(() => {
|
|
6841
7008
|
const result = [];
|
|
6842
7009
|
const daysInMonth = getDaysInMonth(viewYear, viewMonth);
|
|
6843
7010
|
const firstDay = new Date(viewYear, viewMonth, 1).getDay();
|
|
@@ -8000,7 +8167,7 @@ function PlansView({
|
|
|
8000
8167
|
const workspaceCurrencySymbol = getCurrencySymbolByCountry(
|
|
8001
8168
|
workspace?.country
|
|
8002
8169
|
);
|
|
8003
|
-
const allPlans =
|
|
8170
|
+
const allPlans = useMemo3(() => {
|
|
8004
8171
|
if (products.length > 0) {
|
|
8005
8172
|
return products.flatMap(
|
|
8006
8173
|
(product) => product.prices.filter((price) => Boolean(price.metadata?.credits)).map((price) => ({
|
|
@@ -8018,7 +8185,7 @@ function PlansView({
|
|
|
8018
8185
|
}
|
|
8019
8186
|
return [];
|
|
8020
8187
|
}, [products, currentPlanId]);
|
|
8021
|
-
const sortedPlans =
|
|
8188
|
+
const sortedPlans = useMemo3(
|
|
8022
8189
|
() => [...allPlans].sort((a, b) => a.amount - b.amount),
|
|
8023
8190
|
[allPlans]
|
|
8024
8191
|
);
|
|
@@ -8834,8 +9001,8 @@ function BillingContent({
|
|
|
8834
9001
|
toast.success("Plan update submitted");
|
|
8835
9002
|
await fetchBillingOverview();
|
|
8836
9003
|
} catch (err) {
|
|
8837
|
-
const message = err
|
|
8838
|
-
const shouldCreateWorkspace =
|
|
9004
|
+
const message = errorMessage(err, { method: "POST" });
|
|
9005
|
+
const shouldCreateWorkspace = isBillingWorkspaceMissing(err);
|
|
8839
9006
|
if (shouldCreateWorkspace) {
|
|
8840
9007
|
const created = await ensureWorkspaceOnBilling();
|
|
8841
9008
|
if (created && api.updateSubscription) {
|
|
@@ -8888,7 +9055,7 @@ function BillingContent({
|
|
|
8888
9055
|
toast.error("Unable to cancel downgrade");
|
|
8889
9056
|
}
|
|
8890
9057
|
} catch (err) {
|
|
8891
|
-
const msg = err
|
|
9058
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
8892
9059
|
toast.error(msg);
|
|
8893
9060
|
} finally {
|
|
8894
9061
|
setPlanActionInFlight(null);
|
|
@@ -9079,7 +9246,7 @@ function BillingContent({
|
|
|
9079
9246
|
setShowBuyCreditsModal(false);
|
|
9080
9247
|
await fetchBillingOverview();
|
|
9081
9248
|
} catch (err) {
|
|
9082
|
-
const message = err
|
|
9249
|
+
const message = errorMessage(err, { method: "POST" });
|
|
9083
9250
|
toast.error(message);
|
|
9084
9251
|
} finally {
|
|
9085
9252
|
setBuyCreditsInFlight(false);
|
|
@@ -9416,7 +9583,7 @@ function CreateTokenModal({ onClose, onCreated }) {
|
|
|
9416
9583
|
const data = await api.createToken({ name: name.trim(), expiry });
|
|
9417
9584
|
onCreated(data);
|
|
9418
9585
|
} catch (err) {
|
|
9419
|
-
toast.error(err
|
|
9586
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9420
9587
|
} finally {
|
|
9421
9588
|
setLoading(false);
|
|
9422
9589
|
}
|
|
@@ -9771,7 +9938,7 @@ function TokensContent({
|
|
|
9771
9938
|
setTokens((prev) => prev.filter((t) => t._id !== tokenId));
|
|
9772
9939
|
}
|
|
9773
9940
|
} catch (err) {
|
|
9774
|
-
toast.error(err
|
|
9941
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9775
9942
|
} finally {
|
|
9776
9943
|
setDeletingId(null);
|
|
9777
9944
|
}
|
|
@@ -9783,7 +9950,7 @@ function TokensContent({
|
|
|
9783
9950
|
toast.success("Token permanently deleted.");
|
|
9784
9951
|
setTokens((prev) => prev.filter((t) => t._id !== tokenId));
|
|
9785
9952
|
} catch (err) {
|
|
9786
|
-
toast.error(err
|
|
9953
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
9787
9954
|
} finally {
|
|
9788
9955
|
setDeletingId(null);
|
|
9789
9956
|
}
|
|
@@ -10621,7 +10788,7 @@ function ProfileTab() {
|
|
|
10621
10788
|
await auth.refreshProfile();
|
|
10622
10789
|
toast.success("Profile updated");
|
|
10623
10790
|
} catch (err) {
|
|
10624
|
-
const msg = err
|
|
10791
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10625
10792
|
toast.error(msg);
|
|
10626
10793
|
} finally {
|
|
10627
10794
|
setSaving(false);
|
|
@@ -10654,7 +10821,7 @@ function ProfileTab() {
|
|
|
10654
10821
|
toast.success("Profile image updated");
|
|
10655
10822
|
} catch (err) {
|
|
10656
10823
|
setImagePreview(void 0);
|
|
10657
|
-
const msg = err
|
|
10824
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10658
10825
|
toast.error(msg);
|
|
10659
10826
|
} finally {
|
|
10660
10827
|
URL.revokeObjectURL(localPreviewUrl);
|
|
@@ -10674,7 +10841,7 @@ function ProfileTab() {
|
|
|
10674
10841
|
await auth.refreshProfile();
|
|
10675
10842
|
toast.success("Profile image removed");
|
|
10676
10843
|
} catch (err) {
|
|
10677
|
-
const msg = err
|
|
10844
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
10678
10845
|
toast.error(msg);
|
|
10679
10846
|
} finally {
|
|
10680
10847
|
setImageSaving(false);
|
|
@@ -10965,9 +11132,9 @@ function groupWorkspaceList(workspaces, organizations = []) {
|
|
|
10965
11132
|
});
|
|
10966
11133
|
}
|
|
10967
11134
|
}
|
|
10968
|
-
const
|
|
11135
|
+
const known2 = new Set(organizations.map((org) => org._id));
|
|
10969
11136
|
const ungrouped = workspaces.filter(
|
|
10970
|
-
(ws) => !ws.organizationId || !
|
|
11137
|
+
(ws) => !ws.organizationId || !known2.has(ws.organizationId)
|
|
10971
11138
|
);
|
|
10972
11139
|
if (ungrouped.length) {
|
|
10973
11140
|
groups.push({
|
|
@@ -11387,7 +11554,7 @@ function SettingsContentInner({
|
|
|
11387
11554
|
void refreshWorkspaceList();
|
|
11388
11555
|
}, [refreshWorkspaceList]);
|
|
11389
11556
|
const hostListPage = workspace.listPage;
|
|
11390
|
-
const listWorkspacePage =
|
|
11557
|
+
const listWorkspacePage = useMemo4(
|
|
11391
11558
|
() => hostListPage ? async (params) => {
|
|
11392
11559
|
const result = await hostListPage(params);
|
|
11393
11560
|
return {
|
|
@@ -11518,17 +11685,6 @@ function SettingsContentInner({
|
|
|
11518
11685
|
imageRemoved
|
|
11519
11686
|
});
|
|
11520
11687
|
};
|
|
11521
|
-
const getErrorMessage = (err, fallback) => {
|
|
11522
|
-
if (err instanceof Error && err.message.trim()) return err.message;
|
|
11523
|
-
if (err && typeof err === "object" && "body" in err && err.body && typeof err.body === "object" && "status" in err.body && err.body.status && typeof err.body.status === "object" && "message" in err.body.status && typeof err.body.status.message === "string") {
|
|
11524
|
-
return err.body.status.message;
|
|
11525
|
-
}
|
|
11526
|
-
return fallback;
|
|
11527
|
-
};
|
|
11528
|
-
const isSingleAdminError = (message) => {
|
|
11529
|
-
const normalized = message.toLowerCase();
|
|
11530
|
-
return normalized.includes("single admin") || normalized.includes("only admin");
|
|
11531
|
-
};
|
|
11532
11688
|
const getSettingsPath = (nextWorkspaceId) => `/dashboard/${nextWorkspaceId}/settings`;
|
|
11533
11689
|
const getNextWorkspaceId = async (excludedWorkspaceId) => {
|
|
11534
11690
|
try {
|
|
@@ -11612,7 +11768,7 @@ function SettingsContentInner({
|
|
|
11612
11768
|
toast.success("Workspace updated");
|
|
11613
11769
|
return true;
|
|
11614
11770
|
} catch (err) {
|
|
11615
|
-
toast.error(
|
|
11771
|
+
toast.error(errorMessage(err, { method: "PATCH" }));
|
|
11616
11772
|
return false;
|
|
11617
11773
|
} finally {
|
|
11618
11774
|
setUpdatingWorkspace(false);
|
|
@@ -11680,7 +11836,7 @@ function SettingsContentInner({
|
|
|
11680
11836
|
toast.success("Workspace created");
|
|
11681
11837
|
return true;
|
|
11682
11838
|
} catch (err) {
|
|
11683
|
-
const msg = err
|
|
11839
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
11684
11840
|
toast.error(msg);
|
|
11685
11841
|
return false;
|
|
11686
11842
|
} finally {
|
|
@@ -11727,7 +11883,7 @@ function SettingsContentInner({
|
|
|
11727
11883
|
toast.success("Workspace updated");
|
|
11728
11884
|
return true;
|
|
11729
11885
|
} catch (err) {
|
|
11730
|
-
const msg = err
|
|
11886
|
+
const msg = errorMessage(err, { method: "POST" });
|
|
11731
11887
|
toast.error(msg);
|
|
11732
11888
|
return false;
|
|
11733
11889
|
} finally {
|
|
@@ -12203,11 +12359,10 @@ function SettingsContentInner({
|
|
|
12203
12359
|
setLeavingWorkspace(null);
|
|
12204
12360
|
await completeWorkspaceRemoval(wsId, `You left ${wsName}`);
|
|
12205
12361
|
} catch (err) {
|
|
12206
|
-
|
|
12207
|
-
if (isSingleAdminError(message)) {
|
|
12362
|
+
if (isOnlyWorkspaceAdmin(err)) {
|
|
12208
12363
|
toast.error("You are the only admin. Promote another admin before leaving.");
|
|
12209
12364
|
} else {
|
|
12210
|
-
toast.error(
|
|
12365
|
+
toast.error(errorMessage(err, { method: "POST" }));
|
|
12211
12366
|
}
|
|
12212
12367
|
}
|
|
12213
12368
|
},
|
|
@@ -12237,7 +12392,7 @@ function SettingsContentInner({
|
|
|
12237
12392
|
setDeletingWorkspace(null);
|
|
12238
12393
|
await completeWorkspaceRemoval(wsId, `Workspace ${wsName} deleted`);
|
|
12239
12394
|
} catch (err) {
|
|
12240
|
-
toast.error(
|
|
12395
|
+
toast.error(errorMessage(err, { method: "DELETE" }));
|
|
12241
12396
|
}
|
|
12242
12397
|
}
|
|
12243
12398
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamoid/settings",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -36,5 +36,8 @@
|
|
|
36
36
|
"react-dom": "^19.0.0",
|
|
37
37
|
"tsup": "^8.0.0",
|
|
38
38
|
"typescript": "^5.0.0"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@streamoid/errors": "0.1.0"
|
|
39
42
|
}
|
|
40
43
|
}
|