@nubase/core 0.1.13 → 0.1.15

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../frontend/src/http/http-client.ts","../../frontend/src/utils/network-errors.ts","../src/schema/schema.ts","../src/schema/nu.ts","../src/schema/empty-schema.ts","../src/schema/error-schema.ts","../src/schema/errors.ts","../src/schema/widget-data-schema.ts","../src/schema/widget-request-schema.ts"],"sourcesContent":["// Main entry point for @nubase/core\n\n// HTTP\nexport * from \"../../frontend/src/http/http-client\";\nexport * from \"./schema/empty-schema\";\nexport * from \"./schema/error-schema\";\nexport * from \"./schema/errors\";\nexport * from \"./schema/nu\";\nexport * from \"./schema/request-schema\";\nexport * from \"./schema/schema\";\n\n// Widget schemas\nexport * from \"./schema/widget-data-schema\";\nexport * from \"./schema/widget-request-schema\";\n","import axios, { AxiosError } from \"axios\";\nimport {\n ClientNetworkError,\n ServerNetworkError,\n} from \"../utils/network-errors\";\n\nexport interface HttpResponse<T = any> {\n status: number;\n data: T;\n}\n\nexport interface HttpRequestConfig {\n headers?: Record<string, string>;\n timeout?: number;\n params?: Record<string, any>;\n}\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor({ baseUrl = \"\" }: { baseUrl?: string }) {\n this.baseUrl = baseUrl;\n }\n\n private async request<T>(\n url: string,\n method: string,\n data?: any,\n config: HttpRequestConfig = {},\n ): Promise<HttpResponse<T>> {\n const fullUrl = this.baseUrl ? `${this.baseUrl}${url}` : url;\n\n try {\n const response = await axios({\n url: fullUrl,\n method,\n data,\n headers: config.headers,\n timeout: config.timeout,\n params: config.params,\n withCredentials: true, // Required for sending cookies in cross-origin requests\n });\n\n return {\n status: response.status,\n data: response.data,\n };\n } catch (error) {\n if (error instanceof AxiosError) {\n // Check if we have a response (server error) or no response (network error)\n if (error.response) {\n // Server responded with error status\n throw new ServerNetworkError(\n `Server error ${error.response.status} for ${method} ${url}: ${error.response.statusText}`,\n {\n endpoint: url,\n method,\n statusCode: error.response.status,\n responseText: error.response.statusText,\n responseData: error.response.data,\n },\n );\n }\n if (error.request) {\n // Request was made but no response received\n throw ClientNetworkError.fromNetworkFailure(error, {\n endpoint: url,\n method,\n });\n }\n // Something happened in setting up the request\n throw ClientNetworkError.fromNetworkFailure(error, {\n endpoint: url,\n method,\n });\n }\n // Re-throw non-axios errors\n throw error;\n }\n }\n\n async get<T>(\n url: string,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"GET\", undefined, config);\n }\n\n async post<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"POST\", data, config);\n }\n\n async put<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"PUT\", data, config);\n }\n\n async patch<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"PATCH\", data, config);\n }\n\n async delete<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"DELETE\", data, config);\n }\n}\n","import type { ZodError } from \"zod\";\n\nexport interface ParseErrorDetail {\n path: string;\n message: string;\n code: string;\n expected?: string;\n received?: string;\n}\n\nexport interface NetworkErrorOptions {\n endpoint: string;\n method: string;\n statusCode?: number;\n responseText?: string;\n}\n\n/**\n * Base class for all network-related errors\n */\nexport abstract class NetworkError extends Error {\n public readonly endpoint: string;\n public readonly method: string;\n public readonly timestamp: Date;\n\n constructor(message: string, options: NetworkErrorOptions) {\n super(message);\n this.name = this.constructor.name;\n this.endpoint = options.endpoint;\n this.method = options.method;\n this.timestamp = new Date();\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when client-side validation fails before making a network request\n */\nexport class ClientNetworkError extends NetworkError {\n // Custom inspect method for Node.js and some browser consoles\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.toJSON();\n }\n\n // For browsers that support console formatting\n get [Symbol.toStringTag]() {\n return JSON.stringify(this.toJSON(), null, 2);\n }\n public readonly phase:\n | \"request-validation\"\n | \"response-validation\"\n | \"network-failure\";\n public readonly parseErrors?: ParseErrorDetail[];\n public readonly originalError?: unknown;\n public readonly zodError?: ZodError;\n\n constructor(\n message: string,\n options: NetworkErrorOptions & {\n phase: \"request-validation\" | \"response-validation\" | \"network-failure\";\n parseErrors?: ParseErrorDetail[];\n originalError?: unknown;\n zodError?: ZodError;\n },\n ) {\n super(message, options);\n this.phase = options.phase;\n this.parseErrors = options.parseErrors;\n this.originalError = options.originalError;\n this.zodError = options.zodError;\n }\n\n toString(): string {\n const details = [];\n\n details.push(`${this.name}: ${this.message}`);\n details.push(` Endpoint: ${this.method} ${this.endpoint}`);\n details.push(` Phase: ${this.phase}`);\n details.push(` Timestamp: ${this.timestamp.toISOString()}`);\n\n if (this.zodError) {\n details.push(` Zod Error: ${this.zodError.toString()}`);\n if (this.zodError.issues.length > 0) {\n details.push(\" Validation Issues:\");\n this.zodError.issues.forEach((issue, index) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"root\";\n details.push(\n ` ${index + 1}. Path: ${path}, Message: ${issue.message}, Code: ${issue.code}`,\n );\n });\n }\n }\n\n if (this.parseErrors && this.parseErrors.length > 0) {\n details.push(\" Parse Errors:\");\n this.parseErrors.forEach((error, index) => {\n details.push(\n ` ${index + 1}. Path: ${error.path}, Message: ${error.message}, Code: ${error.code}`,\n );\n if (error.expected) details.push(` Expected: ${error.expected}`);\n if (error.received) details.push(` Received: ${error.received}`);\n });\n }\n\n if (this.originalError) {\n const errorStr =\n this.originalError instanceof Error\n ? this.originalError.toString()\n : String(this.originalError);\n details.push(` Original Error: ${errorStr}`);\n }\n\n return details.join(\"\\n\");\n }\n\n toJSON() {\n const result: any = {\n name: this.name,\n message: this.message,\n endpoint: this.endpoint,\n method: this.method,\n phase: this.phase,\n timestamp: this.timestamp.toISOString(),\n };\n\n if (this.zodError) {\n // Use the same beautiful format as ZodError\n result.zodError = this.zodError.issues;\n }\n\n if (this.parseErrors && this.parseErrors.length > 0) {\n result.parseErrors = this.parseErrors;\n }\n\n if (this.originalError) {\n result.originalError =\n this.originalError instanceof Error\n ? {\n name: this.originalError.name,\n message: this.originalError.message,\n }\n : this.originalError;\n }\n\n return result;\n }\n\n /**\n * Creates a ClientNetworkError for network failures (no response from server)\n */\n static fromNetworkFailure(\n error: unknown,\n options: NetworkErrorOptions,\n ): ClientNetworkError {\n const message =\n error instanceof Error\n ? `Network request failed for ${options.method} ${options.endpoint}: ${error.message}`\n : `Network request failed for ${options.method} ${options.endpoint}`;\n\n return new ClientNetworkError(message, {\n ...options,\n phase: \"network-failure\",\n originalError: error,\n });\n }\n}\n\n/**\n * Error thrown when the server returns an error response\n */\nexport class ServerNetworkError extends NetworkError {\n // Custom inspect method for Node.js and some browser consoles\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.toJSON();\n }\n\n // For browsers that support console formatting\n get [Symbol.toStringTag]() {\n return JSON.stringify(this.toJSON(), null, 2);\n }\n public readonly statusCode: number;\n public readonly responseText?: string;\n public readonly responseData?: unknown;\n\n constructor(\n message: string,\n options: NetworkErrorOptions & {\n statusCode: number;\n responseText?: string;\n responseData?: unknown;\n },\n ) {\n super(message, options);\n this.statusCode = options.statusCode;\n this.responseText = options.responseText;\n this.responseData = options.responseData;\n }\n\n toString(): string {\n const details = [];\n\n details.push(`${this.name}: ${this.message}`);\n details.push(` Endpoint: ${this.method} ${this.endpoint}`);\n details.push(` Status Code: ${this.statusCode}`);\n details.push(` Timestamp: ${this.timestamp.toISOString()}`);\n\n if (this.responseText) {\n details.push(` Response Text: ${this.responseText}`);\n }\n\n if (this.responseData) {\n try {\n const dataStr =\n typeof this.responseData === \"string\"\n ? this.responseData\n : JSON.stringify(this.responseData, null, 2);\n details.push(` Response Data: ${dataStr}`);\n } catch {\n details.push(` Response Data: ${String(this.responseData)}`);\n }\n }\n\n return details.join(\"\\n\");\n }\n\n toJSON() {\n const result: any = {\n name: this.name,\n message: this.message,\n endpoint: this.endpoint,\n method: this.method,\n statusCode: this.statusCode,\n timestamp: this.timestamp.toISOString(),\n };\n\n if (this.responseText) {\n result.responseText = this.responseText;\n }\n\n if (this.responseData) {\n result.responseData = this.responseData;\n }\n\n return result;\n }\n\n /**\n * Creates a ServerNetworkError from an HTTP response\n */\n static fromResponse(\n response: Response,\n responseText?: string,\n responseData?: unknown,\n ): ServerNetworkError {\n const message = `Server error ${response.status} for ${response.url}: ${response.statusText}`;\n\n return new ServerNetworkError(message, {\n endpoint: response.url,\n method: \"GET\", // Will be overridden by caller with actual method\n statusCode: response.status,\n responseText,\n responseData,\n });\n }\n\n /**\n * Checks if this is a specific type of server error\n */\n isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n isForbidden(): boolean {\n return this.statusCode === 403;\n }\n\n isServerError(): boolean {\n return this.statusCode >= 500;\n }\n\n isClientError(): boolean {\n return this.statusCode >= 400 && this.statusCode < 500;\n }\n}\n\n/**\n * Type guard to check if an error is a NetworkError\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError;\n}\n\n/**\n * Type guard to check if an error is a ClientNetworkError\n */\nexport function isClientNetworkError(\n error: unknown,\n): error is ClientNetworkError {\n return error instanceof ClientNetworkError;\n}\n\n/**\n * Type guard to check if an error is a ServerNetworkError\n */\nexport function isServerNetworkError(\n error: unknown,\n): error is ServerNetworkError {\n return error instanceof ServerNetworkError;\n}\n\n/**\n * Helper to get a user-friendly error message\n */\nexport function getNetworkErrorMessage(error: unknown): string {\n if (isClientNetworkError(error)) {\n if (error.phase === \"network-failure\") {\n return \"Unable to connect to the server. Please check your internet connection.\";\n }\n if (error.zodError && error.zodError.issues.length > 0) {\n const firstIssue = error.zodError.issues[0];\n if (firstIssue) {\n return `Validation error: ${firstIssue.message}`;\n }\n }\n if (error.parseErrors && error.parseErrors.length > 0) {\n const firstError = error.parseErrors[0];\n if (firstError) {\n return `Validation error: ${firstError.message}`;\n }\n }\n return error.message;\n }\n\n if (isServerNetworkError(error)) {\n if (error.isNotFound()) {\n return \"The requested resource was not found.\";\n }\n if (error.isUnauthorized()) {\n return \"You are not authorized to perform this action.\";\n }\n if (error.isServerError()) {\n return \"A server error occurred. Please try again later.\";\n }\n return error.message;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return \"An unexpected error occurred.\";\n}\n","import { z } from \"zod\";\n\n// Define metadata types\nexport interface SchemaMetadata<Output = any> {\n label?: string;\n description?: string;\n defaultValue?: Output;\n /**\n * Custom renderer identifier to override the default type-based rendering.\n * Examples: \"multiline\", \"email\", \"password\", \"url\"\n */\n renderer?: string;\n validateOnSubmit?: (value: any) => string | undefined;\n validateOnSubmitAsync?: (value: any) => Promise<string | undefined>;\n validateOnBlur?: (value: any) => string | undefined;\n validateOnBlurAsync?: (value: any) => Promise<string | undefined>;\n}\n\n// ComputedSchemaMetadata should have the same properties as SchemaMetadata but\n// the values should be functions that return the same types, but Promises.\nexport type ComputedSchemaMetadata<Output = any, Input = any> = {\n [K in keyof SchemaMetadata<Output>]: (\n input: Input,\n ) => Promise<SchemaMetadata<Output>[K]>;\n};\n\nexport abstract class BaseSchema<Output = any> {\n /**\n * Phantom property used for TypeScript type inference.\n * Does not exist at runtime.\n * @internal\n */\n readonly _outputType!: Output;\n\n /**\n * The type identifier for this schema.\n * Used for type-based form field rendering.\n */\n abstract readonly type: string;\n\n _meta: SchemaMetadata<Output> = {};\n\n /**\n * Replace the schema metadata with a new object.\n * @param meta The new metadata object.\n * @returns The schema instance for chaining.\n */\n withMeta(meta: SchemaMetadata<Output>): this {\n this._meta = meta;\n return this;\n }\n\n /**\n * Add metadata with validation functions to the schema.\n * @param meta The metadata object with validation functions.\n * @returns The schema instance for chaining.\n */\n withMetadata(meta: SchemaMetadata<Output>): this {\n this._meta = { ...this._meta, ...meta };\n return this;\n }\n\n /**\n * Makes this schema optional, allowing undefined values.\n * @returns An OptionalSchema wrapping this schema.\n */\n optional(): OptionalSchema<this> {\n return new OptionalSchema(this);\n }\n\n /**\n * Converts this nubase schema to a Zod schema.\n * @returns The equivalent Zod schema.\n */\n abstract toZod(): z.ZodSchema<Output>;\n}\n\n// --- Primitive Schemas ---\n\nexport class BooleanSchema extends BaseSchema<boolean> {\n readonly type = \"boolean\" as const;\n\n toZod(): z.ZodBoolean {\n return z.boolean();\n }\n}\n\nexport class StringSchema extends BaseSchema<string> {\n readonly type = \"string\" as const;\n // Add string-specific validation methods here (e.g., minLength, pattern)\n\n toZod(): z.ZodString {\n return z.string();\n }\n}\n\nexport class NumberSchema extends BaseSchema<number> {\n readonly type = \"number\" as const;\n // Add number-specific validation methods here (e.g., min, max)\n\n toZod(): z.ZodNumber {\n return z.number();\n }\n}\n\n// --- Optional Schema ---\n\n/**\n * A wrapper schema that makes the wrapped schema optional.\n * Allows undefined values in addition to the wrapped schema's type.\n */\nexport class OptionalSchema<\n TWrapped extends BaseSchema<any>,\n> extends BaseSchema<TWrapped[\"_outputType\"] | undefined> {\n readonly type = \"optional\" as const;\n _wrapped: TWrapped;\n\n constructor(wrapped: TWrapped) {\n super();\n this._wrapped = wrapped;\n }\n\n /**\n * Get the underlying wrapped schema.\n * @returns The wrapped schema.\n */\n unwrap(): TWrapped {\n return this._wrapped;\n }\n\n toZod(): z.ZodOptional<z.ZodNullable<z.ZodSchema<TWrapped[\"_outputType\"]>>> {\n return this._wrapped.toZod().nullable().optional();\n }\n}\n\n// --- Complex Schemas ---\n\n/**\n * Type representing the shape of an object schema (key to schema mapping).\n */\nexport type ObjectShape = {\n [key: string]: BaseSchema<any>;\n};\n\n/**\n * Infers the TypeScript output type from an ObjectShape.\n * Use mapped types to get the output type of each property schema.\n * Required keys are those that are not OptionalSchema instances.\n * Optional keys are those that are OptionalSchema instances.\n */\nexport type ObjectOutput<TShape extends ObjectShape> = {\n [K in keyof TShape as TShape[K] extends OptionalSchema<any>\n ? never\n : K]: TShape[K][\"_outputType\"];\n} & {\n [K in keyof TShape as TShape[K] extends OptionalSchema<any>\n ? K\n : never]?: TShape[K][\"_outputType\"];\n};\n\n/**\n * Type representing computed metadata for object properties.\n */\nexport type ObjectComputedMetadata<TShape extends ObjectShape> = {\n [K in keyof TShape]?: Partial<\n ComputedSchemaMetadata<TShape[K][\"_outputType\"], ObjectOutput<TShape>>\n >;\n};\n\n// --- Layout Types ---\n\n/**\n * Represents a field within a layout group.\n */\nexport interface FormLayoutField<TShape extends ObjectShape> {\n /** The name of the field - must be a valid property key from the object shape */\n name: keyof TShape;\n /** Width of the field in grid units (1-12) - number of 1/12 spaces it occupies */\n fieldWidth?: number;\n /** Additional CSS classes for styling */\n className?: string;\n /** Whether the field should be hidden */\n hidden?: boolean;\n}\n\n/**\n * Represents a group of fields within a layout.\n */\nexport interface LayoutGroup<TShape extends ObjectShape> {\n /** Label for the group */\n label?: string;\n /** Description for the group */\n description?: string;\n /** Array of fields in this group */\n fields: FormLayoutField<TShape>[];\n /** Additional CSS classes for the group */\n className?: string;\n /** Whether the group should be collapsible */\n collapsible?: boolean;\n /** Whether the group is initially collapsed (if collapsible) */\n defaultCollapsed?: boolean;\n}\n\n/**\n * Represents a complete layout configuration.\n */\nexport interface Layout<TShape extends ObjectShape> {\n /** Type of layout */\n type: \"form\" | \"grid\" | \"tabs\" | \"accordion\" | \"custom\" | \"table\";\n /** Groups of fields within the layout */\n groups: LayoutGroup<TShape>[];\n /** Additional CSS classes for the layout */\n className?: string;\n /** Layout-specific configuration */\n config?: {\n /** Number of columns for grid layouts */\n columns?: number;\n /** Gap between elements */\n gap?: string | number;\n /** Other layout-specific options */\n [key: string]: any;\n };\n /** Layout metadata - can contain any metadata, specific layouts may have specific metadata */\n metadata?: Record<string, any>;\n}\n\n/**\n * Form layout specific interface\n */\nexport interface FormLayout<TShape extends ObjectShape> extends Layout<TShape> {\n type: \"form\";\n groups: LayoutGroup<TShape>[];\n}\n\n/**\n * Table layout specific field\n */\nexport interface TableLayoutField<TShape extends ObjectShape> {\n /** The name of the field - must be a valid property key from the object shape */\n name: keyof TShape;\n /** Additional CSS classes for styling */\n className?: string;\n /** Whether the field should be hidden */\n hidden?: boolean;\n /** Column width in pixels - unlike fieldWidth, this is in pixels */\n columnWidthPx?: number;\n /** Whether the column should be pinned/frozen to the left */\n pinned?: boolean;\n}\n\n/**\n * Table layout specific interface\n */\nexport interface TableLayout<TShape extends ObjectShape>\n extends Layout<TShape> {\n type: \"table\";\n /** For tables, we only have one group internally but expose fields directly */\n groups: LayoutGroup<TShape>[];\n /** Table-specific metadata */\n metadata?: {\n /** Fields that should be clickable links to view the entity */\n linkFields?: (keyof TShape)[];\n /** Other metadata */\n [key: string]: any;\n };\n}\n\n/**\n * Type representing multiple layouts for an object schema.\n */\nexport type ObjectLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: Layout<TShape>;\n};\n\n/**\n * Type representing multiple form layouts\n */\nexport type FormLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: FormLayout<TShape>;\n};\n\n/**\n * Type representing multiple table layouts\n */\nexport type TableLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: TableLayout<TShape>;\n};\n\n/**\n * ObjectSchema with optional catchall.\n *\n * Note on typing: When using .catchall(), the output type remains ObjectOutput<TShape>.\n * TypeScript cannot express \"extra keys have type X\" without conflicting with defined keys.\n * The catchall provides runtime validation and passthrough behavior, but dynamic keys\n * should be accessed via type assertion: `(data as any).dynamicKey` or `data[\"dynamicKey\"]`.\n */\nexport class ObjectSchema<\n TShape extends ObjectShape = any,\n TCatchall extends BaseSchema<any> | null = null,\n> extends BaseSchema<ObjectOutput<TShape>> {\n readonly type = \"object\" as const;\n _shape: TShape;\n _computedMeta: ObjectComputedMetadata<TShape> = {};\n _layouts: ObjectLayouts<TShape> = {};\n _idField: keyof ObjectOutput<TShape> = \"id\" as keyof ObjectOutput<TShape>;\n _catchall: TCatchall = null as TCatchall;\n _passthrough = false;\n\n constructor(shape: TShape, catchall?: TCatchall) {\n super();\n this._shape = shape;\n if (catchall) {\n this._catchall = catchall;\n }\n }\n\n /**\n * Allow additional properties beyond the defined shape, validated against the provided schema.\n * Similar to Zod's .catchall() method.\n *\n * @example\n * const chartDataSchema = nu.object({ category: nu.string() }).catchall(nu.number());\n * // Validates: { category: \"Jan\", desktop: 186, mobile: 80 }\n *\n * @param schema The schema to validate additional properties against.\n * @returns A new ObjectSchema that allows additional properties.\n */\n catchall<TCatchallSchema extends BaseSchema<any>>(\n schema: TCatchallSchema,\n ): ObjectSchema<TShape, TCatchallSchema> {\n const newSchema = new ObjectSchema<TShape, TCatchallSchema>(\n this._shape,\n schema,\n );\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta } as any;\n newSchema._computedMeta = { ...this._computedMeta };\n newSchema._layouts = { ...this._layouts };\n newSchema._idField = this._idField;\n newSchema._passthrough = this._passthrough;\n\n return newSchema;\n }\n\n /**\n * Allow any additional properties beyond the defined shape without validation.\n * Similar to Zod's .passthrough() method.\n *\n * @example\n * const rowSchema = nu.object({}).passthrough();\n * // Validates: { user: \"John\", action: \"Created\", time: \"2m ago\" }\n *\n * @returns A new ObjectSchema that passes through additional properties.\n */\n passthrough(): ObjectSchema<TShape, TCatchall> {\n const newSchema = new ObjectSchema<TShape, TCatchall>(\n this._shape,\n this._catchall as TCatchall,\n );\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta } as any;\n newSchema._computedMeta = { ...this._computedMeta };\n newSchema._layouts = { ...this._layouts };\n newSchema._idField = this._idField;\n newSchema._passthrough = true;\n\n return newSchema;\n }\n\n /**\n * Add computed metadata to the object schema.\n * @param computedMeta Object mapping property keys to computed metadata functions.\n * @returns The schema instance for chaining.\n */\n withComputed(computedMeta: ObjectComputedMetadata<TShape>): this {\n this._computedMeta = computedMeta;\n return this;\n }\n\n /**\n * Add layouts to the object schema.\n * @param layouts Object mapping layout names to layout configurations.\n * @returns The schema instance for chaining.\n * @deprecated Use withFormLayouts or withTableLayouts instead\n */\n withLayouts(layouts: ObjectLayouts<TShape>): this {\n this._layouts = layouts;\n return this;\n }\n\n /**\n * Add form layouts to the object schema.\n * @param layouts Object mapping layout names to form layout configurations.\n * @returns The schema instance for chaining.\n */\n withFormLayouts(layouts: FormLayouts<TShape>): this {\n // Form layouts are stored directly in _layouts\n this._layouts = { ...this._layouts, ...layouts };\n return this;\n }\n\n /**\n * Add table layouts to the object schema.\n * @param layouts Object mapping layout names to table layout configurations with fields and optional linkFields.\n * @returns The schema instance for chaining.\n */\n withTableLayouts(layouts: {\n [layoutName: string]: {\n fields: TableLayoutField<TShape>[];\n className?: string;\n config?: Layout<TShape>[\"config\"];\n metadata?: {\n linkFields?: (keyof TShape)[];\n [key: string]: any;\n };\n };\n }): this {\n // Convert the table-specific format to internal Layout format\n const tableLayouts: TableLayouts<TShape> = {};\n\n for (const [name, tableConfig] of Object.entries(layouts)) {\n // Create a single group with all fields for internal consistency\n tableLayouts[name] = {\n type: \"table\",\n groups: [\n {\n fields: tableConfig.fields,\n },\n ],\n className: tableConfig.className,\n config: tableConfig.config,\n metadata: tableConfig.metadata,\n };\n }\n\n this._layouts = { ...this._layouts, ...tableLayouts };\n return this;\n }\n\n /**\n * Specify which field serves as the unique identifier for this object schema.\n * This is used by resource operations to determine how to identify specific records.\n * @param idField The field name or a selector function that returns the ID field.\n * @returns The schema instance for chaining.\n */\n withId<K extends keyof ObjectOutput<TShape>>(\n idField: K | ((schema: ObjectOutput<TShape>) => ObjectOutput<TShape>[K]),\n ): this {\n if (typeof idField === \"function\") {\n // For function form, we need to extract the field name\n // This is a bit tricky, but for now we'll assume the user passes the field name directly\n throw new Error(\n \"Function form of withId is not yet supported. Please pass the field name directly.\",\n );\n }\n this._idField = idField;\n return this;\n }\n\n /**\n * Get the ID field name for this object schema.\n * @returns The field name that serves as the unique identifier.\n */\n getIdField(): keyof ObjectOutput<TShape> {\n return this._idField;\n }\n\n /**\n * Get a specific layout by name.\n * @param layoutName The name of the layout to retrieve.\n * @returns The layout configuration or undefined if not found.\n */\n getLayout(layoutName: string): Layout<TShape> | undefined {\n return this._layouts[layoutName];\n }\n\n /**\n * Get all available layout names.\n * @returns Array of layout names.\n */\n getLayoutNames(): string[] {\n return Object.keys(this._layouts);\n }\n\n /**\n * Check if a layout exists.\n * @param layoutName The name of the layout to check.\n * @returns True if the layout exists, false otherwise.\n */\n hasLayout(layoutName: string): boolean {\n return layoutName in this._layouts;\n }\n\n /**\n * Get the computed metadata for a specific property.\n * @param key The property key.\n * @param data The parsed object data to pass to computed functions.\n * @returns Promise resolving to the computed metadata.\n */\n async getComputedMeta(\n key: keyof TShape,\n data: ObjectOutput<TShape>,\n ): Promise<Partial<SchemaMetadata<TShape[typeof key][\"_outputType\"]>>> {\n const computedMeta = this._computedMeta[key];\n if (!computedMeta) {\n return {};\n }\n\n const result: any = {};\n\n if (computedMeta.label) {\n result.label = await computedMeta.label(data);\n }\n\n if (computedMeta.description) {\n result.description = await computedMeta.description(data);\n }\n\n if (computedMeta.defaultValue) {\n result.defaultValue = await computedMeta.defaultValue(data);\n }\n\n return result;\n }\n\n /**\n * Get all computed metadata for all properties.\n * @param data The parsed object data to pass to computed functions.\n * @returns Promise resolving to a map of property keys to computed metadata.\n */\n async getAllComputedMeta(\n data: ObjectOutput<TShape>,\n ): Promise<Record<keyof TShape, Partial<SchemaMetadata<any>>>> {\n const result: any = {};\n\n for (const key in this._shape) {\n result[key] = await this.getComputedMeta(key, data);\n }\n\n return result;\n }\n\n /**\n * Get merged metadata (static + computed) for all properties.\n * @param data The current form data to pass to computed functions.\n * @returns Promise resolving to a map of property keys to merged metadata.\n */\n async getAllMergedMeta(\n data: Partial<ObjectOutput<TShape>>,\n ): Promise<Record<keyof TShape, SchemaMetadata<any>>> {\n const result: any = {};\n\n // Start with static metadata for each property\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n let schema = this._shape[key];\n if (schema) {\n // If it's an OptionalSchema, get the wrapped schema's metadata\n if (schema instanceof OptionalSchema) {\n schema = schema._wrapped;\n }\n result[key] = { ...(schema?._meta || {}) };\n }\n }\n }\n\n // Only compute if we have computed metadata and valid data\n if (Object.keys(this._computedMeta).length > 0) {\n try {\n // Try to create a complete object for computed functions\n // Use provided data and fill missing properties with default values\n const completeData: any = {};\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n const schema = this._shape[key];\n if (schema) {\n // If it's an OptionalSchema, use the wrapped schema for type checking\n const actualSchema =\n schema instanceof OptionalSchema ? schema._wrapped : schema;\n\n if ((data as any)[key] !== undefined) {\n completeData[key] = (data as any)[key];\n } else if (actualSchema._meta.defaultValue !== undefined) {\n completeData[key] = actualSchema._meta.defaultValue;\n } else {\n // Provide reasonable defaults for computation\n if (actualSchema instanceof StringSchema) {\n completeData[key] = \"\";\n } else if (actualSchema instanceof NumberSchema) {\n completeData[key] = 0;\n } else if (actualSchema instanceof BooleanSchema) {\n completeData[key] = false;\n } else {\n completeData[key] = null;\n }\n }\n }\n }\n }\n\n // Compute all metadata at once\n const computedMeta = await this.getAllComputedMeta(\n completeData as ObjectOutput<TShape>,\n );\n\n // Merge computed metadata with static metadata\n for (const key in computedMeta) {\n if (computedMeta[key]) {\n result[key] = {\n ...result[key],\n ...computedMeta[key],\n };\n }\n }\n } catch (error) {\n // If computation fails, just use static metadata\n console.warn(\"Failed to compute metadata:\", error);\n }\n }\n\n return result;\n }\n\n /**\n * Create a new ObjectSchema with certain properties omitted.\n * @param keys The property keys to omit from the schema.\n * @returns A new ObjectSchema without the specified properties.\n */\n omit<K extends keyof TShape>(...keys: K[]): ObjectSchema<Omit<TShape, K>> {\n const newShape: any = {};\n const keysToOmit = new Set(keys);\n\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && !keysToOmit.has(key as any)) {\n newShape[key] = this._shape[key];\n }\n }\n\n const newSchema = new ObjectSchema(newShape);\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta };\n\n // Copy computed metadata, excluding omitted keys\n const newComputedMeta: any = {};\n for (const key in this._computedMeta) {\n if (!keysToOmit.has(key as any)) {\n newComputedMeta[key] = this._computedMeta[key];\n }\n }\n newSchema._computedMeta = newComputedMeta;\n\n // Copy layouts, updating field references to exclude omitted keys\n const newLayouts: any = {};\n for (const layoutName in this._layouts) {\n const originalLayout = this._layouts[layoutName];\n if (originalLayout) {\n const newGroups = originalLayout.groups.map((group) => ({\n ...group,\n fields: group.fields.filter(\n (field) => !keysToOmit.has(field.name as any),\n ),\n }));\n newLayouts[layoutName] = {\n ...originalLayout,\n groups: newGroups,\n };\n }\n }\n newSchema._layouts = newLayouts;\n\n return newSchema;\n }\n\n /**\n * Create a new ObjectSchema with additional or modified properties.\n * @param shape The new properties to add or existing properties to modify.\n * @returns A new ObjectSchema with the extended shape.\n */\n extend<TExtend extends ObjectShape>(\n shape: TExtend,\n ): ObjectSchema<TShape & TExtend> {\n const newShape = { ...this._shape, ...shape } as TShape & TExtend;\n const newSchema = new ObjectSchema(newShape);\n\n // Copy metadata from parent schema (with proper typing)\n newSchema._meta = { ...this._meta } as any;\n\n // Copy computed metadata from parent schema (with proper typing)\n newSchema._computedMeta = { ...this._computedMeta } as any;\n\n // Copy layouts from parent schema - new fields won't appear in layouts unless explicitly added\n newSchema._layouts = { ...this._layouts } as any;\n\n return newSchema;\n }\n\n /**\n * Create a new ObjectSchema where all top-level properties become optional.\n * This wraps each field in an OptionalSchema, similar to how Zod handles partial.\n * @returns A new ObjectSchema where all properties are optional.\n */\n partial(): ObjectSchema<{ [K in keyof TShape]: OptionalSchema<TShape[K]> }> {\n const partialShape: any = {};\n\n // Wrap each field in OptionalSchema if not already optional\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n const fieldSchema = this._shape[key];\n if (fieldSchema) {\n if (fieldSchema instanceof OptionalSchema) {\n // Already optional, keep as is\n partialShape[key] = fieldSchema;\n } else {\n // Wrap in OptionalSchema to make it optional\n partialShape[key] = fieldSchema.optional();\n }\n }\n }\n }\n\n const partialSchema = new ObjectSchema(partialShape);\n\n // Copy metadata from parent schema\n partialSchema._meta = { ...this._meta };\n\n // Copy computed metadata from parent schema\n partialSchema._computedMeta = { ...this._computedMeta };\n\n // Copy layouts from parent schema\n partialSchema._layouts = { ...this._layouts };\n\n return partialSchema;\n }\n\n toZod(): z.ZodSchema<ObjectOutput<TShape>> {\n const zodShape: Record<string, z.ZodTypeAny> = {};\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && this._shape[key]) {\n const fieldSchema = this._shape[key];\n zodShape[key] = fieldSchema.toZod();\n }\n }\n\n const baseZod = z.object(zodShape);\n\n // If catchall is defined, use it to allow additional properties\n if (this._catchall) {\n return baseZod.catchall(this._catchall.toZod()) as any;\n }\n\n // If passthrough is enabled, allow any additional properties\n if (this._passthrough) {\n return baseZod.passthrough() as any;\n }\n\n return baseZod as any;\n }\n\n /**\n * Returns a Zod schema with URL coercion enabled.\n * This automatically converts string values from URL parameters to the expected types:\n * - \"37\" → 37 (number)\n * - \"true\" → true (boolean)\n * - \"hello\" → \"hello\" (string, unchanged)\n *\n * Use this when parsing URL search params that arrive as strings but need to be typed.\n *\n * @returns A Zod schema with coercion for URL parameter parsing\n */\n toZodWithCoercion(): z.ZodSchema<ObjectOutput<TShape>> {\n const zodShape: Record<string, z.ZodTypeAny> = {};\n\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && this._shape[key]) {\n const fieldSchema = this._shape[key];\n const baseZodSchema = fieldSchema.toZod();\n\n // Apply coercion based on the field's type\n const wrappedType =\n fieldSchema.type === \"optional\"\n ? (fieldSchema as OptionalSchema<any>)._wrapped.type\n : null;\n\n if (fieldSchema.type === \"number\" || wrappedType === \"number\") {\n const coercedSchema = z.coerce.number();\n // For optional fields, preserve the optional nature\n if (fieldSchema.type === \"optional\") {\n zodShape[key] = coercedSchema.nullable().optional();\n } else {\n zodShape[key] = coercedSchema;\n }\n } else if (\n fieldSchema.type === \"boolean\" ||\n wrappedType === \"boolean\"\n ) {\n // Custom boolean coercion that properly handles \"false\" and \"true\" strings\n const customBooleanCoercion = z.preprocess((val) => {\n if (typeof val === \"string\") {\n const lower = val.toLowerCase();\n if (lower === \"true\" || lower === \"1\") return true;\n if (lower === \"false\" || lower === \"0\") return false;\n }\n return val;\n }, z.boolean());\n\n // For optional fields, preserve the optional nature\n if (fieldSchema.type === \"optional\") {\n zodShape[key] = customBooleanCoercion.nullable().optional();\n } else {\n zodShape[key] = customBooleanCoercion;\n }\n } else {\n // For strings and other types, use the original schema\n zodShape[key] = baseZodSchema;\n }\n }\n }\n return z.object(zodShape) as z.ZodSchema<ObjectOutput<TShape>>;\n }\n}\n\n/**\n * Infers the TypeScript output type from an element schema for an array.\n */\nexport type ArrayOutput<TElementSchema extends BaseSchema<any>> = Array<\n TElementSchema[\"_outputType\"]\n>;\n\nexport class ArraySchema<\n TElementSchema extends BaseSchema<any>,\n> extends BaseSchema<ArrayOutput<TElementSchema>> {\n readonly type = \"array\" as const;\n _element: TElementSchema;\n\n constructor(elementSchema: TElementSchema) {\n super();\n this._element = elementSchema;\n }\n\n toZod(): z.ZodArray<z.ZodSchema<TElementSchema[\"_outputType\"]>> {\n return z.array(this._element.toZod());\n }\n}\n\n/**\n * RecordSchema represents a dictionary/map type with string keys and values of a specific type.\n * Similar to TypeScript's Record<string, T> or Zod's z.record().\n *\n * @example\n * const scoresSchema = nu.record(nu.number());\n * // Represents: { [key: string]: number }\n */\nexport class RecordSchema<\n TValueSchema extends BaseSchema<any>,\n> extends BaseSchema<Record<string, TValueSchema[\"_outputType\"]>> {\n readonly type = \"record\" as const;\n _valueSchema: TValueSchema;\n\n constructor(valueSchema: TValueSchema) {\n super();\n this._valueSchema = valueSchema;\n }\n\n toZod(): z.ZodRecord<z.ZodString, z.ZodSchema<TValueSchema[\"_outputType\"]>> {\n return z.record(z.string(), this._valueSchema.toZod());\n }\n}\n\n/**\n * Infers the TypeScript type from a schema.\n * @example\n * const userSchema = nu.object({ name: nu.string() });\n * type User = Infer&lt;typeof userSchema&gt;; // { name: string }\n */\nexport type Infer<T extends BaseSchema<any>> = T[\"_outputType\"];\n\n// Refine NuSchema union after defining concrete types\nexport type NuSchema =\n | BooleanSchema\n | StringSchema\n | NumberSchema\n | OptionalSchema<any>\n | ObjectSchema<any>\n | ArraySchema<any>\n | RecordSchema<any>;\n","import {\n ArraySchema,\n type BaseSchema,\n BooleanSchema,\n NumberSchema,\n ObjectSchema,\n type ObjectShape,\n RecordSchema,\n StringSchema,\n} from \"./schema\";\n\n/**\n * The main nubase schema instance.\n * Provides factory methods to create different schema types.\n */\nexport const nu = {\n boolean: () => new BooleanSchema(),\n /**\n * Creates a string schema.\n */\n string: () => new StringSchema(),\n\n /**\n * Creates a number schema.\n */\n number: () => new NumberSchema(),\n\n /**\n * Creates an object schema with a defined shape.\n * @param shape An object mapping keys to schemas.\n */\n object: <TShape extends ObjectShape>(shape: TShape) =>\n new ObjectSchema(shape),\n\n /**\n * Creates an array schema with a defined element schema.\n * @param elementSchema The schema for elements within the array.\n */\n array: <TElementSchema extends BaseSchema<any>>(\n elementSchema: TElementSchema,\n ) => new ArraySchema(elementSchema),\n\n /**\n * Creates a record schema (dictionary) with string keys and values of a specific type.\n * Similar to TypeScript's Record<string, T>.\n *\n * @example\n * const scoresSchema = nu.record(nu.number());\n * // Represents: { [key: string]: number }\n *\n * @param valueSchema The schema for values in the record.\n */\n record: <TValueSchema extends BaseSchema<any>>(valueSchema: TValueSchema) =>\n new RecordSchema(valueSchema),\n};\n","import { nu } from \"./nu\";\n\nexport const emptySchema = nu.object({});\n\nexport const idNumberSchema = nu.object({\n id: nu.number(),\n});\n\nexport const idStringSchema = nu.object({\n id: nu.string(),\n});\n\n// Simple success response (e.g., for DELETE operations)\nexport const successSchema = nu.object({\n success: nu.boolean(),\n});\n\n// Success response with optional message\nexport const successMessageSchema = nu.object({\n success: nu.boolean(),\n message: nu.string().optional(),\n});\n\n// Success/error response with optional errors array\nexport const successErrorSchema = nu.object({\n success: nu.boolean(),\n message: nu.string().optional(),\n errors: nu\n .array(\n nu.object({\n field: nu.string().optional(),\n message: nu.string(),\n }),\n )\n .optional(),\n});\n","import { nu } from \"./nu\";\n\nexport const errorSchema = nu.object({\n errorCode: nu.string(), // required by default\n errorMessage: nu.string(), // required by default\n});\n","/**\n * Represents a validation error in Nubase schema validation\n */\nexport interface NubaseValidationError {\n path: string;\n message: string;\n value?: unknown;\n}\n\n/**\n * Error thrown when Nubase schema validation fails\n */\nexport class NubaseSchemaError extends Error {\n public readonly errors: NubaseValidationError[];\n\n constructor(errors: NubaseValidationError[]) {\n const message = `Schema validation failed:\\n${errors\n .map((e) => ` - ${e.path}: ${e.message}`)\n .join(\"\\n\")}`;\n\n super(message);\n this.name = \"NubaseSchemaError\";\n this.errors = errors;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Creates a NubaseSchemaError from a list of error messages\n */\n static fromMessages(errorMessages: string[]): NubaseSchemaError {\n const errors: NubaseValidationError[] = errorMessages.map((message) => {\n // Try to extract path from error message format \"Property 'field': message\"\n const match = message.match(/^Property '([^']+)':\\s*(.+)$/);\n if (match?.[1] && match[2]) {\n return {\n path: match[1],\n message: match[2],\n };\n }\n // Fallback for messages without a clear path\n return {\n path: \"root\",\n message: message,\n };\n });\n\n return new NubaseSchemaError(errors);\n }\n\n /**\n * Type guard to check if an error is a NubaseSchemaError\n */\n static isNubaseSchemaError(error: unknown): error is NubaseSchemaError {\n return error instanceof NubaseSchemaError;\n }\n}\n","import { nu } from \"./nu\";\nimport type { Infer } from \"./schema\";\n\n// =============================================================================\n// SERIES DATA (for Line, Bar, Area charts)\n// =============================================================================\n\n/**\n * Configuration for series charts.\n * Defines which data keys represent the series and their display properties.\n */\nexport const seriesConfigSchema = nu.object({\n /** The data key field names that represent numeric series (e.g., [\"desktop\", \"mobile\"]) */\n keys: nu.array(nu.string()),\n /** Optional labels for each key (e.g., { desktop: \"Desktop Users\" }) */\n labels: nu.object({}).optional(),\n /** Optional colors for each key (e.g., { desktop: \"var(--chart1)\" }) */\n colors: nu.object({}).optional(),\n});\n\n/**\n * A single data point in a series chart.\n * The 'category' is the x-axis label (e.g., \"January\", \"Q1\", \"2024-01\").\n * Additional numeric fields are the data series values (e.g., desktop: 186, mobile: 80).\n *\n * Uses .catchall(nu.number()) to allow dynamic numeric fields beyond 'category'.\n */\nexport const seriesDataPointSchema = nu\n .object({\n category: nu.string(),\n })\n .catchall(nu.number());\n\n/**\n * Complete series data response from an endpoint.\n * Used for Line, Bar, and Area charts.\n */\nexport const seriesDataSchema = nu.object({\n type: nu.string(), // \"series\"\n config: seriesConfigSchema,\n data: nu.array(seriesDataPointSchema),\n});\n\nexport type SeriesConfig = Infer<typeof seriesConfigSchema>;\n// The schema uses .catchall(nu.number()) for runtime validation of dynamic fields.\n// TypeScript type is manually extended with Record<string, number> for type safety.\nexport type SeriesDataPoint = Infer<typeof seriesDataPointSchema> &\n Record<string, number>;\nexport type SeriesData = {\n type: \"series\";\n config: SeriesConfig;\n data: SeriesDataPoint[];\n};\n\n// =============================================================================\n// PROPORTIONAL DATA (for Pie, Donut charts)\n// =============================================================================\n\n/**\n * A single segment in a proportional chart.\n * Note: Colors are automatically assigned by the frontend based on index.\n */\nexport const proportionalDataItemSchema = nu.object({\n label: nu.string(),\n value: nu.number(),\n});\n\n/**\n * Complete proportional data response from an endpoint.\n * Used for Pie and Donut charts.\n */\nexport const proportionalDataSchema = nu.object({\n type: nu.string(), // \"proportional\"\n data: nu.array(proportionalDataItemSchema),\n});\n\nexport type ProportionalDataItem = Infer<typeof proportionalDataItemSchema>;\nexport type ProportionalData = {\n type: \"proportional\";\n data: Array<ProportionalDataItem & { fill?: string }>;\n};\n\n// =============================================================================\n// KPI DATA (single value display)\n// =============================================================================\n\n/**\n * KPI/stat widget data for displaying a single metric.\n */\nexport const kpiDataSchema = nu.object({\n type: nu.string(), // \"kpi\"\n value: nu.string(),\n label: nu.string().optional(),\n trend: nu.string().optional(),\n trendDirection: nu.string().optional(), // \"up\" | \"down\" | \"neutral\"\n});\n\nexport type KpiData = {\n type: \"kpi\";\n value: string;\n label?: string;\n trend?: string;\n trendDirection?: \"up\" | \"down\" | \"neutral\";\n};\n\n// =============================================================================\n// TABLE DATA (rows of data)\n// =============================================================================\n\n/**\n * Column definition for table widgets.\n */\nexport const tableColumnSchema = nu.object({\n key: nu.string(),\n label: nu.string(),\n width: nu.string().optional(),\n});\n\n/**\n * Complete table data response from an endpoint.\n * Uses passthrough() for rows to allow any properties in the row objects.\n */\nexport const tableDataSchema = nu.object({\n type: nu.string(), // \"table\"\n columns: nu.array(tableColumnSchema),\n rows: nu.array(nu.object({}).passthrough()), // Record<string, unknown>[]\n});\n\nexport type TableColumn = Infer<typeof tableColumnSchema>;\nexport type TableData = {\n type: \"table\";\n columns: TableColumn[];\n rows: Record<string, unknown>[];\n};\n\n// =============================================================================\n// WIDGET DATA UNION\n// =============================================================================\n\n/**\n * Union of all possible widget data types.\n */\nexport type WidgetData = SeriesData | ProportionalData | KpiData | TableData;\n\n/**\n * Widget data type discriminator.\n */\nexport type WidgetDataType = \"series\" | \"proportional\" | \"kpi\" | \"table\";\n","import { emptySchema } from \"./empty-schema\";\nimport type { ObjectSchema } from \"./schema\";\nimport {\n kpiDataSchema,\n proportionalDataSchema,\n seriesDataSchema,\n tableDataSchema,\n} from \"./widget-data-schema\";\n\n/**\n * Type for a series widget endpoint that preserves the responseBody type.\n */\nexport type SeriesWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof seriesDataSchema;\n};\n\n/**\n * Type for a proportional widget endpoint that preserves the responseBody type.\n */\nexport type ProportionalWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof proportionalDataSchema;\n};\n\n/**\n * Type for a KPI widget endpoint that preserves the responseBody type.\n */\nexport type KpiWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof kpiDataSchema;\n};\n\n/**\n * Type for a table widget endpoint that preserves the responseBody type.\n */\nexport type TableWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof tableDataSchema;\n};\n\n/**\n * Creates a RequestSchema for a Series widget endpoint.\n * The response conforms to SeriesData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/revenue\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for series data\n *\n * @example\n * ```typescript\n * export const getRevenueChartSchema = createSeriesWidgetEndpoint(\"/dashboard/revenue\");\n * ```\n */\nexport function createSeriesWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): SeriesWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: seriesDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a Proportional widget endpoint.\n * The response conforms to ProportionalData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/browser-stats\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for proportional data\n *\n * @example\n * ```typescript\n * export const getBrowserStatsSchema = createProportionalWidgetEndpoint(\"/dashboard/browsers\");\n * ```\n */\nexport function createProportionalWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): ProportionalWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: proportionalDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a KPI widget endpoint.\n * The response conforms to KpiData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/total-revenue\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for KPI data\n *\n * @example\n * ```typescript\n * export const getTotalRevenueSchema = createKpiWidgetEndpoint(\"/dashboard/total-revenue\");\n * ```\n */\nexport function createKpiWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): KpiWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: kpiDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a Table widget endpoint.\n * The response conforms to TableData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/recent-orders\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for table data\n *\n * @example\n * ```typescript\n * export const getRecentOrdersSchema = createTableWidgetEndpoint(\"/dashboard/orders\");\n * ```\n */\nexport function createTableWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): TableWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: tableDataSchema,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAkC;;;ACoB3B,IAAe,eAAf,cAAoC,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YAAY,SAAiB,SAA8B;AACzD,UAAM,OAAO;AACb,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,WAAW,QAAQ;AACxB,SAAK,SAAS,QAAQ;AACtB,SAAK,YAAY,oBAAI,KAAK;AAG1B,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AACF;AAKO,IAAM,qBAAN,MAAM,4BAA2B,aAAa;AAAA;AAAA,EAEnD,CAAC,uBAAO,IAAI,4BAA4B,CAAC,IAAI;AAC3C,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,KAAK,OAAO,WAAW,IAAI;AACzB,WAAO,KAAK,UAAU,KAAK,OAAO,GAAG,MAAM,CAAC;AAAA,EAC9C;AAAA,EACgB;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,SAMA;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,QAAQ,QAAQ;AACrB,SAAK,cAAc,QAAQ;AAC3B,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,WAAW,QAAQ;AAAA,EAC1B;AAAA,EAEA,WAAmB;AACjB,UAAM,UAAU,CAAC;AAEjB,YAAQ,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,OAAO,EAAE;AAC5C,YAAQ,KAAK,eAAe,KAAK,MAAM,IAAI,KAAK,QAAQ,EAAE;AAC1D,YAAQ,KAAK,YAAY,KAAK,KAAK,EAAE;AACrC,YAAQ,KAAK,gBAAgB,KAAK,UAAU,YAAY,CAAC,EAAE;AAE3D,QAAI,KAAK,UAAU;AACjB,cAAQ,KAAK,gBAAgB,KAAK,SAAS,SAAS,CAAC,EAAE;AACvD,UAAI,KAAK,SAAS,OAAO,SAAS,GAAG;AACnC,gBAAQ,KAAK,sBAAsB;AACnC,aAAK,SAAS,OAAO,QAAQ,CAAC,OAAO,UAAU;AAC7C,gBAAM,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,GAAG,IAAI;AAC5D,kBAAQ;AAAA,YACN,OAAO,QAAQ,CAAC,WAAW,IAAI,cAAc,MAAM,OAAO,WAAW,MAAM,IAAI;AAAA,UACjF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,KAAK,eAAe,KAAK,YAAY,SAAS,GAAG;AACnD,cAAQ,KAAK,iBAAiB;AAC9B,WAAK,YAAY,QAAQ,CAAC,OAAO,UAAU;AACzC,gBAAQ;AAAA,UACN,OAAO,QAAQ,CAAC,WAAW,MAAM,IAAI,cAAc,MAAM,OAAO,WAAW,MAAM,IAAI;AAAA,QACvF;AACA,YAAI,MAAM,SAAU,SAAQ,KAAK,oBAAoB,MAAM,QAAQ,EAAE;AACrE,YAAI,MAAM,SAAU,SAAQ,KAAK,oBAAoB,MAAM,QAAQ,EAAE;AAAA,MACvE,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,eAAe;AACtB,YAAM,WACJ,KAAK,yBAAyB,QAC1B,KAAK,cAAc,SAAS,IAC5B,OAAO,KAAK,aAAa;AAC/B,cAAQ,KAAK,qBAAqB,QAAQ,EAAE;AAAA,IAC9C;AAEA,WAAO,QAAQ,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEA,SAAS;AACP,UAAM,SAAc;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK,UAAU,YAAY;AAAA,IACxC;AAEA,QAAI,KAAK,UAAU;AAEjB,aAAO,WAAW,KAAK,SAAS;AAAA,IAClC;AAEA,QAAI,KAAK,eAAe,KAAK,YAAY,SAAS,GAAG;AACnD,aAAO,cAAc,KAAK;AAAA,IAC5B;AAEA,QAAI,KAAK,eAAe;AACtB,aAAO,gBACL,KAAK,yBAAyB,QAC1B;AAAA,QACE,MAAM,KAAK,cAAc;AAAA,QACzB,SAAS,KAAK,cAAc;AAAA,MAC9B,IACA,KAAK;AAAA,IACb;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,mBACL,OACA,SACoB;AACpB,UAAM,UACJ,iBAAiB,QACb,8BAA8B,QAAQ,MAAM,IAAI,QAAQ,QAAQ,KAAK,MAAM,OAAO,KAClF,8BAA8B,QAAQ,MAAM,IAAI,QAAQ,QAAQ;AAEtE,WAAO,IAAI,oBAAmB,SAAS;AAAA,MACrC,GAAG;AAAA,MACH,OAAO;AAAA,MACP,eAAe;AAAA,IACjB,CAAC;AAAA,EACH;AACF;AAKO,IAAM,qBAAN,MAAM,4BAA2B,aAAa;AAAA;AAAA,EAEnD,CAAC,uBAAO,IAAI,4BAA4B,CAAC,IAAI;AAC3C,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,KAAK,OAAO,WAAW,IAAI;AACzB,WAAO,KAAK,UAAU,KAAK,OAAO,GAAG,MAAM,CAAC;AAAA,EAC9C;AAAA,EACgB;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,SAKA;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,aAAa,QAAQ;AAC1B,SAAK,eAAe,QAAQ;AAC5B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEA,WAAmB;AACjB,UAAM,UAAU,CAAC;AAEjB,YAAQ,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,OAAO,EAAE;AAC5C,YAAQ,KAAK,eAAe,KAAK,MAAM,IAAI,KAAK,QAAQ,EAAE;AAC1D,YAAQ,KAAK,kBAAkB,KAAK,UAAU,EAAE;AAChD,YAAQ,KAAK,gBAAgB,KAAK,UAAU,YAAY,CAAC,EAAE;AAE3D,QAAI,KAAK,cAAc;AACrB,cAAQ,KAAK,oBAAoB,KAAK,YAAY,EAAE;AAAA,IACtD;AAEA,QAAI,KAAK,cAAc;AACrB,UAAI;AACF,cAAM,UACJ,OAAO,KAAK,iBAAiB,WACzB,KAAK,eACL,KAAK,UAAU,KAAK,cAAc,MAAM,CAAC;AAC/C,gBAAQ,KAAK,oBAAoB,OAAO,EAAE;AAAA,MAC5C,QAAQ;AACN,gBAAQ,KAAK,oBAAoB,OAAO,KAAK,YAAY,CAAC,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO,QAAQ,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEA,SAAS;AACP,UAAM,SAAc;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK,UAAU,YAAY;AAAA,IACxC;AAEA,QAAI,KAAK,cAAc;AACrB,aAAO,eAAe,KAAK;AAAA,IAC7B;AAEA,QAAI,KAAK,cAAc;AACrB,aAAO,eAAe,KAAK;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aACL,UACA,cACA,cACoB;AACpB,UAAM,UAAU,gBAAgB,SAAS,MAAM,QAAQ,SAAS,GAAG,KAAK,SAAS,UAAU;AAE3F,WAAO,IAAI,oBAAmB,SAAS;AAAA,MACrC,UAAU,SAAS;AAAA,MACnB,QAAQ;AAAA;AAAA,MACR,YAAY,SAAS;AAAA,MACrB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,aAAsB;AACpB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,iBAA0B;AACxB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,gBAAyB;AACvB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,gBAAyB;AACvB,WAAO,KAAK,cAAc,OAAO,KAAK,aAAa;AAAA,EACrD;AACF;;;ADlRO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAER,YAAY,EAAE,UAAU,GAAG,GAAyB;AAClD,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAc,QACZ,KACA,QACA,MACA,SAA4B,CAAC,GACH;AAC1B,UAAM,UAAU,KAAK,UAAU,GAAG,KAAK,OAAO,GAAG,GAAG,KAAK;AAEzD,QAAI;AACF,YAAM,WAAW,UAAM,aAAAA,SAAM;AAAA,QAC3B,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf,iBAAiB;AAAA;AAAA,MACnB,CAAC;AAED,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,MAAM,SAAS;AAAA,MACjB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,yBAAY;AAE/B,YAAI,MAAM,UAAU;AAElB,gBAAM,IAAI;AAAA,YACR,gBAAgB,MAAM,SAAS,MAAM,QAAQ,MAAM,IAAI,GAAG,KAAK,MAAM,SAAS,UAAU;AAAA,YACxF;AAAA,cACE,UAAU;AAAA,cACV;AAAA,cACA,YAAY,MAAM,SAAS;AAAA,cAC3B,cAAc,MAAM,SAAS;AAAA,cAC7B,cAAc,MAAM,SAAS;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AACA,YAAI,MAAM,SAAS;AAEjB,gBAAM,mBAAmB,mBAAmB,OAAO;AAAA,YACjD,UAAU;AAAA,YACV;AAAA,UACF,CAAC;AAAA,QACH;AAEA,cAAM,mBAAmB,mBAAmB,OAAO;AAAA,UACjD,UAAU;AAAA,UACV;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,KACA,QAC0B;AAC1B,WAAO,KAAK,QAAW,KAAK,OAAO,QAAW,MAAM;AAAA,EACtD;AAAA,EAEA,MAAM,KACJ,KACA,MACA,QAC0B;AAC1B,WAAO,KAAK,QAAW,KAAK,QAAQ,MAAM,MAAM;AAAA,EAClD;AAAA,EAEA,MAAM,IACJ,KACA,MACA,QAC0B;AAC1B,WAAO,KAAK,QAAW,KAAK,OAAO,MAAM,MAAM;AAAA,EACjD;AAAA,EAEA,MAAM,MACJ,KACA,MACA,QAC0B;AAC1B,WAAO,KAAK,QAAW,KAAK,SAAS,MAAM,MAAM;AAAA,EACnD;AAAA,EAEA,MAAM,OACJ,KACA,MACA,QAC0B;AAC1B,WAAO,KAAK,QAAW,KAAK,UAAU,MAAM,MAAM;AAAA,EACpD;AACF;;;AEvHA,iBAAkB;AA0BX,IAAe,aAAf,MAAwC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpC;AAAA,EAQT,QAAgC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC,SAAS,MAAoC;AAC3C,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAoC;AAC/C,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAiC;AAC/B,WAAO,IAAI,eAAe,IAAI;AAAA,EAChC;AAOF;AAIO,IAAM,gBAAN,cAA4B,WAAoB;AAAA,EAC5C,OAAO;AAAA,EAEhB,QAAsB;AACpB,WAAO,aAAE,QAAQ;AAAA,EACnB;AACF;AAEO,IAAM,eAAN,cAA2B,WAAmB;AAAA,EAC1C,OAAO;AAAA;AAAA,EAGhB,QAAqB;AACnB,WAAO,aAAE,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,eAAN,cAA2B,WAAmB;AAAA,EAC1C,OAAO;AAAA;AAAA,EAGhB,QAAqB;AACnB,WAAO,aAAE,OAAO;AAAA,EAClB;AACF;AAQO,IAAM,iBAAN,cAEG,WAAgD;AAAA,EAC/C,OAAO;AAAA,EAChB;AAAA,EAEA,YAAY,SAAmB;AAC7B,UAAM;AACN,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAA4E;AAC1E,WAAO,KAAK,SAAS,MAAM,EAAE,SAAS,EAAE,SAAS;AAAA,EACnD;AACF;AAmKO,IAAM,eAAN,MAAM,sBAGH,WAAiC;AAAA,EAChC,OAAO;AAAA,EAChB;AAAA,EACA,gBAAgD,CAAC;AAAA,EACjD,WAAkC,CAAC;AAAA,EACnC,WAAuC;AAAA,EACvC,YAAuB;AAAA,EACvB,eAAe;AAAA,EAEf,YAAY,OAAe,UAAsB;AAC/C,UAAM;AACN,SAAK,SAAS;AACd,QAAI,UAAU;AACZ,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,SACE,QACuC;AACvC,UAAM,YAAY,IAAI;AAAA,MACpB,KAAK;AAAA,MACL;AAAA,IACF;AAGA,cAAU,QAAQ,EAAE,GAAG,KAAK,MAAM;AAClC,cAAU,gBAAgB,EAAE,GAAG,KAAK,cAAc;AAClD,cAAU,WAAW,EAAE,GAAG,KAAK,SAAS;AACxC,cAAU,WAAW,KAAK;AAC1B,cAAU,eAAe,KAAK;AAE9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,cAA+C;AAC7C,UAAM,YAAY,IAAI;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAGA,cAAU,QAAQ,EAAE,GAAG,KAAK,MAAM;AAClC,cAAU,gBAAgB,EAAE,GAAG,KAAK,cAAc;AAClD,cAAU,WAAW,EAAE,GAAG,KAAK,SAAS;AACxC,cAAU,WAAW,KAAK;AAC1B,cAAU,eAAe;AAEzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,cAAoD;AAC/D,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAY,SAAsC;AAChD,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB,SAAoC;AAElD,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,GAAG,QAAQ;AAC/C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiB,SAUR;AAEP,UAAM,eAAqC,CAAC;AAE5C,eAAW,CAAC,MAAM,WAAW,KAAK,OAAO,QAAQ,OAAO,GAAG;AAEzD,mBAAa,IAAI,IAAI;AAAA,QACnB,MAAM;AAAA,QACN,QAAQ;AAAA,UACN;AAAA,YACE,QAAQ,YAAY;AAAA,UACtB;AAAA,QACF;AAAA,QACA,WAAW,YAAY;AAAA,QACvB,QAAQ,YAAY;AAAA,QACpB,UAAU,YAAY;AAAA,MACxB;AAAA,IACF;AAEA,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,GAAG,aAAa;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OACE,SACM;AACN,QAAI,OAAO,YAAY,YAAY;AAGjC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAyC;AACvC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,YAAgD;AACxD,WAAO,KAAK,SAAS,UAAU;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAA2B;AACzB,WAAO,OAAO,KAAK,KAAK,QAAQ;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,YAA6B;AACrC,WAAO,cAAc,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBACJ,KACA,MACqE;AACrE,UAAM,eAAe,KAAK,cAAc,GAAG;AAC3C,QAAI,CAAC,cAAc;AACjB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAc,CAAC;AAErB,QAAI,aAAa,OAAO;AACtB,aAAO,QAAQ,MAAM,aAAa,MAAM,IAAI;AAAA,IAC9C;AAEA,QAAI,aAAa,aAAa;AAC5B,aAAO,cAAc,MAAM,aAAa,YAAY,IAAI;AAAA,IAC1D;AAEA,QAAI,aAAa,cAAc;AAC7B,aAAO,eAAe,MAAM,aAAa,aAAa,IAAI;AAAA,IAC5D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBACJ,MAC6D;AAC7D,UAAM,SAAc,CAAC;AAErB,eAAW,OAAO,KAAK,QAAQ;AAC7B,aAAO,GAAG,IAAI,MAAM,KAAK,gBAAgB,KAAK,IAAI;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,MACoD;AACpD,UAAM,SAAc,CAAC;AAGrB,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,GAAG;AACnC,YAAI,SAAS,KAAK,OAAO,GAAG;AAC5B,YAAI,QAAQ;AAEV,cAAI,kBAAkB,gBAAgB;AACpC,qBAAS,OAAO;AAAA,UAClB;AACA,iBAAO,GAAG,IAAI,EAAE,GAAI,QAAQ,SAAS,CAAC,EAAG;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,KAAK,aAAa,EAAE,SAAS,GAAG;AAC9C,UAAI;AAGF,cAAM,eAAoB,CAAC;AAC3B,mBAAW,OAAO,KAAK,QAAQ;AAC7B,cAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,GAAG;AACnC,kBAAM,SAAS,KAAK,OAAO,GAAG;AAC9B,gBAAI,QAAQ;AAEV,oBAAM,eACJ,kBAAkB,iBAAiB,OAAO,WAAW;AAEvD,kBAAK,KAAa,GAAG,MAAM,QAAW;AACpC,6BAAa,GAAG,IAAK,KAAa,GAAG;AAAA,cACvC,WAAW,aAAa,MAAM,iBAAiB,QAAW;AACxD,6BAAa,GAAG,IAAI,aAAa,MAAM;AAAA,cACzC,OAAO;AAEL,oBAAI,wBAAwB,cAAc;AACxC,+BAAa,GAAG,IAAI;AAAA,gBACtB,WAAW,wBAAwB,cAAc;AAC/C,+BAAa,GAAG,IAAI;AAAA,gBACtB,WAAW,wBAAwB,eAAe;AAChD,+BAAa,GAAG,IAAI;AAAA,gBACtB,OAAO;AACL,+BAAa,GAAG,IAAI;AAAA,gBACtB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,eAAe,MAAM,KAAK;AAAA,UAC9B;AAAA,QACF;AAGA,mBAAW,OAAO,cAAc;AAC9B,cAAI,aAAa,GAAG,GAAG;AACrB,mBAAO,GAAG,IAAI;AAAA,cACZ,GAAG,OAAO,GAAG;AAAA,cACb,GAAG,aAAa,GAAG;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AAEd,gBAAQ,KAAK,+BAA+B,KAAK;AAAA,MACnD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAgC,MAA0C;AACxE,UAAM,WAAgB,CAAC;AACvB,UAAM,aAAa,IAAI,IAAI,IAAI;AAE/B,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,KAAK,CAAC,WAAW,IAAI,GAAU,GAAG;AAClE,iBAAS,GAAG,IAAI,KAAK,OAAO,GAAG;AAAA,MACjC;AAAA,IACF;AAEA,UAAM,YAAY,IAAI,cAAa,QAAQ;AAG3C,cAAU,QAAQ,EAAE,GAAG,KAAK,MAAM;AAGlC,UAAM,kBAAuB,CAAC;AAC9B,eAAW,OAAO,KAAK,eAAe;AACpC,UAAI,CAAC,WAAW,IAAI,GAAU,GAAG;AAC/B,wBAAgB,GAAG,IAAI,KAAK,cAAc,GAAG;AAAA,MAC/C;AAAA,IACF;AACA,cAAU,gBAAgB;AAG1B,UAAM,aAAkB,CAAC;AACzB,eAAW,cAAc,KAAK,UAAU;AACtC,YAAM,iBAAiB,KAAK,SAAS,UAAU;AAC/C,UAAI,gBAAgB;AAClB,cAAM,YAAY,eAAe,OAAO,IAAI,CAAC,WAAW;AAAA,UACtD,GAAG;AAAA,UACH,QAAQ,MAAM,OAAO;AAAA,YACnB,CAAC,UAAU,CAAC,WAAW,IAAI,MAAM,IAAW;AAAA,UAC9C;AAAA,QACF,EAAE;AACF,mBAAW,UAAU,IAAI;AAAA,UACvB,GAAG;AAAA,UACH,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,cAAU,WAAW;AAErB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OACE,OACgC;AAChC,UAAM,WAAW,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM;AAC5C,UAAM,YAAY,IAAI,cAAa,QAAQ;AAG3C,cAAU,QAAQ,EAAE,GAAG,KAAK,MAAM;AAGlC,cAAU,gBAAgB,EAAE,GAAG,KAAK,cAAc;AAGlD,cAAU,WAAW,EAAE,GAAG,KAAK,SAAS;AAExC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAA4E;AAC1E,UAAM,eAAoB,CAAC;AAG3B,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,GAAG;AACnC,cAAM,cAAc,KAAK,OAAO,GAAG;AACnC,YAAI,aAAa;AACf,cAAI,uBAAuB,gBAAgB;AAEzC,yBAAa,GAAG,IAAI;AAAA,UACtB,OAAO;AAEL,yBAAa,GAAG,IAAI,YAAY,SAAS;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,IAAI,cAAa,YAAY;AAGnD,kBAAc,QAAQ,EAAE,GAAG,KAAK,MAAM;AAGtC,kBAAc,gBAAgB,EAAE,GAAG,KAAK,cAAc;AAGtD,kBAAc,WAAW,EAAE,GAAG,KAAK,SAAS;AAE5C,WAAO;AAAA,EACT;AAAA,EAEA,QAA2C;AACzC,UAAM,WAAyC,CAAC;AAChD,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,KAAK,KAAK,OAAO,GAAG,GAAG;AACvD,cAAM,cAAc,KAAK,OAAO,GAAG;AACnC,iBAAS,GAAG,IAAI,YAAY,MAAM;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,UAAU,aAAE,OAAO,QAAQ;AAGjC,QAAI,KAAK,WAAW;AAClB,aAAO,QAAQ,SAAS,KAAK,UAAU,MAAM,CAAC;AAAA,IAChD;AAGA,QAAI,KAAK,cAAc;AACrB,aAAO,QAAQ,YAAY;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,oBAAuD;AACrD,UAAM,WAAyC,CAAC;AAEhD,eAAW,OAAO,KAAK,QAAQ;AAC7B,UAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,KAAK,KAAK,OAAO,GAAG,GAAG;AACvD,cAAM,cAAc,KAAK,OAAO,GAAG;AACnC,cAAM,gBAAgB,YAAY,MAAM;AAGxC,cAAM,cACJ,YAAY,SAAS,aAChB,YAAoC,SAAS,OAC9C;AAEN,YAAI,YAAY,SAAS,YAAY,gBAAgB,UAAU;AAC7D,gBAAM,gBAAgB,aAAE,OAAO,OAAO;AAEtC,cAAI,YAAY,SAAS,YAAY;AACnC,qBAAS,GAAG,IAAI,cAAc,SAAS,EAAE,SAAS;AAAA,UACpD,OAAO;AACL,qBAAS,GAAG,IAAI;AAAA,UAClB;AAAA,QACF,WACE,YAAY,SAAS,aACrB,gBAAgB,WAChB;AAEA,gBAAM,wBAAwB,aAAE,WAAW,CAAC,QAAQ;AAClD,gBAAI,OAAO,QAAQ,UAAU;AAC3B,oBAAM,QAAQ,IAAI,YAAY;AAC9B,kBAAI,UAAU,UAAU,UAAU,IAAK,QAAO;AAC9C,kBAAI,UAAU,WAAW,UAAU,IAAK,QAAO;AAAA,YACjD;AACA,mBAAO;AAAA,UACT,GAAG,aAAE,QAAQ,CAAC;AAGd,cAAI,YAAY,SAAS,YAAY;AACnC,qBAAS,GAAG,IAAI,sBAAsB,SAAS,EAAE,SAAS;AAAA,UAC5D,OAAO;AACL,qBAAS,GAAG,IAAI;AAAA,UAClB;AAAA,QACF,OAAO;AAEL,mBAAS,GAAG,IAAI;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,WAAO,aAAE,OAAO,QAAQ;AAAA,EAC1B;AACF;AASO,IAAM,cAAN,cAEG,WAAwC;AAAA,EACvC,OAAO;AAAA,EAChB;AAAA,EAEA,YAAY,eAA+B;AACzC,UAAM;AACN,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,QAAgE;AAC9D,WAAO,aAAE,MAAM,KAAK,SAAS,MAAM,CAAC;AAAA,EACtC;AACF;AAUO,IAAM,eAAN,cAEG,WAAwD;AAAA,EACvD,OAAO;AAAA,EAChB;AAAA,EAEA,YAAY,aAA2B;AACrC,UAAM;AACN,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,QAA4E;AAC1E,WAAO,aAAE,OAAO,aAAE,OAAO,GAAG,KAAK,aAAa,MAAM,CAAC;AAAA,EACvD;AACF;;;ACt1BO,IAAM,KAAK;AAAA,EAChB,SAAS,MAAM,IAAI,cAAc;AAAA;AAAA;AAAA;AAAA,EAIjC,QAAQ,MAAM,IAAI,aAAa;AAAA;AAAA;AAAA;AAAA,EAK/B,QAAQ,MAAM,IAAI,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,QAAQ,CAA6B,UACnC,IAAI,aAAa,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxB,OAAO,CACL,kBACG,IAAI,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYlC,QAAQ,CAAuC,gBAC7C,IAAI,aAAa,WAAW;AAChC;;;ACpDO,IAAM,cAAc,GAAG,OAAO,CAAC,CAAC;AAEhC,IAAM,iBAAiB,GAAG,OAAO;AAAA,EACtC,IAAI,GAAG,OAAO;AAChB,CAAC;AAEM,IAAM,iBAAiB,GAAG,OAAO;AAAA,EACtC,IAAI,GAAG,OAAO;AAChB,CAAC;AAGM,IAAM,gBAAgB,GAAG,OAAO;AAAA,EACrC,SAAS,GAAG,QAAQ;AACtB,CAAC;AAGM,IAAM,uBAAuB,GAAG,OAAO;AAAA,EAC5C,SAAS,GAAG,QAAQ;AAAA,EACpB,SAAS,GAAG,OAAO,EAAE,SAAS;AAChC,CAAC;AAGM,IAAM,qBAAqB,GAAG,OAAO;AAAA,EAC1C,SAAS,GAAG,QAAQ;AAAA,EACpB,SAAS,GAAG,OAAO,EAAE,SAAS;AAAA,EAC9B,QAAQ,GACL;AAAA,IACC,GAAG,OAAO;AAAA,MACR,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,MAC5B,SAAS,GAAG,OAAO;AAAA,IACrB,CAAC;AAAA,EACH,EACC,SAAS;AACd,CAAC;;;ACjCM,IAAM,cAAc,GAAG,OAAO;AAAA,EACnC,WAAW,GAAG,OAAO;AAAA;AAAA,EACrB,cAAc,GAAG,OAAO;AAAA;AAC1B,CAAC;;;ACOM,IAAM,oBAAN,MAAM,2BAA0B,MAAM;AAAA,EAC3B;AAAA,EAEhB,YAAY,QAAiC;AAC3C,UAAM,UAAU;AAAA,EAA8B,OAC3C,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE,EACxC,KAAK,IAAI,CAAC;AAEb,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AAGd,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aAAa,eAA4C;AAC9D,UAAM,SAAkC,cAAc,IAAI,CAAC,YAAY;AAErE,YAAM,QAAQ,QAAQ,MAAM,8BAA8B;AAC1D,UAAI,QAAQ,CAAC,KAAK,MAAM,CAAC,GAAG;AAC1B,eAAO;AAAA,UACL,MAAM,MAAM,CAAC;AAAA,UACb,SAAS,MAAM,CAAC;AAAA,QAClB;AAAA,MACF;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,IAAI,mBAAkB,MAAM;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,oBAAoB,OAA4C;AACrE,WAAO,iBAAiB;AAAA,EAC1B;AACF;;;AChDO,IAAM,qBAAqB,GAAG,OAAO;AAAA;AAAA,EAE1C,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAAA;AAAA,EAE1B,QAAQ,GAAG,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA,EAE/B,QAAQ,GAAG,OAAO,CAAC,CAAC,EAAE,SAAS;AACjC,CAAC;AASM,IAAM,wBAAwB,GAClC,OAAO;AAAA,EACN,UAAU,GAAG,OAAO;AACtB,CAAC,EACA,SAAS,GAAG,OAAO,CAAC;AAMhB,IAAM,mBAAmB,GAAG,OAAO;AAAA,EACxC,MAAM,GAAG,OAAO;AAAA;AAAA,EAChB,QAAQ;AAAA,EACR,MAAM,GAAG,MAAM,qBAAqB;AACtC,CAAC;AAqBM,IAAM,6BAA6B,GAAG,OAAO;AAAA,EAClD,OAAO,GAAG,OAAO;AAAA,EACjB,OAAO,GAAG,OAAO;AACnB,CAAC;AAMM,IAAM,yBAAyB,GAAG,OAAO;AAAA,EAC9C,MAAM,GAAG,OAAO;AAAA;AAAA,EAChB,MAAM,GAAG,MAAM,0BAA0B;AAC3C,CAAC;AAeM,IAAM,gBAAgB,GAAG,OAAO;AAAA,EACrC,MAAM,GAAG,OAAO;AAAA;AAAA,EAChB,OAAO,GAAG,OAAO;AAAA,EACjB,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,EAC5B,gBAAgB,GAAG,OAAO,EAAE,SAAS;AAAA;AACvC,CAAC;AAiBM,IAAM,oBAAoB,GAAG,OAAO;AAAA,EACzC,KAAK,GAAG,OAAO;AAAA,EACf,OAAO,GAAG,OAAO;AAAA,EACjB,OAAO,GAAG,OAAO,EAAE,SAAS;AAC9B,CAAC;AAMM,IAAM,kBAAkB,GAAG,OAAO;AAAA,EACvC,MAAM,GAAG,OAAO;AAAA;AAAA,EAChB,SAAS,GAAG,MAAM,iBAAiB;AAAA,EACnC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC;AAAA;AAC5C,CAAC;;;AChEM,SAAS,2BACd,MACA,eAC2B;AAC3B,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC,cAAc;AAAA,EAChB;AACF;AAeO,SAAS,iCACd,MACA,eACiC;AACjC,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC,cAAc;AAAA,EAChB;AACF;AAeO,SAAS,wBACd,MACA,eACwB;AACxB,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC,cAAc;AAAA,EAChB;AACF;AAeO,SAAS,0BACd,MACA,eAC0B;AAC1B,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC,cAAc;AAAA,EAChB;AACF;","names":["axios"]}
1
+ {"version":3,"sources":["../src/index.ts","../../frontend/src/http/http-client.ts","../../frontend/src/utils/network-errors.ts","../src/schema/schema.ts","../src/schema/nu.ts","../src/schema/empty-schema.ts","../src/schema/error-schema.ts","../src/schema/errors.ts","../src/schema/lookup.ts","../src/schema/widget-data-schema.ts","../src/schema/widget-request-schema.ts"],"sourcesContent":["// Main entry point for @nubase/core\n\n// HTTP\nexport * from \"../../frontend/src/http/http-client\";\nexport * from \"./schema/empty-schema\";\nexport * from \"./schema/error-schema\";\nexport * from \"./schema/errors\";\nexport * from \"./schema/lookup\";\nexport * from \"./schema/nu\";\nexport * from \"./schema/request-schema\";\nexport * from \"./schema/schema\";\n\n// Widget schemas\nexport * from \"./schema/widget-data-schema\";\nexport * from \"./schema/widget-request-schema\";\n","import axios, { AxiosError } from \"axios\";\nimport {\n ClientNetworkError,\n ServerNetworkError,\n} from \"../utils/network-errors\";\n\nexport interface HttpResponse<T = any> {\n status: number;\n data: T;\n}\n\nexport interface HttpRequestConfig {\n headers?: Record<string, string>;\n timeout?: number;\n params?: Record<string, any>;\n}\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor({ baseUrl = \"\" }: { baseUrl?: string }) {\n this.baseUrl = baseUrl;\n }\n\n private async request<T>(\n url: string,\n method: string,\n data?: any,\n config: HttpRequestConfig = {},\n ): Promise<HttpResponse<T>> {\n const fullUrl = this.baseUrl ? `${this.baseUrl}${url}` : url;\n\n try {\n const response = await axios({\n url: fullUrl,\n method,\n data,\n headers: config.headers,\n timeout: config.timeout,\n params: config.params,\n withCredentials: true, // Required for sending cookies in cross-origin requests\n });\n\n return {\n status: response.status,\n data: response.data,\n };\n } catch (error) {\n if (error instanceof AxiosError) {\n // Check if we have a response (server error) or no response (network error)\n if (error.response) {\n // Server responded with error status\n throw new ServerNetworkError(\n `Server error ${error.response.status} for ${method} ${url}: ${error.response.statusText}`,\n {\n endpoint: url,\n method,\n statusCode: error.response.status,\n responseText: error.response.statusText,\n responseData: error.response.data,\n },\n );\n }\n if (error.request) {\n // Request was made but no response received\n throw ClientNetworkError.fromNetworkFailure(error, {\n endpoint: url,\n method,\n });\n }\n // Something happened in setting up the request\n throw ClientNetworkError.fromNetworkFailure(error, {\n endpoint: url,\n method,\n });\n }\n // Re-throw non-axios errors\n throw error;\n }\n }\n\n async get<T>(\n url: string,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"GET\", undefined, config);\n }\n\n async post<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"POST\", data, config);\n }\n\n async put<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"PUT\", data, config);\n }\n\n async patch<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"PATCH\", data, config);\n }\n\n async delete<T>(\n url: string,\n data?: any,\n config?: HttpRequestConfig,\n ): Promise<HttpResponse<T>> {\n return this.request<T>(url, \"DELETE\", data, config);\n }\n}\n","import type { ZodError } from \"zod\";\n\nexport interface ParseErrorDetail {\n path: string;\n message: string;\n code: string;\n expected?: string;\n received?: string;\n}\n\nexport interface NetworkErrorOptions {\n endpoint: string;\n method: string;\n statusCode?: number;\n responseText?: string;\n}\n\n/**\n * Base class for all network-related errors\n */\nexport abstract class NetworkError extends Error {\n public readonly endpoint: string;\n public readonly method: string;\n public readonly timestamp: Date;\n\n constructor(message: string, options: NetworkErrorOptions) {\n super(message);\n this.name = this.constructor.name;\n this.endpoint = options.endpoint;\n this.method = options.method;\n this.timestamp = new Date();\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when client-side validation fails before making a network request\n */\nexport class ClientNetworkError extends NetworkError {\n // Custom inspect method for Node.js and some browser consoles\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.toJSON();\n }\n\n // For browsers that support console formatting\n get [Symbol.toStringTag]() {\n return JSON.stringify(this.toJSON(), null, 2);\n }\n public readonly phase:\n | \"request-validation\"\n | \"response-validation\"\n | \"network-failure\";\n public readonly parseErrors?: ParseErrorDetail[];\n public readonly originalError?: unknown;\n public readonly zodError?: ZodError;\n\n constructor(\n message: string,\n options: NetworkErrorOptions & {\n phase: \"request-validation\" | \"response-validation\" | \"network-failure\";\n parseErrors?: ParseErrorDetail[];\n originalError?: unknown;\n zodError?: ZodError;\n },\n ) {\n super(message, options);\n this.phase = options.phase;\n this.parseErrors = options.parseErrors;\n this.originalError = options.originalError;\n this.zodError = options.zodError;\n }\n\n toString(): string {\n const details = [];\n\n details.push(`${this.name}: ${this.message}`);\n details.push(` Endpoint: ${this.method} ${this.endpoint}`);\n details.push(` Phase: ${this.phase}`);\n details.push(` Timestamp: ${this.timestamp.toISOString()}`);\n\n if (this.zodError) {\n details.push(` Zod Error: ${this.zodError.toString()}`);\n if (this.zodError.issues.length > 0) {\n details.push(\" Validation Issues:\");\n this.zodError.issues.forEach((issue, index) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"root\";\n details.push(\n ` ${index + 1}. Path: ${path}, Message: ${issue.message}, Code: ${issue.code}`,\n );\n });\n }\n }\n\n if (this.parseErrors && this.parseErrors.length > 0) {\n details.push(\" Parse Errors:\");\n this.parseErrors.forEach((error, index) => {\n details.push(\n ` ${index + 1}. Path: ${error.path}, Message: ${error.message}, Code: ${error.code}`,\n );\n if (error.expected) details.push(` Expected: ${error.expected}`);\n if (error.received) details.push(` Received: ${error.received}`);\n });\n }\n\n if (this.originalError) {\n const errorStr =\n this.originalError instanceof Error\n ? this.originalError.toString()\n : String(this.originalError);\n details.push(` Original Error: ${errorStr}`);\n }\n\n return details.join(\"\\n\");\n }\n\n toJSON() {\n const result: any = {\n name: this.name,\n message: this.message,\n endpoint: this.endpoint,\n method: this.method,\n phase: this.phase,\n timestamp: this.timestamp.toISOString(),\n };\n\n if (this.zodError) {\n // Use the same beautiful format as ZodError\n result.zodError = this.zodError.issues;\n }\n\n if (this.parseErrors && this.parseErrors.length > 0) {\n result.parseErrors = this.parseErrors;\n }\n\n if (this.originalError) {\n result.originalError =\n this.originalError instanceof Error\n ? {\n name: this.originalError.name,\n message: this.originalError.message,\n }\n : this.originalError;\n }\n\n return result;\n }\n\n /**\n * Creates a ClientNetworkError for network failures (no response from server)\n */\n static fromNetworkFailure(\n error: unknown,\n options: NetworkErrorOptions,\n ): ClientNetworkError {\n const message =\n error instanceof Error\n ? `Network request failed for ${options.method} ${options.endpoint}: ${error.message}`\n : `Network request failed for ${options.method} ${options.endpoint}`;\n\n return new ClientNetworkError(message, {\n ...options,\n phase: \"network-failure\",\n originalError: error,\n });\n }\n}\n\n/**\n * Error thrown when the server returns an error response\n */\nexport class ServerNetworkError extends NetworkError {\n // Custom inspect method for Node.js and some browser consoles\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.toJSON();\n }\n\n // For browsers that support console formatting\n get [Symbol.toStringTag]() {\n return JSON.stringify(this.toJSON(), null, 2);\n }\n public readonly statusCode: number;\n public readonly responseText?: string;\n public readonly responseData?: unknown;\n\n constructor(\n message: string,\n options: NetworkErrorOptions & {\n statusCode: number;\n responseText?: string;\n responseData?: unknown;\n },\n ) {\n super(message, options);\n this.statusCode = options.statusCode;\n this.responseText = options.responseText;\n this.responseData = options.responseData;\n }\n\n toString(): string {\n const details = [];\n\n details.push(`${this.name}: ${this.message}`);\n details.push(` Endpoint: ${this.method} ${this.endpoint}`);\n details.push(` Status Code: ${this.statusCode}`);\n details.push(` Timestamp: ${this.timestamp.toISOString()}`);\n\n if (this.responseText) {\n details.push(` Response Text: ${this.responseText}`);\n }\n\n if (this.responseData) {\n try {\n const dataStr =\n typeof this.responseData === \"string\"\n ? this.responseData\n : JSON.stringify(this.responseData, null, 2);\n details.push(` Response Data: ${dataStr}`);\n } catch {\n details.push(` Response Data: ${String(this.responseData)}`);\n }\n }\n\n return details.join(\"\\n\");\n }\n\n toJSON() {\n const result: any = {\n name: this.name,\n message: this.message,\n endpoint: this.endpoint,\n method: this.method,\n statusCode: this.statusCode,\n timestamp: this.timestamp.toISOString(),\n };\n\n if (this.responseText) {\n result.responseText = this.responseText;\n }\n\n if (this.responseData) {\n result.responseData = this.responseData;\n }\n\n return result;\n }\n\n /**\n * Creates a ServerNetworkError from an HTTP response\n */\n static fromResponse(\n response: Response,\n responseText?: string,\n responseData?: unknown,\n ): ServerNetworkError {\n const message = `Server error ${response.status} for ${response.url}: ${response.statusText}`;\n\n return new ServerNetworkError(message, {\n endpoint: response.url,\n method: \"GET\", // Will be overridden by caller with actual method\n statusCode: response.status,\n responseText,\n responseData,\n });\n }\n\n /**\n * Checks if this is a specific type of server error\n */\n isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n isForbidden(): boolean {\n return this.statusCode === 403;\n }\n\n isServerError(): boolean {\n return this.statusCode >= 500;\n }\n\n isClientError(): boolean {\n return this.statusCode >= 400 && this.statusCode < 500;\n }\n}\n\n/**\n * Type guard to check if an error is a NetworkError\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError;\n}\n\n/**\n * Type guard to check if an error is a ClientNetworkError\n */\nexport function isClientNetworkError(\n error: unknown,\n): error is ClientNetworkError {\n return error instanceof ClientNetworkError;\n}\n\n/**\n * Type guard to check if an error is a ServerNetworkError\n */\nexport function isServerNetworkError(\n error: unknown,\n): error is ServerNetworkError {\n return error instanceof ServerNetworkError;\n}\n\n/**\n * Helper to get a user-friendly error message\n */\nexport function getNetworkErrorMessage(error: unknown): string {\n if (isClientNetworkError(error)) {\n if (error.phase === \"network-failure\") {\n return \"Unable to connect to the server. Please check your internet connection.\";\n }\n if (error.zodError && error.zodError.issues.length > 0) {\n const firstIssue = error.zodError.issues[0];\n if (firstIssue) {\n return `Validation error: ${firstIssue.message}`;\n }\n }\n if (error.parseErrors && error.parseErrors.length > 0) {\n const firstError = error.parseErrors[0];\n if (firstError) {\n return `Validation error: ${firstError.message}`;\n }\n }\n return error.message;\n }\n\n if (isServerNetworkError(error)) {\n if (error.isNotFound()) {\n return \"The requested resource was not found.\";\n }\n if (error.isUnauthorized()) {\n return \"You are not authorized to perform this action.\";\n }\n if (error.isServerError()) {\n return \"A server error occurred. Please try again later.\";\n }\n return error.message;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return \"An unexpected error occurred.\";\n}\n","import { z } from \"zod\";\n\n// Define metadata types\nexport interface SchemaMetadata<Output = any> {\n label?: string;\n description?: string;\n defaultValue?: Output;\n /**\n * Custom renderer identifier to override the default type-based rendering.\n * Examples: \"multiline\", \"email\", \"password\", \"url\", \"lookup\"\n */\n renderer?: string;\n /**\n * When renderer is \"lookup\", this specifies which resource to use for the lookup.\n * The resource must have a lookup endpoint configured.\n */\n lookupResource?: string;\n validateOnSubmit?: (value: any) => string | undefined;\n validateOnSubmitAsync?: (value: any) => Promise<string | undefined>;\n validateOnBlur?: (value: any) => string | undefined;\n validateOnBlurAsync?: (value: any) => Promise<string | undefined>;\n}\n\n// ComputedSchemaMetadata should have the same properties as SchemaMetadata but\n// the values should be functions that return the same types, but Promises.\nexport type ComputedSchemaMetadata<Output = any, Input = any> = {\n [K in keyof SchemaMetadata<Output>]: (\n input: Input,\n ) => Promise<SchemaMetadata<Output>[K]>;\n};\n\nexport abstract class BaseSchema<Output = any> {\n /**\n * Phantom property used for TypeScript type inference.\n * Does not exist at runtime.\n * @internal\n */\n readonly _outputType!: Output;\n\n /**\n * The type identifier for this schema.\n * Used for type-based form field rendering.\n */\n abstract readonly type: string;\n\n /**\n * The base type of this schema, unwrapping any wrapper schemas (like OptionalSchema).\n * For most schemas, this is the same as `type`. For wrapper schemas like OptionalSchema,\n * this returns the type of the innermost wrapped schema.\n */\n get baseType(): string {\n return this.type;\n }\n\n /**\n * The default value for this schema type.\n * Returns the user-configured default from metadata, or a sensible type-specific default.\n * Subclasses override this to provide appropriate defaults (e.g., false for boolean, 0 for number).\n */\n get defaultValue(): Output | undefined {\n return this._meta?.defaultValue;\n }\n\n _meta: SchemaMetadata<Output> = {};\n\n /**\n * Replace the schema metadata with a new object.\n * @param meta The new metadata object.\n * @returns The schema instance for chaining.\n */\n withMeta(meta: SchemaMetadata<Output>): this {\n this._meta = meta;\n return this;\n }\n\n /**\n * Add metadata with validation functions to the schema.\n * @param meta The metadata object with validation functions.\n * @returns The schema instance for chaining.\n */\n withMetadata(meta: SchemaMetadata<Output>): this {\n this._meta = { ...this._meta, ...meta };\n return this;\n }\n\n /**\n * Makes this schema optional, allowing undefined values.\n * @returns An OptionalSchema wrapping this schema.\n */\n optional(): OptionalSchema<this> {\n return new OptionalSchema(this);\n }\n\n /**\n * Converts this nubase schema to a Zod schema.\n * @returns The equivalent Zod schema.\n */\n abstract toZod(): z.ZodSchema<Output>;\n}\n\n// --- Primitive Schemas ---\n\nexport class BooleanSchema extends BaseSchema<boolean> {\n readonly type = \"boolean\" as const;\n\n override get defaultValue(): boolean {\n return this._meta?.defaultValue ?? false;\n }\n\n toZod(): z.ZodBoolean {\n return z.boolean();\n }\n}\n\nexport class StringSchema extends BaseSchema<string> {\n readonly type = \"string\" as const;\n\n override get defaultValue(): string {\n return this._meta?.defaultValue ?? \"\";\n }\n\n toZod(): z.ZodString {\n return z.string();\n }\n}\n\nexport class NumberSchema extends BaseSchema<number> {\n readonly type = \"number\" as const;\n\n override get defaultValue(): number {\n return this._meta?.defaultValue ?? 0;\n }\n\n toZod(): z.ZodNumber {\n return z.number();\n }\n}\n\n// --- Optional Schema ---\n\n/**\n * A wrapper schema that makes the wrapped schema optional.\n * Allows undefined values in addition to the wrapped schema's type.\n */\nexport class OptionalSchema<\n TWrapped extends BaseSchema<any>,\n> extends BaseSchema<TWrapped[\"_outputType\"] | undefined> {\n readonly type = \"optional\" as const;\n _wrapped: TWrapped;\n\n constructor(wrapped: TWrapped) {\n super();\n this._wrapped = wrapped;\n }\n\n /**\n * Get the underlying wrapped schema.\n * @returns The wrapped schema.\n */\n unwrap(): TWrapped {\n return this._wrapped;\n }\n\n /**\n * Returns the base type of the wrapped schema.\n * This allows getting the underlying type (e.g., \"number\") even when wrapped in OptionalSchema.\n */\n override get baseType(): string {\n return this._wrapped.baseType;\n }\n\n /**\n * Optional fields default to undefined (which becomes null during validation).\n */\n override get defaultValue(): TWrapped[\"_outputType\"] | undefined {\n return this._meta?.defaultValue ?? undefined;\n }\n\n toZod(): z.ZodOptional<z.ZodNullable<z.ZodSchema<TWrapped[\"_outputType\"]>>> {\n return this._wrapped.toZod().nullable().optional();\n }\n}\n\n// --- Complex Schemas ---\n\n/**\n * Type representing the shape of an object schema (key to schema mapping).\n */\nexport type ObjectShape = {\n [key: string]: BaseSchema<any>;\n};\n\n/**\n * Infers the TypeScript output type from an ObjectShape.\n * Use mapped types to get the output type of each property schema.\n * Required keys are those that are not OptionalSchema instances.\n * Optional keys are those that are OptionalSchema instances.\n */\nexport type ObjectOutput<TShape extends ObjectShape> = {\n [K in keyof TShape as TShape[K] extends OptionalSchema<any>\n ? never\n : K]: TShape[K][\"_outputType\"];\n} & {\n [K in keyof TShape as TShape[K] extends OptionalSchema<any>\n ? K\n : never]?: TShape[K][\"_outputType\"];\n};\n\n/**\n * Type representing computed metadata for object properties.\n */\nexport type ObjectComputedMetadata<TShape extends ObjectShape> = {\n [K in keyof TShape]?: Partial<\n ComputedSchemaMetadata<TShape[K][\"_outputType\"], ObjectOutput<TShape>>\n >;\n};\n\n// --- Layout Types ---\n\n/**\n * Represents a field within a layout group.\n */\nexport interface FormLayoutField<TShape extends ObjectShape> {\n /** The name of the field - must be a valid property key from the object shape */\n name: keyof TShape;\n /** Width of the field in grid units (1-12) - number of 1/12 spaces it occupies */\n fieldWidth?: number;\n /** Additional CSS classes for styling */\n className?: string;\n /** Whether the field should be hidden */\n hidden?: boolean;\n}\n\n/**\n * Represents a group of fields within a layout.\n */\nexport interface LayoutGroup<TShape extends ObjectShape> {\n /** Label for the group */\n label?: string;\n /** Description for the group */\n description?: string;\n /** Array of fields in this group */\n fields: FormLayoutField<TShape>[];\n /** Additional CSS classes for the group */\n className?: string;\n /** Whether the group should be collapsible */\n collapsible?: boolean;\n /** Whether the group is initially collapsed (if collapsible) */\n defaultCollapsed?: boolean;\n}\n\n/**\n * Represents a complete layout configuration.\n */\nexport interface Layout<TShape extends ObjectShape> {\n /** Type of layout */\n type: \"form\" | \"grid\" | \"tabs\" | \"accordion\" | \"custom\" | \"table\";\n /** Groups of fields within the layout */\n groups: LayoutGroup<TShape>[];\n /** Additional CSS classes for the layout */\n className?: string;\n /** Layout-specific configuration */\n config?: {\n /** Number of columns for grid layouts */\n columns?: number;\n /** Gap between elements */\n gap?: string | number;\n /** Other layout-specific options */\n [key: string]: any;\n };\n /** Layout metadata - can contain any metadata, specific layouts may have specific metadata */\n metadata?: Record<string, any>;\n}\n\n/**\n * Form layout specific interface\n */\nexport interface FormLayout<TShape extends ObjectShape> extends Layout<TShape> {\n type: \"form\";\n groups: LayoutGroup<TShape>[];\n}\n\n/**\n * Table layout specific field\n */\nexport interface TableLayoutField<TShape extends ObjectShape> {\n /** The name of the field - must be a valid property key from the object shape */\n name: keyof TShape;\n /** Additional CSS classes for styling */\n className?: string;\n /** Whether the field should be hidden */\n hidden?: boolean;\n /** Column width in pixels - unlike fieldWidth, this is in pixels */\n columnWidthPx?: number;\n /** Whether the column should be pinned/frozen to the left */\n pinned?: boolean;\n}\n\n/**\n * Table layout specific interface\n */\nexport interface TableLayout<TShape extends ObjectShape>\n extends Layout<TShape> {\n type: \"table\";\n /** For tables, we only have one group internally but expose fields directly */\n groups: LayoutGroup<TShape>[];\n /** Table-specific metadata */\n metadata?: {\n /** Fields that should be clickable links to view the entity */\n linkFields?: (keyof TShape)[];\n /** Other metadata */\n [key: string]: any;\n };\n}\n\n/**\n * Type representing multiple layouts for an object schema.\n */\nexport type ObjectLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: Layout<TShape>;\n};\n\n/**\n * Type representing multiple form layouts\n */\nexport type FormLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: FormLayout<TShape>;\n};\n\n/**\n * Type representing multiple table layouts\n */\nexport type TableLayouts<TShape extends ObjectShape> = {\n [layoutName: string]: TableLayout<TShape>;\n};\n\n/**\n * ObjectSchema with optional catchall.\n *\n * Note on typing: When using .catchall(), the output type remains ObjectOutput<TShape>.\n * TypeScript cannot express \"extra keys have type X\" without conflicting with defined keys.\n * The catchall provides runtime validation and passthrough behavior, but dynamic keys\n * should be accessed via type assertion: `(data as any).dynamicKey` or `data[\"dynamicKey\"]`.\n */\nexport class ObjectSchema<\n TShape extends ObjectShape = any,\n TCatchall extends BaseSchema<any> | null = null,\n> extends BaseSchema<ObjectOutput<TShape>> {\n readonly type = \"object\" as const;\n _shape: TShape;\n _computedMeta: ObjectComputedMetadata<TShape> = {};\n _layouts: ObjectLayouts<TShape> = {};\n _idField: keyof ObjectOutput<TShape> = \"id\" as keyof ObjectOutput<TShape>;\n _catchall: TCatchall = null as TCatchall;\n _passthrough = false;\n\n constructor(shape: TShape, catchall?: TCatchall) {\n super();\n this._shape = shape;\n if (catchall) {\n this._catchall = catchall;\n }\n }\n\n /**\n * Allow additional properties beyond the defined shape, validated against the provided schema.\n * Similar to Zod's .catchall() method.\n *\n * @example\n * const chartDataSchema = nu.object({ category: nu.string() }).catchall(nu.number());\n * // Validates: { category: \"Jan\", desktop: 186, mobile: 80 }\n *\n * @param schema The schema to validate additional properties against.\n * @returns A new ObjectSchema that allows additional properties.\n */\n catchall<TCatchallSchema extends BaseSchema<any>>(\n schema: TCatchallSchema,\n ): ObjectSchema<TShape, TCatchallSchema> {\n const newSchema = new ObjectSchema<TShape, TCatchallSchema>(\n this._shape,\n schema,\n );\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta } as any;\n newSchema._computedMeta = { ...this._computedMeta };\n newSchema._layouts = { ...this._layouts };\n newSchema._idField = this._idField;\n newSchema._passthrough = this._passthrough;\n\n return newSchema;\n }\n\n /**\n * Allow any additional properties beyond the defined shape without validation.\n * Similar to Zod's .passthrough() method.\n *\n * @example\n * const rowSchema = nu.object({}).passthrough();\n * // Validates: { user: \"John\", action: \"Created\", time: \"2m ago\" }\n *\n * @returns A new ObjectSchema that passes through additional properties.\n */\n passthrough(): ObjectSchema<TShape, TCatchall> {\n const newSchema = new ObjectSchema<TShape, TCatchall>(\n this._shape,\n this._catchall as TCatchall,\n );\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta } as any;\n newSchema._computedMeta = { ...this._computedMeta };\n newSchema._layouts = { ...this._layouts };\n newSchema._idField = this._idField;\n newSchema._passthrough = true;\n\n return newSchema;\n }\n\n /**\n * Add computed metadata to the object schema.\n * @param computedMeta Object mapping property keys to computed metadata functions.\n * @returns The schema instance for chaining.\n */\n withComputed(computedMeta: ObjectComputedMetadata<TShape>): this {\n this._computedMeta = computedMeta;\n return this;\n }\n\n /**\n * Add layouts to the object schema.\n * @param layouts Object mapping layout names to layout configurations.\n * @returns The schema instance for chaining.\n * @deprecated Use withFormLayouts or withTableLayouts instead\n */\n withLayouts(layouts: ObjectLayouts<TShape>): this {\n this._layouts = layouts;\n return this;\n }\n\n /**\n * Add form layouts to the object schema.\n * @param layouts Object mapping layout names to form layout configurations.\n * @returns The schema instance for chaining.\n */\n withFormLayouts(layouts: FormLayouts<TShape>): this {\n // Form layouts are stored directly in _layouts\n this._layouts = { ...this._layouts, ...layouts };\n return this;\n }\n\n /**\n * Add table layouts to the object schema.\n * @param layouts Object mapping layout names to table layout configurations with fields and optional linkFields.\n * @returns The schema instance for chaining.\n */\n withTableLayouts(layouts: {\n [layoutName: string]: {\n fields: TableLayoutField<TShape>[];\n className?: string;\n config?: Layout<TShape>[\"config\"];\n metadata?: {\n linkFields?: (keyof TShape)[];\n [key: string]: any;\n };\n };\n }): this {\n // Convert the table-specific format to internal Layout format\n const tableLayouts: TableLayouts<TShape> = {};\n\n for (const [name, tableConfig] of Object.entries(layouts)) {\n // Create a single group with all fields for internal consistency\n tableLayouts[name] = {\n type: \"table\",\n groups: [\n {\n fields: tableConfig.fields,\n },\n ],\n className: tableConfig.className,\n config: tableConfig.config,\n metadata: tableConfig.metadata,\n };\n }\n\n this._layouts = { ...this._layouts, ...tableLayouts };\n return this;\n }\n\n /**\n * Specify which field serves as the unique identifier for this object schema.\n * This is used by resource operations to determine how to identify specific records.\n * @param idField The field name or a selector function that returns the ID field.\n * @returns The schema instance for chaining.\n */\n withId<K extends keyof ObjectOutput<TShape>>(\n idField: K | ((schema: ObjectOutput<TShape>) => ObjectOutput<TShape>[K]),\n ): this {\n if (typeof idField === \"function\") {\n // For function form, we need to extract the field name\n // This is a bit tricky, but for now we'll assume the user passes the field name directly\n throw new Error(\n \"Function form of withId is not yet supported. Please pass the field name directly.\",\n );\n }\n this._idField = idField;\n return this;\n }\n\n /**\n * Get the ID field name for this object schema.\n * @returns The field name that serves as the unique identifier.\n */\n getIdField(): keyof ObjectOutput<TShape> {\n return this._idField;\n }\n\n /**\n * Get a specific layout by name.\n * @param layoutName The name of the layout to retrieve.\n * @returns The layout configuration or undefined if not found.\n */\n getLayout(layoutName: string): Layout<TShape> | undefined {\n return this._layouts[layoutName];\n }\n\n /**\n * Get all available layout names.\n * @returns Array of layout names.\n */\n getLayoutNames(): string[] {\n return Object.keys(this._layouts);\n }\n\n /**\n * Check if a layout exists.\n * @param layoutName The name of the layout to check.\n * @returns True if the layout exists, false otherwise.\n */\n hasLayout(layoutName: string): boolean {\n return layoutName in this._layouts;\n }\n\n /**\n * Get the computed metadata for a specific property.\n * @param key The property key.\n * @param data The parsed object data to pass to computed functions.\n * @returns Promise resolving to the computed metadata.\n */\n async getComputedMeta(\n key: keyof TShape,\n data: ObjectOutput<TShape>,\n ): Promise<Partial<SchemaMetadata<TShape[typeof key][\"_outputType\"]>>> {\n const computedMeta = this._computedMeta[key];\n if (!computedMeta) {\n return {};\n }\n\n const result: any = {};\n\n if (computedMeta.label) {\n result.label = await computedMeta.label(data);\n }\n\n if (computedMeta.description) {\n result.description = await computedMeta.description(data);\n }\n\n if (computedMeta.defaultValue) {\n result.defaultValue = await computedMeta.defaultValue(data);\n }\n\n return result;\n }\n\n /**\n * Get all computed metadata for all properties.\n * @param data The parsed object data to pass to computed functions.\n * @returns Promise resolving to a map of property keys to computed metadata.\n */\n async getAllComputedMeta(\n data: ObjectOutput<TShape>,\n ): Promise<Record<keyof TShape, Partial<SchemaMetadata<any>>>> {\n const result: any = {};\n\n for (const key in this._shape) {\n result[key] = await this.getComputedMeta(key, data);\n }\n\n return result;\n }\n\n /**\n * Get merged metadata (static + computed) for all properties.\n * @param data The current form data to pass to computed functions.\n * @returns Promise resolving to a map of property keys to merged metadata.\n */\n async getAllMergedMeta(\n data: Partial<ObjectOutput<TShape>>,\n ): Promise<Record<keyof TShape, SchemaMetadata<any>>> {\n const result: any = {};\n\n // Start with static metadata for each property\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n let schema = this._shape[key];\n if (schema) {\n // If it's an OptionalSchema, get the wrapped schema's metadata\n if (schema instanceof OptionalSchema) {\n schema = schema._wrapped;\n }\n result[key] = { ...(schema?._meta || {}) };\n }\n }\n }\n\n // Only compute if we have computed metadata and valid data\n if (Object.keys(this._computedMeta).length > 0) {\n try {\n // Try to create a complete object for computed functions\n // Use provided data and fill missing properties with default values\n const completeData: any = {};\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n const schema = this._shape[key];\n if (schema) {\n // If it's an OptionalSchema, use the wrapped schema for type checking\n const actualSchema =\n schema instanceof OptionalSchema ? schema._wrapped : schema;\n\n if ((data as any)[key] !== undefined) {\n completeData[key] = (data as any)[key];\n } else if (actualSchema._meta.defaultValue !== undefined) {\n completeData[key] = actualSchema._meta.defaultValue;\n } else {\n // Provide reasonable defaults for computation\n if (actualSchema instanceof StringSchema) {\n completeData[key] = \"\";\n } else if (actualSchema instanceof NumberSchema) {\n completeData[key] = 0;\n } else if (actualSchema instanceof BooleanSchema) {\n completeData[key] = false;\n } else {\n completeData[key] = null;\n }\n }\n }\n }\n }\n\n // Compute all metadata at once\n const computedMeta = await this.getAllComputedMeta(\n completeData as ObjectOutput<TShape>,\n );\n\n // Merge computed metadata with static metadata\n for (const key in computedMeta) {\n if (computedMeta[key]) {\n result[key] = {\n ...result[key],\n ...computedMeta[key],\n };\n }\n }\n } catch (error) {\n // If computation fails, just use static metadata\n console.warn(\"Failed to compute metadata:\", error);\n }\n }\n\n return result;\n }\n\n /**\n * Create a new ObjectSchema with certain properties omitted.\n * @param keys The property keys to omit from the schema.\n * @returns A new ObjectSchema without the specified properties.\n */\n omit<K extends keyof TShape>(...keys: K[]): ObjectSchema<Omit<TShape, K>> {\n const newShape: any = {};\n const keysToOmit = new Set(keys);\n\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && !keysToOmit.has(key as any)) {\n newShape[key] = this._shape[key];\n }\n }\n\n const newSchema = new ObjectSchema(newShape);\n\n // Copy metadata from parent schema\n newSchema._meta = { ...this._meta };\n\n // Copy computed metadata, excluding omitted keys\n const newComputedMeta: any = {};\n for (const key in this._computedMeta) {\n if (!keysToOmit.has(key as any)) {\n newComputedMeta[key] = this._computedMeta[key];\n }\n }\n newSchema._computedMeta = newComputedMeta;\n\n // Copy layouts, updating field references to exclude omitted keys\n const newLayouts: any = {};\n for (const layoutName in this._layouts) {\n const originalLayout = this._layouts[layoutName];\n if (originalLayout) {\n const newGroups = originalLayout.groups.map((group) => ({\n ...group,\n fields: group.fields.filter(\n (field) => !keysToOmit.has(field.name as any),\n ),\n }));\n newLayouts[layoutName] = {\n ...originalLayout,\n groups: newGroups,\n };\n }\n }\n newSchema._layouts = newLayouts;\n\n return newSchema;\n }\n\n /**\n * Create a new ObjectSchema with additional or modified properties.\n * @param shape The new properties to add or existing properties to modify.\n * @returns A new ObjectSchema with the extended shape.\n */\n extend<TExtend extends ObjectShape>(\n shape: TExtend,\n ): ObjectSchema<TShape & TExtend> {\n const newShape = { ...this._shape, ...shape } as TShape & TExtend;\n const newSchema = new ObjectSchema(newShape);\n\n // Copy metadata from parent schema (with proper typing)\n newSchema._meta = { ...this._meta } as any;\n\n // Copy computed metadata from parent schema (with proper typing)\n newSchema._computedMeta = { ...this._computedMeta } as any;\n\n // Copy layouts from parent schema - new fields won't appear in layouts unless explicitly added\n newSchema._layouts = { ...this._layouts } as any;\n\n return newSchema;\n }\n\n /**\n * Create a new ObjectSchema where all top-level properties become optional.\n * This wraps each field in an OptionalSchema, similar to how Zod handles partial.\n * @returns A new ObjectSchema where all properties are optional.\n */\n partial(): ObjectSchema<{ [K in keyof TShape]: OptionalSchema<TShape[K]> }> {\n const partialShape: any = {};\n\n // Wrap each field in OptionalSchema if not already optional\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key)) {\n const fieldSchema = this._shape[key];\n if (fieldSchema) {\n if (fieldSchema instanceof OptionalSchema) {\n // Already optional, keep as is\n partialShape[key] = fieldSchema;\n } else {\n // Wrap in OptionalSchema to make it optional\n partialShape[key] = fieldSchema.optional();\n }\n }\n }\n }\n\n const partialSchema = new ObjectSchema(partialShape);\n\n // Copy metadata from parent schema\n partialSchema._meta = { ...this._meta };\n\n // Copy computed metadata from parent schema\n partialSchema._computedMeta = { ...this._computedMeta };\n\n // Copy layouts from parent schema\n partialSchema._layouts = { ...this._layouts };\n\n return partialSchema;\n }\n\n toZod(): z.ZodSchema<ObjectOutput<TShape>> {\n const zodShape: Record<string, z.ZodTypeAny> = {};\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && this._shape[key]) {\n const fieldSchema = this._shape[key];\n zodShape[key] = fieldSchema.toZod();\n }\n }\n\n const baseZod = z.object(zodShape);\n\n // If catchall is defined, use it to allow additional properties\n if (this._catchall) {\n return baseZod.catchall(this._catchall.toZod()) as any;\n }\n\n // If passthrough is enabled, allow any additional properties\n if (this._passthrough) {\n return baseZod.passthrough() as any;\n }\n\n return baseZod as any;\n }\n\n /**\n * Returns a Zod schema with URL coercion enabled.\n * This automatically converts string values from URL parameters to the expected types:\n * - \"37\" → 37 (number)\n * - \"true\" → true (boolean)\n * - \"hello\" → \"hello\" (string, unchanged)\n *\n * Use this when parsing URL search params that arrive as strings but need to be typed.\n *\n * @returns A Zod schema with coercion for URL parameter parsing\n */\n toZodWithCoercion(): z.ZodSchema<ObjectOutput<TShape>> {\n const zodShape: Record<string, z.ZodTypeAny> = {};\n\n for (const key in this._shape) {\n if (Object.hasOwn(this._shape, key) && this._shape[key]) {\n const fieldSchema = this._shape[key];\n const baseZodSchema = fieldSchema.toZod();\n\n // Apply coercion based on the field's type\n const wrappedType =\n fieldSchema.type === \"optional\"\n ? (fieldSchema as OptionalSchema<any>)._wrapped.type\n : null;\n\n if (fieldSchema.type === \"number\" || wrappedType === \"number\") {\n const coercedSchema = z.coerce.number();\n // For optional fields, preserve the optional nature\n if (fieldSchema.type === \"optional\") {\n zodShape[key] = coercedSchema.nullable().optional();\n } else {\n zodShape[key] = coercedSchema;\n }\n } else if (\n fieldSchema.type === \"boolean\" ||\n wrappedType === \"boolean\"\n ) {\n // Custom boolean coercion that properly handles \"false\" and \"true\" strings\n const customBooleanCoercion = z.preprocess((val) => {\n if (typeof val === \"string\") {\n const lower = val.toLowerCase();\n if (lower === \"true\" || lower === \"1\") return true;\n if (lower === \"false\" || lower === \"0\") return false;\n }\n return val;\n }, z.boolean());\n\n // For optional fields, preserve the optional nature\n if (fieldSchema.type === \"optional\") {\n zodShape[key] = customBooleanCoercion.nullable().optional();\n } else {\n zodShape[key] = customBooleanCoercion;\n }\n } else {\n // For strings and other types, use the original schema\n zodShape[key] = baseZodSchema;\n }\n }\n }\n return z.object(zodShape) as z.ZodSchema<ObjectOutput<TShape>>;\n }\n}\n\n/**\n * Infers the TypeScript output type from an element schema for an array.\n */\nexport type ArrayOutput<TElementSchema extends BaseSchema<any>> = Array<\n TElementSchema[\"_outputType\"]\n>;\n\nexport class ArraySchema<\n TElementSchema extends BaseSchema<any>,\n> extends BaseSchema<ArrayOutput<TElementSchema>> {\n readonly type = \"array\" as const;\n _element: TElementSchema;\n\n constructor(elementSchema: TElementSchema) {\n super();\n this._element = elementSchema;\n }\n\n toZod(): z.ZodArray<z.ZodSchema<TElementSchema[\"_outputType\"]>> {\n return z.array(this._element.toZod());\n }\n}\n\n/**\n * RecordSchema represents a dictionary/map type with string keys and values of a specific type.\n * Similar to TypeScript's Record<string, T> or Zod's z.record().\n *\n * @example\n * const scoresSchema = nu.record(nu.number());\n * // Represents: { [key: string]: number }\n */\nexport class RecordSchema<\n TValueSchema extends BaseSchema<any>,\n> extends BaseSchema<Record<string, TValueSchema[\"_outputType\"]>> {\n readonly type = \"record\" as const;\n _valueSchema: TValueSchema;\n\n constructor(valueSchema: TValueSchema) {\n super();\n this._valueSchema = valueSchema;\n }\n\n toZod(): z.ZodRecord<z.ZodString, z.ZodSchema<TValueSchema[\"_outputType\"]>> {\n return z.record(z.string(), this._valueSchema.toZod());\n }\n}\n\n/**\n * Infers the TypeScript type from a schema.\n * @example\n * const userSchema = nu.object({ name: nu.string() });\n * type User = Infer&lt;typeof userSchema&gt;; // { name: string }\n */\nexport type Infer<T extends BaseSchema<any>> = T[\"_outputType\"];\n\n// Refine NuSchema union after defining concrete types\nexport type NuSchema =\n | BooleanSchema\n | StringSchema\n | NumberSchema\n | OptionalSchema<any>\n | ObjectSchema<any>\n | ArraySchema<any>\n | RecordSchema<any>;\n","import {\n ArraySchema,\n type BaseSchema,\n BooleanSchema,\n NumberSchema,\n ObjectSchema,\n type ObjectShape,\n RecordSchema,\n StringSchema,\n} from \"./schema\";\n\n/**\n * The main nubase schema instance.\n * Provides factory methods to create different schema types.\n */\nexport const nu = {\n boolean: () => new BooleanSchema(),\n /**\n * Creates a string schema.\n */\n string: () => new StringSchema(),\n\n /**\n * Creates a number schema.\n */\n number: () => new NumberSchema(),\n\n /**\n * Creates an object schema with a defined shape.\n * @param shape An object mapping keys to schemas.\n */\n object: <TShape extends ObjectShape>(shape: TShape) =>\n new ObjectSchema(shape),\n\n /**\n * Creates an array schema with a defined element schema.\n * @param elementSchema The schema for elements within the array.\n */\n array: <TElementSchema extends BaseSchema<any>>(\n elementSchema: TElementSchema,\n ) => new ArraySchema(elementSchema),\n\n /**\n * Creates a record schema (dictionary) with string keys and values of a specific type.\n * Similar to TypeScript's Record<string, T>.\n *\n * @example\n * const scoresSchema = nu.record(nu.number());\n * // Represents: { [key: string]: number }\n *\n * @param valueSchema The schema for values in the record.\n */\n record: <TValueSchema extends BaseSchema<any>>(valueSchema: TValueSchema) =>\n new RecordSchema(valueSchema),\n};\n","import { nu } from \"./nu\";\n\nexport const emptySchema = nu.object({});\n\nexport const idNumberSchema = nu.object({\n id: nu.number(),\n});\n\nexport const idStringSchema = nu.object({\n id: nu.string(),\n});\n\n// Simple success response (e.g., for DELETE operations)\nexport const successSchema = nu.object({\n success: nu.boolean(),\n});\n\n// Success response with optional message\nexport const successMessageSchema = nu.object({\n success: nu.boolean(),\n message: nu.string().optional(),\n});\n\n// Success/error response with optional errors array\nexport const successErrorSchema = nu.object({\n success: nu.boolean(),\n message: nu.string().optional(),\n errors: nu\n .array(\n nu.object({\n field: nu.string().optional(),\n message: nu.string(),\n }),\n )\n .optional(),\n});\n","import { nu } from \"./nu\";\n\nexport const errorSchema = nu.object({\n errorCode: nu.string(), // required by default\n errorMessage: nu.string(), // required by default\n});\n","/**\n * Represents a validation error in Nubase schema validation\n */\nexport interface NubaseValidationError {\n path: string;\n message: string;\n value?: unknown;\n}\n\n/**\n * Error thrown when Nubase schema validation fails\n */\nexport class NubaseSchemaError extends Error {\n public readonly errors: NubaseValidationError[];\n\n constructor(errors: NubaseValidationError[]) {\n const message = `Schema validation failed:\\n${errors\n .map((e) => ` - ${e.path}: ${e.message}`)\n .join(\"\\n\")}`;\n\n super(message);\n this.name = \"NubaseSchemaError\";\n this.errors = errors;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Creates a NubaseSchemaError from a list of error messages\n */\n static fromMessages(errorMessages: string[]): NubaseSchemaError {\n const errors: NubaseValidationError[] = errorMessages.map((message) => {\n // Try to extract path from error message format \"Property 'field': message\"\n const match = message.match(/^Property '([^']+)':\\s*(.+)$/);\n if (match?.[1] && match[2]) {\n return {\n path: match[1],\n message: match[2],\n };\n }\n // Fallback for messages without a clear path\n return {\n path: \"root\",\n message: message,\n };\n });\n\n return new NubaseSchemaError(errors);\n }\n\n /**\n * Type guard to check if an error is a NubaseSchemaError\n */\n static isNubaseSchemaError(error: unknown): error is NubaseSchemaError {\n return error instanceof NubaseSchemaError;\n }\n}\n","import { nu } from \"./nu\";\nimport type { RequestSchema } from \"./request-schema\";\nimport type { Infer, NumberSchema, StringSchema } from \"./schema\";\n\n/**\n * Schema type that can be used for lookup IDs.\n * Supports both string IDs (UUIDs) and numeric IDs (auto-increment).\n */\nexport type LookupIdSchema = StringSchema | NumberSchema;\n\n/**\n * Creates a lookup schema with the specified ID type.\n * This is the standardized format that all lookup endpoints must return.\n *\n * @param idSchema The schema for the ID field (nu.string() or nu.number())\n */\nexport function createLookupSchema<TIdSchema extends LookupIdSchema>(\n idSchema: TIdSchema,\n) {\n return nu.object({\n /** Unique identifier for the entity */\n id: idSchema,\n /** Primary display text (e.g., user's display name) */\n title: nu.string(),\n /** Optional secondary text (e.g., email address) */\n subtitle: nu.string().optional(),\n /** Optional image URL or data URL for avatar display */\n image: nu.string().optional(),\n });\n}\n\n/**\n * The default Lookup schema with string IDs.\n * For numeric IDs, use createLookupSchema(nu.number()) instead.\n */\nexport const lookupSchema = createLookupSchema(nu.string());\n\n/**\n * The Lookup type with string IDs - the display representation of an entity in lookup/select components.\n * For numeric IDs, use Infer<ReturnType<typeof createLookupSchema<NumberSchema>>>.\n */\nexport type Lookup = Infer<typeof lookupSchema>;\n\n/**\n * Creates a lookup endpoint schema for a resource.\n * Lookup endpoints accept a query string and return an array of Lookup objects.\n *\n * @example\n * ```typescript\n * // For string IDs (UUIDs):\n * export const lookupUsersSchema = createLookupEndpoint(\"users\", nu.string());\n *\n * // For numeric IDs (auto-increment):\n * export const lookupUsersSchema = createLookupEndpoint(\"users\", nu.number());\n *\n * // Creates: GET /lookup/users?q=<query> → Lookup[]\n * ```\n *\n * @param resourceName The name of the resource (used in the path: /lookup/{resourceName})\n * @param idSchema The schema for the ID field - use nu.string() for UUIDs or nu.number() for auto-increment IDs\n * @returns A RequestSchema for the lookup endpoint\n */\nexport function createLookupEndpoint<TIdSchema extends LookupIdSchema>(\n resourceName: string,\n idSchema: TIdSchema,\n): RequestSchema {\n return {\n method: \"GET\" as const,\n path: `/lookup/${resourceName}`,\n requestParams: nu.object({\n /** The search query string */\n q: nu.string(),\n }),\n responseBody: nu.array(createLookupSchema(idSchema)),\n };\n}\n","import { nu } from \"./nu\";\nimport type { Infer } from \"./schema\";\n\n// =============================================================================\n// SERIES DATA (for Line, Bar, Area charts)\n// =============================================================================\n\n/**\n * Configuration for series charts.\n * Defines which data keys represent the series and their display properties.\n */\nexport const seriesConfigSchema = nu.object({\n /** The data key field names that represent numeric series (e.g., [\"desktop\", \"mobile\"]) */\n keys: nu.array(nu.string()),\n /** Optional labels for each key (e.g., { desktop: \"Desktop Users\" }) */\n labels: nu.object({}).optional(),\n /** Optional colors for each key (e.g., { desktop: \"var(--chart1)\" }) */\n colors: nu.object({}).optional(),\n});\n\n/**\n * A single data point in a series chart.\n * The 'category' is the x-axis label (e.g., \"January\", \"Q1\", \"2024-01\").\n * Additional numeric fields are the data series values (e.g., desktop: 186, mobile: 80).\n *\n * Uses .catchall(nu.number()) to allow dynamic numeric fields beyond 'category'.\n */\nexport const seriesDataPointSchema = nu\n .object({\n category: nu.string(),\n })\n .catchall(nu.number());\n\n/**\n * Complete series data response from an endpoint.\n * Used for Line, Bar, and Area charts.\n */\nexport const seriesDataSchema = nu.object({\n type: nu.string(), // \"series\"\n config: seriesConfigSchema,\n data: nu.array(seriesDataPointSchema),\n});\n\nexport type SeriesConfig = Infer<typeof seriesConfigSchema>;\n// The schema uses .catchall(nu.number()) for runtime validation of dynamic fields.\n// TypeScript type is manually extended with Record<string, number> for type safety.\nexport type SeriesDataPoint = Infer<typeof seriesDataPointSchema> &\n Record<string, number>;\nexport type SeriesData = {\n type: \"series\";\n config: SeriesConfig;\n data: SeriesDataPoint[];\n};\n\n// =============================================================================\n// PROPORTIONAL DATA (for Pie, Donut charts)\n// =============================================================================\n\n/**\n * A single segment in a proportional chart.\n * Note: Colors are automatically assigned by the frontend based on index.\n */\nexport const proportionalDataItemSchema = nu.object({\n label: nu.string(),\n value: nu.number(),\n});\n\n/**\n * Complete proportional data response from an endpoint.\n * Used for Pie and Donut charts.\n */\nexport const proportionalDataSchema = nu.object({\n type: nu.string(), // \"proportional\"\n data: nu.array(proportionalDataItemSchema),\n});\n\nexport type ProportionalDataItem = Infer<typeof proportionalDataItemSchema>;\nexport type ProportionalData = {\n type: \"proportional\";\n data: Array<ProportionalDataItem & { fill?: string }>;\n};\n\n// =============================================================================\n// KPI DATA (single value display)\n// =============================================================================\n\n/**\n * KPI/stat widget data for displaying a single metric.\n */\nexport const kpiDataSchema = nu.object({\n type: nu.string(), // \"kpi\"\n value: nu.string(),\n label: nu.string().optional(),\n trend: nu.string().optional(),\n trendDirection: nu.string().optional(), // \"up\" | \"down\" | \"neutral\"\n});\n\nexport type KpiData = {\n type: \"kpi\";\n value: string;\n label?: string;\n trend?: string;\n trendDirection?: \"up\" | \"down\" | \"neutral\";\n};\n\n// =============================================================================\n// TABLE DATA (rows of data)\n// =============================================================================\n\n/**\n * Column definition for table widgets.\n */\nexport const tableColumnSchema = nu.object({\n key: nu.string(),\n label: nu.string(),\n width: nu.string().optional(),\n});\n\n/**\n * Complete table data response from an endpoint.\n * Uses passthrough() for rows to allow any properties in the row objects.\n */\nexport const tableDataSchema = nu.object({\n type: nu.string(), // \"table\"\n columns: nu.array(tableColumnSchema),\n rows: nu.array(nu.object({}).passthrough()), // Record<string, unknown>[]\n});\n\nexport type TableColumn = Infer<typeof tableColumnSchema>;\nexport type TableData = {\n type: \"table\";\n columns: TableColumn[];\n rows: Record<string, unknown>[];\n};\n\n// =============================================================================\n// WIDGET DATA UNION\n// =============================================================================\n\n/**\n * Union of all possible widget data types.\n */\nexport type WidgetData = SeriesData | ProportionalData | KpiData | TableData;\n\n/**\n * Widget data type discriminator.\n */\nexport type WidgetDataType = \"series\" | \"proportional\" | \"kpi\" | \"table\";\n","import { emptySchema } from \"./empty-schema\";\nimport type { ObjectSchema } from \"./schema\";\nimport {\n kpiDataSchema,\n proportionalDataSchema,\n seriesDataSchema,\n tableDataSchema,\n} from \"./widget-data-schema\";\n\n/**\n * Type for a series widget endpoint that preserves the responseBody type.\n */\nexport type SeriesWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof seriesDataSchema;\n};\n\n/**\n * Type for a proportional widget endpoint that preserves the responseBody type.\n */\nexport type ProportionalWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof proportionalDataSchema;\n};\n\n/**\n * Type for a KPI widget endpoint that preserves the responseBody type.\n */\nexport type KpiWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof kpiDataSchema;\n};\n\n/**\n * Type for a table widget endpoint that preserves the responseBody type.\n */\nexport type TableWidgetRequestSchema = {\n method: \"GET\";\n path: string;\n requestParams: ObjectSchema<any>;\n responseBody: typeof tableDataSchema;\n};\n\n/**\n * Creates a RequestSchema for a Series widget endpoint.\n * The response conforms to SeriesData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/revenue\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for series data\n *\n * @example\n * ```typescript\n * export const getRevenueChartSchema = createSeriesWidgetEndpoint(\"/dashboard/revenue\");\n * ```\n */\nexport function createSeriesWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): SeriesWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: seriesDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a Proportional widget endpoint.\n * The response conforms to ProportionalData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/browser-stats\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for proportional data\n *\n * @example\n * ```typescript\n * export const getBrowserStatsSchema = createProportionalWidgetEndpoint(\"/dashboard/browsers\");\n * ```\n */\nexport function createProportionalWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): ProportionalWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: proportionalDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a KPI widget endpoint.\n * The response conforms to KpiData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/total-revenue\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for KPI data\n *\n * @example\n * ```typescript\n * export const getTotalRevenueSchema = createKpiWidgetEndpoint(\"/dashboard/total-revenue\");\n * ```\n */\nexport function createKpiWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): KpiWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: kpiDataSchema,\n };\n}\n\n/**\n * Creates a RequestSchema for a Table widget endpoint.\n * The response conforms to TableData shape.\n *\n * @param path The API endpoint path (e.g., \"/dashboard/recent-orders\")\n * @param requestParams Optional request parameters schema\n * @returns A RequestSchema configured for table data\n *\n * @example\n * ```typescript\n * export const getRecentOrdersSchema = createTableWidgetEndpoint(\"/dashboard/orders\");\n * ```\n */\nexport function createTableWidgetEndpoint(\n path: string,\n requestParams?: ObjectSchema<any>,\n): TableWidgetRequestSchema {\n return {\n method: \"GET\",\n path,\n requestParams: requestParams || emptySchema,\n responseBody: tableDataSchema,\n };\n}\n"],"mappings":"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","names":["axios"]}
package/dist/index.mjs CHANGED
@@ -271,6 +271,22 @@ var BaseSchema = class {
271
271
  * @internal
272
272
  */
273
273
  _outputType;
274
+ /**
275
+ * The base type of this schema, unwrapping any wrapper schemas (like OptionalSchema).
276
+ * For most schemas, this is the same as `type`. For wrapper schemas like OptionalSchema,
277
+ * this returns the type of the innermost wrapped schema.
278
+ */
279
+ get baseType() {
280
+ return this.type;
281
+ }
282
+ /**
283
+ * The default value for this schema type.
284
+ * Returns the user-configured default from metadata, or a sensible type-specific default.
285
+ * Subclasses override this to provide appropriate defaults (e.g., false for boolean, 0 for number).
286
+ */
287
+ get defaultValue() {
288
+ return this._meta?.defaultValue;
289
+ }
274
290
  _meta = {};
275
291
  /**
276
292
  * Replace the schema metadata with a new object.
@@ -300,20 +316,27 @@ var BaseSchema = class {
300
316
  };
301
317
  var BooleanSchema = class extends BaseSchema {
302
318
  type = "boolean";
319
+ get defaultValue() {
320
+ return this._meta?.defaultValue ?? false;
321
+ }
303
322
  toZod() {
304
323
  return z.boolean();
305
324
  }
306
325
  };
307
326
  var StringSchema = class extends BaseSchema {
308
327
  type = "string";
309
- // Add string-specific validation methods here (e.g., minLength, pattern)
328
+ get defaultValue() {
329
+ return this._meta?.defaultValue ?? "";
330
+ }
310
331
  toZod() {
311
332
  return z.string();
312
333
  }
313
334
  };
314
335
  var NumberSchema = class extends BaseSchema {
315
336
  type = "number";
316
- // Add number-specific validation methods here (e.g., min, max)
337
+ get defaultValue() {
338
+ return this._meta?.defaultValue ?? 0;
339
+ }
317
340
  toZod() {
318
341
  return z.number();
319
342
  }
@@ -332,6 +355,19 @@ var OptionalSchema = class extends BaseSchema {
332
355
  unwrap() {
333
356
  return this._wrapped;
334
357
  }
358
+ /**
359
+ * Returns the base type of the wrapped schema.
360
+ * This allows getting the underlying type (e.g., "number") even when wrapped in OptionalSchema.
361
+ */
362
+ get baseType() {
363
+ return this._wrapped.baseType;
364
+ }
365
+ /**
366
+ * Optional fields default to undefined (which becomes null during validation).
367
+ */
368
+ get defaultValue() {
369
+ return this._meta?.defaultValue ?? void 0;
370
+ }
335
371
  toZod() {
336
372
  return this._wrapped.toZod().nullable().optional();
337
373
  }
@@ -862,6 +898,32 @@ ${errors.map((e) => ` - ${e.path}: ${e.message}`).join("\n")}`;
862
898
  }
863
899
  };
864
900
 
901
+ // src/schema/lookup.ts
902
+ function createLookupSchema(idSchema) {
903
+ return nu.object({
904
+ /** Unique identifier for the entity */
905
+ id: idSchema,
906
+ /** Primary display text (e.g., user's display name) */
907
+ title: nu.string(),
908
+ /** Optional secondary text (e.g., email address) */
909
+ subtitle: nu.string().optional(),
910
+ /** Optional image URL or data URL for avatar display */
911
+ image: nu.string().optional()
912
+ });
913
+ }
914
+ var lookupSchema = createLookupSchema(nu.string());
915
+ function createLookupEndpoint(resourceName, idSchema) {
916
+ return {
917
+ method: "GET",
918
+ path: `/lookup/${resourceName}`,
919
+ requestParams: nu.object({
920
+ /** The search query string */
921
+ q: nu.string()
922
+ }),
923
+ responseBody: nu.array(createLookupSchema(idSchema))
924
+ };
925
+ }
926
+
865
927
  // src/schema/widget-data-schema.ts
866
928
  var seriesConfigSchema = nu.object({
867
929
  /** The data key field names that represent numeric series (e.g., ["desktop", "mobile"]) */
@@ -956,6 +1018,8 @@ export {
956
1018
  RecordSchema,
957
1019
  StringSchema,
958
1020
  createKpiWidgetEndpoint,
1021
+ createLookupEndpoint,
1022
+ createLookupSchema,
959
1023
  createProportionalWidgetEndpoint,
960
1024
  createSeriesWidgetEndpoint,
961
1025
  createTableWidgetEndpoint,
@@ -964,6 +1028,7 @@ export {
964
1028
  idNumberSchema,
965
1029
  idStringSchema,
966
1030
  kpiDataSchema,
1031
+ lookupSchema,
967
1032
  nu,
968
1033
  proportionalDataItemSchema,
969
1034
  proportionalDataSchema,