import {z} from 'zod' export type WidgetOptionsMetric = {data_source?: ('table' | 'view' | 'filter') | undefined, metric?: ({type: 'count' | 'summary', field_id?: string | undefined, aggregation: 'sum' | 'avg' | 'count' | 'min' | 'max'}) | undefined, appearance?: ({type?: ('default' | 'filled' | 'coloured') | undefined, theme?: ('gray' | 'red' | 'green' | 'yellow' | 'pink' | 'blue' | 'orange' | 'maroon' | 'purple') | undefined}) | undefined}; export type WidgetOptionsText = {content?: string | undefined, type?: ('markdown' | 'text') | undefined, appearance?: ({formatting?: ({horizontal_align?: ('flex-start' | 'center' | 'flex-end') | undefined, vertical_align?: ('flex-start' | 'center' | 'flex-end') | undefined, bold?: boolean | undefined, italic?: boolean | undefined, underline?: boolean | undefined, strikethrough?: boolean | undefined}) | undefined, font?: ({family?: string | undefined, weight?: number | undefined, size?: number | undefined, line_height?: number | undefined}) | undefined, color?: string | undefined}) | undefined}; export type WidgetOptionsIframe = {url?: string | undefined, allow_fullscreen?: boolean | undefined}; export type WidgetOptionsPieChart = {chart_type: 'pie', data_source?: ('table' | 'view' | 'filter') | undefined, data?: ({category?: ({field_id: string, order_by?: ('default' | 'asc' | 'desc') | undefined, category_limit?: number | undefined, include_empty_records?: boolean | undefined, include_others?: boolean | undefined}) | undefined, value?: ({type: 'count' | 'summary', field_id?: string | undefined, aggregation?: string | undefined}) | undefined}) | undefined, appearance?: ({size?: ('small' | 'medium' | 'large') | undefined, show_count_in_legend?: boolean | undefined, show_percentage_on_chart?: boolean | undefined, legend_position?: ('top' | 'right' | 'bottom' | 'left' | 'none') | undefined, color_schema?: ('default' | 'classic' | 'vibrant' | 'pastel' | 'earth' | 'monoBlue' | 'custom') | undefined, custom_color_schema?: (Array<{color?: string | undefined, label?: string | undefined}>) | undefined}) | undefined}; export type WidgetOptionsDonutChart = {chart_type: 'donut', data_source?: ('table' | 'view' | 'filter') | undefined, data?: ({category?: ({field_id: string, order_by?: ('default' | 'asc' | 'desc') | undefined, category_limit?: number | undefined, include_empty_records?: boolean | undefined, include_others?: boolean | undefined}) | undefined, value?: ({type: 'count' | 'summary', field_id?: string | undefined, aggregation?: string | undefined}) | undefined}) | undefined, appearance?: ({size?: ('small' | 'medium' | 'large') | undefined, show_count_in_legend?: boolean | undefined, show_percentage_on_chart?: boolean | undefined, legend_position?: ('top' | 'right' | 'bottom' | 'left' | 'none') | undefined, color_schema?: ('default' | 'classic' | 'vibrant' | 'pastel' | 'earth' | 'monoBlue' | 'custom') | undefined, custom_color_schema?: (Array<{color?: string | undefined, label?: string | undefined}>) | undefined}) | undefined}; export type WidgetOptionsBarChart = {chart_type: 'bar', data_source?: ('table' | 'view' | 'filter') | undefined, data?: ({x_axis?: ({field_id: string, sort_by?: ('x_axis' | 'y_axis') | undefined, order_by?: ('default' | 'asc' | 'desc') | undefined, include_empty_records?: boolean | undefined, include_others?: boolean | undefined, category_limit?: number | undefined}) | undefined, y_axis?: ({start_at_zero?: boolean | undefined, fields?: Array<{field_id: string, aggregation: string}> | undefined, group_by?: (string | null) | undefined}) | undefined}) | undefined, appearance?: ({size?: ('small' | 'medium' | 'large') | undefined, show_count_in_legend?: boolean | undefined, show_value_in_chart?: boolean | undefined, legend_position?: ('top' | 'right' | 'bottom' | 'left' | 'none') | undefined, color_schema?: ('default' | 'classic' | 'vibrant' | 'pastel' | 'earth' | 'monoBlue' | 'custom') | undefined}) | undefined}; export type WidgetOptionsLineChart = {chart_type: 'line', data_source?: ('table' | 'view' | 'filter') | undefined, data?: ({x_axis?: ({field_id: string, sort_by?: ('x_axis' | 'y_axis') | undefined, order_by?: ('default' | 'asc' | 'desc') | undefined, include_empty_records?: boolean | undefined, include_others?: boolean | undefined, category_limit?: number | undefined}) | undefined, y_axis?: ({start_at_zero?: boolean | undefined, fields?: Array<{field_id: string, aggregation: string}> | undefined, group_by?: (string | null) | undefined}) | undefined}) | undefined, appearance?: ({size?: ('small' | 'medium' | 'large') | undefined, smooth_lines?: boolean | undefined, plot_data_points?: boolean | undefined, show_count_in_legend?: boolean | undefined, show_value_in_chart?: boolean | undefined, legend_position?: ('top' | 'right' | 'bottom' | 'left' | 'none') | undefined, color_schema?: ('default' | 'classic' | 'vibrant' | 'pastel' | 'earth' | 'monoBlue' | 'custom') | undefined}) | undefined}; export type WidgetOptionsScatter = {chart_type: 'scatter', data_source?: ('table' | 'view' | 'filter') | undefined, data?: ({x_axis?: ({field_id: string, sort_by?: ('x_axis' | 'y_axis') | undefined, order_by?: ('default' | 'asc' | 'desc') | undefined, include_empty_records?: boolean | undefined, include_others?: boolean | undefined, category_limit?: number | undefined}) | undefined, y_axis?: ({start_at_zero?: boolean | undefined, fields?: Array<{field_id: string, aggregation: string}> | undefined, group_by?: (string | null) | undefined}) | undefined}) | undefined, appearance?: ({size?: ('small' | 'medium' | 'large') | undefined, show_count_in_legend?: boolean | undefined, show_value_in_chart?: boolean | undefined, legend_position?: ('top' | 'right' | 'bottom' | 'left' | 'none') | undefined, color_schema?: ('default' | 'classic' | 'vibrant' | 'pastel' | 'earth' | 'monoBlue' | 'custom') | undefined}) | undefined}; export type WidgetUpdateReq = {title?: string | undefined, description?: (string | null) | undefined, options?: (WidgetOptionsMetric | WidgetOptionsText | WidgetOptionsIframe | WidgetOptionsPieChart | WidgetOptionsDonutChart | WidgetOptionsBarChart | WidgetOptionsLineChart | WidgetOptionsScatter) | undefined, order?: number | undefined, position?: ({x?: number | undefined, y?: number | undefined, w?: number | undefined, h?: number | undefined}) | undefined, table_id?: (string | null) | undefined, view_id?: (string | null) | undefined}; export type PatchApiApiV3MetaBasesBaseIdDashboardsDashboardIdWidgetsWidgetIdArgs = {baseId: string, dashboardId: string, widgetId: string, body: WidgetUpdateReq}; export type PatchApiApiV3MetaBasesBaseIdDashboardsDashboardIdWidgetsWidgetIdOptions = {baseUrl?: string | undefined, xcToken?: string | undefined, fetch?: typeof fetch | undefined}; export const widgetOptionsMetric = z.object({data_source: z.enum(["table", "view", "filter"]).optional(), metric: z.object({type: z.enum(["count", "summary"]), field_id: z.string().optional(), aggregation: z.enum(["sum", "avg", "count", "min", "max"])}).optional(), appearance: z.object({type: z.enum(["default", "filled", "coloured"]).optional(), theme: z.enum(["gray", "red", "green", "yellow", "pink", "blue", "orange", "maroon", "purple"]).optional()}).optional()}); export const widgetOptionsPieChart = z.object({chart_type: z.literal("pie"), data_source: z.enum(["table", "view", "filter"]).optional(), data: z.object({category: z.object({field_id: z.string(), order_by: z.enum(["default", "asc", "desc"]).optional(), category_limit: z.number().optional(), include_empty_records: z.boolean().optional(), include_others: z.boolean().optional()}).optional(), value: z.object({type: z.enum(["count", "summary"]), field_id: z.string().optional(), aggregation: z.string().optional()}).optional()}).optional(), appearance: z.object({size: z.enum(["small", "medium", "large"]).optional(), show_count_in_legend: z.boolean().optional(), show_percentage_on_chart: z.boolean().optional(), legend_position: z.enum(["top", "right", "bottom", "left", "none"]).optional(), color_schema: z.enum(["default", "classic", "vibrant", "pastel", "earth", "monoBlue", "custom"]).optional(), custom_color_schema: z.array(z.object({color: z.string().optional(), label: z.string().optional()})).optional()}).optional()}); export const widgetOptionsDonutChart = z.object({chart_type: z.literal("donut"), data_source: z.enum(["table", "view", "filter"]).optional(), data: z.object({category: z.object({field_id: z.string(), order_by: z.enum(["default", "asc", "desc"]).optional(), category_limit: z.number().optional(), include_empty_records: z.boolean().optional(), include_others: z.boolean().optional()}).optional(), value: z.object({type: z.enum(["count", "summary"]), field_id: z.string().optional(), aggregation: z.string().optional()}).optional()}).optional(), appearance: z.object({size: z.enum(["small", "medium", "large"]).optional(), show_count_in_legend: z.boolean().optional(), show_percentage_on_chart: z.boolean().optional(), legend_position: z.enum(["top", "right", "bottom", "left", "none"]).optional(), color_schema: z.enum(["default", "classic", "vibrant", "pastel", "earth", "monoBlue", "custom"]).optional(), custom_color_schema: z.array(z.object({color: z.string().optional(), label: z.string().optional()})).optional()}).optional()}); export const widgetOptionsBarChart = z.object({chart_type: z.literal("bar"), data_source: z.enum(["table", "view", "filter"]).optional(), data: z.object({x_axis: z.object({field_id: z.string(), sort_by: z.enum(["x_axis", "y_axis"]).optional(), order_by: z.enum(["default", "asc", "desc"]).optional(), include_empty_records: z.boolean().optional(), include_others: z.boolean().optional(), category_limit: z.number().optional()}).optional(), y_axis: z.object({start_at_zero: z.boolean().optional(), fields: z.array(z.object({field_id: z.string(), aggregation: z.string()})).optional(), group_by: z.string().nullable().optional()}).optional()}).optional(), appearance: z.object({size: z.enum(["small", "medium", "large"]).optional(), show_count_in_legend: z.boolean().optional(), show_value_in_chart: z.boolean().optional(), legend_position: z.enum(["top", "right", "bottom", "left", "none"]).optional(), color_schema: z.enum(["default", "classic", "vibrant", "pastel", "earth", "monoBlue", "custom"]).optional()}).optional()}); export const widgetOptionsLineChart = z.object({chart_type: z.literal("line"), data_source: z.enum(["table", "view", "filter"]).optional(), data: z.object({x_axis: z.object({field_id: z.string(), sort_by: z.enum(["x_axis", "y_axis"]).optional(), order_by: z.enum(["default", "asc", "desc"]).optional(), include_empty_records: z.boolean().optional(), include_others: z.boolean().optional(), category_limit: z.number().optional()}).optional(), y_axis: z.object({start_at_zero: z.boolean().optional(), fields: z.array(z.object({field_id: z.string(), aggregation: z.string()})).optional(), group_by: z.string().nullable().optional()}).optional()}).optional(), appearance: z.object({size: z.enum(["small", "medium", "large"]).optional(), smooth_lines: z.boolean().optional(), plot_data_points: z.boolean().optional(), show_count_in_legend: z.boolean().optional(), show_value_in_chart: z.boolean().optional(), legend_position: z.enum(["top", "right", "bottom", "left", "none"]).optional(), color_schema: z.enum(["default", "classic", "vibrant", "pastel", "earth", "monoBlue", "custom"]).optional()}).optional()}); export const widgetOptionsScatter = z.object({chart_type: z.literal("scatter"), data_source: z.enum(["table", "view", "filter"]).optional(), data: z.object({x_axis: z.object({field_id: z.string(), sort_by: z.enum(["x_axis", "y_axis"]).optional(), order_by: z.enum(["default", "asc", "desc"]).optional(), include_empty_records: z.boolean().optional(), include_others: z.boolean().optional(), category_limit: z.number().optional()}).optional(), y_axis: z.object({start_at_zero: z.boolean().optional(), fields: z.array(z.object({field_id: z.string(), aggregation: z.string()})).optional(), group_by: z.string().nullable().optional()}).optional()}).optional(), appearance: z.object({size: z.enum(["small", "medium", "large"]).optional(), show_count_in_legend: z.boolean().optional(), show_value_in_chart: z.boolean().optional(), legend_position: z.enum(["top", "right", "bottom", "left", "none"]).optional(), color_schema: z.enum(["default", "classic", "vibrant", "pastel", "earth", "monoBlue", "custom"]).optional()}).optional()}); export const widgetOptionsText = z.object({content: z.string().optional(), type: z.enum(["markdown", "text"]).optional(), appearance: z.object({formatting: z.object({horizontal_align: z.enum(["flex-start", "center", "flex-end"]).optional(), vertical_align: z.enum(["flex-start", "center", "flex-end"]).optional(), bold: z.boolean().optional(), italic: z.boolean().optional(), underline: z.boolean().optional(), strikethrough: z.boolean().optional()}).optional(), font: z.object({family: z.string().optional(), weight: z.union([z.literal(100), z.literal(200), z.literal(300), z.literal(400), z.literal(500), z.literal(600), z.literal(700), z.literal(800), z.literal(900)]).optional(), size: z.number().optional(), line_height: z.number().optional()}).optional(), color: z.string().optional()}).optional()}); export const widgetOptionsIframe = z.object({url: z.string().optional(), allow_fullscreen: z.boolean().optional()}); export const widgetRead = z.object({id: z.string(), title: z.string(), description: z.string().nullable().optional(), dashboard_id: z.string(), type: z.enum(["chart", "metric", "gauge", "table", "pivot", "text", "iframe"]), options: z.union([widgetOptionsMetric, widgetOptionsPieChart, widgetOptionsDonutChart, widgetOptionsBarChart, widgetOptionsLineChart, widgetOptionsScatter, widgetOptionsText, widgetOptionsIframe, z.object({})]).optional(), order: z.number().nullable().optional(), position: z.object({x: z.number().optional(), y: z.number().optional(), w: z.number().optional(), h: z.number().optional()}).nullable().optional(), table_id: z.string().nullable().optional(), view_id: z.string().nullable().optional(), error: z.boolean().optional(), created_at: z.string(), updated_at: z.string()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Update Widget * * PATCH /api/v3/meta/bases/{baseId}/dashboards/{dashboardId}/widgets/{widgetId} * * Also accepts auth: bearerAuth */ export const patchApiApiV3MetaBasesBaseIdDashboardsDashboardIdWidgetsWidgetId = async (args: PatchApiApiV3MetaBasesBaseIdDashboardsDashboardIdWidgetsWidgetIdArgs, options?: PatchApiApiV3MetaBasesBaseIdDashboardsDashboardIdWidgetsWidgetIdOptions) => { const {baseUrl = "https://app.nocodb.com", fetch: fetchFn = fetch, xcToken} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (xcToken !== undefined) headers.set("xc-token", xcToken) const url = `${baseUrl.replace(/\/+$/, '')}/api/v3/meta/bases/${encodeURIComponent(String(args.baseId))}/dashboards/${encodeURIComponent(String(args.dashboardId))}/widgets/${encodeURIComponent(String(args.widgetId))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "PATCH", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(widgetRead, await res.json()) };