import {z} from 'zod' export type ViewOptionsGrid = {groups?: (Array<{field_id: string, direction?: ('asc' | 'desc') | undefined}>) | undefined, row_height?: ('short' | 'medium' | 'tall' | 'extra') | undefined}; export type SortCreate = {field_id: string, direction?: ('asc' | 'desc') | undefined, order_by?: ('alphabetical' | 'option_order') | undefined}; export type Filter = {id?: string | undefined, parent_id?: string | undefined, field_id: string, operator: string, sub_operator?: (string | null) | undefined, value?: (string | number | boolean | null) | undefined, enabled?: boolean | undefined}; export type FilterGroup = {id: string, parent_id?: string | undefined, group_operator: 'AND' | 'OR', enabled?: boolean | undefined, filters: Array}; export type FilterCreateUpdate = {id?: string | undefined, parent_id?: string | undefined, field_id: string, operator: string, sub_operator?: (string | null) | undefined, value?: (string | number | boolean | null) | undefined, enabled?: boolean | undefined} | {id: string, parent_id?: string | undefined, group_operator: 'AND' | 'OR', enabled?: boolean | undefined, filters: Array}; export type ViewAggregationEnum = 'sum' | 'min' | 'max' | 'avg' | 'median' | 'std_dev' | 'range' | 'count' | 'count_empty' | 'count_filled' | 'count_unique' | 'percent_empty' | 'percent_filled' | 'percent_unique' | 'none' | 'attachment_size' | 'checked' | 'unchecked' | 'percent_checked' | 'percent_unchecked' | 'earliest_date' | 'latest_date' | 'date_range' | 'month_range'; export type ViewFields = Array<{field_id: string, show: boolean, width?: number | undefined, aggregation?: ViewAggregationEnum | undefined}>; export type ViewRowColour = {mode: 'filter', conditions: Array<{apply_as_row_background?: boolean | undefined, color?: string | undefined, filters?: FilterCreateUpdate | undefined}>} | {mode: 'select', field_id: string, apply_as_row_background?: boolean | undefined}; export type ViewOptionsGallery = {cover_field_id?: string | undefined}; export type ViewOptionsKanban = {stack_by: {field_id: string, stack_order?: Array | undefined}, cover_field_id?: string | undefined}; export type ViewOptionsCalendar = {date_ranges: Array<{start_date_field_id: string, end_date_field_id?: string | undefined}>}; export type ViewOptionsTimelineCreate = {date_ranges: Array<{start_date_field_id: string, end_date_field_id?: (string | null) | undefined}>}; export type DateDependency = {dates?: {start_field_id: string, end_field_id: string} | undefined, duration_field_id?: (string | null) | undefined, dependency?: ({linkrow_field_id: string, linkrow_role: 'predecessors' | 'successors', connection_type: 'end-to-start' | 'end-to-end' | 'start-to-end' | 'start-to-start', buffer_type: 'flexible' | 'fixed' | 'none', buffer_days: number}) | undefined, include_weekends?: boolean | undefined, is_active?: boolean | undefined}; export type ViewOptionsGanttCreate = {date_dependency: DateDependency | null}; export type ViewOptionsMap = {geo_data_field_id?: string | undefined}; export type FormImage = {url?: string | undefined, path?: string | undefined, title?: string | undefined, mimetype?: string | undefined, size?: number | undefined, icon?: string | undefined, signedUrl?: string | undefined, signedPath?: string | undefined}; export type FormFieldValidator = {type: 'minLength' | 'maxLength' | 'startsWith' | 'endsWith' | 'includes' | 'notIncludes' | 'regex' | 'email' | 'businessEmail' | 'phoneNumber' | 'url' | 'min' | 'max' | 'minDate' | 'maxDate' | 'minTime' | 'maxTime' | 'minYear' | 'maxYear' | 'minSelected' | 'maxSelected' | 'fileTypes' | 'fileSize' | 'fileCount', value?: (string | number | Array | null) | undefined, message?: string | undefined, regex?: string | undefined, unit?: ('KB' | 'MB') | undefined}; export type FormFieldConfig = {alias?: string | undefined, description?: string | undefined, required?: boolean | undefined, allow_scanner_input?: boolean | undefined, is_list?: boolean | undefined, is_limit_option?: boolean | undefined, validators?: Array | undefined}; export type ViewOptionsForm = {form_title?: string | undefined, form_description?: string | undefined, thank_you_message?: string | undefined, form_redirect_after_secs?: number | undefined, show_submit_another_button?: boolean | undefined, reset_form_after_submit?: boolean | undefined, save_draft_to_browser?: boolean | undefined, form_hide_banner?: boolean | undefined, form_hide_branding?: boolean | undefined, banner?: (string | FormImage | null) | undefined, logo?: (string | FormImage | null) | undefined, form_background_color?: string | undefined, redirect_url?: string | undefined, submit_button_label?: string | undefined, send_response_email_to?: string | undefined, fields_by_id?: {[key: string]: FormFieldConfig} | undefined}; export type FilterCreate = {id?: string | undefined, parent_id?: string | undefined, field_id: string, operator: string, sub_operator?: (string | null) | undefined, value?: (string | number | boolean | null) | undefined, enabled?: boolean | undefined} | {group_operator: 'AND' | 'OR', filters: Array<{id?: string | undefined, parent_id?: string | undefined, field_id: string, operator: string, sub_operator?: (string | null) | undefined, value?: (string | number | boolean | null) | undefined, enabled?: boolean | undefined} | {group_operator: 'AND' | 'OR', filters: Array<{id?: string | undefined, parent_id?: string | undefined, field_id: string, operator: string, sub_operator?: (string | null) | undefined, value?: (string | number | boolean | null) | undefined, enabled?: boolean | undefined} | {group_operator: 'AND' | 'OR', filters: Array}>}>}; export type ViewOptionsList = {levels?: (Array<{level: number, table_id: string, link_field_id?: (string | null) | undefined, filters?: FilterCreate | undefined, sorts?: Array | undefined, fields?: ViewFields | undefined}>) | undefined, show_empty_parents?: boolean | undefined, row_height?: ('short' | 'medium' | 'tall' | 'extra') | undefined}; export type ViewCreate = {title: string, type: 'grid', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options?: ViewOptionsGrid | undefined, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'gallery', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options?: ViewOptionsGallery | undefined, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'kanban', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options: ViewOptionsKanban, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'calendar', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options: ViewOptionsCalendar, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'timeline', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options: ViewOptionsTimelineCreate, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'gantt', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options: ViewOptionsGanttCreate, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'map', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options?: ViewOptionsMap | undefined, sorts?: Array | undefined, filters?: FilterCreateUpdate | undefined, fields?: ViewFields | undefined, row_coloring?: ViewRowColour | undefined} | {title: string, type: 'form', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options?: ViewOptionsForm | undefined, fields?: ViewFields | undefined} | {title: string, type: 'list', lock_type?: ('collaborative' | 'locked' | 'personal') | undefined, description?: string | undefined, options?: ViewOptionsList | undefined}; export type CreateApiApiV3MetaBasesBaseIdTablesTableIdViewsArgs = {baseId: string, tableId: string, body: ViewCreate}; export type CreateApiApiV3MetaBasesBaseIdTablesTableIdViewsOptions = {baseUrl?: string | undefined, xcToken?: string | undefined, fetch?: typeof fetch | undefined}; export const viewOptionsGrid = z.object({groups: z.array(z.object({field_id: z.string(), direction: z.enum(["asc", "desc"]).optional()})).optional(), row_height: z.enum(["short", "medium", "tall", "extra"]).optional()}); export const sortCreate = z.object({field_id: z.string(), direction: z.enum(["asc", "desc"]).optional(), order_by: z.enum(["alphabetical", "option_order"]).optional()}); export const filterResponse = z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.string().nullable().optional(), enabled: z.boolean().optional()}); export const filterGroupResponse: z.ZodType = z.object({id: z.string(), parent_id: z.string().optional(), group_operator: z.enum(["AND", "OR"]), enabled: z.boolean().optional(), filters: z.array(z.union([filterResponse, z.lazy(() => filterGroupResponse)]))}); export const filterCreateUpdateResponse = z.union([filterResponse, filterGroupResponse]); export const viewAggregationEnum = z.enum(["sum", "min", "max", "avg", "median", "std_dev", "range", "count", "count_empty", "count_filled", "count_unique", "percent_empty", "percent_filled", "percent_unique", "none", "attachment_size", "checked", "unchecked", "percent_checked", "percent_unchecked", "earliest_date", "latest_date", "date_range", "month_range"]); export const viewFields = z.array(z.object({field_id: z.string(), show: z.boolean(), width: z.number().int().optional(), aggregation: viewAggregationEnum.optional()})); export const filter = z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.union([z.string(), z.number(), z.boolean()]).nullable().optional(), enabled: z.boolean().optional()}); export const filterGroup: z.ZodType = z.object({id: z.string(), parent_id: z.string().optional(), group_operator: z.enum(["AND", "OR"]), enabled: z.boolean().optional(), filters: z.array(z.union([filter, z.lazy(() => filterGroup)]))}); export const filterCreateUpdate = z.union([z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.union([z.string(), z.number(), z.boolean()]).nullable().optional(), enabled: z.boolean().optional()}), z.object({id: z.string(), parent_id: z.string().optional(), group_operator: z.enum(["AND", "OR"]), enabled: z.boolean().optional(), filters: z.array(z.union([filter, filterGroup]))})]); export const viewRowColour = z.discriminatedUnion("mode", [z.object({mode: z.literal("filter"), conditions: z.array(z.object({apply_as_row_background: z.boolean().optional(), color: z.string().optional(), filters: filterCreateUpdate.optional()}))}), z.object({mode: z.literal("select"), field_id: z.string(), apply_as_row_background: z.boolean().optional()})]); export const viewOptionsGallery = z.object({cover_field_id: z.string().optional()}); export const viewOptionsKanban = z.object({stack_by: z.object({field_id: z.string(), stack_order: z.array(z.string()).optional()}), cover_field_id: z.string().optional()}); export const viewOptionsCalendar = z.object({date_ranges: z.array(z.object({start_date_field_id: z.string(), end_date_field_id: z.string().optional()}))}); export const viewOptionsTimeline = z.object({date_ranges: z.array(z.object({start_date_field_id: z.string(), end_date_field_id: z.string().nullable().optional()})).optional()}); export const dateDependency = z.object({dates: z.object({start_field_id: z.string(), end_field_id: z.string()}).optional(), duration_field_id: z.string().nullable().optional(), dependency: z.object({linkrow_field_id: z.string(), linkrow_role: z.enum(["predecessors", "successors"]), connection_type: z.enum(["end-to-start", "end-to-end", "start-to-end", "start-to-start"]), buffer_type: z.enum(["flexible", "fixed", "none"]), buffer_days: z.number().int().gte(0)}).optional(), include_weekends: z.boolean().optional(), is_active: z.boolean().optional()}); export const viewOptionsGantt = z.object({date_dependency: dateDependency.nullable().optional()}); export const viewOptionsMap = z.object({geo_data_field_id: z.string().optional()}); export const filterCreate = z.union([z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.union([z.string(), z.number(), z.boolean()]).nullable().optional(), enabled: z.boolean().optional()}), z.object({group_operator: z.enum(["AND", "OR"]), filters: z.array(z.union([z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.union([z.string(), z.number(), z.boolean()]).nullable().optional(), enabled: z.boolean().optional()}), z.object({group_operator: z.enum(["AND", "OR"]), filters: z.array(z.union([z.object({id: z.string().optional(), parent_id: z.string().optional(), field_id: z.string(), operator: z.string(), sub_operator: z.string().nullable().optional(), value: z.union([z.string(), z.number(), z.boolean()]).nullable().optional(), enabled: z.boolean().optional()}), z.object({group_operator: z.enum(["AND", "OR"]), filters: z.array(filter)})]))})]))})]); export const viewOptionsList = z.object({levels: z.array(z.object({level: z.number(), table_id: z.string(), link_field_id: z.string().nullable().optional(), filters: filterCreate.optional(), sorts: z.array(sortCreate).optional(), fields: viewFields.optional()})).optional(), show_empty_parents: z.boolean().optional(), row_height: z.enum(["short", "medium", "tall", "extra"]).optional()}); export const view = z.union([z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("grid"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsGrid.optional(), sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("gallery"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsGallery.optional(), sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("kanban"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsKanban, sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("calendar"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsCalendar, sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("timeline"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsTimeline, sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("gantt"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsGantt.optional(), sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("map"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsMap.optional(), sorts: z.array(sortCreate).optional(), filters: filterCreateUpdateResponse.optional(), fields: viewFields.optional(), row_coloring: viewRowColour.optional()}), z.object({id: z.string(), table_id: z.string().optional(), title: z.string(), type: z.literal("list"), lock_type: z.enum(["collaborative", "locked", "personal"]).optional(), description: z.string().optional(), created_by: z.string().optional(), owned_by: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), options: viewOptionsList.optional()})]); 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 }; /** * Create view * * POST /api/v3/meta/bases/{baseId}/tables/{tableId}/views * * Also accepts auth: bearerAuth */ export const createApiApiV3MetaBasesBaseIdTablesTableIdViews = async (args: CreateApiApiV3MetaBasesBaseIdTablesTableIdViewsArgs, options?: CreateApiApiV3MetaBasesBaseIdTablesTableIdViewsOptions) => { 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))}/tables/${encodeURIComponent(String(args.tableId))}/views${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", 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(view, await res.json()) };