UNPKG

@basetime/a2w-api-ts

Version:

Client library that communicates with the addtowallet API.

1,542 lines (1,528 loc) 673 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ApiError: () => ApiError, ApiKeySchema: () => ApiKeySchema, AttributeItemSchema: () => AttributeItemSchema, AttributeTypeSchema: () => AttributeTypeSchema, AttributesSchema: () => AttributesSchema, AuthedSchema: () => AuthedSchema, BarcodeRenderInputSchema: () => BarcodeRenderInputSchema, BarcodeTypeSchema: () => BarcodeTypeSchema, BarcodesEndpoint: () => BarcodesEndpoint, BaseAuthProvider: () => BaseAuthProvider, CampaignClaimsEndpoint: () => CampaignClaimsEndpoint, CampaignEnrollmentsEndpoint: () => CampaignEnrollmentsEndpoint, CampaignJobsEndpoint: () => CampaignJobsEndpoint, CampaignPassesEndpoint: () => CampaignPassesEndpoint, CampaignSchema: () => CampaignSchema, CampaignStatsEndpoint: () => CampaignStatsEndpoint, CampaignStatsSchema: () => CampaignStatsSchema, CampaignWalletEnrollmentResponseSchema: () => CampaignWalletEnrollmentResponseSchema, CampaignWalletsEndpoint: () => CampaignWalletsEndpoint, CampaignWalletsResponseSchema: () => CampaignWalletsResponseSchema, CampaignWorkflowInputSchema: () => CampaignWorkflowInputSchema, CampaignWorkflowRunsWhenSchema: () => CampaignWorkflowRunsWhenSchema, CampaignWorkflowSchema: () => CampaignWorkflowSchema, CampaignWorkflowsEndpoint: () => CampaignWorkflowsEndpoint, CampaignsEndpoint: () => CampaignsEndpoint, ClaimSchema: () => ClaimSchema, ClaimsEndpoint: () => ClaimsEndpoint, Client: () => Client, DEFAULT_BASE_URL: () => DEFAULT_BASE_URL, DailyStatsSchema: () => DailyStatsSchema, DataStoreInputSchema: () => DataStoreInputSchema, DataStoreKeyValueSchema: () => DataStoreKeyValueSchema, DataStoreSchema: () => DataStoreSchema, DataStoreSourceSchema: () => DataStoreSourceSchema, DetailedStatsSchema: () => DetailedStatsSchema, DomainSchema: () => DomainSchema, Endpoint: () => Endpoint, EnrollmentResponseSchema: () => EnrollmentResponseSchema, EnrollmentSchema: () => EnrollmentSchema, ExporterInputSchema: () => ExporterInputSchema, ExporterLogSchema: () => ExporterLogSchema, ExporterLogStatusSchema: () => ExporterLogStatusSchema, ExporterSchema: () => ExporterSchema, ExporterSourceSchema: () => ExporterSourceSchema, ExporterWhenSchema: () => ExporterWhenSchema, GoogleTemplateSchema: () => GoogleTemplateSchema, HttpRequester: () => HttpRequester, ImageSchema: () => ImageSchema, ImagesEndpoint: () => ImagesEndpoint, JobModeSchema: () => JobModeSchema, JobSchema: () => JobSchema, JobStatusSchema: () => JobStatusSchema, KeysProvider: () => KeysProvider, MetaValueSchema: () => MetaValueSchema, MetaValuesSchema: () => MetaValuesSchema, OAuthProvider: () => OAuthProvider, OrganizationDataStoresEndpoint: () => OrganizationDataStoresEndpoint, OrganizationExportersEndpoint: () => OrganizationExportersEndpoint, OrganizationSchema: () => OrganizationSchema, OrganizationWebhooksEndpoint: () => OrganizationWebhooksEndpoint, OrganizationsEndpoint: () => OrganizationsEndpoint, PassSchema: () => PassSchema, ScannerAppSchema: () => ScannerAppSchema, ScannerDeviceInfoSchema: () => ScannerDeviceInfoSchema, ScannerInviteSchema: () => ScannerInviteSchema, ScannerLogSchema: () => ScannerLogSchema, ScannersEndpoint: () => ScannersEndpoint, ScheduleSchema: () => ScheduleSchema, ScheduleWhenSchema: () => ScheduleWhenSchema, SnippetLibrarySchema: () => SnippetLibrarySchema, StoredProvider: () => StoredProvider, TOKEN_SKEW_SECONDS: () => TOKEN_SKEW_SECONDS, TaskSchema: () => TaskSchema, TemplateAttributeSchema: () => TemplateAttributeSchema, TemplateAttributeTypeSchema: () => TemplateAttributeTypeSchema, TemplateAttributesSchema: () => TemplateAttributesSchema, TemplateSchema: () => TemplateSchema, TemplateThumbnailSchema: () => TemplateThumbnailSchema, TemplatesEndpoint: () => TemplatesEndpoint, UserSchema: () => UserSchema, WalletUpdateReasonSchema: () => WalletUpdateReasonSchema, WalletUpdateSchema: () => WalletUpdateSchema, WebhookEventSchema: () => WebhookEventSchema, WebhookInputSchema: () => WebhookInputSchema, WebhookLogSchema: () => WebhookLogSchema, WebhookSchema: () => WebhookSchema, WidgetsEndpoint: () => WidgetsEndpoint, WorkflowJobSchema: () => WorkflowJobSchema, WorkflowJobStatusSchema: () => WorkflowJobStatusSchema, WorkflowJobsEndpoint: () => WorkflowJobsEndpoint, WorkflowMessageSchema: () => WorkflowMessageSchema, WorkflowSchema: () => WorkflowSchema, WorkflowsEndpoint: () => WorkflowsEndpoint, parseAuthed: () => parseAuthed }); module.exports = __toCommonJS(src_exports); // src/version.ts var version = "2.0.1"; // src/NoopLogger.ts var NoopLogger = class { /** * @inheritDoc */ debug(message, meta3) { } /** * @inheritDoc */ info(message, meta3) { } /** * @inheritDoc */ error(message, meta3) { } }; // src/constants.ts var DEFAULT_BASE_URL = "https://app.addtowallet.io/api/v1"; // src/http/ApiError.ts var ApiError = class extends Error { /** * The HTTP status code returned by the API. */ status; /** * The HTTP status text returned by the API. */ statusText; /** * The parsed response body. JSON-decoded when the response was JSON, raw string * otherwise. */ body; /** * The absolute URL of the failing request (after base URL resolution and * `?api=true` injection). */ url; /** * Constructor. * * @param status The HTTP status code. * @param statusText The HTTP status text. * @param body The parsed response body. * @param url The absolute URL of the request. * @param options Optional `cause` field for chaining underlying errors. */ constructor(status, statusText, body, url2, options) { const detail = extractDetail(body) ?? statusText; super(`${status} ${detail} (${url2})`); this.name = "ApiError"; this.status = status; this.statusText = statusText; this.body = body; this.url = url2; if (options && "cause" in options) { this.cause = options.cause; } } }; var extractDetail = (body) => { if (!body || typeof body !== "object") { if (typeof body === "string" && body.length > 0) { return body; } return void 0; } const record2 = body; if (typeof record2.error === "string") { return record2.error; } if (typeof record2.message === "string") { return record2.message; } return void 0; }; // src/http/HttpRequester.ts var HttpRequester = class { /** * The authentication object. * * Exposed via a read-only getter. Use {@link setAuth} to change it so the logger and * base URL are wired into the new provider. */ _auth; /** * The logger. */ logger; /** * The user agent string. */ userAgent = ""; /** * The API base URL (e.g. `https://app.addtowallet.io/api/v1`). */ baseUrl; /** * The derived site base URL (the API base URL with a trailing `/api/v1` stripped). * * Used by `siteRoot`-mode endpoints like `BarcodesEndpoint` and `WidgetsEndpoint` * to target routes mounted outside `/api/v1`. */ siteBaseUrl; /** * Constructor. * * @param auth The authentication provider. * @param logger The logger to use. * @param options Additional options (currently just `baseUrl`). */ constructor(auth, logger, options = {}) { this.logger = logger || new NoopLogger(); this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL; this.siteBaseUrl = deriveSiteBaseUrl(this.baseUrl); if (auth) { this.setAuth(auth); } } /** * The authentication provider currently in use. * * Read-only from outside the class; assignment is a TypeScript error. Use * {@link setAuth} to change it. */ get auth() { return this._auth; } /** * @inheritdoc */ setBaseUrl = (url2) => { this.baseUrl = url2; this.siteBaseUrl = deriveSiteBaseUrl(url2); if (this._auth) { this._auth.setBaseUrl(url2); } }; /** * @inheritdoc */ getBaseUrl = () => { return this.baseUrl; }; /** * @inheritdoc */ getSiteBaseUrl = () => { return this.siteBaseUrl; }; /** * @inheritdoc */ setAuth = (auth) => { this._auth = auth; auth.setLogger(this.logger); auth.setBaseUrl(this.baseUrl); }; /** * @inheritdoc */ setUserAgent = (userAgent) => { this.userAgent = userAgent; }; /** * @inheritdoc */ getLogger = () => { return this.logger; }; /** * @inheritdoc */ doGet = async (url2, authenticate = true) => { return await this.fetch(url2, { method: "GET" }, authenticate); }; /** * @inheritdoc */ doPost = async (url2, body, authenticate = true) => { return await this.fetch( url2, { method: "POST", body: JSON.stringify(body) }, authenticate ); }; /** * @inheritdoc */ doPut = async (url2, body, authenticate = true) => { return await this.fetch( url2, { method: "PUT", body: JSON.stringify(body) }, authenticate ); }; /** * @inheritdoc */ doDelete = async (url2, authenticate = true, body = void 0) => { const options = { method: "DELETE" }; if (body !== void 0) { options.body = JSON.stringify(body); } return await this.fetch(url2, options, authenticate); }; /** * @inheritdoc * * When `url` is a fully-qualified URL (starts with `http://` or `https://`) it is used * as-is without prepending the configured API base URL and without injecting the * `api=true` marker. This lets endpoint helpers target routes that live outside * `/api/v1` (e.g. `/barcodes`, `/widgets`) while still benefiting from the shared * header, auth, and error-handling logic. * * On a 401 response and when an auth provider is configured, the request is retried * once after `auth.refresh()` succeeds; further 401s are surfaced as `ApiError`s. */ fetch = async (url2, options = {}, authenticate = true) => { return this.fetchInternal(url2, options, authenticate, false); }; /** * Internal implementation of {@link fetch} that tracks whether the current call is * already a 401 retry, so we never recurse more than once. * * @param url The url to send the request to. * @param options The fetch options. * @param authenticate Whether to authenticate the request. * @param isRetry Whether this is the 401-recovery retry pass. */ fetchInternal = async (url2, options, authenticate, isRetry) => { const resolvedUrl = this.resolveUrl(url2); const headers = await this.buildHeaders(options, authenticate); const opts = { ...options, headers }; this.logger.debug( `${(options == null ? void 0 : options.method) || "GET"} ${resolvedUrl}, ${authenticate ? "authenticate" : "no authenticate"}, body: ${options.body ? JSON.stringify(options.body) : "none"}` ); const resp = await fetch(resolvedUrl, opts); if (resp.ok) { if (headers.get("Accept") === "application/json") { return await resp.json(); } return await resp.text(); } if (resp.status === 401 && authenticate && this._auth && !isRetry) { this.logger.debug(`401 from ${resolvedUrl}, attempting token refresh`); try { await this._auth.refresh(); } catch (err) { this.logger.error(`Token refresh failed: ${err.message ?? err}`); } return this.fetchInternal(url2, options, authenticate, true); } const rawBody = await resp.text(); let parsedBody = rawBody; let parseError; try { parsedBody = JSON.parse(rawBody); } catch (err) { parseError = err; } throw new ApiError(resp.status, resp.statusText, parsedBody, resolvedUrl, { cause: parseError }); }; /** * Resolves a caller-supplied URL into the final absolute URL that will be sent. * * - Absolute URLs (`http://`/`https://`) are returned unchanged. * - Relative URLs are joined with {@link baseUrl}. * - The `api=true` marker is appended to the resolved URL's query string only when * it isn't already present. * * @param url The raw URL passed to {@link fetch}. */ resolveUrl = (url2) => { const isAbsolute = /^https?:\/\//i.test(url2); if (isAbsolute) { const parsed2 = new URL(url2); if (!parsed2.searchParams.has("api")) { parsed2.searchParams.set("api", "true"); } return parsed2.toString(); } const base = this.baseUrl.replace(/\/$/, ""); const path = url2.startsWith("/") ? url2 : `/${url2}`; const parsed = new URL(`${base}${path}`); if (!parsed.searchParams.has("api")) { parsed.searchParams.set("api", "true"); } return parsed.toString(); }; /** * Builds the headers for a single request: User-Agent, default Accept/Content-Type, * and (when applicable) Authorization. * * @param options The caller's fetch options. * @param authenticate Whether to attach the bearer token. */ buildHeaders = async (options, authenticate) => { const headers = options.headers ? new Headers(options.headers) : new Headers(); if (this.userAgent) { headers.set("User-Agent", this.userAgent); } else { headers.set("User-Agent", `a2w-api-ts/${version} (Node.js ${process.version})`); } if (!headers.has("Accept")) { headers.set("Accept", "application/json"); } const isStringBody = typeof options.body === "string" || options.body == null; if (!headers.has("Content-Type") && isStringBody) { headers.set("Content-Type", "application/json"); } if (authenticate && this._auth) { const authed = this._auth.getAuthed(); if (authed) { headers.set("Authorization", `Bearer ${authed.idToken}`); } else { const bearerToken = await this._auth.authenticate(); headers.set("Authorization", `Bearer ${bearerToken}`); } } return headers; }; }; var deriveSiteBaseUrl = (baseUrl) => { return baseUrl.replace(/\/api\/v1\/?$/, ""); }; // src/http/QueryBuilder.ts var UrlBuilder = class { /** * Constructor. * * @param template The raw path template, e.g. `/campaigns/{id}/passes`. Anything between * `{` and `}` is treated as a placeholder name that must be supplied via {@link addParam} * before {@link toString} is called. * @param resolvePrefix Optional resolver returning a prefix prepended at * {@link toString} time. Used by site-root endpoints to inject the requester's * current site base URL lazily. */ constructor(template, resolvePrefix) { this.template = template; this.resolvePrefix = resolvePrefix; } /** * Values for `{name}` placeholders in the path template, set via {@link addParam}. */ params = /* @__PURE__ */ new Map(); /** * Ordered list of query parameters set via {@link addQuery}. Order is preserved and * duplicate keys are permitted so callers can build `key=a&key=b` style strings. */ queries = []; /** * Records a value for a `{name}` placeholder in the path template. * * Values are coerced to string and URL-encoded at {@link toString} time, not now, so * later overrides win. * * @param key The placeholder name (without braces). * @param value The value to substitute. */ addParam = (key, value) => { this.params.set(key, String(value)); return this; }; /** * Appends a query parameter. * * Order of calls is preserved in the generated query string. Duplicate keys are allowed * and emitted as repeated `key=value` pairs. * * @param key The query parameter name. * @param value The query parameter value. */ addQuery = (key, value) => { this.queries.push([key, String(value)]); return this; }; /** * Renders the final URL. * * Replaces every `{name}` placeholder with its URL-encoded value, prepends the lazy * prefix when one was supplied, and appends the collected query parameters as a * `?k=v&...` suffix when any are present. * * @throws Error If the template references a placeholder that was never supplied via * {@link addParam}. */ toString = () => { const path = this.template.replace(/\{(\w+)\}/g, (_match, key) => { const value = this.params.get(key); if (value === void 0) { throw new Error(`QueryBuilder: missing value for placeholder '{${key}}' in template '${this.template}'`); } return encodeURIComponent(value); }); const prefix = this.resolvePrefix ? this.resolvePrefix() : ""; const full = `${prefix}${path}`; if (this.queries.length === 0) { return full; } const qs = this.queries.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&"); return `${full}?${qs}`; }; }; var QueryBuilder = class { /** * Constructor. * * @param baseUrl The static base URL prepended to every produced URL. Pass `''` to * produce a relative path (the default mode used by the SDK's `Endpoint` base class). * @param endpointPath The endpoint path appended after the base URL, e.g. `/campaigns`. * @param resolvePrefix Optional resolver returning a prefix prepended at * `UrlBuilder.toString()` time. When supplied, the resolver overrides the static * `baseUrl` for prefixing purposes. */ constructor(baseUrl, endpointPath, resolvePrefix) { this.baseUrl = baseUrl; this.endpointPath = endpointPath; this.resolvePrefix = resolvePrefix; } /** * Creates a new {@link UrlBuilder} for a path under the endpoint. * * The supplied `path` is appended verbatim to `${baseUrl}${endpointPath}` and may * contain `{name}` placeholders that are filled in via {@link UrlBuilder.addParam}. * * @param path The path fragment beneath the endpoint root, e.g. `/{id}/passes`. Defaults * to an empty string, which targets the endpoint root itself. */ create = (path = "") => { return new UrlBuilder( `${this.baseUrl}${this.endpointPath}${path}`, this.resolvePrefix ); }; }; // src/endpoint/EndpointDo.ts var EndpointDo = class { /** * Constructor. * * @param req The object to use to make requests. * @param endpointPath The path prefix prepended to every string URL passed to a verb * method, e.g. `/campaigns`. * @param resolvePrefix Optional resolver returning a prefix prepended at request * time (used by site-root endpoints to inject the requester's current site base * URL lazily, so a later `setBaseUrl(...)` is picked up). */ constructor(req, endpointPath, resolvePrefix) { this.req = req; this.endpointPath = endpointPath; this.resolvePrefix = resolvePrefix; } /** * Resolves a `string | UrlBuilder` into a plain URL string suitable for the requester. * * String paths are prefixed with `endpointPath` (and the optional resolved prefix); * builders are returned via `toString()` unchanged because they already carry the * prefix via the resolver passed to {@link UrlBuilder}. * * @param url The url or builder to resolve. */ resolve = (url2) => { if (typeof url2 !== "string") { return url2.toString(); } const prefix = this.resolvePrefix ? this.resolvePrefix() : ""; return `${prefix}${this.endpointPath}${url2}`; }; /** * Validates a raw response against an optional Zod schema, logging mismatches. * * @param raw The raw response payload. * @param schema The schema to validate against, when one was supplied. * @param url The URL the response came from (for log context). */ validate = (raw, schema, url2) => { if (!schema) { return raw; } const result = schema.safeParse(raw); if (result.success) { return result.data; } this.req.getLogger().error("Response shape mismatch", { url: url2, issues: result.error.issues }); return raw; }; /** * Makes a GET request to a path relative to the endpoint root. * * @param url Path string (prepended with the endpoint root) or a pre-built UrlBuilder. * @param schema Optional Zod schema to validate the response against. * @param authenticate Whether to authenticate the request. */ get = async (url2, schema, authenticate = true) => { const resolved = this.resolve(url2); const raw = await this.req.doGet(resolved, authenticate); return this.validate(raw, schema, resolved); }; /** * Makes a POST request to a path relative to the endpoint root. * * @param url Path string (prepended with the endpoint root) or a pre-built UrlBuilder. * @param body The body to send. Serialised to JSON by the underlying requester. * @param schema Optional Zod schema to validate the response against. * @param authenticate Whether to authenticate the request. */ post = async (url2, body, schema, authenticate = true) => { const resolved = this.resolve(url2); const raw = await this.req.doPost(resolved, body, authenticate); return this.validate(raw, schema, resolved); }; /** * Makes a PUT request to a path relative to the endpoint root. * * @param url Path string (prepended with the endpoint root) or a pre-built UrlBuilder. * @param body The body to send. Serialised to JSON by the underlying requester. * @param schema Optional Zod schema to validate the response against. * @param authenticate Whether to authenticate the request. */ put = async (url2, body, schema, authenticate = true) => { const resolved = this.resolve(url2); const raw = await this.req.doPut(resolved, body, authenticate); return this.validate(raw, schema, resolved); }; /** * Makes a DELETE request to a path relative to the endpoint root. * * The body is optional; when supplied it is sent as JSON, otherwise the request goes * out without one. * * @param url Path string (prepended with the endpoint root) or a pre-built UrlBuilder. * @param schema Optional Zod schema to validate the response against. * @param authenticate Whether to authenticate the request. * @param body The body to send. */ del = async (url2, schema, authenticate = true, body = void 0) => { const resolved = this.resolve(url2); const raw = await this.req.doDelete(resolved, authenticate, body); return this.validate(raw, schema, resolved); }; /** * Makes a raw request with caller-supplied `RequestInit` options. * * Escape hatch for cases that don't fit the JSON-in / JSON-out shape of the verb * helpers — for example, a GET that needs a custom `Accept` header and returns a binary * payload as text. Schema validation is intentionally not applied here because the * response can be any media type. * * @param url Path string (prepended with the endpoint root) or a pre-built UrlBuilder. * @param options The fetch options. Defaults to an empty object (GET, default headers). * @param authenticate Whether to authenticate the request. */ fetch = async (url2, options = {}, authenticate = true) => { return await this.req.fetch(this.resolve(url2), options, authenticate); }; }; // src/endpoint/Endpoint.ts var Endpoint = class _Endpoint { /** * The object used to make requests. Same instance as the parent's when the subclass * was constructed via `super(parent)`. */ req; /** * Verb wrapper bound to this endpoint's path. Subclasses call `this.do.get('/foo')`, * etc.; the wrapper handles prefixing and delegation to the requester. */ do; /** * Fluent URL builder rooted at this endpoint's path. Produces relative URLs * (e.g. `/campaigns/abc/passes?sort=desc`) for API-rooted endpoints, or absolute * URLs starting with the requester's site base URL for `siteRoot` endpoints. */ qb; /** * Constructor. * * Accepts either a {@link Requester} + path (for top-level endpoints) or a parent * {@link Endpoint} (for sub-endpoints that share their parent's path prefix). * * @param reqOrParent The requester (top-level) or parent endpoint (sub-endpoint). * @param endpointPath The path prefix shared by `this.do` and `this.qb`, * e.g. `/campaigns`. Required when `reqOrParent` is a `Requester`. * @param options Additional options (currently just `siteRoot`). */ constructor(reqOrParent, endpointPath, options) { if (reqOrParent instanceof _Endpoint) { this.req = reqOrParent.req; this.do = reqOrParent.do; this.qb = reqOrParent.qb; return; } if (endpointPath === void 0) { throw new Error("Endpoint: endpointPath is required when constructing from a Requester"); } const siteRoot = (options == null ? void 0 : options.siteRoot) ?? false; this.req = reqOrParent; const resolvePrefix = siteRoot ? () => reqOrParent.getSiteBaseUrl() : void 0; this.do = new EndpointDo(reqOrParent, endpointPath, resolvePrefix); this.qb = new QueryBuilder("", endpointPath, resolvePrefix); } }; // src/endpoint/BarcodesEndpoint.ts var BarcodesEndpoint = class extends Endpoint { /** * Constructor. * * @param req The object to use to make requests. */ constructor(req) { super(req, "/barcodes", { siteRoot: true }); } /** * Renders a barcode and returns the PNG body as a string. * * The body is returned via `Response.text()` to match the SDK's existing pkpass * download convention. Consumers that need the binary buffer should call the URL * directly via `client.http.fetch(...)` with a custom `Accept` header. * * @param input The barcode render input. */ render = async (input) => { const url2 = this.qb.create("").addQuery("type", input.type).addQuery("data", input.data); if (input.width !== void 0) { url2.addQuery("width", input.width); } if (input.height !== void 0) { url2.addQuery("height", input.height); } if (input.color !== void 0) { url2.addQuery("color", input.color); } if (input.background !== void 0) { url2.addQuery("background", input.background); } return await this.do.fetch( url2, { method: "GET", headers: { Accept: "image/png" } }, false ); }; }; // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js var external_exports = {}; __export(external_exports, { $brand: () => $brand, $input: () => $input, $output: () => $output, NEVER: () => NEVER, TimePrecision: () => TimePrecision, ZodAny: () => ZodAny, ZodArray: () => ZodArray, ZodBase64: () => ZodBase64, ZodBase64URL: () => ZodBase64URL, ZodBigInt: () => ZodBigInt, ZodBigIntFormat: () => ZodBigIntFormat, ZodBoolean: () => ZodBoolean, ZodCIDRv4: () => ZodCIDRv4, ZodCIDRv6: () => ZodCIDRv6, ZodCUID: () => ZodCUID, ZodCUID2: () => ZodCUID2, ZodCatch: () => ZodCatch, ZodCodec: () => ZodCodec, ZodCustom: () => ZodCustom, ZodCustomStringFormat: () => ZodCustomStringFormat, ZodDate: () => ZodDate, ZodDefault: () => ZodDefault, ZodDiscriminatedUnion: () => ZodDiscriminatedUnion, ZodE164: () => ZodE164, ZodEmail: () => ZodEmail, ZodEmoji: () => ZodEmoji, ZodEnum: () => ZodEnum, ZodError: () => ZodError, ZodExactOptional: () => ZodExactOptional, ZodFile: () => ZodFile, ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind, ZodFunction: () => ZodFunction, ZodGUID: () => ZodGUID, ZodIPv4: () => ZodIPv4, ZodIPv6: () => ZodIPv6, ZodISODate: () => ZodISODate, ZodISODateTime: () => ZodISODateTime, ZodISODuration: () => ZodISODuration, ZodISOTime: () => ZodISOTime, ZodIntersection: () => ZodIntersection, ZodIssueCode: () => ZodIssueCode, ZodJWT: () => ZodJWT, ZodKSUID: () => ZodKSUID, ZodLazy: () => ZodLazy, ZodLiteral: () => ZodLiteral, ZodMAC: () => ZodMAC, ZodMap: () => ZodMap, ZodNaN: () => ZodNaN, ZodNanoID: () => ZodNanoID, ZodNever: () => ZodNever, ZodNonOptional: () => ZodNonOptional, ZodNull: () => ZodNull, ZodNullable: () => ZodNullable, ZodNumber: () => ZodNumber, ZodNumberFormat: () => ZodNumberFormat, ZodObject: () => ZodObject, ZodOptional: () => ZodOptional, ZodPipe: () => ZodPipe, ZodPrefault: () => ZodPrefault, ZodPreprocess: () => ZodPreprocess, ZodPromise: () => ZodPromise, ZodReadonly: () => ZodReadonly, ZodRealError: () => ZodRealError, ZodRecord: () => ZodRecord, ZodSet: () => ZodSet, ZodString: () => ZodString, ZodStringFormat: () => ZodStringFormat, ZodSuccess: () => ZodSuccess, ZodSymbol: () => ZodSymbol, ZodTemplateLiteral: () => ZodTemplateLiteral, ZodTransform: () => ZodTransform, ZodTuple: () => ZodTuple, ZodType: () => ZodType, ZodULID: () => ZodULID, ZodURL: () => ZodURL, ZodUUID: () => ZodUUID, ZodUndefined: () => ZodUndefined, ZodUnion: () => ZodUnion, ZodUnknown: () => ZodUnknown, ZodVoid: () => ZodVoid, ZodXID: () => ZodXID, ZodXor: () => ZodXor, _ZodString: () => _ZodString, _default: () => _default2, _function: () => _function, any: () => any, array: () => array, base64: () => base642, base64url: () => base64url2, bigint: () => bigint2, boolean: () => boolean2, catch: () => _catch2, check: () => check, cidrv4: () => cidrv42, cidrv6: () => cidrv62, clone: () => clone, codec: () => codec, coerce: () => coerce_exports, config: () => config, core: () => core_exports2, cuid: () => cuid3, cuid2: () => cuid22, custom: () => custom, date: () => date3, decode: () => decode2, decodeAsync: () => decodeAsync2, describe: () => describe2, discriminatedUnion: () => discriminatedUnion, e164: () => e1642, email: () => email2, emoji: () => emoji2, encode: () => encode2, encodeAsync: () => encodeAsync2, endsWith: () => _endsWith, enum: () => _enum2, exactOptional: () => exactOptional, file: () => file, flattenError: () => flattenError, float32: () => float32, float64: () => float64, formatError: () => formatError, fromJSONSchema: () => fromJSONSchema, function: () => _function, getErrorMap: () => getErrorMap, globalRegistry: () => globalRegistry, gt: () => _gt, gte: () => _gte, guid: () => guid2, hash: () => hash, hex: () => hex2, hostname: () => hostname2, httpUrl: () => httpUrl, includes: () => _includes, instanceof: () => _instanceof, int: () => int, int32: () => int32, int64: () => int64, intersection: () => intersection, invertCodec: () => invertCodec, ipv4: () => ipv42, ipv6: () => ipv62, iso: () => iso_exports, json: () => json, jwt: () => jwt, keyof: () => keyof, ksuid: () => ksuid2, lazy: () => lazy, length: () => _length, literal: () => literal, locales: () => locales_exports, looseObject: () => looseObject, looseRecord: () => looseRecord, lowercase: () => _lowercase, lt: () => _lt, lte: () => _lte, mac: () => mac2, map: () => map, maxLength: () => _maxLength, maxSize: () => _maxSize, meta: () => meta2, mime: () => _mime, minLength: () => _minLength, minSize: () => _minSize, multipleOf: () => _multipleOf, nan: () => nan, nanoid: () => nanoid2, nativeEnum: () => nativeEnum, negative: () => _negative, never: () => never, nonnegative: () => _nonnegative, nonoptional: () => nonoptional, nonpositive: () => _nonpositive, normalize: () => _normalize, null: () => _null3, nullable: () => nullable, nullish: () => nullish2, number: () => number2, object: () => object, optional: () => optional, overwrite: () => _overwrite, parse: () => parse2, parseAsync: () => parseAsync2, partialRecord: () => partialRecord, pipe: () => pipe, positive: () => _positive, prefault: () => prefault, preprocess: () => preprocess, prettifyError: () => prettifyError, promise: () => promise, property: () => _property, readonly: () => readonly, record: () => record, refine: () => refine, regex: () => _regex, regexes: () => regexes_exports, registry: () => registry, safeDecode: () => safeDecode2, safeDecodeAsync: () => safeDecodeAsync2, safeEncode: () => safeEncode2, safeEncodeAsync: () => safeEncodeAsync2, safeParse: () => safeParse2, safeParseAsync: () => safeParseAsync2, set: () => set, setErrorMap: () => setErrorMap, size: () => _size, slugify: () => _slugify, startsWith: () => _startsWith, strictObject: () => strictObject, string: () => string2, stringFormat: () => stringFormat, stringbool: () => stringbool, success: () => success, superRefine: () => superRefine, symbol: () => symbol, templateLiteral: () => templateLiteral, toJSONSchema: () => toJSONSchema, toLowerCase: () => _toLowerCase, toUpperCase: () => _toUpperCase, transform: () => transform, treeifyError: () => treeifyError, trim: () => _trim, tuple: () => tuple, uint32: () => uint32, uint64: () => uint64, ulid: () => ulid2, undefined: () => _undefined3, union: () => union, unknown: () => unknown, uppercase: () => _uppercase, url: () => url, util: () => util_exports, uuid: () => uuid2, uuidv4: () => uuidv4, uuidv6: () => uuidv6, uuidv7: () => uuidv7, void: () => _void2, xid: () => xid2, xor: () => xor }); // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/index.js var core_exports2 = {}; __export(core_exports2, { $ZodAny: () => $ZodAny, $ZodArray: () => $ZodArray, $ZodAsyncError: () => $ZodAsyncError, $ZodBase64: () => $ZodBase64, $ZodBase64URL: () => $ZodBase64URL, $ZodBigInt: () => $ZodBigInt, $ZodBigIntFormat: () => $ZodBigIntFormat, $ZodBoolean: () => $ZodBoolean, $ZodCIDRv4: () => $ZodCIDRv4, $ZodCIDRv6: () => $ZodCIDRv6, $ZodCUID: () => $ZodCUID, $ZodCUID2: () => $ZodCUID2, $ZodCatch: () => $ZodCatch, $ZodCheck: () => $ZodCheck, $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat, $ZodCheckEndsWith: () => $ZodCheckEndsWith, $ZodCheckGreaterThan: () => $ZodCheckGreaterThan, $ZodCheckIncludes: () => $ZodCheckIncludes, $ZodCheckLengthEquals: () => $ZodCheckLengthEquals, $ZodCheckLessThan: () => $ZodCheckLessThan, $ZodCheckLowerCase: () => $ZodCheckLowerCase, $ZodCheckMaxLength: () => $ZodCheckMaxLength, $ZodCheckMaxSize: () => $ZodCheckMaxSize, $ZodCheckMimeType: () => $ZodCheckMimeType, $ZodCheckMinLength: () => $ZodCheckMinLength, $ZodCheckMinSize: () => $ZodCheckMinSize, $ZodCheckMultipleOf: () => $ZodCheckMultipleOf, $ZodCheckNumberFormat: () => $ZodCheckNumberFormat, $ZodCheckOverwrite: () => $ZodCheckOverwrite, $ZodCheckProperty: () => $ZodCheckProperty, $ZodCheckRegex: () => $ZodCheckRegex, $ZodCheckSizeEquals: () => $ZodCheckSizeEquals, $ZodCheckStartsWith: () => $ZodCheckStartsWith, $ZodCheckStringFormat: () => $ZodCheckStringFormat, $ZodCheckUpperCase: () => $ZodCheckUpperCase, $ZodCodec: () => $ZodCodec, $ZodCustom: () => $ZodCustom, $ZodCustomStringFormat: () => $ZodCustomStringFormat, $ZodDate: () => $ZodDate, $ZodDefault: () => $ZodDefault, $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion, $ZodE164: () => $ZodE164, $ZodEmail: () => $ZodEmail, $ZodEmoji: () => $ZodEmoji, $ZodEncodeError: () => $ZodEncodeError, $ZodEnum: () => $ZodEnum, $ZodError: () => $ZodError, $ZodExactOptional: () => $ZodExactOptional, $ZodFile: () => $ZodFile, $ZodFunction: () => $ZodFunction, $ZodGUID: () => $ZodGUID, $ZodIPv4: () => $ZodIPv4, $ZodIPv6: () => $ZodIPv6, $ZodISODate: () => $ZodISODate, $ZodISODateTime: () => $ZodISODateTime, $ZodISODuration: () => $ZodISODuration, $ZodISOTime: () => $ZodISOTime, $ZodIntersection: () => $ZodIntersection, $ZodJWT: () => $ZodJWT, $ZodKSUID: () => $ZodKSUID, $ZodLazy: () => $ZodLazy, $ZodLiteral: () => $ZodLiteral, $ZodMAC: () => $ZodMAC, $ZodMap: () => $ZodMap, $ZodNaN: () => $ZodNaN, $ZodNanoID: () => $ZodNanoID, $ZodNever: () => $ZodNever, $ZodNonOptional: () => $ZodNonOptional, $ZodNull: () => $ZodNull, $ZodNullable: () => $ZodNullable, $ZodNumber: () => $ZodNumber, $ZodNumberFormat: () => $ZodNumberFormat, $ZodObject: () => $ZodObject, $ZodObjectJIT: () => $ZodObjectJIT, $ZodOptional: () => $ZodOptional, $ZodPipe: () => $ZodPipe, $ZodPrefault: () => $ZodPrefault, $ZodPreprocess: () => $ZodPreprocess, $ZodPromise: () => $ZodPromise, $ZodReadonly: () => $ZodReadonly, $ZodRealError: () => $ZodRealError, $ZodRecord: () => $ZodRecord, $ZodRegistry: () => $ZodRegistry, $ZodSet: () => $ZodSet, $ZodString: () => $ZodString, $ZodStringFormat: () => $ZodStringFormat, $ZodSuccess: () => $ZodSuccess, $ZodSymbol: () => $ZodSymbol, $ZodTemplateLiteral: () => $ZodTemplateLiteral, $ZodTransform: () => $ZodTransform, $ZodTuple: () => $ZodTuple, $ZodType: () => $ZodType, $ZodULID: () => $ZodULID, $ZodURL: () => $ZodURL, $ZodUUID: () => $ZodUUID, $ZodUndefined: () => $ZodUndefined, $ZodUnion: () => $ZodUnion, $ZodUnknown: () => $ZodUnknown, $ZodVoid: () => $ZodVoid, $ZodXID: () => $ZodXID, $ZodXor: () => $ZodXor, $brand: () => $brand, $constructor: () => $constructor, $input: () => $input, $output: () => $output, Doc: () => Doc, JSONSchema: () => json_schema_exports, JSONSchemaGenerator: () => JSONSchemaGenerator, NEVER: () => NEVER, TimePrecision: () => TimePrecision, _any: () => _any, _array: () => _array, _base64: () => _base64, _base64url: () => _base64url, _bigint: () => _bigint, _boolean: () => _boolean, _catch: () => _catch, _check: () => _check, _cidrv4: () => _cidrv4, _cidrv6: () => _cidrv6, _coercedBigint: () => _coercedBigint, _coercedBoolean: () => _coercedBoolean, _coercedDate: () => _coercedDate, _coercedNumber: () => _coercedNumber, _coercedString: () => _coercedString, _cuid: () => _cuid, _cuid2: () => _cuid2, _custom: () => _custom, _date: () => _date, _decode: () => _decode, _decodeAsync: () => _decodeAsync, _default: () => _default, _discriminatedUnion: () => _discriminatedUnion, _e164: () => _e164, _email: () => _email, _emoji: () => _emoji2, _encode: () => _encode, _encodeAsync: () => _encodeAsync, _endsWith: () => _endsWith, _enum: () => _enum, _file: () => _file, _float32: () => _float32, _float64: () => _float64, _gt: () => _gt, _gte: () => _gte, _guid: () => _guid, _includes: () => _includes, _int: () => _int, _int32: () => _int32, _int64: () => _int64, _intersection: () => _intersection, _ipv4: () => _ipv4, _ipv6: () => _ipv6, _isoDate: () => _isoDate, _isoDateTime: () => _isoDateTime, _isoDuration: () => _isoDuration, _isoTime: () => _isoTime, _jwt: () => _jwt, _ksuid: () => _ksuid, _lazy: () => _lazy, _length: () => _length, _literal: () => _literal, _lowercase: () => _lowercase, _lt: () => _lt, _lte: () => _lte, _mac: () => _mac, _map: () => _map, _max: () => _lte, _maxLength: () => _maxLength, _maxSize: () => _maxSize, _mime: () => _mime, _min: () => _gte, _minLength: () => _minLength, _minSize: () => _minSize, _multipleOf: () => _multipleOf, _nan: () => _nan, _nanoid: () => _nanoid, _nativeEnum: () => _nativeEnum, _negative: () => _negative, _never: () => _never, _nonnegative: () => _nonnegative, _nonoptional: () => _nonoptional, _nonpositive: () => _nonpositive, _normalize: () => _normalize, _null: () => _null2, _nullable: () => _nullable, _number: () => _number, _optional: () => _optional, _overwrite: () => _overwrite, _parse: () => _parse, _parseAsync: () => _parseAsync, _pipe: () => _pipe, _positive: () => _positive, _promise: () => _promise, _property: () => _property, _readonly: () => _readonly, _record: () => _record, _refine: () => _refine, _regex: () => _regex, _safeDecode: () => _safeDecode, _safeDecodeAsync: () => _safeDecodeAsync, _safeEncode: () => _safeEncode, _safeEncodeAsync: () => _safeEncodeAsync, _safeParse: () => _safeParse, _safeParseAsync: () => _safeParseAsync, _set: () => _set, _size: () => _size, _slugify: () => _slugify, _startsWith: () => _startsWith, _string: () => _string, _stringFormat: () => _stringFormat, _stringbool: () => _stringbool, _success: () => _success, _superRefine: () => _superRefine, _symbol: () => _symbol, _templateLiteral: () => _templateLiteral, _toLowerCase: () => _toLowerCase, _toUpperCase: () => _toUpperCase, _transform: () => _transform, _trim: () => _trim, _tuple: () => _tuple, _uint32: () => _uint32, _uint64: () => _uint64, _ulid: () => _ulid, _undefined: () => _undefined2, _union: () => _union, _unknown: () => _unknown, _uppercase: () => _uppercase, _url: () => _url, _uuid: () => _uuid, _uuidv4: () => _uuidv4, _uuidv6: () => _uuidv6, _uuidv7: () => _uuidv7, _void: () => _void, _xid: () => _xid, _xor: () => _xor, clone: () => clone, config: () => config, createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod, createToJSONSchemaMethod: () => createToJSONSchemaMethod, decode: () => decode, decodeAsync: () => decodeAsync, describe: () => describe, encode: () => encode, encodeAsync: () => encodeAsync, extractDefs: () => extractDefs, finalize: () => finalize, flattenError: () => flattenError, formatError: () => formatError, globalConfig: () => globalConfig, globalRegistry: () => globalRegistry, initializeContext: () => initializeContext, isValidBase64: () => isValidBase64, isValidBase64URL: () => isValidBase64URL, isValidJWT: () => isValidJWT, locales: () => locales_exports, meta: () => meta, parse: () => parse, parseAsync: () => parseAsync, prettifyError: () => prettifyError, process: () => process2, regexes: () => regexes_exports, registry: () => registry, safeDecode: () => safeDecode, safeDecodeAsync: () => safeDecodeAsync, safeEncode: () => safeEncode, safeEncodeAsync: () => safeEncodeAsync, safeParse: () => safeParse, safeParseAsync: () => safeParseAsync, toDotPath: () => toDotPath, toJSONSchema: () => toJSONSchema, treeifyError: () => treeifyError, util: () => util_exports, version: () => version2 }); // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js var _a; var NEVER = /* @__PURE__ */ Object.freeze({ status: "aborted" }); // @__NO_SIDE_EFFECTS__ function $constructor(name, initializer3, params) { function init(inst, def) { if (!inst._zod) { Object.defineProperty(inst, "_zod", { value: { def, constr: _, traits: /* @__PURE__ */ new Set() }, enumerable: false }); } if (inst._zod.traits.has(name)) { return; } inst._zod.traits.add(name); initializer3(inst, def); const proto = _.prototype; const keys = Object.keys(proto); for (let i = 0; i < keys.length; i++) { const k = keys[i]; if (!(k in inst)) { inst[k] = proto[k].bind(inst); } } } const Parent = (params == null ? void 0 : params.Parent) ?? Object; class Definition extends Parent { } Object.defineProperty(Definition, "name", { value: name }); function _(def) { var _a3; const inst = (params == null ? void 0 : params.Parent) ? new Definition() : this; init(inst, def); (_a3 = inst._zod).deferred ?? (_a3.deferred = []); for (const fn of inst._zod.deferred) { fn(); } return inst; } Object.defineProperty(_, "init", { value: init }); Object.defineProperty(_, Symbol.hasInstance, { value: (inst) => { var _a3, _b; if ((params == null ? void 0 : params.Parent) && inst instanceof params.Parent) return true; return (_b = (_a3 = inst == null ? void 0 : inst._zod) == null ? void 0 : _a3.traits) == null ? void 0 : _b.has(name); } }); Object.defineProperty(_, "name", { value: name }); return _; } var $brand = Symbol("zod_brand"); var $ZodAsyncError = class extends Error { constructor() { super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`); } }; var $ZodEncodeError = class extends Error { constructor(name) { super(`Encountered unidirectional transform during encode: ${name}`); this.name = "ZodEncodeError"; } }; (_a = globalThis).__zod_globalConfig ?? (_a.__zod_globalConfig = {}); var globalConfig = globalThis.__zod_globalConfig; function config(newConfig) { if (newConfig) Object.assign(globalConfig, newConfig); return globalConfig; } // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js var util_exports = {}; __export(util_exports, { BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES, Class: () => Class, NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES, aborted: () => aborted, allowsEval: () => allowsEval, assert: () => assert, assertEqual: () => assertEqual, assertIs: () => assertIs, assertNever: () => assertNever, assertNotEqual: () => assertNotEqual, assignProp: () => assignProp, base64ToUint8Array: () => base64ToUint8Array, base64urlToUint8Array: () => base64urlToUint8Array, cached: () => cached, captureStackTrace: () => captureStackTrace, cleanEnum: () => cleanEnum, cleanRegex: () => cleanRegex, clone: () => clone, cloneDef: () => cloneDef, createTransparentProxy: () => createTransparentProxy, defineLazy: () => defineLazy, esc: () => esc, escapeRegex: () => escapeRegex, explicitlyAborted: () => explicitlyAborted, extend: () => extend, finalizeIssue: () => finalizeIssue, floatSafeRemainder: () => floatSafeRemainder, getElementAtPath: () => getElementAtPath, getEnumValues: () => getEnumValues, getLengthableOrigin: () => getLengthableOrigin, getParsedType: () => getParsedType, getSizableOrigin: () => getSizableOrigin, hexToUint8Array: () => hexToUint8Array, isObject: () => isObject, isPlainObject: () => isPlainObject, issue: () => issue, joinValues: () => joinValues, jsonStringifyReplacer: () => jsonStringifyReplacer, merge: () => merge, mergeDefs: () => mergeDefs, normalizeParams: () => normalizeParams, nullish: () => nullish, numKeys: () => numKeys, objectClone: () => objectClone, omit: () => omit, optionalKeys: () => optionalKeys, parsedType: () => parsedType, partial: () => partial, pick: () => pick, prefixIssues: () => prefixIssues, primitiveTypes: () => primitiveTypes, promiseAllObject: () => promiseAllObject, propertyKeyTypes: () => propertyKeyTypes, randomString: () => randomString, required: () => required, safeExtend: () => safeExtend, shallowClone: () => shallowClone, slugify: () => slugify, stringifyPrimitive: () => stringifyPrimitive, uint8ArrayToBase64: () => uint8ArrayToBase64, uint8ArrayToBase64url: () => uint8ArrayToBase64url, uint8ArrayToHex: () => uint8ArrayToHex, unwrapMessage: () => unwrapMessage }); function assertEqual(val) { return val; } function assertNotEqual(val) { return val; } function assertIs(_arg) { } function assertNever(_x) { throw new Error("Unexpected value in exhaustive check"); } function assert(_) { } function getEnumValues(entries) { const numericValues = Object.values(entries).filter((v) => typeof v === "number"); const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v); return values; } function joinValues(array2, separator = "|") { return array2.map((val) => stringifyPrimitive(val)).join(separator); } function jsonStringifyReplacer(_, value) { if (typeof value === "bigint") return value.toString(); return value; } function cached(getter) { const set2 = false; return { get value() { if (!set2) { const value = getter(); Object.defineProperty(this, "value", { value }); return value; } throw new Error("cached value already set"); } }; } function nullish(input) { return input === null || input === void 0; } function cleanRegex(source) { const start = source.startsWith("^") ? 1 : 0; const end = source.endsWith("$") ? source.length - 1 : source.length; return source.slice(start, end); } function floatSafeRemainder(val, step) { const ratio = val / step; const roundedRatio = Math.round(ratio); const tolerance = Number.EPSILON * Math.max(Math.abs(ratio), 1); if (Math.abs(ratio - roundedRatio) < tolerance) return 0; return ratio - roundedRatio; } var EVALUATING = /* @__PURE__ */ Symbol("evaluating"); function defineLazy(object2, key, getter) { let value = void 0; Object.defineProperty(object2, key, { get() { if (value === EVALUATING) { return void 0; } if (value === void 0) { value = EVALUATING; value = getter(); } return value; }, set(v) { Object.defineProperty(object2, key, { value: v // configurable: true, }); }, configurable: true }); } function objectClone(obj) { return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); } function assignProp(target, prop, value) { Object.defineProperty(target, prop, { value, writable: true, en