@finueva/auth 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -1,709 +1,271 @@
1
- String.fromCharCode;
2
- const HASH_RE = /#/g;
3
- const AMPERSAND_RE = /&/g;
4
- const SLASH_RE = /\//g;
5
- const EQUAL_RE = /=/g;
6
- const PLUS_RE = /\+/g;
7
- const ENC_CARET_RE = /%5e/gi;
8
- const ENC_BACKTICK_RE = /%60/gi;
9
- const ENC_PIPE_RE = /%7c/gi;
10
- const ENC_SPACE_RE = /%20/gi;
11
- function encode$2(text) {
12
- return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
1
+ //#region src/errors.ts
2
+ const messages = {
3
+ invalid_credentials: "The credentials are invalid.",
4
+ invalid_auth_input: "The authentication input is invalid.",
5
+ account_conflict: "The account is not available.",
6
+ social_signup_required: "No account is available for this social sign-in. Start sign-up to create one.",
7
+ google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
8
+ google_recovery_not_required: "Google account recovery is not required.",
9
+ google_recovery_invalid: "The Google account recovery request is invalid.",
10
+ google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
11
+ google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
12
+ password_reset_invalid: "The password reset request is invalid.",
13
+ authentication_required: "Authentication is required.",
14
+ request_origin_denied: "The request origin is not allowed.",
15
+ invalid_request: "The request is invalid.",
16
+ invalid_invitation: "The invitation is invalid.",
17
+ invitation_unavailable: "The invitation is not available.",
18
+ recipient_unavailable: "The recipient is unavailable.",
19
+ invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
20
+ invitation_recovery_required: "Invitation administration requires separate recovery.",
21
+ membership_removal_recovery_required: "Membership removal requires separate recovery.",
22
+ email_verification_required: "Email verification is required.",
23
+ invalid_workspace_selection: "The workspace selection is invalid.",
24
+ organization_context_too_large: "The organization context is too large.",
25
+ credential_rate_limited: "Credential requests are temporarily limited.",
26
+ auth_request_rate_limited: "Authentication requests are temporarily limited.",
27
+ organization_slug_unavailable: "The organization address is unavailable.",
28
+ state_conflict: "The authentication state conflicts with the request.",
29
+ access_denied: "Access is denied.",
30
+ platform_target_unavailable: "The platform administration target is unavailable.",
31
+ platform_quorum_unavailable: "Platform administration quorum is unavailable.",
32
+ platform_recovery_required: "Platform administration requires separate recovery.",
33
+ identity_authority_unavailable: "Authentication is temporarily unavailable.",
34
+ two_factor_required: "A second authentication factor is required.",
35
+ two_factor_code_invalid: "The verification code is invalid.",
36
+ two_factor_challenge_expired: "The second-factor challenge has ended. Sign in again.",
37
+ two_factor_locked: "Second-factor verification is temporarily locked.",
38
+ recent_sign_in_required: "A recent sign-in is required.",
39
+ enterprise_recovery_required: "Enterprise administration evidence requires operator recovery.",
40
+ recent_authentication_required: "A ready recent-authentication action is required.",
41
+ organization_closure_confirmation_mismatch: "The confirmation does not match the organization.",
42
+ organization_closure_cancellation_ended: "The closure cancellation period has ended.",
43
+ ceremony_return_refused: "The return address is not registered for this application.",
44
+ password_sign_in_required: "A password sign-in method is required for this passkey change."
45
+ };
46
+ var AuthError = class extends Error {
47
+ code;
48
+ status;
49
+ retryAfterSeconds;
50
+ constructor(code, status, retryAfterSeconds) {
51
+ super(messages[code]);
52
+ this.name = "AuthError";
53
+ this.code = code;
54
+ this.status = status;
55
+ this.retryAfterSeconds = retryAfterSeconds;
56
+ }
57
+ };
58
+ //#endregion
59
+ //#region src/shared.ts
60
+ const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
61
+ const id$3 = /^[A-Za-z0-9_-]{1,128}$/;
62
+ const email = /^[^\s@]+@[^\s@]+$/;
63
+ const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
64
+ function normalizeEmail(value) {
65
+ if (typeof value !== "string") throw new TypeError("email is invalid");
66
+ const normalized = value.trim().toLowerCase();
67
+ if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
68
+ return normalized;
13
69
  }
14
- function encodeQueryValue(input) {
15
- return encode$2(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
70
+ function normalizeSocialIdTokenInput(value) {
71
+ if (!isObject$1(value)) throw new TypeError("social ID token input is invalid");
72
+ const keys = Object.keys(value);
73
+ if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
74
+ return {
75
+ provider: value.provider,
76
+ idToken: value.idToken,
77
+ ...value.nonce === void 0 ? {} : { nonce: value.nonce },
78
+ signUp: value.signUp
79
+ };
16
80
  }
17
- function encodeQueryKey(text) {
18
- return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
81
+ function socialIdTokenRequest(value) {
82
+ return {
83
+ provider: value.provider,
84
+ idToken: {
85
+ token: value.idToken,
86
+ ...value.nonce === void 0 ? {} : { nonce: value.nonce }
87
+ },
88
+ requestSignUp: value.signUp
89
+ };
19
90
  }
20
- function decode$1(text = "") {
91
+ function normalizeOrigin(value, name) {
92
+ if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
93
+ let url;
21
94
  try {
22
- return decodeURIComponent("" + text);
95
+ url = new URL(value);
23
96
  } catch {
24
- return "" + text;
25
- }
26
- }
27
- function decodeQueryKey(text) {
28
- return decode$1(text.replace(PLUS_RE, " "));
29
- }
30
- function decodeQueryValue(text) {
31
- return decode$1(text.replace(PLUS_RE, " "));
32
- }
33
- function parseQuery(parametersString = "") {
34
- const object = Object.create(null);
35
- if (parametersString[0] === "?") parametersString = parametersString.slice(1);
36
- for (const parameter of parametersString.split("&")) {
37
- const s = parameter.match(/([^=]+)=?(.*)/) || [];
38
- if (s.length < 2) continue;
39
- const key = decodeQueryKey(s[1]);
40
- if (key === "__proto__" || key === "constructor") continue;
41
- const value = decodeQueryValue(s[2] || "");
42
- if (object[key] === void 0) object[key] = value;
43
- else if (Array.isArray(object[key])) object[key].push(value);
44
- else object[key] = [object[key], value];
97
+ throw new TypeError(`${name} must be an ASCII HTTP origin`);
45
98
  }
46
- return object;
47
- }
48
- function encodeQueryItem(key, value) {
49
- if (typeof value === "number" || typeof value === "boolean") value = String(value);
50
- if (!value) return encodeQueryKey(key);
51
- if (Array.isArray(value)) return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
52
- return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
99
+ const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
100
+ if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
101
+ return url.origin;
53
102
  }
54
- function stringifyQuery(query) {
55
- return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
103
+ function normalizeTimeout(value) {
104
+ const timeout = value ?? 1e4;
105
+ if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
106
+ return timeout;
56
107
  }
57
- const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
58
- const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
59
- const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
60
- const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
61
- const JOIN_LEADING_SLASH_RE = /^\.?\//;
62
- function hasProtocol(inputString, opts = {}) {
63
- if (typeof opts === "boolean") opts = { acceptRelative: opts };
64
- if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
65
- return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
108
+ function normalizeSession(value) {
109
+ if (value === null) return null;
110
+ if (!isObject$1(value) || !isObject$1(value.session) || !isObject$1(value.user)) throw authorityUnavailable();
111
+ const expiresAt = toDate(value.session.expiresAt);
112
+ const image = value.user.image;
113
+ if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
114
+ return {
115
+ id: value.session.id,
116
+ expiresAt,
117
+ user: {
118
+ id: value.user.id,
119
+ name: value.user.name,
120
+ email: value.user.email,
121
+ emailVerified: value.user.emailVerified,
122
+ image: image ?? null
123
+ }
124
+ };
66
125
  }
67
- function hasTrailingSlash(input = "", respectQueryAndFragment) {
68
- if (!respectQueryAndFragment) return input.endsWith("/");
69
- return TRAILING_SLASH_RE.test(input);
126
+ function normalizeDriveCredential(value, now) {
127
+ if (!isObject$1(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
128
+ return {
129
+ tokenType: "Bearer",
130
+ token: value.token,
131
+ expiresAt: new Date(now + value.expiresIn * 1e3)
132
+ };
70
133
  }
71
- function withoutTrailingSlash(input = "", respectQueryAndFragment) {
72
- if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
73
- if (!hasTrailingSlash(input, true)) return input || "/";
74
- let path = input;
75
- let fragment = "";
76
- const fragmentIndex = input.indexOf("#");
77
- if (fragmentIndex !== -1) {
78
- path = input.slice(0, fragmentIndex);
79
- fragment = input.slice(fragmentIndex);
134
+ function normalizeOrganizationPageInput(value) {
135
+ if (value === void 0) return new URLSearchParams();
136
+ if (!isObject$1(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
137
+ const input = value;
138
+ const query = new URLSearchParams();
139
+ if (input.limit !== void 0) {
140
+ if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
141
+ query.set("limit", String(input.limit));
80
142
  }
81
- const [s0, ...s] = path.split("?");
82
- return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
83
- }
84
- function withTrailingSlash(input = "", respectQueryAndFragment) {
85
- if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
86
- if (hasTrailingSlash(input, true)) return input || "/";
87
- let path = input;
88
- let fragment = "";
89
- const fragmentIndex = input.indexOf("#");
90
- if (fragmentIndex !== -1) {
91
- path = input.slice(0, fragmentIndex);
92
- fragment = input.slice(fragmentIndex);
93
- if (!path) return fragment;
143
+ if (input.cursor !== void 0) {
144
+ if (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.cursor)) throw new AuthError("invalid_request", 400);
145
+ query.set("cursor", input.cursor);
94
146
  }
95
- const [s0, ...s] = path.split("?");
96
- return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
147
+ return query;
97
148
  }
98
- function withBase(input, base) {
99
- if (isEmptyURL(base) || hasProtocol(input)) return input;
100
- const _base = withoutTrailingSlash(base);
101
- if (input.startsWith(_base)) {
102
- const nextChar = input[_base.length];
103
- if (!nextChar || nextChar === "/" || nextChar === "?") return input;
149
+ function normalizeOrganizationMemberPageInput(value) {
150
+ if (value === void 0) return new URLSearchParams();
151
+ if (!isObject$1(value) || Object.keys(value).some((key) => ![
152
+ "limit",
153
+ "cursor",
154
+ "search"
155
+ ].includes(key))) throw new AuthError("invalid_request", 400);
156
+ const { search, ...page } = value;
157
+ const query = normalizeOrganizationPageInput(page);
158
+ if (search !== void 0) {
159
+ if (typeof search !== "string") throw new AuthError("invalid_request", 400);
160
+ const prefix = search.trim().replace(/[A-Z]/g, (character) => character.toLowerCase());
161
+ if (!prefix || prefix.length > 128 || Array.from(prefix).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) throw new AuthError("invalid_request", 400);
162
+ query.set("search", prefix);
104
163
  }
105
- return joinURL(_base, input);
106
- }
107
- function withQuery(input, query) {
108
- const parsed = parseURL(input);
109
- parsed.search = stringifyQuery({
110
- ...parseQuery(parsed.search),
111
- ...query
112
- });
113
- return stringifyParsedURL(parsed);
164
+ return query;
114
165
  }
115
- function isEmptyURL(url) {
116
- return !url || url === "/";
166
+ function normalizeIdInput(value) {
167
+ if (!isId(value)) throw new AuthError("invalid_request", 400);
168
+ return value;
117
169
  }
118
- function isNonEmptyURL(url) {
119
- return url && url !== "/";
120
- }
121
- function joinURL(base, ...input) {
122
- let url = base || "";
123
- for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
124
- const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
125
- url = withTrailingSlash(url) + _segment;
126
- } else url = segment;
127
- return url;
128
- }
129
- const protocolRelative = Symbol.for("ufo:protocolRelative");
130
- function parseURL(input = "", defaultProto) {
131
- const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
132
- if (_specialProtoMatch) {
133
- const [, _proto, _pathname = ""] = _specialProtoMatch;
134
- return {
135
- protocol: _proto.toLowerCase(),
136
- pathname: _pathname,
137
- href: _proto + _pathname,
138
- auth: "",
139
- host: "",
140
- search: "",
141
- hash: ""
142
- };
143
- }
144
- if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
145
- const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
146
- let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
147
- if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
148
- const { pathname, search, hash } = parsePath(path);
170
+ function normalizeOrganization(value) {
171
+ exact$7(value, [
172
+ "capabilities",
173
+ "id",
174
+ "lifecycle",
175
+ "logo",
176
+ "name",
177
+ "role",
178
+ "slug"
179
+ ]);
180
+ if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject$1(value.capabilities)) throw authorityUnavailable();
181
+ exact$7(value.capabilities, [
182
+ "readInvitations",
183
+ "readMembers",
184
+ "readTeams"
185
+ ]);
186
+ if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
149
187
  return {
150
- protocol: protocol.toLowerCase(),
151
- auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
152
- host,
153
- pathname,
154
- search,
155
- hash,
156
- [protocolRelative]: !protocol
188
+ id: value.id,
189
+ name: value.name,
190
+ slug: value.slug,
191
+ logo: nullableHttpsUrl(value.logo),
192
+ lifecycle: value.lifecycle,
193
+ role: value.role,
194
+ capabilities: {
195
+ readMembers: true,
196
+ readTeams: true,
197
+ readInvitations: value.capabilities.readInvitations
198
+ }
157
199
  };
158
200
  }
159
- function parsePath(input = "") {
160
- const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
201
+ function normalizeOrganizationDisplayInput(value) {
202
+ if (!isObject$1(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
203
+ if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
204
+ let logo;
205
+ try {
206
+ logo = nullableHttpsUrl(value.logo);
207
+ } catch {
208
+ throw new AuthError("invalid_request", 400);
209
+ }
161
210
  return {
162
- pathname,
163
- search,
164
- hash
211
+ name: value.name,
212
+ slug: value.slug,
213
+ logo
165
214
  };
166
215
  }
167
- function stringifyParsedURL(parsed) {
168
- const pathname = parsed.pathname || "";
169
- const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
170
- const hash = parsed.hash || "";
171
- const auth = parsed.auth ? parsed.auth + "@" : "";
172
- const host = parsed.host || "";
173
- return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
174
- }
175
- //#endregion
176
- //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
177
- const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
178
- const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
179
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
180
- function jsonParseTransform(key, value) {
181
- if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
182
- warnKeyDropped(key);
183
- return;
216
+ function normalizeOrganizationDisplay(value) {
217
+ try {
218
+ return normalizeOrganizationDisplayInput(value);
219
+ } catch {
220
+ throw authorityUnavailable();
184
221
  }
185
- return value;
186
222
  }
187
- function warnKeyDropped(key) {
188
- console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
223
+ function normalizeOrganizationTeamDisplayInput(value) {
224
+ if (!isObject$1(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
225
+ return { name: value.name };
189
226
  }
190
- function destr(value, options = {}) {
191
- if (typeof value !== "string") return value;
192
- if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
193
- const _value = value.trim();
194
- if (_value.length <= 9) switch (_value.toLowerCase()) {
195
- case "true": return true;
196
- case "false": return false;
197
- case "undefined": return;
198
- case "null": return null;
199
- case "nan": return NaN;
200
- case "infinity": return Number.POSITIVE_INFINITY;
201
- case "-infinity": return Number.NEGATIVE_INFINITY;
202
- }
203
- if (!JsonSigRx.test(value)) {
204
- if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
205
- return value;
206
- }
227
+ function normalizeOrganizationTeamDisplay(value) {
207
228
  try {
208
- if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
209
- if (options.strict) throw new Error("[destr] Possible prototype pollution");
210
- return JSON.parse(value, jsonParseTransform);
211
- }
212
- return JSON.parse(value);
213
- } catch (error) {
214
- if (options.strict) throw error;
215
- return value;
216
- }
217
- }
218
- //#endregion
219
- //#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
220
- var FetchError = class extends Error {
221
- constructor(message, opts) {
222
- super(message, opts);
223
- this.name = "FetchError";
224
- if (opts?.cause && !this.cause) this.cause = opts.cause;
229
+ return normalizeOrganizationTeamDisplayInput(value);
230
+ } catch {
231
+ throw authorityUnavailable();
225
232
  }
226
- };
227
- function createFetchError(ctx) {
228
- const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
229
- const method = ctx.request?.method || ctx.options?.method || "GET";
230
- const url = ctx.request?.url || String(ctx.request) || "/";
231
- const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
232
- for (const key of [
233
- "request",
234
- "options",
235
- "response"
236
- ]) Object.defineProperty(fetchError, key, { get() {
237
- return ctx[key];
238
- } });
239
- for (const [key, refKey] of [
240
- ["data", "_data"],
241
- ["status", "status"],
242
- ["statusCode", "status"],
243
- ["statusText", "statusText"],
244
- ["statusMessage", "statusText"]
245
- ]) Object.defineProperty(fetchError, key, { get() {
246
- return ctx.response && ctx.response[refKey];
247
- } });
248
- return fetchError;
249
- }
250
- const payloadMethods = new Set(Object.freeze([
251
- "PATCH",
252
- "POST",
253
- "PUT",
254
- "DELETE"
255
- ]));
256
- function isPayloadMethod(method = "GET") {
257
- return payloadMethods.has(method.toUpperCase());
258
- }
259
- function isJSONSerializable(value) {
260
- if (value === void 0) return false;
261
- const t = typeof value;
262
- if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
263
- if (t !== "object") return false;
264
- if (Array.isArray(value)) return true;
265
- if (value.buffer) return false;
266
- if (value instanceof FormData || value instanceof URLSearchParams) return false;
267
- return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
268
- }
269
- const textTypes = new Set([
270
- "image/svg",
271
- "application/xml",
272
- "application/xhtml",
273
- "application/html"
274
- ]);
275
- const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
276
- function detectResponseType(_contentType = "") {
277
- if (!_contentType) return "json";
278
- const contentType = _contentType.split(";").shift() || "";
279
- if (JSON_RE.test(contentType)) return "json";
280
- if (contentType === "text/event-stream") return "stream";
281
- if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
282
- return "blob";
283
233
  }
284
- function resolveFetchOptions(request, input, defaults, Headers) {
285
- const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
286
- let query;
287
- if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
288
- ...defaults?.params,
289
- ...defaults?.query,
290
- ...input?.params,
291
- ...input?.query
234
+ function normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
235
+ if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255) || typeof slug !== "string" || !/^[a-z0-9-]{1,128}$/.test(slug)) throw new AuthError("invalid_request", 400);
236
+ return {
237
+ name,
238
+ slug,
239
+ idempotencyKey
292
240
  };
241
+ }
242
+ function normalizeCreatedOrganization(value) {
243
+ exact$7(value, [
244
+ "id",
245
+ "name",
246
+ "slug"
247
+ ]);
248
+ if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 128)) throw authorityUnavailable();
293
249
  return {
294
- ...defaults,
295
- ...input,
296
- query,
297
- params: query,
298
- headers
250
+ id: value.id,
251
+ name: value.name,
252
+ slug: value.slug
299
253
  };
300
254
  }
301
- function mergeHeaders(input, defaults, Headers) {
302
- if (!defaults) return new Headers(input);
303
- const headers = new Headers(defaults);
304
- if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
305
- return headers;
255
+ function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
256
+ if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
257
+ return {
258
+ name,
259
+ idempotencyKey
260
+ };
306
261
  }
307
- async function callHooks(context, hooks) {
308
- if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
309
- else await hooks(context);
310
- }
311
- const retryStatusCodes = new Set([
312
- 408,
313
- 409,
314
- 425,
315
- 429,
316
- 500,
317
- 502,
318
- 503,
319
- 504
320
- ]);
321
- const nullBodyResponses = new Set([
322
- 101,
323
- 204,
324
- 205,
325
- 304
326
- ]);
327
- function createFetch(globalOptions = {}) {
328
- const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
329
- async function onError(context) {
330
- const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
331
- if (context.options.retry !== false && !isAbort) {
332
- let retries;
333
- if (typeof context.options.retry === "number") retries = context.options.retry;
334
- else retries = isPayloadMethod(context.options.method) ? 0 : 1;
335
- const responseCode = context.response && context.response.status || 500;
336
- if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
337
- const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
338
- if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
339
- return $fetchRaw(context.request, {
340
- ...context.options,
341
- retry: retries - 1
342
- });
343
- }
344
- }
345
- const error = createFetchError(context);
346
- if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
347
- throw error;
348
- }
349
- const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
350
- const context = {
351
- request: _request,
352
- options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
353
- response: void 0,
354
- error: void 0
355
- };
356
- if (context.options.method) context.options.method = context.options.method.toUpperCase();
357
- if (context.options.onRequest) {
358
- await callHooks(context, context.options.onRequest);
359
- if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
360
- }
361
- if (typeof context.request === "string") {
362
- if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
363
- if (context.options.query) {
364
- context.request = withQuery(context.request, context.options.query);
365
- delete context.options.query;
366
- }
367
- if ("query" in context.options) delete context.options.query;
368
- if ("params" in context.options) delete context.options.params;
369
- }
370
- if (context.options.body && isPayloadMethod(context.options.method)) {
371
- if (isJSONSerializable(context.options.body)) {
372
- const contentType = context.options.headers.get("content-type");
373
- if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
374
- if (!contentType) context.options.headers.set("content-type", "application/json");
375
- if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
376
- } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
377
- if (!("duplex" in context.options)) context.options.duplex = "half";
378
- }
379
- }
380
- let abortTimeout;
381
- if (!context.options.signal && context.options.timeout) {
382
- const controller = new AbortController();
383
- abortTimeout = setTimeout(() => {
384
- const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
385
- error.name = "TimeoutError";
386
- error.code = 23;
387
- controller.abort(error);
388
- }, context.options.timeout);
389
- context.options.signal = controller.signal;
390
- }
391
- try {
392
- context.response = await fetch(context.request, context.options);
393
- } catch (error) {
394
- context.error = error;
395
- if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
396
- return await onError(context);
397
- } finally {
398
- if (abortTimeout) clearTimeout(abortTimeout);
399
- }
400
- if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
401
- const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
402
- switch (responseType) {
403
- case "json": {
404
- const data = await context.response.text();
405
- const parseFunction = context.options.parseResponse || destr;
406
- context.response._data = parseFunction(data);
407
- break;
408
- }
409
- case "stream":
410
- context.response._data = context.response.body || context.response._bodyInit;
411
- break;
412
- default: context.response._data = await context.response[responseType]();
413
- }
414
- }
415
- if (context.options.onResponse) await callHooks(context, context.options.onResponse);
416
- if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
417
- if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
418
- return await onError(context);
419
- }
420
- return context.response;
421
- };
422
- const $fetch = async function $fetch2(request, options) {
423
- return (await $fetchRaw(request, options))._data;
424
- };
425
- $fetch.raw = $fetchRaw;
426
- $fetch.native = (...args) => fetch(...args);
427
- $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
428
- ...globalOptions,
429
- ...customGlobalOptions,
430
- defaults: {
431
- ...globalOptions.defaults,
432
- ...customGlobalOptions.defaults,
433
- ...defaultOptions
434
- }
435
- });
436
- return $fetch;
437
- }
438
- //#endregion
439
- //#region src/errors.ts
440
- const messages = {
441
- invalid_credentials: "The credentials are invalid.",
442
- invalid_auth_input: "The authentication input is invalid.",
443
- account_conflict: "The account is not available.",
444
- social_signup_required: "No account is available for this social sign-in. Start sign-up to create one.",
445
- google_recovery_in_progress: "A Google connection is already being completed. Return to that sign-in, or wait up to ten minutes and restart.",
446
- google_recovery_not_required: "Google account recovery is not required.",
447
- google_recovery_invalid: "The Google account recovery request is invalid.",
448
- google_recovery_expired: "Google account recovery has expired. Start Google sign-in again.",
449
- google_recovery_account_mismatch: "Sign in to the existing account associated with this Google identity.",
450
- password_reset_invalid: "The password reset request is invalid.",
451
- authentication_required: "Authentication is required.",
452
- request_origin_denied: "The request origin is not allowed.",
453
- invalid_request: "The request is invalid.",
454
- invalid_invitation: "The invitation is invalid.",
455
- invitation_unavailable: "The invitation is not available.",
456
- recipient_unavailable: "The recipient is unavailable.",
457
- invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
458
- invitation_recovery_required: "Invitation administration requires separate recovery.",
459
- membership_removal_recovery_required: "Membership removal requires separate recovery.",
460
- email_verification_required: "Email verification is required.",
461
- invalid_workspace_selection: "The workspace selection is invalid.",
462
- organization_context_too_large: "The organization context is too large.",
463
- credential_rate_limited: "Credential requests are temporarily limited.",
464
- auth_request_rate_limited: "Authentication requests are temporarily limited.",
465
- organization_slug_unavailable: "The organization address is unavailable.",
466
- state_conflict: "The authentication state conflicts with the request.",
467
- access_denied: "Access is denied.",
468
- platform_target_unavailable: "The platform administration target is unavailable.",
469
- platform_quorum_unavailable: "Platform administration quorum is unavailable.",
470
- platform_recovery_required: "Platform administration requires separate recovery.",
471
- identity_authority_unavailable: "Authentication is temporarily unavailable.",
472
- two_factor_required: "A second authentication factor is required.",
473
- two_factor_code_invalid: "The verification code is invalid.",
474
- two_factor_challenge_expired: "The second-factor challenge has ended. Sign in again.",
475
- two_factor_locked: "Second-factor verification is temporarily locked.",
476
- recent_sign_in_required: "A recent sign-in is required.",
477
- enterprise_recovery_required: "Enterprise administration evidence requires operator recovery.",
478
- recent_authentication_required: "A ready recent-authentication action is required.",
479
- organization_closure_confirmation_mismatch: "The confirmation does not match the organization.",
480
- organization_closure_cancellation_ended: "The closure cancellation period has ended.",
481
- ceremony_return_refused: "The return address is not registered for this application.",
482
- password_sign_in_required: "A password sign-in method is required for this passkey change."
483
- };
484
- var AuthError = class extends Error {
485
- code;
486
- status;
487
- retryAfterSeconds;
488
- constructor(code, status, retryAfterSeconds) {
489
- super(messages[code]);
490
- this.name = "AuthError";
491
- this.code = code;
492
- this.status = status;
493
- this.retryAfterSeconds = retryAfterSeconds;
494
- }
495
- };
496
- //#endregion
497
- //#region src/shared.ts
498
- const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
499
- const id$3 = /^[A-Za-z0-9_-]{1,128}$/;
500
- const email = /^[^\s@]+@[^\s@]+$/;
501
- const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
502
- function normalizeEmail(value) {
503
- if (typeof value !== "string") throw new TypeError("email is invalid");
504
- const normalized = value.trim().toLowerCase();
505
- if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
506
- return normalized;
507
- }
508
- function normalizeSocialIdTokenInput(value) {
509
- if (!isObject$1(value)) throw new TypeError("social ID token input is invalid");
510
- const keys = Object.keys(value);
511
- if (keys.length !== 3 && keys.length !== 4 || keys.some((key) => key !== "provider" && key !== "idToken" && key !== "nonce" && key !== "signUp") || value.provider !== "google" && value.provider !== "apple" || typeof value.signUp !== "boolean" || typeof value.idToken !== "string" || value.idToken.length < 1 || new TextEncoder().encode(value.idToken).byteLength > MAX_SOCIAL_ID_TOKEN_BYTES || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.idToken) || value.nonce !== void 0 && (typeof value.nonce !== "string" || value.nonce.length < 1 || value.nonce.length > 256 || !/^[\x20-\x7e]+$/.test(value.nonce))) throw new TypeError("social ID token input is invalid");
512
- return {
513
- provider: value.provider,
514
- idToken: value.idToken,
515
- ...value.nonce === void 0 ? {} : { nonce: value.nonce },
516
- signUp: value.signUp
517
- };
518
- }
519
- function socialIdTokenRequest(value) {
520
- return {
521
- provider: value.provider,
522
- idToken: {
523
- token: value.idToken,
524
- ...value.nonce === void 0 ? {} : { nonce: value.nonce }
525
- },
526
- requestSignUp: value.signUp
527
- };
528
- }
529
- function normalizeOrigin(value, name) {
530
- if (value.length === 0 || value.length > 2048 || /[^\x20-\x7e]/.test(value)) throw new TypeError(`${name} must be an ASCII HTTP origin`);
531
- let url;
532
- try {
533
- url = new URL(value);
534
- } catch {
535
- throw new TypeError(`${name} must be an ASCII HTTP origin`);
536
- }
537
- const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1";
538
- if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== value) throw new TypeError(`${name} must be an ASCII HTTP origin`);
539
- return url.origin;
540
- }
541
- function normalizeTimeout(value) {
542
- const timeout = value ?? 1e4;
543
- if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4) throw new TypeError("timeoutMs must be an integer from 1 to 60000");
544
- return timeout;
545
- }
546
- function normalizeSession(value) {
547
- if (value === null) return null;
548
- if (!isObject$1(value) || !isObject$1(value.session) || !isObject$1(value.user)) throw authorityUnavailable();
549
- const expiresAt = toDate(value.session.expiresAt);
550
- const image = value.user.image;
551
- if (!isId(value.session.id) || !expiresAt || !isId(value.user.id) || typeof value.user.name !== "string" || value.user.name.length > 256 || typeof value.user.email !== "string" || value.user.email.length > 320 || !email.test(value.user.email) || typeof value.user.emailVerified !== "boolean" || image !== null && image !== void 0 && (typeof image !== "string" || image.length > 2048)) throw authorityUnavailable();
552
- return {
553
- id: value.session.id,
554
- expiresAt,
555
- user: {
556
- id: value.user.id,
557
- name: value.user.name,
558
- email: value.user.email,
559
- emailVerified: value.user.emailVerified,
560
- image: image ?? null
561
- }
562
- };
563
- }
564
- function normalizeDriveCredential(value, now) {
565
- if (!isObject$1(value) || value.tokenType !== "Bearer" || value.expiresIn !== DRIVE_CREDENTIAL_LIFETIME_SECONDS || typeof value.token !== "string" || value.token.length === 0 || new TextEncoder().encode(`Bearer ${value.token}`).byteLength > 16 * 1024) throw authorityUnavailable();
566
- return {
567
- tokenType: "Bearer",
568
- token: value.token,
569
- expiresAt: new Date(now + value.expiresIn * 1e3)
570
- };
571
- }
572
- function normalizeOrganizationPageInput(value) {
573
- if (value === void 0) return new URLSearchParams();
574
- if (!isObject$1(value) || Object.keys(value).some((key) => key !== "limit" && key !== "cursor")) throw new AuthError("invalid_request", 400);
575
- const input = value;
576
- const query = new URLSearchParams();
577
- if (input.limit !== void 0) {
578
- if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) throw new AuthError("invalid_request", 400);
579
- query.set("limit", String(input.limit));
580
- }
581
- if (input.cursor !== void 0) {
582
- if (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.cursor)) throw new AuthError("invalid_request", 400);
583
- query.set("cursor", input.cursor);
584
- }
585
- return query;
586
- }
587
- function normalizeOrganizationMemberPageInput(value) {
588
- if (value === void 0) return new URLSearchParams();
589
- if (!isObject$1(value) || Object.keys(value).some((key) => ![
590
- "limit",
591
- "cursor",
592
- "search"
593
- ].includes(key))) throw new AuthError("invalid_request", 400);
594
- const { search, ...page } = value;
595
- const query = normalizeOrganizationPageInput(page);
596
- if (search !== void 0) {
597
- if (typeof search !== "string") throw new AuthError("invalid_request", 400);
598
- const prefix = search.trim().replace(/[A-Z]/g, (character) => character.toLowerCase());
599
- if (!prefix || prefix.length > 128 || Array.from(prefix).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) throw new AuthError("invalid_request", 400);
600
- query.set("search", prefix);
601
- }
602
- return query;
603
- }
604
- function normalizeIdInput(value) {
605
- if (!isId(value)) throw new AuthError("invalid_request", 400);
606
- return value;
607
- }
608
- function normalizeOrganization(value) {
609
- exact$6(value, [
610
- "capabilities",
611
- "id",
612
- "lifecycle",
613
- "logo",
614
- "name",
615
- "role",
616
- "slug"
617
- ]);
618
- if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject$1(value.capabilities)) throw authorityUnavailable();
619
- exact$6(value.capabilities, [
620
- "readInvitations",
621
- "readMembers",
622
- "readTeams"
623
- ]);
624
- if (value.capabilities.readMembers !== true || value.capabilities.readTeams !== true || typeof value.capabilities.readInvitations !== "boolean") throw authorityUnavailable();
625
- return {
626
- id: value.id,
627
- name: value.name,
628
- slug: value.slug,
629
- logo: nullableHttpsUrl(value.logo),
630
- lifecycle: value.lifecycle,
631
- role: value.role,
632
- capabilities: {
633
- readMembers: true,
634
- readTeams: true,
635
- readInvitations: value.capabilities.readInvitations
636
- }
637
- };
638
- }
639
- function normalizeOrganizationDisplayInput(value) {
640
- if (!isObject$1(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
641
- if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
642
- let logo;
643
- try {
644
- logo = nullableHttpsUrl(value.logo);
645
- } catch {
646
- throw new AuthError("invalid_request", 400);
647
- }
648
- return {
649
- name: value.name,
650
- slug: value.slug,
651
- logo
652
- };
653
- }
654
- function normalizeOrganizationDisplay(value) {
655
- try {
656
- return normalizeOrganizationDisplayInput(value);
657
- } catch {
658
- throw authorityUnavailable();
659
- }
660
- }
661
- function normalizeOrganizationTeamDisplayInput(value) {
662
- if (!isObject$1(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
663
- return { name: value.name };
664
- }
665
- function normalizeOrganizationTeamDisplay(value) {
666
- try {
667
- return normalizeOrganizationTeamDisplayInput(value);
668
- } catch {
669
- throw authorityUnavailable();
670
- }
671
- }
672
- function normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
673
- if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255) || typeof slug !== "string" || !/^[a-z0-9-]{1,128}$/.test(slug)) throw new AuthError("invalid_request", 400);
674
- return {
675
- name,
676
- slug,
677
- idempotencyKey
678
- };
679
- }
680
- function normalizeCreatedOrganization(value) {
681
- exact$6(value, [
682
- "id",
683
- "name",
684
- "slug"
685
- ]);
686
- if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 128)) throw authorityUnavailable();
687
- return {
688
- id: value.id,
689
- name: value.name,
690
- slug: value.slug
691
- };
692
- }
693
- function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
694
- if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
695
- return {
696
- name,
697
- idempotencyKey
698
- };
699
- }
700
- function normalizeCreatedOrganizationTeam(value) {
701
- exact$6(value, ["id", "name"]);
702
- if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
703
- return {
704
- id: value.id,
705
- name: value.name
706
- };
262
+ function normalizeCreatedOrganizationTeam(value) {
263
+ exact$7(value, ["id", "name"]);
264
+ if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
265
+ return {
266
+ id: value.id,
267
+ name: value.name
268
+ };
707
269
  }
708
270
  function normalizeOrganizationMemberInvitationCreationInput(value) {
709
271
  if (!isObject$1(value)) throw new AuthError("invalid_request", 400);
@@ -725,7 +287,7 @@ function normalizeOrganizationMemberInvitationCreationInput(value) {
725
287
  };
726
288
  }
727
289
  function normalizeCreatedOrganizationMemberInvitation(value) {
728
- exact$6(value, ["expiresAt", "id"]);
290
+ exact$7(value, ["expiresAt", "id"]);
729
291
  if (!isId(value.id)) throw authorityUnavailable();
730
292
  return {
731
293
  id: value.id,
@@ -742,7 +304,7 @@ function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
742
304
  return { idempotencyKey };
743
305
  }
744
306
  function normalizeCanceledOrganizationInvitation(value) {
745
- exact$6(value, ["status"]);
307
+ exact$7(value, ["status"]);
746
308
  if (value.status !== "canceled") throw authorityUnavailable();
747
309
  return { status: "canceled" };
748
310
  }
@@ -751,12 +313,12 @@ function normalizeOrganizationMembershipRemovalInput(idempotencyKey) {
751
313
  return { idempotencyKey };
752
314
  }
753
315
  function normalizeRemovedOrganizationMember(value) {
754
- exact$6(value, ["status"]);
316
+ exact$7(value, ["status"]);
755
317
  if (value.status !== "removed") throw authorityUnavailable();
756
318
  return { status: "removed" };
757
319
  }
758
320
  function normalizeOrganizationDeparture(value) {
759
- exact$6(value, ["status"]);
321
+ exact$7(value, ["status"]);
760
322
  if (value.status !== "left") throw authorityUnavailable();
761
323
  return { status: "left" };
762
324
  }
@@ -765,22 +327,22 @@ function normalizeOrganizationTeamMembershipInput(idempotencyKey) {
765
327
  return { idempotencyKey };
766
328
  }
767
329
  function normalizeAddedOrganizationTeamMember(value) {
768
- exact$6(value, ["status"]);
330
+ exact$7(value, ["status"]);
769
331
  if (value.status !== "added") throw authorityUnavailable();
770
332
  return { status: "added" };
771
333
  }
772
334
  function normalizeRemovedOrganizationTeamMember(value) {
773
- exact$6(value, ["status"]);
335
+ exact$7(value, ["status"]);
774
336
  if (value.status !== "removed") throw authorityUnavailable();
775
337
  return { status: "removed" };
776
338
  }
777
339
  function normalizeDeletedOrganizationTeam(value) {
778
- exact$6(value, ["status"]);
340
+ exact$7(value, ["status"]);
779
341
  if (value.status !== "deleted") throw authorityUnavailable();
780
342
  return { status: "deleted" };
781
343
  }
782
344
  function normalizeOrganizations(value) {
783
- exact$6(value, ["nextCursor", "organizations"]);
345
+ exact$7(value, ["nextCursor", "organizations"]);
784
346
  if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
785
347
  return {
786
348
  organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
@@ -788,11 +350,11 @@ function normalizeOrganizations(value) {
788
350
  };
789
351
  }
790
352
  function normalizeOrganizationMembers(value) {
791
- exact$6(value, ["members", "nextCursor"]);
353
+ exact$7(value, ["members", "nextCursor"]);
792
354
  if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
793
355
  return {
794
356
  members: unique(value.members.map((member) => {
795
- exact$6(member, [
357
+ exact$7(member, [
796
358
  "email",
797
359
  "id",
798
360
  "image",
@@ -821,11 +383,11 @@ function normalizeOrganizationMembers(value) {
821
383
  };
822
384
  }
823
385
  function normalizeOrganizationTeams(value) {
824
- exact$6(value, ["nextCursor", "teams"]);
386
+ exact$7(value, ["nextCursor", "teams"]);
825
387
  if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
826
388
  return {
827
389
  teams: unique(value.teams.map((team) => {
828
- exact$6(team, [
390
+ exact$7(team, [
829
391
  "category",
830
392
  "createdAt",
831
393
  "id",
@@ -843,7 +405,7 @@ function normalizeOrganizationTeams(value) {
843
405
  };
844
406
  }
845
407
  function normalizeOrganizationTeamMembers(value) {
846
- exact$6(value, ["memberIds", "nextCursor"]);
408
+ exact$7(value, ["memberIds", "nextCursor"]);
847
409
  if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
848
410
  return {
849
411
  memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
@@ -851,7 +413,7 @@ function normalizeOrganizationTeamMembers(value) {
851
413
  };
852
414
  }
853
415
  function normalizeOrganizationInvitation(value) {
854
- exact$6(value, [
416
+ exact$7(value, [
855
417
  "createdAt",
856
418
  "email",
857
419
  "expiresAt",
@@ -862,7 +424,7 @@ function normalizeOrganizationInvitation(value) {
862
424
  "teamIds"
863
425
  ]);
864
426
  if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject$1(value.inviter)) throw authorityUnavailable();
865
- exact$6(value.inviter, ["membershipId", "name"]);
427
+ exact$7(value.inviter, ["membershipId", "name"]);
866
428
  if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
867
429
  return {
868
430
  id: value.id,
@@ -879,7 +441,7 @@ function normalizeOrganizationInvitation(value) {
879
441
  };
880
442
  }
881
443
  function normalizeOrganizationInvitations(value) {
882
- exact$6(value, ["invitations", "nextCursor"]);
444
+ exact$7(value, ["invitations", "nextCursor"]);
883
445
  if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
884
446
  return {
885
447
  invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
@@ -887,7 +449,7 @@ function normalizeOrganizationInvitations(value) {
887
449
  };
888
450
  }
889
451
  function normalizeReceivedInvitation(value) {
890
- exact$6(value, [
452
+ exact$7(value, [
891
453
  "expiresAt",
892
454
  "id",
893
455
  "inviterName",
@@ -896,7 +458,7 @@ function normalizeReceivedInvitation(value) {
896
458
  "teams"
897
459
  ]);
898
460
  if (!isId(value.id) || !boundedString(value.inviterName, 255) || !role(value.role) || !Array.isArray(value.teams) || value.teams.length > 100 || !isObject$1(value.organization)) throw authorityUnavailable();
899
- exact$6(value.organization, [
461
+ exact$7(value.organization, [
900
462
  "id",
901
463
  "logo",
902
464
  "name",
@@ -913,7 +475,7 @@ function normalizeReceivedInvitation(value) {
913
475
  },
914
476
  role: value.role,
915
477
  teams: unique(value.teams.map((team) => {
916
- exact$6(team, ["id", "name"]);
478
+ exact$7(team, ["id", "name"]);
917
479
  if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
918
480
  return {
919
481
  id: team.id,
@@ -925,7 +487,7 @@ function normalizeReceivedInvitation(value) {
925
487
  };
926
488
  }
927
489
  function normalizeReceivedInvitations(value) {
928
- exact$6(value, ["invitations", "nextCursor"]);
490
+ exact$7(value, ["invitations", "nextCursor"]);
929
491
  if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
930
492
  return {
931
493
  invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
@@ -1015,7 +577,7 @@ function fromOrganizationMembershipRemovalError(value, status, retryAfter) {
1015
577
  return fromOrganizationMutationAuthorityError(value, status, retryAfter);
1016
578
  }
1017
579
  function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
1018
- exact$6(value, [
580
+ exact$7(value, [
1019
581
  "organizationId",
1020
582
  "actor",
1021
583
  "target"
@@ -1033,7 +595,7 @@ function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
1033
595
  };
1034
596
  }
1035
597
  function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
1036
- exact$6(value, [
598
+ exact$7(value, [
1037
599
  "memberId",
1038
600
  "manualRole",
1039
601
  "role",
@@ -1061,113 +623,620 @@ function fromInvitationAuthorityError(value, status) {
1061
623
  if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
1062
624
  return authorityUnavailable();
1063
625
  }
1064
- function fromInvitationError(error) {
1065
- return error instanceof AuthError ? error : authorityUnavailable();
626
+ function fromInvitationError(error) {
627
+ return error instanceof AuthError ? error : authorityUnavailable();
628
+ }
629
+ function mapError(code, status) {
630
+ if (code === "authentication_required") return {
631
+ code,
632
+ status: 401
633
+ };
634
+ if (code === "request_origin_denied") return {
635
+ code,
636
+ status: 403
637
+ };
638
+ if (code === "invalid_workspace_selection") return {
639
+ code,
640
+ status: 422
641
+ };
642
+ if (code === "organization_context_too_large") return {
643
+ code,
644
+ status: 422
645
+ };
646
+ if (code === "credential_rate_limited") return {
647
+ code,
648
+ status: 429
649
+ };
650
+ if (code === "identity_authority_unavailable") return {
651
+ code,
652
+ status: 503
653
+ };
654
+ if (status === 401 || status === 400) return {
655
+ code: "invalid_credentials",
656
+ status: 401
657
+ };
658
+ if (status === 403) return {
659
+ code: "access_denied",
660
+ status: 403
661
+ };
662
+ if (status === 409) return {
663
+ code: "state_conflict",
664
+ status: 409
665
+ };
666
+ if (status === 422) return {
667
+ code: "invalid_workspace_selection",
668
+ status: 422
669
+ };
670
+ if (status === 429) return {
671
+ code: "credential_rate_limited",
672
+ status: 429
673
+ };
674
+ return {
675
+ code: "identity_authority_unavailable",
676
+ status: 503
677
+ };
678
+ }
679
+ function parseRetryAfter(value) {
680
+ if (!value || !/^\d+$/.test(value)) return void 0;
681
+ const seconds = Number(value);
682
+ return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
683
+ }
684
+ function toDate(value) {
685
+ const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
686
+ return result && Number.isFinite(result.getTime()) ? result : void 0;
687
+ }
688
+ function isId(value) {
689
+ return typeof value === "string" && id$3.test(value);
690
+ }
691
+ function exact$7(value, keys) {
692
+ if (!isObject$1(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
693
+ }
694
+ function boundedString(value, maximum) {
695
+ return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
696
+ }
697
+ function role(value) {
698
+ return value === "owner" || value === "admin" || value === "member";
699
+ }
700
+ function nullableHttpsUrl(value) {
701
+ if (value === null) return null;
702
+ if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
703
+ let url;
704
+ try {
705
+ url = new URL(value);
706
+ } catch {
707
+ throw authorityUnavailable();
708
+ }
709
+ if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
710
+ return value;
711
+ }
712
+ function responseDate(value) {
713
+ if (typeof value !== "string") throw authorityUnavailable();
714
+ const date = new Date(value);
715
+ if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
716
+ return date;
717
+ }
718
+ function nullableCursor(value) {
719
+ if (value === null) return null;
720
+ if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
721
+ return value;
722
+ }
723
+ function normalizeResponseId(value) {
724
+ if (!isId(value)) throw authorityUnavailable();
725
+ return value;
726
+ }
727
+ function unique(items, key) {
728
+ if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
729
+ return items;
730
+ }
731
+ function isObject$1(value) {
732
+ return typeof value === "object" && value !== null && !Array.isArray(value);
733
+ }
734
+ //#endregion
735
+ //#region src/organization-directory/contract.ts
736
+ function record$1(value) {
737
+ return value !== null && typeof value === "object" && !Array.isArray(value);
738
+ }
739
+ function exact$6(value, keys) {
740
+ return record$1(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
741
+ }
742
+ function directoryId(value) {
743
+ return typeof value === "string" && /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(value);
744
+ }
745
+ function directoryGeneration(value) {
746
+ return typeof value === "string" && /^[a-f0-9]{32}$(?![\s\S])/.test(value);
747
+ }
748
+ function normalizeDirectoryEntry(value, applicationId) {
749
+ if (!exact$6(value, [
750
+ "organizationId",
751
+ "applicationId",
752
+ "organizationGeneration",
753
+ "name",
754
+ "lifecycle",
755
+ "registeredAt"
756
+ ]) || !directoryId(value.organizationId) || value.applicationId !== applicationId || !directoryGeneration(value.organizationGeneration) || typeof value.name !== "string" || !value.name.length || new TextEncoder().encode(value.name).byteLength > 255 || value.lifecycle !== "active" && value.lifecycle !== "closing" && value.lifecycle !== "deleted" || typeof value.registeredAt !== "number" || !Number.isInteger(value.registeredAt) || value.registeredAt < 0 || value.registeredAt > 864e13) throw authorityUnavailable();
757
+ return {
758
+ organizationId: value.organizationId,
759
+ applicationId,
760
+ organizationGeneration: value.organizationGeneration,
761
+ name: value.name,
762
+ lifecycle: value.lifecycle,
763
+ registeredAt: value.registeredAt
764
+ };
765
+ }
766
+ //#endregion
767
+ //#region src/organization-directory/registration.ts
768
+ function registrationTarget(organizationId, applicationId) {
769
+ if (!directoryId(organizationId) || !directoryId(applicationId)) throw new AuthError("invalid_request", 400);
770
+ return `${organizationId}/applications/${applicationId}/registration`;
771
+ }
772
+ function registrationInput(input) {
773
+ if (!exact$6(input, ["organizationGeneration", "idempotencyKey"]) || !directoryGeneration(input.organizationGeneration) || typeof input.idempotencyKey !== "string" || !/^[A-Za-z0-9_-]{16,128}$(?![\s\S])/.test(input.idempotencyKey)) throw new AuthError("invalid_request", 400);
774
+ return {
775
+ organizationGeneration: input.organizationGeneration,
776
+ idempotencyKey: input.idempotencyKey
777
+ };
778
+ }
779
+ function normalizeOrganizationApplicationRegistration(value, organizationId, applicationId) {
780
+ if (!exact$6(value, [
781
+ "organizationId",
782
+ "applicationId",
783
+ "organizationGeneration",
784
+ "name",
785
+ "registered"
786
+ ]) || value.organizationId !== organizationId || value.applicationId !== applicationId || !directoryGeneration(value.organizationGeneration) || typeof value.name !== "string" || !value.name.length || new TextEncoder().encode(value.name).byteLength > 255 || typeof value.registered !== "boolean") throw authorityUnavailable();
787
+ return {
788
+ organizationId,
789
+ applicationId,
790
+ organizationGeneration: value.organizationGeneration,
791
+ name: value.name,
792
+ registered: value.registered
793
+ };
794
+ }
795
+ function normalizeRegisteredOrganizationApplication(value, organizationId, applicationId, generation) {
796
+ if (!exact$6(value, ["organization", "outcome"]) || value.outcome !== "registered" && value.outcome !== "replayed") throw authorityUnavailable();
797
+ const organization = normalizeDirectoryEntry(value.organization, applicationId);
798
+ if (organization.organizationId !== organizationId || organization.organizationGeneration !== generation || organization.lifecycle !== "active") throw authorityUnavailable();
799
+ return {
800
+ organization,
801
+ outcome: value.outcome
802
+ };
803
+ }
804
+ String.fromCharCode;
805
+ const HASH_RE = /#/g;
806
+ const AMPERSAND_RE = /&/g;
807
+ const SLASH_RE = /\//g;
808
+ const EQUAL_RE = /=/g;
809
+ const PLUS_RE = /\+/g;
810
+ const ENC_CARET_RE = /%5e/gi;
811
+ const ENC_BACKTICK_RE = /%60/gi;
812
+ const ENC_PIPE_RE = /%7c/gi;
813
+ const ENC_SPACE_RE = /%20/gi;
814
+ function encode$2(text) {
815
+ return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
816
+ }
817
+ function encodeQueryValue(input) {
818
+ return encode$2(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
819
+ }
820
+ function encodeQueryKey(text) {
821
+ return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
822
+ }
823
+ function decode$1(text = "") {
824
+ try {
825
+ return decodeURIComponent("" + text);
826
+ } catch {
827
+ return "" + text;
828
+ }
829
+ }
830
+ function decodeQueryKey(text) {
831
+ return decode$1(text.replace(PLUS_RE, " "));
832
+ }
833
+ function decodeQueryValue(text) {
834
+ return decode$1(text.replace(PLUS_RE, " "));
835
+ }
836
+ function parseQuery(parametersString = "") {
837
+ const object = Object.create(null);
838
+ if (parametersString[0] === "?") parametersString = parametersString.slice(1);
839
+ for (const parameter of parametersString.split("&")) {
840
+ const s = parameter.match(/([^=]+)=?(.*)/) || [];
841
+ if (s.length < 2) continue;
842
+ const key = decodeQueryKey(s[1]);
843
+ if (key === "__proto__" || key === "constructor") continue;
844
+ const value = decodeQueryValue(s[2] || "");
845
+ if (object[key] === void 0) object[key] = value;
846
+ else if (Array.isArray(object[key])) object[key].push(value);
847
+ else object[key] = [object[key], value];
848
+ }
849
+ return object;
850
+ }
851
+ function encodeQueryItem(key, value) {
852
+ if (typeof value === "number" || typeof value === "boolean") value = String(value);
853
+ if (!value) return encodeQueryKey(key);
854
+ if (Array.isArray(value)) return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
855
+ return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
856
+ }
857
+ function stringifyQuery(query) {
858
+ return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
859
+ }
860
+ const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
861
+ const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
862
+ const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
863
+ const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
864
+ const JOIN_LEADING_SLASH_RE = /^\.?\//;
865
+ function hasProtocol(inputString, opts = {}) {
866
+ if (typeof opts === "boolean") opts = { acceptRelative: opts };
867
+ if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
868
+ return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
869
+ }
870
+ function hasTrailingSlash(input = "", respectQueryAndFragment) {
871
+ if (!respectQueryAndFragment) return input.endsWith("/");
872
+ return TRAILING_SLASH_RE.test(input);
873
+ }
874
+ function withoutTrailingSlash(input = "", respectQueryAndFragment) {
875
+ if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
876
+ if (!hasTrailingSlash(input, true)) return input || "/";
877
+ let path = input;
878
+ let fragment = "";
879
+ const fragmentIndex = input.indexOf("#");
880
+ if (fragmentIndex !== -1) {
881
+ path = input.slice(0, fragmentIndex);
882
+ fragment = input.slice(fragmentIndex);
883
+ }
884
+ const [s0, ...s] = path.split("?");
885
+ return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
886
+ }
887
+ function withTrailingSlash(input = "", respectQueryAndFragment) {
888
+ if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
889
+ if (hasTrailingSlash(input, true)) return input || "/";
890
+ let path = input;
891
+ let fragment = "";
892
+ const fragmentIndex = input.indexOf("#");
893
+ if (fragmentIndex !== -1) {
894
+ path = input.slice(0, fragmentIndex);
895
+ fragment = input.slice(fragmentIndex);
896
+ if (!path) return fragment;
897
+ }
898
+ const [s0, ...s] = path.split("?");
899
+ return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
900
+ }
901
+ function withBase(input, base) {
902
+ if (isEmptyURL(base) || hasProtocol(input)) return input;
903
+ const _base = withoutTrailingSlash(base);
904
+ if (input.startsWith(_base)) {
905
+ const nextChar = input[_base.length];
906
+ if (!nextChar || nextChar === "/" || nextChar === "?") return input;
907
+ }
908
+ return joinURL(_base, input);
909
+ }
910
+ function withQuery(input, query) {
911
+ const parsed = parseURL(input);
912
+ parsed.search = stringifyQuery({
913
+ ...parseQuery(parsed.search),
914
+ ...query
915
+ });
916
+ return stringifyParsedURL(parsed);
917
+ }
918
+ function isEmptyURL(url) {
919
+ return !url || url === "/";
920
+ }
921
+ function isNonEmptyURL(url) {
922
+ return url && url !== "/";
1066
923
  }
1067
- function mapError(code, status) {
1068
- if (code === "authentication_required") return {
1069
- code,
1070
- status: 401
1071
- };
1072
- if (code === "request_origin_denied") return {
1073
- code,
1074
- status: 403
1075
- };
1076
- if (code === "invalid_workspace_selection") return {
1077
- code,
1078
- status: 422
1079
- };
1080
- if (code === "organization_context_too_large") return {
1081
- code,
1082
- status: 422
1083
- };
1084
- if (code === "credential_rate_limited") return {
1085
- code,
1086
- status: 429
1087
- };
1088
- if (code === "identity_authority_unavailable") return {
1089
- code,
1090
- status: 503
1091
- };
1092
- if (status === 401 || status === 400) return {
1093
- code: "invalid_credentials",
1094
- status: 401
1095
- };
1096
- if (status === 403) return {
1097
- code: "access_denied",
1098
- status: 403
1099
- };
1100
- if (status === 409) return {
1101
- code: "state_conflict",
1102
- status: 409
1103
- };
1104
- if (status === 422) return {
1105
- code: "invalid_workspace_selection",
1106
- status: 422
1107
- };
1108
- if (status === 429) return {
1109
- code: "credential_rate_limited",
1110
- status: 429
1111
- };
924
+ function joinURL(base, ...input) {
925
+ let url = base || "";
926
+ for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
927
+ const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
928
+ url = withTrailingSlash(url) + _segment;
929
+ } else url = segment;
930
+ return url;
931
+ }
932
+ const protocolRelative = Symbol.for("ufo:protocolRelative");
933
+ function parseURL(input = "", defaultProto) {
934
+ const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
935
+ if (_specialProtoMatch) {
936
+ const [, _proto, _pathname = ""] = _specialProtoMatch;
937
+ return {
938
+ protocol: _proto.toLowerCase(),
939
+ pathname: _pathname,
940
+ href: _proto + _pathname,
941
+ auth: "",
942
+ host: "",
943
+ search: "",
944
+ hash: ""
945
+ };
946
+ }
947
+ if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
948
+ const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
949
+ let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
950
+ if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
951
+ const { pathname, search, hash } = parsePath(path);
1112
952
  return {
1113
- code: "identity_authority_unavailable",
1114
- status: 503
953
+ protocol: protocol.toLowerCase(),
954
+ auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
955
+ host,
956
+ pathname,
957
+ search,
958
+ hash,
959
+ [protocolRelative]: !protocol
1115
960
  };
1116
961
  }
1117
- function parseRetryAfter(value) {
1118
- if (!value || !/^\d+$/.test(value)) return void 0;
1119
- const seconds = Number(value);
1120
- return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 3600 ? seconds : void 0;
1121
- }
1122
- function toDate(value) {
1123
- const result = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
1124
- return result && Number.isFinite(result.getTime()) ? result : void 0;
1125
- }
1126
- function isId(value) {
1127
- return typeof value === "string" && id$3.test(value);
962
+ function parsePath(input = "") {
963
+ const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
964
+ return {
965
+ pathname,
966
+ search,
967
+ hash
968
+ };
1128
969
  }
1129
- function exact$6(value, keys) {
1130
- if (!isObject$1(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
970
+ function stringifyParsedURL(parsed) {
971
+ const pathname = parsed.pathname || "";
972
+ const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
973
+ const hash = parsed.hash || "";
974
+ const auth = parsed.auth ? parsed.auth + "@" : "";
975
+ const host = parsed.host || "";
976
+ return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
1131
977
  }
1132
- function boundedString(value, maximum) {
1133
- return typeof value === "string" && value.length > 0 && new TextEncoder().encode(value).byteLength <= maximum;
978
+ //#endregion
979
+ //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
980
+ const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
981
+ const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
982
+ const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
983
+ function jsonParseTransform(key, value) {
984
+ if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
985
+ warnKeyDropped(key);
986
+ return;
987
+ }
988
+ return value;
1134
989
  }
1135
- function role(value) {
1136
- return value === "owner" || value === "admin" || value === "member";
990
+ function warnKeyDropped(key) {
991
+ console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
1137
992
  }
1138
- function nullableHttpsUrl(value) {
1139
- if (value === null) return null;
1140
- if (typeof value !== "string" || value.length > 2048) throw authorityUnavailable();
1141
- let url;
993
+ function destr(value, options = {}) {
994
+ if (typeof value !== "string") return value;
995
+ if (value[0] === "\"" && value[value.length - 1] === "\"" && value.indexOf("\\") === -1) return value.slice(1, -1);
996
+ const _value = value.trim();
997
+ if (_value.length <= 9) switch (_value.toLowerCase()) {
998
+ case "true": return true;
999
+ case "false": return false;
1000
+ case "undefined": return;
1001
+ case "null": return null;
1002
+ case "nan": return NaN;
1003
+ case "infinity": return Number.POSITIVE_INFINITY;
1004
+ case "-infinity": return Number.NEGATIVE_INFINITY;
1005
+ }
1006
+ if (!JsonSigRx.test(value)) {
1007
+ if (options.strict) throw new SyntaxError("[destr] Invalid JSON");
1008
+ return value;
1009
+ }
1142
1010
  try {
1143
- url = new URL(value);
1144
- } catch {
1145
- throw authorityUnavailable();
1011
+ if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
1012
+ if (options.strict) throw new Error("[destr] Possible prototype pollution");
1013
+ return JSON.parse(value, jsonParseTransform);
1014
+ }
1015
+ return JSON.parse(value);
1016
+ } catch (error) {
1017
+ if (options.strict) throw error;
1018
+ return value;
1146
1019
  }
1147
- if (url.protocol !== "https:" || url.username || url.password || url.toString() !== value) throw authorityUnavailable();
1148
- return value;
1149
1020
  }
1150
- function responseDate(value) {
1151
- if (typeof value !== "string") throw authorityUnavailable();
1152
- const date = new Date(value);
1153
- if (!Number.isFinite(date.getTime()) || date.toISOString() !== value) throw authorityUnavailable();
1154
- return date;
1021
+ //#endregion
1022
+ //#region ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs
1023
+ var FetchError = class extends Error {
1024
+ constructor(message, opts) {
1025
+ super(message, opts);
1026
+ this.name = "FetchError";
1027
+ if (opts?.cause && !this.cause) this.cause = opts.cause;
1028
+ }
1029
+ };
1030
+ function createFetchError(ctx) {
1031
+ const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
1032
+ const method = ctx.request?.method || ctx.options?.method || "GET";
1033
+ const url = ctx.request?.url || String(ctx.request) || "/";
1034
+ const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
1035
+ for (const key of [
1036
+ "request",
1037
+ "options",
1038
+ "response"
1039
+ ]) Object.defineProperty(fetchError, key, { get() {
1040
+ return ctx[key];
1041
+ } });
1042
+ for (const [key, refKey] of [
1043
+ ["data", "_data"],
1044
+ ["status", "status"],
1045
+ ["statusCode", "status"],
1046
+ ["statusText", "statusText"],
1047
+ ["statusMessage", "statusText"]
1048
+ ]) Object.defineProperty(fetchError, key, { get() {
1049
+ return ctx.response && ctx.response[refKey];
1050
+ } });
1051
+ return fetchError;
1155
1052
  }
1156
- function nullableCursor(value) {
1157
- if (value === null) return null;
1158
- if (typeof value !== "string" || value.length < 1 || value.length > 820 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) throw authorityUnavailable();
1159
- return value;
1053
+ const payloadMethods = new Set(Object.freeze([
1054
+ "PATCH",
1055
+ "POST",
1056
+ "PUT",
1057
+ "DELETE"
1058
+ ]));
1059
+ function isPayloadMethod(method = "GET") {
1060
+ return payloadMethods.has(method.toUpperCase());
1160
1061
  }
1161
- function normalizeResponseId(value) {
1162
- if (!isId(value)) throw authorityUnavailable();
1163
- return value;
1062
+ function isJSONSerializable(value) {
1063
+ if (value === void 0) return false;
1064
+ const t = typeof value;
1065
+ if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
1066
+ if (t !== "object") return false;
1067
+ if (Array.isArray(value)) return true;
1068
+ if (value.buffer) return false;
1069
+ if (value instanceof FormData || value instanceof URLSearchParams) return false;
1070
+ return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
1071
+ }
1072
+ const textTypes = new Set([
1073
+ "image/svg",
1074
+ "application/xml",
1075
+ "application/xhtml",
1076
+ "application/html"
1077
+ ]);
1078
+ const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
1079
+ function detectResponseType(_contentType = "") {
1080
+ if (!_contentType) return "json";
1081
+ const contentType = _contentType.split(";").shift() || "";
1082
+ if (JSON_RE.test(contentType)) return "json";
1083
+ if (contentType === "text/event-stream") return "stream";
1084
+ if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
1085
+ return "blob";
1086
+ }
1087
+ function resolveFetchOptions(request, input, defaults, Headers) {
1088
+ const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers);
1089
+ let query;
1090
+ if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
1091
+ ...defaults?.params,
1092
+ ...defaults?.query,
1093
+ ...input?.params,
1094
+ ...input?.query
1095
+ };
1096
+ return {
1097
+ ...defaults,
1098
+ ...input,
1099
+ query,
1100
+ params: query,
1101
+ headers
1102
+ };
1164
1103
  }
1165
- function unique(items, key) {
1166
- if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
1167
- return items;
1104
+ function mergeHeaders(input, defaults, Headers) {
1105
+ if (!defaults) return new Headers(input);
1106
+ const headers = new Headers(defaults);
1107
+ if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) headers.set(key, value);
1108
+ return headers;
1168
1109
  }
1169
- function isObject$1(value) {
1170
- return typeof value === "object" && value !== null && !Array.isArray(value);
1110
+ async function callHooks(context, hooks) {
1111
+ if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
1112
+ else await hooks(context);
1113
+ }
1114
+ const retryStatusCodes = new Set([
1115
+ 408,
1116
+ 409,
1117
+ 425,
1118
+ 429,
1119
+ 500,
1120
+ 502,
1121
+ 503,
1122
+ 504
1123
+ ]);
1124
+ const nullBodyResponses = new Set([
1125
+ 101,
1126
+ 204,
1127
+ 205,
1128
+ 304
1129
+ ]);
1130
+ function createFetch(globalOptions = {}) {
1131
+ const { fetch = globalThis.fetch, Headers = globalThis.Headers, AbortController = globalThis.AbortController } = globalOptions;
1132
+ async function onError(context) {
1133
+ const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
1134
+ if (context.options.retry !== false && !isAbort) {
1135
+ let retries;
1136
+ if (typeof context.options.retry === "number") retries = context.options.retry;
1137
+ else retries = isPayloadMethod(context.options.method) ? 0 : 1;
1138
+ const responseCode = context.response && context.response.status || 500;
1139
+ if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
1140
+ const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
1141
+ if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
1142
+ return $fetchRaw(context.request, {
1143
+ ...context.options,
1144
+ retry: retries - 1
1145
+ });
1146
+ }
1147
+ }
1148
+ const error = createFetchError(context);
1149
+ if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
1150
+ throw error;
1151
+ }
1152
+ const $fetchRaw = async function $fetchRaw2(_request, _options = {}) {
1153
+ const context = {
1154
+ request: _request,
1155
+ options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
1156
+ response: void 0,
1157
+ error: void 0
1158
+ };
1159
+ if (context.options.method) context.options.method = context.options.method.toUpperCase();
1160
+ if (context.options.onRequest) {
1161
+ await callHooks(context, context.options.onRequest);
1162
+ if (!(context.options.headers instanceof Headers)) context.options.headers = new Headers(context.options.headers || {});
1163
+ }
1164
+ if (typeof context.request === "string") {
1165
+ if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
1166
+ if (context.options.query) {
1167
+ context.request = withQuery(context.request, context.options.query);
1168
+ delete context.options.query;
1169
+ }
1170
+ if ("query" in context.options) delete context.options.query;
1171
+ if ("params" in context.options) delete context.options.params;
1172
+ }
1173
+ if (context.options.body && isPayloadMethod(context.options.method)) {
1174
+ if (isJSONSerializable(context.options.body)) {
1175
+ const contentType = context.options.headers.get("content-type");
1176
+ if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
1177
+ if (!contentType) context.options.headers.set("content-type", "application/json");
1178
+ if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
1179
+ } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
1180
+ if (!("duplex" in context.options)) context.options.duplex = "half";
1181
+ }
1182
+ }
1183
+ let abortTimeout;
1184
+ if (!context.options.signal && context.options.timeout) {
1185
+ const controller = new AbortController();
1186
+ abortTimeout = setTimeout(() => {
1187
+ const error = new Error("[TimeoutError]: The operation was aborted due to timeout");
1188
+ error.name = "TimeoutError";
1189
+ error.code = 23;
1190
+ controller.abort(error);
1191
+ }, context.options.timeout);
1192
+ context.options.signal = controller.signal;
1193
+ }
1194
+ try {
1195
+ context.response = await fetch(context.request, context.options);
1196
+ } catch (error) {
1197
+ context.error = error;
1198
+ if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
1199
+ return await onError(context);
1200
+ } finally {
1201
+ if (abortTimeout) clearTimeout(abortTimeout);
1202
+ }
1203
+ if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
1204
+ const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
1205
+ switch (responseType) {
1206
+ case "json": {
1207
+ const data = await context.response.text();
1208
+ const parseFunction = context.options.parseResponse || destr;
1209
+ context.response._data = parseFunction(data);
1210
+ break;
1211
+ }
1212
+ case "stream":
1213
+ context.response._data = context.response.body || context.response._bodyInit;
1214
+ break;
1215
+ default: context.response._data = await context.response[responseType]();
1216
+ }
1217
+ }
1218
+ if (context.options.onResponse) await callHooks(context, context.options.onResponse);
1219
+ if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
1220
+ if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
1221
+ return await onError(context);
1222
+ }
1223
+ return context.response;
1224
+ };
1225
+ const $fetch = async function $fetch2(request, options) {
1226
+ return (await $fetchRaw(request, options))._data;
1227
+ };
1228
+ $fetch.raw = $fetchRaw;
1229
+ $fetch.native = (...args) => fetch(...args);
1230
+ $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
1231
+ ...globalOptions,
1232
+ ...customGlobalOptions,
1233
+ defaults: {
1234
+ ...globalOptions.defaults,
1235
+ ...customGlobalOptions.defaults,
1236
+ ...defaultOptions
1237
+ }
1238
+ });
1239
+ return $fetch;
1171
1240
  }
1172
1241
  //#endregion
1173
1242
  //#region src/http.ts
@@ -1252,6 +1321,82 @@ async function readJson(response, maximum = MAX_RESPONSE_BYTES, signal) {
1252
1321
  }
1253
1322
  }
1254
1323
  //#endregion
1324
+ //#region src/organization-directory/service.ts
1325
+ function createOrganizationDirectoryAuth(options) {
1326
+ const origin = normalizeOrigin(options.authOrigin, "authOrigin");
1327
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
1328
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
1329
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
1330
+ let inFlight = 0;
1331
+ async function exchange(operation, body, assertion) {
1332
+ if (typeof assertion !== "string" || assertion.length > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(assertion)) throw new AuthError("invalid_request", 400);
1333
+ if (inFlight >= 4) throw new AuthError("state_conflict", 409);
1334
+ inFlight += 1;
1335
+ const controller = new AbortController();
1336
+ let timer;
1337
+ const deadline = new Promise((_, reject) => {
1338
+ timer = setTimeout(() => {
1339
+ reject(authorityUnavailable());
1340
+ controller.abort();
1341
+ }, timeoutMs);
1342
+ });
1343
+ try {
1344
+ return await Promise.race([requestJson(joinURL(origin, "api/v1/auth/organization-directory", operation), {
1345
+ fetch: fetchImpl,
1346
+ timeoutMs,
1347
+ method: "POST",
1348
+ credentials: "omit",
1349
+ cache: "no-store",
1350
+ headers: {
1351
+ "x-finueva-service-assertion": assertion,
1352
+ "content-type": "application/json",
1353
+ accept: "application/json"
1354
+ },
1355
+ body,
1356
+ maxResponseBytes: 256 * 1024,
1357
+ signal: controller.signal
1358
+ }).finally(() => {
1359
+ inFlight -= 1;
1360
+ }), deadline]);
1361
+ } finally {
1362
+ clearTimeout(timer);
1363
+ controller.abort();
1364
+ }
1365
+ }
1366
+ return {
1367
+ async lookupOrganization(input, assertion) {
1368
+ if (!exact$6(input, [
1369
+ "organizationId",
1370
+ "applicationId",
1371
+ "organizationGeneration"
1372
+ ]) || !directoryId(input.organizationId) || !directoryId(input.applicationId) || !directoryGeneration(input.organizationGeneration)) throw new AuthError("invalid_request", 400);
1373
+ const value = await exchange("lookup", input, assertion);
1374
+ if (!exact$6(value, ["organization"])) throw authorityUnavailable();
1375
+ if (value.organization === null) return null;
1376
+ const organization = normalizeDirectoryEntry(value.organization, input.applicationId);
1377
+ if (organization.organizationId !== input.organizationId || organization.organizationGeneration !== input.organizationGeneration) throw authorityUnavailable();
1378
+ return organization;
1379
+ },
1380
+ async searchOrganizations(input, assertion) {
1381
+ if (!record$1(input) || Object.keys(input).some((key) => ![
1382
+ "applicationId",
1383
+ "query",
1384
+ "limit",
1385
+ "cursor"
1386
+ ].includes(key)) || !directoryId(input.applicationId) || input.query !== void 0 && (typeof input.query !== "string" || input.query.length < 1 || input.query.length > 128 || Array.from(input.query).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) || input.limit !== void 0 && (!Number.isInteger(input.limit) || input.limit < 1 || input.limit > 100) || input.cursor !== void 0 && (typeof input.cursor !== "string" || input.cursor.length > 2048)) throw new AuthError("invalid_request", 400);
1387
+ const limit = input.limit ?? 50;
1388
+ const value = await exchange("search", input, assertion);
1389
+ if (!exact$6(value, ["organizations", "nextCursor"]) || !Array.isArray(value.organizations) || value.organizations.length > limit || value.nextCursor !== null && (typeof value.nextCursor !== "string" || !value.nextCursor.length || value.nextCursor.length > 2048)) throw authorityUnavailable();
1390
+ const organizations = value.organizations.map((item) => normalizeDirectoryEntry(item, input.applicationId));
1391
+ if (organizations.some((organization) => organization.lifecycle === "deleted") || new Set(organizations.map((organization) => `${organization.organizationId}:${organization.organizationGeneration}`)).size !== organizations.length) throw authorityUnavailable();
1392
+ return {
1393
+ organizations,
1394
+ nextCursor: value.nextCursor
1395
+ };
1396
+ }
1397
+ };
1398
+ }
1399
+ //#endregion
1255
1400
  //#region src/product-operations/contract.ts
1256
1401
  const id$2 = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
1257
1402
  const digest$1 = /^[a-f0-9]{64}$(?![\s\S])/;
@@ -3330,6 +3475,168 @@ function createDriveProvisioningAuth(options) {
3330
3475
  } };
3331
3476
  }
3332
3477
  //#endregion
3478
+ //#region src/user-directory.ts
3479
+ function user(value, applicationId) {
3480
+ if (!exact$6(value, [
3481
+ "applicationId",
3482
+ "userId",
3483
+ "userGeneration",
3484
+ "lifecycle"
3485
+ ]) || value.applicationId !== applicationId || !directoryGeneration(value.userId) || !directoryGeneration(value.userGeneration) || ![
3486
+ "active",
3487
+ "suspended",
3488
+ "deleted"
3489
+ ].includes(String(value.lifecycle))) throw authorityUnavailable();
3490
+ return {
3491
+ applicationId,
3492
+ userId: value.userId,
3493
+ userGeneration: value.userGeneration,
3494
+ lifecycle: value.lifecycle
3495
+ };
3496
+ }
3497
+ function exactInput(input) {
3498
+ if (!exact$6(input, [
3499
+ "applicationId",
3500
+ "userId",
3501
+ "userGeneration"
3502
+ ]) || !directoryId(input.applicationId) || !directoryGeneration(input.userId) || !directoryGeneration(input.userGeneration)) throw new AuthError("invalid_request", 400);
3503
+ }
3504
+ function pageInput(input, members = false) {
3505
+ if (!record$1(input) || Object.keys(input).some((key) => ![
3506
+ "applicationId",
3507
+ "limit",
3508
+ "cursor",
3509
+ ...members ? ["organizationId", "organizationGeneration"] : []
3510
+ ].includes(key)) || !directoryId(input.applicationId) || input.limit !== void 0 && (!Number.isInteger(input.limit) || input.limit < 1 || input.limit > 100) || input.cursor !== void 0 && (typeof input.cursor !== "string" || input.cursor.length < 1 || input.cursor.length > 2048) || members && (!directoryId(input.organizationId) || !directoryGeneration(input.organizationGeneration))) throw new AuthError("invalid_request", 400);
3511
+ }
3512
+ function nextCursor(value) {
3513
+ if (value !== null && (typeof value !== "string" || !value.length || value.length > 2048)) throw authorityUnavailable();
3514
+ return value;
3515
+ }
3516
+ function selectedUser(value, input) {
3517
+ const normalized = user(value, input.applicationId);
3518
+ if (normalized.userId !== input.userId || normalized.userGeneration !== input.userGeneration) throw authorityUnavailable();
3519
+ return normalized;
3520
+ }
3521
+ function createUserDirectoryAuth(options) {
3522
+ const origin = normalizeOrigin(options.authOrigin, "authOrigin");
3523
+ const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
3524
+ if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
3525
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
3526
+ let inFlight = 0;
3527
+ async function exchange(operation, body, assertion) {
3528
+ if (typeof assertion !== "string" || assertion.length > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$(?![\s\S])/.test(assertion)) throw new AuthError("invalid_request", 400);
3529
+ if (inFlight >= 4) throw new AuthError("state_conflict", 409);
3530
+ inFlight += 1;
3531
+ const controller = new AbortController();
3532
+ let timer;
3533
+ const deadline = new Promise((_, reject) => {
3534
+ timer = setTimeout(() => {
3535
+ reject(authorityUnavailable());
3536
+ controller.abort();
3537
+ }, timeoutMs);
3538
+ });
3539
+ try {
3540
+ return await Promise.race([requestJson(joinURL(origin, "api/v1/auth/user-directory", operation), {
3541
+ fetch: fetchImpl,
3542
+ timeoutMs,
3543
+ method: "POST",
3544
+ credentials: "omit",
3545
+ cache: "no-store",
3546
+ headers: {
3547
+ "x-finueva-service-assertion": assertion,
3548
+ "content-type": "application/json",
3549
+ accept: "application/json"
3550
+ },
3551
+ body,
3552
+ maxResponseBytes: 128 * 1024,
3553
+ signal: controller.signal
3554
+ }).finally(() => {
3555
+ inFlight -= 1;
3556
+ }), deadline]);
3557
+ } catch (cause) {
3558
+ if (cause instanceof AuthError) throw cause;
3559
+ throw authorityUnavailable();
3560
+ } finally {
3561
+ clearTimeout(timer);
3562
+ controller.abort();
3563
+ }
3564
+ }
3565
+ return {
3566
+ async listUsers(input, assertion) {
3567
+ pageInput(input);
3568
+ const value = await exchange("list", input, assertion);
3569
+ if (!exact$6(value, ["users", "nextCursor"]) || !Array.isArray(value.users) || value.users.length > (input.limit ?? 50)) throw authorityUnavailable();
3570
+ const users = value.users.map((item) => user(item, input.applicationId));
3571
+ if (users.some((item) => item.lifecycle === "deleted") || new Set(users.map((item) => item.userId)).size !== users.length) throw authorityUnavailable();
3572
+ return {
3573
+ users,
3574
+ nextCursor: nextCursor(value.nextCursor)
3575
+ };
3576
+ },
3577
+ async lookupUser(input, assertion) {
3578
+ exactInput(input);
3579
+ const value = await exchange("lookup", input, assertion);
3580
+ if (!exact$6(value, ["user"])) throw authorityUnavailable();
3581
+ return value.user === null ? null : selectedUser(value.user, input);
3582
+ },
3583
+ async listOrganizationMembers(input, assertion) {
3584
+ pageInput(input, true);
3585
+ const value = await exchange("members", input, assertion);
3586
+ if (!exact$6(value, [
3587
+ "applicationId",
3588
+ "organizationId",
3589
+ "organizationGeneration",
3590
+ "members",
3591
+ "nextCursor"
3592
+ ]) || value.applicationId !== input.applicationId || value.organizationId !== input.organizationId || value.organizationGeneration !== input.organizationGeneration || !Array.isArray(value.members) || value.members.length > (input.limit ?? 50)) throw authorityUnavailable();
3593
+ const members = value.members.map((item) => {
3594
+ if (!exact$6(item, [
3595
+ "user",
3596
+ "role",
3597
+ "membershipStatus"
3598
+ ]) || item.role !== "owner" && item.role !== "admin" && item.role !== "member" || item.membershipStatus !== "active" && item.membershipStatus !== "suspended") throw authorityUnavailable();
3599
+ const normalized = user(item.user, input.applicationId);
3600
+ if (normalized.lifecycle === "deleted") throw authorityUnavailable();
3601
+ return {
3602
+ user: normalized,
3603
+ role: item.role,
3604
+ membershipStatus: item.membershipStatus
3605
+ };
3606
+ });
3607
+ if (new Set(members.map((item) => item.user.userId)).size !== members.length) throw authorityUnavailable();
3608
+ return {
3609
+ applicationId: input.applicationId,
3610
+ organizationId: input.organizationId,
3611
+ organizationGeneration: input.organizationGeneration,
3612
+ members,
3613
+ nextCursor: nextCursor(value.nextCursor)
3614
+ };
3615
+ },
3616
+ async resolveUser(input, assertion) {
3617
+ if (!exact$6(input, ["applicationId", "authUserId"]) || !directoryId(input.applicationId) || !directoryId(input.authUserId)) throw new AuthError("invalid_request", 400);
3618
+ const value = await exchange("resolve", input, assertion);
3619
+ if (!exact$6(value, ["user"])) throw authorityUnavailable();
3620
+ const result = value.user === null ? null : user(value.user, input.applicationId);
3621
+ if (result?.lifecycle === "deleted") throw authorityUnavailable();
3622
+ return result;
3623
+ },
3624
+ async resolveUserBinding(input, assertion) {
3625
+ exactInput(input);
3626
+ const value = await exchange("binding", input, assertion);
3627
+ if (!exact$6(value, ["binding"])) throw authorityUnavailable();
3628
+ if (value.binding === null) return null;
3629
+ if (!exact$6(value.binding, ["user", "authUserId"]) || !directoryId(value.binding.authUserId)) throw authorityUnavailable();
3630
+ const result = selectedUser(value.binding.user, input);
3631
+ if (result.lifecycle === "deleted") throw authorityUnavailable();
3632
+ return {
3633
+ user: result,
3634
+ authUserId: value.binding.authUserId
3635
+ };
3636
+ }
3637
+ };
3638
+ }
3639
+ //#endregion
3333
3640
  //#region src/server.ts
3334
3641
  const MAX_AUTHORIZATION_BYTES = 16 * 1024;
3335
3642
  function createServerAuth(options) {
@@ -3525,6 +3832,37 @@ function createServerAuth(options) {
3525
3832
  const member = normalizeIdInput(memberId);
3526
3833
  return organizationRead(`${organization}/members/${member}/authority`, void 0, (value) => normalizeOrganizationMemberAuthority(value, organization, member));
3527
3834
  },
3835
+ async getOrganizationApplicationRegistration(organizationId, applicationId) {
3836
+ if (authorization) throw new AuthError("state_conflict", 409);
3837
+ const path = registrationTarget(organizationId, applicationId);
3838
+ return normalizeOrganizationApplicationRegistration(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", path), {
3839
+ fetch: fetchImpl,
3840
+ timeoutMs,
3841
+ method: "GET",
3842
+ credentials: "include",
3843
+ cache: "no-store",
3844
+ headers: authHeaders(true),
3845
+ mapError: fromOrganizationReadAuthorityError
3846
+ }), organizationId, applicationId);
3847
+ },
3848
+ async registerOrganizationApplication(organizationId, applicationId, input) {
3849
+ if (authorization) throw new AuthError("state_conflict", 409);
3850
+ const path = registrationTarget(organizationId, applicationId);
3851
+ const body = registrationInput(input);
3852
+ return normalizeRegisteredOrganizationApplication(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", path), {
3853
+ fetch: fetchImpl,
3854
+ timeoutMs,
3855
+ method: "POST",
3856
+ credentials: "include",
3857
+ cache: "no-store",
3858
+ headers: {
3859
+ ...authHeaders(true),
3860
+ "content-type": "application/json"
3861
+ },
3862
+ body,
3863
+ mapError: fromOrganizationMutationAuthorityError
3864
+ }), organizationId, applicationId, body.organizationGeneration);
3865
+ },
3528
3866
  async createOrganization(name, slug, idempotencyKey) {
3529
3867
  const body = normalizeOrganizationCreationInput(name, slug, idempotencyKey);
3530
3868
  return normalizeCreatedOrganization(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations"), {
@@ -3859,4 +4197,4 @@ function authAuthorizationHeader(value) {
3859
4197
  return value;
3860
4198
  }
3861
4199
  //#endregion
3862
- export { AuthError, createAccountProductOperationAuth, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createServerAuth, createUserApiVerifier };
4200
+ export { AuthError, createAccountProductOperationAuth, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createMembershipResolverAuth, createOrganizationDirectoryAuth, createServerAuth, createUserApiVerifier, createUserDirectoryAuth };