@lotics/app-sdk 0.125.9 → 0.126.1
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/AGENTS.md +2 -2
- package/dist/{chunk-2KJSE73G.js → chunk-GACWCLEV.js} +14 -13
- package/dist/index.d.ts +0 -1
- package/dist/index.js +51 -16
- package/dist/open_external.d.ts +1 -1
- package/dist/router.d.ts +4 -0
- package/dist/router.js +11 -2
- package/dist/rpc.d.ts +4 -11
- package/dist/shared_types.d.ts +3 -26
- package/dist/viewer.d.ts +0 -5
- package/docs/data_fetching.md +4 -4
- package/docs/members_and_options.md +2 -96
- package/docs/mutations.md +1 -2
- package/docs/navigation_and_state.md +7 -0
- package/docs/queries.md +2 -2
- package/docs/runtime.md +9 -64
- package/docs/security.md +0 -4
- package/package.json +1 -1
- package/dist/open_app.d.ts +0 -24
package/dist/shared_types.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface AppFile {
|
|
|
24
24
|
place?: PhotoPlace;
|
|
25
25
|
}
|
|
26
26
|
export type AppLoadTiming = { boot_ms?: number | undefined; page_bytes?: number | undefined; page_connect_ms?: number | undefined; page_decoded_bytes?: number | undefined; page_download_ms?: number | undefined; page_ttfb_ms?: number | undefined; };
|
|
27
|
+
export type AppSpec = { version: 31; app: { alias: string; label: string; description: string | null; locale: ReportLanguage; scope: { entity: string; param: string; counts: { query: string; param: string | null; } | null; list: string | null; } | null; opens_on: { days: 30; } | { span: "month" | "quarter" | "year"; } | null; }; entities: Record<string, { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; }>; views: ({ kind: "list"; key: string; label: string; entity: string; scope: { field: string; } | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; source_column: boolean; beside: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; sources: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; entities: string[]; sources: { entity: string; fields: Record<string, string>; scope: string | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; source_column: boolean; beside: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; sources: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; }[]; place: { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; } | null; bound: { read: { query: string; param: string; }; same: { field: string; param: string; } | null; bounds: { field: string; param: string; of: "date" | "number"; lookup: boolean; }[]; via: string; } | null; } | { kind: "sheet"; key: string; label: string; readings: { reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; }; scope: { field: string; } | null; }[]; })[]; pages: Record<string, { door: "drawer" | "page" | null; sections: { title: string | null; description: string | null; at: string[] | null; fields: string[]; groups: { label: string; fields: string[]; }[]; reads: string[]; blocks: ({ kind: "funnel"; entity: string; read: { query: string; param: string; }; label: string; steps: string[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "agenda"; key: string; day: string; time: string | null; part: string | null; start: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "figures"; fields: string[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "files"; fields: string[]; title: string; add_label: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "list"; key: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { key: string; totals: Record<string, string>; narrower: string[]; soonest: string[]; expect: string | null; of: string | null; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; edits: string[]; pick: { read: { query: string; param: string | null; }; back: string; same: { field: string; param: string; }[]; admits: { query: string; param: string | null; } | null; } | null; checklist: { photo: string | null; clause: string | null; words: string[]; failed: string[]; passed: string | null; } | null; gantt: { start: string; end: string; milestones: string[]; planned: { start: string | null; end: string | null; } | null; progress: string | null; after: string | null; } | null; compare: { before: string; after: string; } | null; current: string | null; post: { bodies: string[]; text: string; compute: { expression: string; reads: Record<string, { from: "row"; field: string; } | { from: "record"; field: string; } | { from: "place"; field: string; } | { from: "formula"; expression: string; }>; } | null; media: string; link: string | null; network: string; group: string | null; networks: Record<string, "facebook" | "instagram" | "linkedin" | "threads" | "x">; } | null; under: { field: string; entity: string; via: string; back: string; read: { query: string; param: string; }; key: string; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; } | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; kind: "rows"; } | { key: string; totals: Record<string, string>; narrower: string[]; soonest: string[]; expect: string | null; of: string | null; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; edits: string[]; pick: { read: { query: string; param: string | null; }; back: string; same: { field: string; param: string; }[]; admits: { query: string; param: string | null; } | null; } | null; checklist: { photo: string | null; clause: string | null; words: string[]; failed: string[]; passed: string | null; } | null; gantt: { start: string; end: string; milestones: string[]; planned: { start: string | null; end: string | null; } | null; progress: string | null; after: string | null; } | null; compare: { before: string; after: string; } | null; current: string | null; post: { bodies: string[]; text: string; compute: { expression: string; reads: Record<string, { from: "row"; field: string; } | { from: "record"; field: string; } | { from: "place"; field: string; } | { from: "formula"; expression: string; }>; } | null; media: string; link: string | null; network: string; group: string | null; networks: Record<string, "facebook" | "instagram" | "linkedin" | "threads" | "x">; } | null; under: { field: string; entity: string; via: string; back: string; read: { query: string; param: string; }; key: string; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; } | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; kind: "outline"; counts: { query: string; param: string; }; } | { kind: "reading"; reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; }; via: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "statement"; title: string; lines: { field: string; op: "equals" | "minus" | "plus" | "times" | null; rate: string | null; parts: { entity: string; read: { query: string; param: string; }; same: string; before: { field: string; param: string; } | null; columns: string[]; figure: string; } | null; }[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "text"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "choices"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "linked"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "timeline"; key: string; at: string; by: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; })[]; acts: string[]; entry: string[]; acts_last: boolean; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; page: string | null; side: boolean; }[]; views: { kind: "list"; key: string; label: string; entity: string; scope: { field: string; } | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; source_column: boolean; beside: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; sources: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; entities: string[]; sources: { entity: string; fields: Record<string, string>; scope: string | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; source_column: boolean; beside: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; sources: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; }[]; place: { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; } | null; bound: { read: { query: string; param: string; }; same: { field: string; param: string; } | null; bounds: { field: string; param: string; of: "date" | "number"; lookup: boolean; }[]; via: string; } | null; }[]; draws: string[]; outside: { key: string; entity: string; at: string[]; one: { query: string; param: string; }; page: { door: "page"; draws: string[]; sections: [{ title: string; description: string | null; fields: string[]; blocks: { kind: "list"; key: string; reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; }; via: string; same: { field: string; param: string; } | null; bounds: { field: string; param: string; of: "date" | "number"; lookup: boolean; }[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; acts: string[]; }]; }; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; }[]; moves: { entity: string; via: string; read: { query: string; param: string; }; title: string; at: string; by: string | null; create: string[] | null; add_label: string | null; } | null; }>; acts: { alias: string; label: string; on: "record" | "rows" | "view"; of: string; workflow: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; to: string | null; writes: boolean; into: string | null; paper: { entity: string; option: string; } | null; marks: Record<string, boolean>; requires: string[]; recommends: string[]; asks: (string | { input: string; label: string; type: "date" | "file" | "link" | "long_text" | "member" | "number" | "select" | "text"; options: { alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; entity: string | null; required: boolean; default: string | null; accept: string | null; })[]; asking: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "boolean" | "date" | "files" | "number" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; starts: Record<string, "me" | "today">; makes: string | null; papers: { template: string; label: string; when: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }[] | null; archive: string | null; intake: { agent: string; papers: { entity: string; kind: string; files: string; }; fields: string[]; parties: { link: string; fields: string[]; key: string[]; }[]; rows: { entity: string; fields: string[]; key: string[]; }[]; links: { entity: string; table: string; }[]; } | null; recording: { into: string; via: string; audio: string; transcript: string; video: string | null; agent: string | null; } | null; sign: { into: string; by: string; at: string; witness: string | null; } | null; review: boolean; confirm: string | true | null; danger: boolean; corrects: boolean; drafted: boolean; stands: string[]; views: string[]; }[]; checks: { field: string; of: string; blocks: "all" | string[] | null; resolve: string[]; reads: string[]; stands: string[]; }[]; };
|
|
27
28
|
/** What a body read needs of a table: its id, its name for a refusal, and its fields. */
|
|
28
29
|
export type BodyTable = { id: string; name: string; fields: (TableField)[]; title_field_key: string | null; };
|
|
29
30
|
/**
|
|
@@ -36,12 +37,6 @@ export type Bound<R = { record: string; }> = string | number | R | { now: true;
|
|
|
36
37
|
export interface CardsSpec {
|
|
37
38
|
kind: "cards";
|
|
38
39
|
}
|
|
39
|
-
/** One node of the page as the model and the spec state it. */
|
|
40
|
-
export type ComposeNode = { use: "Column"; children: ComposeOf<StatedComposeRows>[]; } | { use: "Bar"; children: ComposeOf<StatedComposeRows>[]; } | { use: "Group"; title: string; children: ComposeOf<StatedComposeRows>[]; } | { use: "Panel"; title: string; children: ComposeOf<StatedComposeRows>[]; } | { use: "Title"; } | { use: "Status"; } | { use: "Field"; field: string; } | { use: "Document"; field: string; } | { use: "Act"; act: string; } | { use: "Copy"; field: string; as: "plain" | "raw"; } | StatedComposeRows;
|
|
41
|
-
/** One node of a page over what its `Rows` pieces are: the piece it mounts (`use`), that piece's props, and what it holds. */
|
|
42
|
-
export type ComposeOf<Rows extends { use: "Rows"; child: string; }> = Rows | { use: "Column"; children: ComposeOf<Rows>[]; } | { use: "Bar"; children: ComposeOf<Rows>[]; } | { use: "Group"; title: string; children: ComposeOf<Rows>[]; } | { use: "Panel"; title: string; children: ComposeOf<Rows>[]; } | { use: "Title"; } | { use: "Status"; } | { use: "Field"; field: string; } | { use: "Document"; field: string; } | { use: "Act"; act: string; } | { use: "Copy"; field: string; as: "plain" | "raw"; };
|
|
43
|
-
/** What every `Rows` piece names: the child whose rows it lists. */
|
|
44
|
-
export type ComposeRowsPiece = { use: "Rows"; child: string; };
|
|
45
40
|
export interface ExportCall {
|
|
46
41
|
params?: { [x: string]: unknown; };
|
|
47
42
|
filter?: QueryFilterGroup<string> | QueryFilterCondition<string>;
|
|
@@ -64,7 +59,7 @@ export interface ExportCall {
|
|
|
64
59
|
* tab `sheet` — or a template the query declares under `templates`, by its name there.
|
|
65
60
|
*/
|
|
66
61
|
export type ExportFile = { kind: "workbook"; language: ReportLanguage; sheet: string; columns: ReportColumn[]; } | { kind: "template"; template: string; };
|
|
67
|
-
export type ExportNarrowing = { status?: string[] | undefined; filters?: Record<string, { kind: "ids"; ids: string[]; unset?: true | undefined; } | { kind: "members"; mine: boolean; ids: string[]; unset?: true | undefined; } | { kind: "dates"; from: string | null; to: string | null; unset?: true | undefined; } | { kind: "yes_no"; value: boolean; } | { kind: "number"; min: number | null; max: number | null; unit?: string | undefined; } | { kind: "bands"; bands: { min: number | null; max: number | null; }[]; } | null> | undefined; search?: string | undefined; overdue?: true | undefined; waiting?: boolean | undefined; tab?: string | undefined; period?: { from: string; to: string; } | undefined; window?: { from: string; to: string; } | undefined; sort?: { field: string; dir: "asc" | "desc"; } | undefined; group?: string | null | undefined; folder?: string | undefined; per?: string | undefined; };
|
|
62
|
+
export type ExportNarrowing = { status?: string[] | undefined; filters?: Record<string, { kind: "ids"; ids: string[]; unset?: true | undefined; } | { kind: "members"; mine: boolean; ids: string[]; unset?: true | undefined; } | { kind: "dates"; from: string | null; to: string | null; unset?: true | undefined; } | { kind: "yes_no"; value: boolean; } | { kind: "number"; min: number | null; max: number | null; unit?: string | undefined; } | { kind: "bands"; bands: { min: number | null; max: number | null; }[]; } | null> | undefined; search?: string | undefined; overdue?: true | undefined; waiting?: boolean | undefined; tab?: string | undefined; period?: { from: string; to: string; } | undefined; window?: { from: string; to: string; } | undefined; sort?: { field: string; dir: "asc" | "desc"; } | undefined; group?: string | null | undefined; folder?: string | undefined; row?: string | undefined; per?: string | undefined; };
|
|
68
63
|
/**
|
|
69
64
|
* What an export states of its rows beside them: the page's title, one line per thing narrowing them, and the
|
|
70
65
|
* figures over them as the screen drew them.
|
|
@@ -111,16 +106,6 @@ export interface ExportedFile {
|
|
|
111
106
|
created_at: string;
|
|
112
107
|
}
|
|
113
108
|
export type ListOutsideLinksResult = { record_title: string; outside: { key: string; title: string; live: OutsideLink | null; last_closed: OutsideLink | null; }[]; };
|
|
114
|
-
/**
|
|
115
|
-
* An app the reader can open, as the host names it to another app: its id and name, the table its working register
|
|
116
|
-
* lists (`table_id`) and each of its logs (`logs`), where the host says.
|
|
117
|
-
*/
|
|
118
|
-
export interface OpenableApp {
|
|
119
|
-
id: string;
|
|
120
|
-
name: string;
|
|
121
|
-
table_id?: string;
|
|
122
|
-
logs?: readonly RegisterLog[];
|
|
123
|
-
}
|
|
124
109
|
export type OutsideLink = { id: string; outside_key: string; record_id: string; recipient: string; issued_by_member_id: string; created_at: string; expires_at: string; opened_at: string | null; revoked_at: string | null; revoked_reason: "issuer_left" | "left_stage" | "owner_changed" | "record_deleted" | "replaced" | "revoked" | "used" | null; };
|
|
125
110
|
/** Where a device stood: degrees north and east, and how many metres off it said it may be. */
|
|
126
111
|
export interface PhotoPlace {
|
|
@@ -198,11 +183,6 @@ export type QuerySortKey<C extends string = string> = QueryFieldSortKey<C> | Que
|
|
|
198
183
|
export type QueryWriteShape = { columns: Record<string, { table_id: string; field_key: string; } | { table_id: string; via: string; target_table_id: string; field_key: string; } | null>; rows?: { table_id: string; filter?: TableRecordFilters | undefined; closed: boolean; sort: { field_key: string; order: "asc" | "desc"; }[]; } | undefined; totals?: { table_id: string; filter?: TableRecordFilters | undefined; by: { output: string; field_key: string; }[]; aggregates: { output: string; operation: "avg" | "checked" | "count" | "date_range" | "earliest" | "empty" | "filled" | "latest" | "max" | "median" | "min" | "percent_checked" | "percent_empty" | "percent_filled" | "percent_unchecked" | "percent_unique" | "range" | "selected" | "string_agg" | "sum" | "unchecked" | "unique"; field_key?: string | undefined; }[]; } | undefined; };
|
|
199
184
|
/** A bound read from a field of the record a List stands beside: the day or figure that field holds when the rows are read. */
|
|
200
185
|
export type RecordBound = { record: string; };
|
|
201
|
-
/** A further List of an app over a table, as the host names it to another app: a row of the table opens at the log's own path there. */
|
|
202
|
-
export interface RegisterLog {
|
|
203
|
-
table_id: string;
|
|
204
|
-
key: string;
|
|
205
|
-
}
|
|
206
186
|
export interface ReportColumn {
|
|
207
187
|
/** Each row's cell by it. */
|
|
208
188
|
key: string;
|
|
@@ -293,14 +273,11 @@ export interface ResolvedOption {
|
|
|
293
273
|
/** A brand or icon mark, from `useFieldOptions` only. */
|
|
294
274
|
mark?: { kind: "brand"; name: string; } | { kind: "icon"; name: string; };
|
|
295
275
|
}
|
|
296
|
-
export type SpecFile = { version: 30; app: { alias: string; label: string; description: string | null; locale: ReportLanguage; }; entities: Record<string, { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; }>; lists: { key: string | null; label: string | null; entity: string; scope: { field: string; entity: string; param: string; counts: { query: string; param: string | null; }; list: string | null; } | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; book: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; heading: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; books: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; open: { kind: "app"; app: { id: string; }; } | { kind: "drawer"; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; entities: string[]; books: { entity: string; fields: Record<string, string>; scope: string | null; register: { columns: string[]; filters: (string | { field: string; tiers: number[]; })[]; book: boolean; search: string[] | null; sort: { field: string; desc: boolean; }[] | null; group: string | null; tabs: { tab: string; label: string; term: { kind: "in"; field: string; } | { kind: "open"; from: string; to: string; } | null; totals: { via: string; read: { query: string; }; columns: { alias: string; label: string; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; }[]; } | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; sort: { field: string; desc: boolean; }[] | null; }[] | null; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; layout: SpecLayout; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; opens: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; remove: boolean; create: string[] | null; add_label: string | null; heading: string | null; export: { label: string | null; description: string | null; query: string; template: string | null; filename: string | null; where: ({ field: string; options: string[]; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; per: string | null; per_row: string[]; books: string[] | null; held: Record<string, string[]> | null; per_field: { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; } | null; fixed: boolean; key: string; }[]; readings: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; open: { kind: "app"; app: { id: string; }; } | { kind: "drawer"; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; attention: boolean; }; }[]; place: { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; } | null; owns: { queries: string[]; workflows: string[]; entities: string[]; } | null; }[]; pages: Record<string, { door: "beside" | "drawer" | "page" | null; sections: { title: string | null; description: string | null; at: string[] | null; fields: string[]; groups: { label: string; fields: string[]; }[]; reads: string[]; blocks: ({ kind: "funnel"; entity: string; read: { query: string; param: string; }; label: string; steps: string[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "agenda"; entity: string; via: string; read: { query: string; param: string; }; title: string; columns: string[]; day: string; time: string | null; part: string | null; start: string | null; create: string[] | null; add_label: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "figures"; fields: string[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "files"; fields: string[]; title: string; add_label: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "list"; reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; open: { kind: "app"; app: { id: string; }; } | { kind: "drawer"; }; }; via: string; same: { field: string; param: string; } | null; bounds: { field: string; param: string; of: "date" | "number"; lookup: boolean; }[]; open: "in_place" | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { entity: string; via: string; read: { query: string; param: string; }; title: string; columns: string[]; create: string[] | null; add_label: string | null; totals: Record<string, string>; narrower: string[]; soonest: string[]; expect: string | null; of: string | null; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; filters: (string | { field: string; tiers: number[]; })[]; search: string[]; group: string | null; sort: { field: string; desc: boolean; }[] | null; edits: string[]; remove: boolean; pick: { read: { query: string; param: string | null; }; back: string; same: { field: string; param: string; }[]; admits: { query: string; param: string | null; } | null; } | null; checklist: { photo: string | null; clause: string | null; words: string[]; failed: string[]; passed: string | null; } | null; gantt: { start: string; end: string; milestones: string[]; planned: { start: string | null; end: string | null; } | null; progress: string | null; after: string | null; } | null; compare: { before: string; after: string; } | null; current: string | null; post: { bodies: string[]; text: string; compute: { expression: string; reads: Record<string, { from: "row"; field: string; } | { from: "record"; field: string; } | { from: "place"; field: string; } | { from: "formula"; expression: string; }>; } | null; media: string; link: string | null; network: string; group: string | null; networks: Record<string, "facebook" | "instagram" | "linkedin" | "threads" | "x">; } | null; under: { field: string; entity: string; via: string; back: string; read: { query: string; param: string; }; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; } | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; kind: "rows"; } | { entity: string; via: string; read: { query: string; param: string; }; title: string; columns: string[]; create: string[] | null; add_label: string | null; totals: Record<string, string>; narrower: string[]; soonest: string[]; expect: string | null; of: string | null; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; filters: (string | { field: string; tiers: number[]; })[]; search: string[]; group: string | null; sort: { field: string; desc: boolean; }[] | null; edits: string[]; remove: boolean; pick: { read: { query: string; param: string | null; }; back: string; same: { field: string; param: string; }[]; admits: { query: string; param: string | null; } | null; } | null; checklist: { photo: string | null; clause: string | null; words: string[]; failed: string[]; passed: string | null; } | null; gantt: { start: string; end: string; milestones: string[]; planned: { start: string | null; end: string | null; } | null; progress: string | null; after: string | null; } | null; compare: { before: string; after: string; } | null; current: string | null; post: { bodies: string[]; text: string; compute: { expression: string; reads: Record<string, { from: "row"; field: string; } | { from: "record"; field: string; } | { from: "place"; field: string; } | { from: "formula"; expression: string; }>; } | null; media: string; link: string | null; network: string; group: string | null; networks: Record<string, "facebook" | "instagram" | "linkedin" | "threads" | "x">; } | null; under: { field: string; entity: string; via: string; back: string; read: { query: string; param: string; }; where: { field: string; options: string[]; }[]; add_form: { preset: Record<string, { id: string; label: string; }>; among: Record<string, string[]>; } | null; } | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; kind: "outline"; counts: { query: string; param: string; }; } | { kind: "reading"; reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; open: { kind: "app"; app: { id: string; }; } | { kind: "drawer"; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "progress"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; planned: { start: string; end: string; }; done: string; finished: string | null; weight: string | null; measured: { via: string; read: { query: string; param: string; }; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; }; via: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "statement"; title: string; lines: { field: string; op: "equals" | "minus" | "plus" | "times" | null; rate: string | null; parts: { entity: string; read: { query: string; param: string; }; same: string; before: { field: string; param: string; } | null; columns: string[]; figure: string; } | null; }[]; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "text"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "choices"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "linked"; field: string; title: string; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | { kind: "timeline"; entity: string; via: string; read: { query: string; param: string; }; title: string; at: string; by: string | null; create: string[] | null; add_label: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; })[]; acts: string[]; entry: string[]; acts_last: boolean; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; page: string | null; side: boolean; }[]; draws: string[]; outside: { key: string; entity: string; at: string[]; one: { query: string; param: string; }; page: { door: "page"; draws: string[]; sections: [{ title: string; description: string | null; fields: string[]; blocks: { kind: "list"; via: string; same: { field: string; param: string; } | null; bounds: { field: string; param: string; of: "date" | "number"; lookup: boolean; }[]; open: "in_place" | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; reading: { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; }; }[]; acts: string[]; }]; }; opens_on: { days: number; } | { span: "day" | "month" | "quarter" | "week" | "year"; view: "day" | "month" | "week" | null; }; }[]; comments: boolean; moves: { kind: "timeline"; entity: string; via: string; read: { query: string; param: string; }; title: string; at: string; by: string | null; create: string[] | null; add_label: string | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; } | null; compose: { use: "Title"; } | { use: "Status"; } | { use: "Field"; field: string; } | { use: "Document"; field: string; } | { use: "Act"; act: string; } | { use: "Rows"; child: string; create: boolean; remove: boolean; } | { use: "Copy"; field: string; as: "plain" | "raw"; } | { use: "Column"; children: ComposeNode[]; } | { use: "Bar"; children: ComposeNode[]; } | { use: "Group"; title: string; children: ComposeNode[]; } | { use: "Panel"; title: string; children: ComposeNode[]; } | null; }>; acts: { alias: string; label: string; on: "record" | "rows" | "view"; of: string; workflow: string | null; open: { app: string; } | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; to: string | null; writes: boolean; into: string | null; paper: { entity: string; option: string; } | null; marks: Record<string, boolean>; requires: string[]; recommends: string[]; asks: (string | { input: string; label: string; type: "date" | "file" | "link" | "long_text" | "member" | "number" | "select" | "text"; options: { alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; entity: string | null; required: boolean; default: string | null; accept: string | null; })[]; asking: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; starts: Record<string, "me" | "today">; makes: string | null; papers: { template: string; label: string; when: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }[] | null; archive: string | null; intake: { agent: string; papers: { entity: string; kind: string; files: string; }; fields: string[]; parties: { link: string; fields: string[]; }[]; rows: { entity: string; fields: string[]; key: string[]; }[]; links: { entity: string; table: string; }[]; } | null; recording: { into: string; via: string; audio: string; transcript: string; video: string | null; agent: string | null; } | null; sign: { into: string; by: string; at: string; witness: string | null; } | null; review: boolean; confirm: string | true | null; danger: boolean; corrects: boolean; stands: string[]; }[]; checks: { field: string; of: string; blocks: "all" | string[] | null; resolve: string[]; reads: string[]; stands: string[]; }[]; } | { version: 30; app: { alias: string; label: string; description: string | null; locale: ReportLanguage; }; dashboard: ({ entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "breakdown"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "list"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number | RecordBound>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | RecordBound | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; columns: string[]; open: { kind: "app"; app: { id: string; }; } | { kind: "drawer"; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "metric"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; value: string | null; average: boolean; over: string | null; target: number | null; better: "down" | "up" | null; bound: { value: number; } | { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; } | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "pivot"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; rows: string | { field: string; tiers: number[]; }; columns: string | { field: string; tiers: number[]; }; value: string | null; over: string | null; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "shortfall"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; by: string; across: string | null; value: string | null; on_hand: { entity: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; by: string | null; across: string | null; value: string | null; }; } | { entity: string; label: string; read: { query: string; param: string | null; aggregate: { by: string[] | null; bands: Record<string, number[]> | null; day: string | null; sum: string | null; } | null; }; kind: "trend"; where: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<number>; of: "number"; zone: string | null; } | { field: string; compare: StatedBounds<string | { now: true; }>; of: "date" | "datetime"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; } | { field: string; member: "me"; })[]; tab: string | null; over: string; value: string | null; ahead: boolean; })[]; tabs: { tab: string; label: string; }[] | null; opens_on: { days: 30; } | { span: "month" | "quarter" | "year"; }; entities: Record<string, { alias: string; label: string; singular: string | null; table: string; fields: Record<string, { alias: string; id: string; type: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text"; result: "autonumber" | "boolean" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | null; label: string; description: string | null; format: "datetime" | "link" | "markdown" | "text" | null; multi: boolean; required: boolean; readonly: boolean; notation: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | null; limit: { field: string; } | { value: number; } | null; gate: { field: string; } | { value: number; } | null; tolerance: number | null; due: boolean; frees: boolean; summed: boolean; accumulates: boolean; whole: boolean; restates: string | null; starts: "me" | "today" | null; default: string | number | boolean | string[] | null; options: { id: string; alias: string; label: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc" | null; mark: { kind: string; name: string; } | null; short: string | null; }[] | null; link: string | null; accept: string | null; image: string | null; party: "organization" | "person" | null; pictures: { query: string; param: string; } | null; face: Record<string, string>; default_from: { link: string; field: string; } | null; reads: string[]; through: { link: string; field: string; } | null; pick: { query: string; param: string; same: { field: string; param: string; }[]; } | null; picks_only: boolean; suggest: { query: string; param: string; column: string; } | null; applies: ({ field: string; options: string[]; } | { field: string; value: boolean; })[]; }>; title: string; subtitle: string[]; image: string | null; mark: string | null; description: string | null; party: "organization" | "person" | null; mine: string | null; status: { field: string; closed: string[]; history: string | null; dates: Record<string, string>; stages: { option: string; label: string; owner: { kind: "member"; column: string; label: string; } | { kind: "group"; group: string; label: string; }; within: number | null; when: ({ field: string; options: string[]; } | { field: string; compare: StatedBounds<Bound>; of: "date" | "datetime" | "number"; zone: string | null; } | { field: string; empty: boolean; } | { field: string; value: boolean; })[]; }[]; maker: string | null; moves: { query: string; param: string; link: string; status: string; at: string; by: string | null; went: Record<string, string>; } | null; } | null; settled: string | null; task: { close: { to: string; act: string | null; } | null; reopen: { to: string; act: string | null; } | null; member: string | null; } | null; progress: { entity: string; via: string; passed: string | null; read: { query: string; param: string; }; }[]; figure: string | null; scan: { read: "iso6346" | "text"; agent: string; } | { read: "code"; } | null; place: { address: string; latitude: string; longitude: string; accuracy: string | null; } | null; on_site: { photos: string[]; place: string | null; latitude: string; longitude: string; radius: number; } | null; pin: { on: string; x: string; y: string; } | null; size: { across: string; along: string; up: string; } | null; nests: { parent: string; children: string; closed: string | null; } | null; filed: Record<string, string>; list: { query: string; param: string | null; }; listed: string[] | null; one: { query: string; param: string; }; create: { workflow: string; fields: string[]; picker: string[] | null; } | null; update: { workflow: string; fields: string[]; } | null; remove: { workflow: string; with: string[]; } | null; }>; };
|
|
297
276
|
/** The register's layout as the spec states it: `kind` and the facts the runtime draws it from. */
|
|
298
277
|
export type SpecLayout = CardsSpec | TableSpec | { kind: "calendar"; date: string; end: string | null; } | { kind: "lanes"; field: string; group: string | null; start: string; end: string | null; loads: { value: string; against: string; }[]; read: { query: string; param: string; } | null; } | { kind: "plan"; at: string; across: string; up: string; fill: string | null; mark: { field: string; option: string; } | null; size: { field: string; options: Record<string, { across: number; along: number; up: number; }>; } | null; place: { entity: string; read: { query: string; param: string | null; }; kind: string; kinds: { bay: string; area: string; landmark: string; }; sheet: string | null; scale: string | null; x: string; y: string; width: string | null; depth: string | null; across: string; up: string; reach_from: string | null; stacked: string | null; reaches: { first: string; last: string; both: string; } | null; size: { across: string; along: string; up: string; } | null; }; load: { query: string; param: string | null; } | null; } | { kind: "roster"; entity: string; via: string; day: string | null; end: string | null; expect: string | null; of: string | null; cadence: { on: ("fri" | "mon" | "sat" | "sun" | "thu" | "tue" | "wed")[]; from: string | null; until: string | null; } | null; read: { query: string; param: string; }; create: string[] | null; } | { start: string; end: string; milestones: string[]; planned: { start: string | null; end: string | null; } | null; progress: string | null; after: string | null; kind: "gantt"; };
|
|
299
278
|
/** A comparison as a compiled app states it: every key, `null` where it bounds nothing. */
|
|
300
279
|
export type StatedBounds<V> = { gt: V | null; gte: V | null; lt: V | null; lte: V | null; };
|
|
301
|
-
|
|
302
|
-
export type StatedComposeRows = ComposeRowsPiece & { create: boolean; remove: boolean; };
|
|
303
|
-
export type TableField = { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "number"; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; format: "currency" | "number" | "percentage"; currency?: string | null | undefined; unit?: string | null | undefined; unit_field?: string | null | undefined; currency_field?: string | null | undefined; default_value?: number | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "text"; unique?: boolean | undefined; format?: "link" | "markdown" | "text" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "date"; format?: "date" | "date_range" | "datetime" | "datetime_range" | undefined; timezone?: string | undefined; derive_from?: "created_at" | "updated_at" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "boolean"; default_value?: boolean | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select"; options: { key: string; alias?: string | undefined; name: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc"; mark?: { kind: string; name: string; } | undefined; short?: string | undefined; }[]; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select_member"; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select_record_link"; table_id: string; paired_field_key?: string | undefined; cardinality?: "many" | "one" | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "rollup"; source_field_key: string; aggregate_option: { operation: "checked" | "percent_checked" | "percent_unchecked" | "unchecked"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "selected"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "unique"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "selected" | "unique"; field_key: string; } | { operation: "date_range" | "earliest" | "empty" | "filled" | "latest" | "percent_empty" | "percent_filled" | "percent_unique" | "unique"; field_key: string; } | { operation: "avg" | "empty" | "filled" | "max" | "median" | "min" | "percent_empty" | "percent_filled" | "percent_unique" | "range" | "sum" | "unique"; field_key: string; } | { operation: "avg" | "date_range" | "earliest" | "empty" | "filled" | "latest" | "max" | "median" | "min" | "percent_empty" | "percent_filled" | "percent_unique" | "range" | "sum" | "unique"; field_key: string; } | { operation: "avg" | "checked" | "date_range" | "earliest" | "empty" | "filled" | "latest" | "max" | "median" | "min" | "percent_checked" | "percent_empty" | "percent_filled" | "percent_unchecked" | "percent_unique" | "range" | "sum" | "unchecked" | "unique"; field_key: string; } | { operation: "count"; field_key?: string | undefined; }; filter?: TableRecordFiltersGroupNode | undefined; aggregate_field_type?: "autonumber" | "boolean" | "button" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | undefined; aggregate_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; aggregate_field_format?: string | undefined; aggregate_field_currency?: string | undefined; aggregate_field_unit?: string | undefined; aggregate_field_unit_field?: string | undefined; aggregate_field_currency_field?: string | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "lookup"; source_field_key: string; lookup_field_key: string; lookup_field_type?: "autonumber" | "boolean" | "button" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | undefined; lookup_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; lookup_field_format?: string | undefined; lookup_field_currency?: string | undefined; lookup_field_unit?: string | undefined; lookup_field_options?: { key: string; name: string; color?: string | undefined; mark?: { kind: string; name: string; } | undefined; }[] | undefined; lookup_field_autonumber?: boolean | undefined; order_by?: { field_key: string; direction: "asc" | "desc"; } | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "files"; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "formula"; formula: { expression: string; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; link?: true | undefined; format?: "currency" | "link" | "number" | "percentage" | undefined; currency?: string | undefined; unit?: string | undefined; unit_field?: string | undefined; currency_field?: string | undefined; options?: { key: string; alias?: string | undefined; name: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc"; mark?: { kind: string; name: string; } | undefined; short?: string | undefined; }[] | undefined; output_type?: "boolean" | "date" | "datetime" | "number" | "select" | "text" | undefined; volatile?: boolean | undefined; }; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "button"; text: string; workflow_id?: string | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "autonumber"; prefix?: string | undefined; padding?: number | undefined; template?: string | undefined; };
|
|
280
|
+
export type TableField = { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "number"; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; format: "currency" | "number" | "percentage"; currency?: string | null | undefined; unit?: string | null | undefined; unit_field?: string | null | undefined; currency_field?: string | null | undefined; default_value?: number | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "text"; unique?: boolean | undefined; format?: "link" | "markdown" | "text" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "date"; format?: "date" | "date_range" | "datetime" | "datetime_range" | undefined; timezone?: string | undefined; derive_from?: "created_at" | "updated_at" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "boolean"; default_value?: boolean | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select"; options: { key: string; alias?: string | undefined; name: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc"; mark?: { kind: string; name: string; } | undefined; short?: string | undefined; }[]; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select_member"; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "select_record_link"; table_id: string; paired_field_key?: string | undefined; cardinality?: "many" | "one" | undefined; default_from?: { link_field_key: string; through?: string[] | undefined; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "rollup"; source_field_key: string; aggregate_option: { operation: "checked" | "percent_checked" | "percent_unchecked" | "unchecked"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "selected"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "unique"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "selected" | "unique"; field_key: string; } | { operation: "date_range" | "earliest" | "empty" | "filled" | "latest" | "percent_empty" | "percent_filled" | "percent_unique" | "unique"; field_key: string; } | { operation: "avg" | "empty" | "filled" | "max" | "median" | "min" | "percent_empty" | "percent_filled" | "percent_unique" | "range" | "sum" | "unique"; field_key: string; } | { operation: "avg" | "date_range" | "earliest" | "empty" | "filled" | "latest" | "max" | "median" | "min" | "percent_empty" | "percent_filled" | "percent_unique" | "range" | "sum" | "unique"; field_key: string; } | { operation: "avg" | "checked" | "date_range" | "earliest" | "empty" | "filled" | "latest" | "max" | "median" | "min" | "percent_checked" | "percent_empty" | "percent_filled" | "percent_unchecked" | "percent_unique" | "range" | "sum" | "unchecked" | "unique"; field_key: string; } | { operation: "count"; field_key?: string | undefined; }; filter?: TableRecordFiltersGroupNode | undefined; aggregate_field_type?: "autonumber" | "boolean" | "button" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | undefined; aggregate_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; aggregate_field_format?: string | undefined; aggregate_field_currency?: string | undefined; aggregate_field_unit?: string | undefined; aggregate_field_unit_field?: string | undefined; aggregate_field_currency_field?: string | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "lookup"; source_field_key: string; lookup_field_key: string; lookup_field_type?: "autonumber" | "boolean" | "button" | "date" | "files" | "formula" | "lookup" | "number" | "rollup" | "select" | "select_member" | "select_record_link" | "text" | undefined; lookup_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; lookup_field_format?: string | undefined; lookup_field_currency?: string | undefined; lookup_field_unit?: string | undefined; lookup_field_options?: { key: string; name: string; color?: string | undefined; mark?: { kind: string; name: string; } | undefined; }[] | undefined; lookup_field_autonumber?: boolean | undefined; lookup_field_several?: true | undefined; order_by?: { field_key: string; direction: "asc" | "desc"; } | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "files"; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "formula"; formula: { expression: string; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; link?: true | undefined; format?: "currency" | "link" | "number" | "percentage" | undefined; currency?: string | undefined; unit?: string | undefined; unit_field?: string | undefined; currency_field?: string | undefined; options?: { key: string; alias?: string | undefined; name: string; color: "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "neutral" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "slate" | "stone" | "teal" | "violet" | "yellow" | "zinc"; mark?: { kind: string; name: string; } | undefined; short?: string | undefined; }[] | undefined; output_type?: "boolean" | "date" | "datetime" | "number" | "select" | "text" | undefined; volatile?: boolean | undefined; }; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "button"; text: string; workflow_id?: string | null | undefined; } | { key: string; alias?: string | undefined; name: string; description: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; type: "autonumber"; prefix?: string | undefined; padding?: number | undefined; template?: string | undefined; };
|
|
304
281
|
export type TableRecordFilters = TableRecordFiltersConditionNode | TableRecordFiltersGroupNode | TableRecordFiltersTraversalNode;
|
|
305
282
|
export type TableRecordFiltersConditionNode = { node_type: "condition"; field_key?: string; type?: string; operator: string; value?: unknown; unit_option?: string; };
|
|
306
283
|
export type TableRecordFiltersGroupNode = { node_type: "group"; logic: "and" | "or"; children: (TableRecordFiltersConditionNode | TableRecordFiltersTraversalNode | TableRecordFiltersGroupNode)[]; };
|
package/dist/viewer.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { AppAbsence } from "./shared_types.js";
|
|
2
|
-
import type { OpenableApp } from "./shared_types.js";
|
|
3
2
|
import { type AppContext } from "./rpc.js";
|
|
4
3
|
/** The store key the host's context is held under, read by every screen and by the write model alike. */
|
|
5
4
|
export declare const APP_CONTEXT_KEY = "app-context";
|
|
@@ -17,12 +16,8 @@ export declare function useAppContext(): {
|
|
|
17
16
|
groupIds: readonly string[] | null;
|
|
18
17
|
/** Who in the organization is away, or will be, and who stands in; `null` where the host did not say. */
|
|
19
18
|
absences: readonly AppAbsence[] | null;
|
|
20
|
-
/** The apps the viewer can open, by id and name, with the table each one's register lists where the host says; `null` where the host did not say. */
|
|
21
|
-
openableApps: readonly OpenableApp[] | null;
|
|
22
19
|
commentsEnabled: boolean;
|
|
23
20
|
recordingEnabled: boolean;
|
|
24
|
-
/** The host draws another app's record in a sheet over this one (`peekApp`). */
|
|
25
|
-
peekAppEnabled: boolean;
|
|
26
21
|
/** The host's own chrome already names the app, so a screen need not title itself with the app's name. */
|
|
27
22
|
hostNamesApp: boolean;
|
|
28
23
|
timezone: string | undefined;
|
package/docs/data_fetching.md
CHANGED
|
@@ -25,7 +25,7 @@ untyped. It is written from the app's live bindings by `lotics app deploy` and
|
|
|
25
25
|
| `useQueries(calls, opts?)` | one state per `{ alias, params?, filter?, sort?, aggregate?, total?, rows? }`, in order — a `sort` orders that call's rows before the cap cuts them | reads that are DATA — a list known only at render, one read per item, or one count per stage (`rows: false, total: true`, each state's `.total`); the deploy's alias scan reads a list as dynamic, so every alias in it is still declared. With `aggregate` a call answers the groups of its filtered rows instead of the rows ([queries](./queries.md)) |
|
|
26
26
|
| `queryAll(alias, params?, { filter, sort })` | a promise of every row | outside React, for a job that must hold the whole narrowed set in the browser (the ids an act runs on): it asks page after page until the server says the set ended, never stopping at the 10,000-row cap. The server's rows as stored — no write of this app is drawn over them |
|
|
27
27
|
| `exportQuery(alias, { params, filter, sort, tabs?, report, file, labels? })` | a promise of an `ExportedFile`: `{ filename, mime_type, url, size, created_at }` | every row the narrowed set holds, made into one file by the server — no row reaches the browser. `tabs` (2 to 5, each `{ tab, label, filter?, sort?, totals? }`; `totals` is `{ query, params, via, columns }`, the read of a totals tab beside its rows, joined on the link column `via`, refused where that read lacks `via` or a column or answers two groups for one row) are each read as the export's own rows are — same query and params, under the tab's own filter and sort (absent, the declared order) — and a template reads each one's rows under its `tab`, a name none of the report's keys nor the template's `rows` key holds. `report` is `{ title, lines, readings, dates?, period?, per?, per_row?, filename? }` — `dates` each date filter's `{ from?, to? }` by field alias, each bound a day (`yyyy-MM-dd`) or a minute of one (`yyyy-MM-ddTHH:mm`) with no zone; `period` the tabs' `{ from, to }`, bounds of the same form; `per` the value the report was picked for, in the reader's words; `per_row` the picked row's fields by field alias, each a text, number, boolean or `null`, which `filename` and a template read as `per_row.<field>`; `filename` the file's name in the template grammar over one value each — `title`, `at` (the moment the server made the file), `dates.<field>.from` or `.to`, `period.from` or `.to`, `per`, `per_row.<field>`, `lines | lookup:<n>`, with `| add_days:<n>` shifting a date by whole days — at most 200 bytes once filled (absent, the template's name, or `title`); `file` is `{ kind: "workbook", language, sheet, columns }` (the default report workbook, its head closing with the moment the server made it, each column `{ key, header, type }` an output column of the query — a `number` one on a number column, a `date` one on a date or datetime; with `tabs`, one sheet per tab named by its `label` in place of `sheet`) or `{ kind: "template", template }`, one the query declares under `templates` by name ([queries](./queries.md)). `labels`, by `select` output column, the words each option key prints as in either file — a cell no field of the query names (a union's literal column) arrives as its bare key; a cell its field's option names prints as that, a key the map lacks as itself, and a column no select of the query holds as it is. Past 20,000 rows, in any tab, it rejects, never cuts; each caller makes at most 60 exports a minute. The file has no `id` — it is a download, not a workspace file a workflow or a field takes: its `url` is signed for the caller for at most an hour, so download it with `downloadFileFromUrl(url, filename)` (`@lotics/ui/download`) when the promise resolves — a tab `openExternal` opens seconds after the click is a pop-up the browser blocks; the server deletes the file a day after it is made |
|
|
28
|
-
| `exportApp(key, narrowing)` | a promise of an `ExportedFile`, as `exportQuery`'s | the file the server makes of an Export `key` of a JSON app's tree (a custom-code app has no Export and makes its files with `exportQuery`) over the register as `narrowing` states it (`tab`, `status`, `filters`, `search`, `overdue`, `waiting`, `period`, `window`, `sort`, `group`, `folder`, `per`; a `filters` entry `null` clears the chip the register opens on): the server reads the rows, the band's readings and the names under the caller's own access. Download it as `exportQuery`'s |
|
|
28
|
+
| `exportApp(key, narrowing)` | a promise of an `ExportedFile`, as `exportQuery`'s | the file the server makes of an Export `key` of a JSON app's tree (a custom-code app has no Export and makes its files with `exportQuery`) over the register as `narrowing` states it (`tab`, `status`, `filters`, `search`, `overdue`, `waiting`, `period`, `window`, `sort`, `group`, `folder`, `row`, `per`; a `filters` entry `null` clears the chip the register opens on; `row` is the id of the row a List below a Record page hangs from, required there and refused elsewhere): the server reads the rows, the band's readings and the names under the caller's own access. Download it as `exportQuery`'s |
|
|
29
29
|
|
|
30
30
|
Every hook answers the same `QueryState`: `rows`, `truncated`, `total`, `counts`, `loading`,
|
|
31
31
|
`isValidating`, `answeredAt`, `error`, `pending`, `refetch`, `page`, `setPage`, `pageCount`, `hasMore`,
|
|
@@ -247,8 +247,8 @@ Reads paginate two different ways, and the difference is load-bearing:
|
|
|
247
247
|
matters — **never skips or duplicates a row as the set shifts** under concurrent inserts/deletes.
|
|
248
248
|
The cursor is internal: the hook sends it and reads the next one back; you never see it. The
|
|
249
249
|
server keysets the sort's column keys (the runtime `sort`, else the template's own order on the
|
|
250
|
-
columns it projects,
|
|
251
|
-
key it can't seek. So an infinite feed needs **no
|
|
250
|
+
columns it projects), breaking their ties by when each row was made, then by the record id, and
|
|
251
|
+
falls back to offset transparently for a `first` key it can't seek. So an infinite feed needs **no
|
|
252
252
|
dedupe** — key rows by `__source_record_id` for stable React keys, not to guard against repeats.
|
|
253
253
|
- **`page`, `limit`, `queryAll` and manual `rpc("query", { limit, offset })` use offset
|
|
254
254
|
pagination** — count `offset` rows, skip them, return the next page. Two consequences a keyset
|
|
@@ -261,7 +261,7 @@ Shared by both:
|
|
|
261
261
|
says the cap cut the result, so a screen can say so instead of quietly under-reporting.
|
|
262
262
|
- **Always give a paginated query a deterministic order.** With no `ORDER BY` (neither in the
|
|
263
263
|
template nor runtime `sort`), row order is unspecified — offset pages may overlap or skip rows
|
|
264
|
-
even without concurrent writes, and keyset falls back to the
|
|
264
|
+
even without concurrent writes, and keyset falls back to the order the rows were made in. Sort by a stable
|
|
265
265
|
column (unique where possible).
|
|
266
266
|
|
|
267
267
|
Offset-only (`page`, `limit`, and manual `rpc`):
|