@ai-matrx/records 0.87.31 → 0.92.0

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.
Files changed (107) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +115 -0
  3. package/dist/{client-E0VQ0NPO.d.ts → client-DE9Mq6YX.d.cts} +8 -5
  4. package/dist/{client-C3ZZNfGH.d.cts → client-vJAb7g9r.d.ts} +8 -5
  5. package/dist/core/index.cjs +25 -7
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +23 -12
  8. package/dist/core/index.d.ts +23 -12
  9. package/dist/core/index.js +25 -7
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/data/index.cjs +19 -7
  12. package/dist/data/index.cjs.map +1 -1
  13. package/dist/data/index.d.cts +12 -142
  14. package/dist/data/index.d.ts +12 -142
  15. package/dist/data/index.js +19 -7
  16. package/dist/data/index.js.map +1 -1
  17. package/dist/{declareTable-BK3zufr7.d.cts → declareTable-Btg5bql1.d.cts} +4 -4
  18. package/dist/{declareTable-B12XybRp.d.ts → declareTable-JKt2q34d.d.ts} +4 -4
  19. package/dist/entity/index.cjs +984 -0
  20. package/dist/entity/index.cjs.map +1 -0
  21. package/dist/entity/index.d.cts +36 -0
  22. package/dist/entity/index.d.ts +36 -0
  23. package/dist/entity/index.js +964 -0
  24. package/dist/entity/index.js.map +1 -0
  25. package/dist/entity/react.cjs +1024 -0
  26. package/dist/entity/react.cjs.map +1 -0
  27. package/dist/entity/react.d.cts +511 -0
  28. package/dist/entity/react.d.ts +511 -0
  29. package/dist/entity/react.js +1015 -0
  30. package/dist/entity/react.js.map +1 -0
  31. package/dist/{field-BanTVGK2.d.cts → field-BJBnTyJ0.d.cts} +1 -1
  32. package/dist/{field-BPABOJ2Y.d.ts → field-Ti5iAxFr.d.ts} +1 -1
  33. package/dist/forms/index.cjs +984 -0
  34. package/dist/forms/index.cjs.map +1 -0
  35. package/dist/forms/index.d.cts +333 -0
  36. package/dist/forms/index.d.ts +333 -0
  37. package/dist/forms/index.js +961 -0
  38. package/dist/forms/index.js.map +1 -0
  39. package/dist/index.cjs +10 -1
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +11 -8
  42. package/dist/index.d.ts +11 -8
  43. package/dist/index.js +10 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/memory/index.d.cts +7 -6
  46. package/dist/memory/index.d.ts +7 -6
  47. package/dist/port-CPVBfDxS.d.cts +301 -0
  48. package/dist/port-D2i2o7Lg.d.ts +301 -0
  49. package/dist/portal-Db4CYyHe.d.ts +331 -0
  50. package/dist/portal-DfeY2Boy.d.cts +331 -0
  51. package/dist/{ports-TMWX-t9l.d.ts → ports-BWtxAnXh.d.ts} +2 -2
  52. package/dist/{ports-D8-iuY1P.d.cts → ports-DSU2RsR6.d.cts} +2 -2
  53. package/dist/react/index.cjs +55 -523
  54. package/dist/react/index.cjs.map +1 -1
  55. package/dist/react/index.d.cts +14 -1
  56. package/dist/react/index.d.ts +14 -1
  57. package/dist/react/index.js +52 -527
  58. package/dist/react/index.js.map +1 -1
  59. package/dist/realtime/index.d.cts +2 -2
  60. package/dist/realtime/index.d.ts +2 -2
  61. package/dist/{record-DpB2QgAZ.d.cts → record-BQi92d4-.d.cts} +7 -1
  62. package/dist/{record-DpB2QgAZ.d.ts → record-BQi92d4-.d.ts} +7 -1
  63. package/dist/relation-DMwkmzgN.d.cts +230 -0
  64. package/dist/relation-DlcqV_W5.d.ts +230 -0
  65. package/dist/rule-B8kR0l01.d.ts +250 -0
  66. package/dist/rule-BMViCLmW.d.cts +250 -0
  67. package/dist/search/index.cjs +283 -0
  68. package/dist/search/index.cjs.map +1 -0
  69. package/dist/search/index.d.cts +44 -0
  70. package/dist/search/index.d.ts +44 -0
  71. package/dist/search/index.js +260 -0
  72. package/dist/search/index.js.map +1 -0
  73. package/dist/setup/index.cjs +6854 -0
  74. package/dist/setup/index.cjs.map +1 -0
  75. package/dist/setup/index.d.cts +87 -0
  76. package/dist/setup/index.d.ts +87 -0
  77. package/dist/setup/index.js +6829 -0
  78. package/dist/setup/index.js.map +1 -0
  79. package/dist/{subscription-D7KQBHXN.d.ts → subscription-5CLN3Jug.d.ts} +3 -249
  80. package/dist/{subscription-BD9DnJxX.d.cts → subscription-D-VEzvyy.d.cts} +3 -249
  81. package/dist/{table-kind-BZu8mtND.d.cts → table-kind-CVp43g6h.d.ts} +3 -558
  82. package/dist/{table-kind-xKxTHtrV.d.ts → table-kind-Cm6PXkWx.d.cts} +3 -558
  83. package/dist/templates/index.d.cts +10 -9
  84. package/dist/templates/index.d.ts +10 -9
  85. package/dist/typed-table/index.cjs +19 -7
  86. package/dist/typed-table/index.cjs.map +1 -1
  87. package/dist/typed-table/index.d.cts +10 -7
  88. package/dist/typed-table/index.d.ts +10 -7
  89. package/dist/typed-table/index.js +19 -7
  90. package/dist/typed-table/index.js.map +1 -1
  91. package/dist/{types-CLP5H4Wk.d.cts → types-9Q5SHRDJ.d.cts} +2 -2
  92. package/dist/{types-DmPkWQic.d.ts → types-CfYy-vdV.d.ts} +2 -2
  93. package/dist/{types-C2uspRtf.d.cts → types-Cs2MyE3u.d.cts} +2 -2
  94. package/dist/{types-Dv61jStB.d.ts → types-DF-dxB_l.d.ts} +2 -2
  95. package/dist/types-DTEGaxso.d.cts +139 -0
  96. package/dist/types-Dji5SpFS.d.ts +139 -0
  97. package/dist/use-cases/index.d.cts +5 -5
  98. package/dist/use-cases/index.d.ts +5 -5
  99. package/dist/{validate-CWVToe1T.d.ts → validate-BydKd-Le.d.ts} +1 -1
  100. package/dist/{validate-DEB_mn4Y.d.cts → validate-CqJakTKk.d.cts} +1 -1
  101. package/dist/versions/index.cjs +375 -0
  102. package/dist/versions/index.cjs.map +1 -0
  103. package/dist/versions/index.d.cts +160 -0
  104. package/dist/versions/index.d.ts +160 -0
  105. package/dist/versions/index.js +353 -0
  106. package/dist/versions/index.js.map +1 -0
  107. package/package.json +62 -2
@@ -0,0 +1,250 @@
1
+ import { U as Uuid, e as RuleNodeKind, f as RuleUse, T as Timestamp } from './record-BQi92d4-.js';
2
+
3
+ /**
4
+ * A rule expression as `custom.rule_eval` ACTUALLY evaluates it — read off the
5
+ * door's own body, not invented here. A leaf is the node's name carrying its
6
+ * payload (`{"const": 3}`, `{"field": "<uuid>"}`); an operator is
7
+ * `{"op": "eq", "args": [...]}`.
8
+ *
9
+ * `field` / `parent_field` name a Field BY ID (REC-17 — the door refuses
10
+ * `field_name`, `field_key` and `field_label` by name), and `merge_field` is
11
+ * the resolver's seam, storable today and refused `0A000` until W5-MERGE-B.
12
+ *
13
+ * `p_values` is keyed by the Field's KEY: the door resolves the id to a key
14
+ * (`custom.rule_field_key`) and then reads `p_values -> key`.
15
+ */
16
+ type RuleExpression = {
17
+ const: unknown;
18
+ } | {
19
+ field: Uuid;
20
+ } | {
21
+ parent_field: Uuid;
22
+ } | {
23
+ merge_field: string;
24
+ } | {
25
+ op: RuleNodeKind;
26
+ args: RuleExpression[];
27
+ };
28
+ /** REC-15. One Rule, four uses; a Rule may serve more than one. */
29
+ interface Rule {
30
+ id: Uuid;
31
+ organization_id: Uuid;
32
+ name: string;
33
+ kind: string | null;
34
+ /** The Table this Rule is scoped to. */
35
+ scope_table_id: Uuid | null;
36
+ uses: RuleUse[];
37
+ validates: boolean;
38
+ computes: boolean;
39
+ defines_membership: boolean;
40
+ /**
41
+ * REC-16. An applicability Rule reads the record's own Values and its
42
+ * parent's, ONE level up, and no further.
43
+ */
44
+ decides_applicability: boolean;
45
+ applies_to_types: string[];
46
+ use_types: string[];
47
+ expr: RuleExpression;
48
+ /** Which Field this Rule's answer is about (REC-17: by id). */
49
+ target_field_id: Uuid | null;
50
+ /** What a person reads when this Rule refuses. */
51
+ message: string | null;
52
+ sort: number | null;
53
+ created_by: Uuid | null;
54
+ updated_by: Uuid | null;
55
+ created_at: Timestamp;
56
+ updated_at: Timestamp;
57
+ /** REC-19. Rules have versions, and History knows which one produced a Value. */
58
+ version: number;
59
+ metadata: Record<string, unknown>;
60
+ visibility: string;
61
+ }
62
+ /** What the store answers when a Rule is run: the answer and the version that gave it. */
63
+ interface RuleAnswer {
64
+ rule_id: Uuid;
65
+ rule_name: string;
66
+ rule_version: number;
67
+ applies: boolean;
68
+ answer: unknown;
69
+ }
70
+ /** One form as `custom.forms` reports it to its owner. */
71
+ interface FormSummary {
72
+ form_id: string;
73
+ table_id: string;
74
+ title: string | null;
75
+ slug: string;
76
+ published_at: string | null;
77
+ closed_at: string | null;
78
+ submission_cap: number | null;
79
+ /** Every answer that arrived, rejected ones excluded from `in_table` and `held`. */
80
+ responses: number;
81
+ /** Answers that became records — the only number that means "it is in the table". */
82
+ in_table: number;
83
+ /** Answers waiting for a person, because the form's accept Rule did not clear them. */
84
+ held: number;
85
+ /** Answers the accept Rule or the decoy turned away. */
86
+ rejected: number;
87
+ /** draft · open · closed · full — the store's own word, never derived on a screen. */
88
+ state: "draft" | "open" | "closed" | "full";
89
+ quarantine_rule_id: string | null;
90
+ notify_rule_id: string | null;
91
+ presentation: Record<string, unknown>;
92
+ }
93
+ /**
94
+ * THE ROUTE THROUGH A FORM, AS THE STORE WALKED IT (lane TYPEFORM-DUP) — `custom._form_route`,
95
+ * reached by the owner's preview (`custom.form_preview_route`) and the stranger's page
96
+ * (`custom.form_public_route`). One row per question in order (`asked` false only when a condition
97
+ * hid it or a logic jump carried the person past it); the ending reached (null = the thank-you
98
+ * screen); the score (null when no question carries points).
99
+ */
100
+ interface FormRoute {
101
+ asks: Array<{
102
+ field_key: string;
103
+ asked: boolean;
104
+ decided: boolean;
105
+ said: string | null;
106
+ }>;
107
+ ending: string | null;
108
+ score: number | null;
109
+ }
110
+ /** A form's results for its owner — `custom.form_results`. Every number is the store's. */
111
+ interface FormResults {
112
+ form_id: string;
113
+ /** Visits to the public link (one per page open, counted through the app's own route). */
114
+ views: number;
115
+ /** Visits that answered at least one question. */
116
+ starts: number;
117
+ /** Submissions that arrived (the decoy's excluded). */
118
+ completions: number;
119
+ /** completions / starts, as a percentage with one decimal; null before anybody started. */
120
+ completion_rate: number | null;
121
+ questions: Array<{
122
+ field_key: string;
123
+ /** Visits that were shown this question. */
124
+ reached: number;
125
+ /** Visits whose last question was this one and that never sent: the drop-off. */
126
+ left: number;
127
+ /** Submissions that answered it. */
128
+ answered: number;
129
+ /** The twelve most common answers (a list answer counts each of its parts). */
130
+ answers: Array<{
131
+ value: string;
132
+ count: number;
133
+ }>;
134
+ }>;
135
+ endings: Array<{
136
+ ending: string | null;
137
+ count: number;
138
+ }>;
139
+ hidden: Array<{
140
+ key: string;
141
+ value: string;
142
+ count: number;
143
+ }>;
144
+ score: {
145
+ count: number;
146
+ average: number;
147
+ min: number;
148
+ max: number;
149
+ } | null;
150
+ }
151
+ /**
152
+ * ONE BOOKING PAGE, AS ITS OWNER SEES IT — `custom.bookings` (PRODUCTS row 14).
153
+ *
154
+ * A booking page is an `anon_form` whose `presentation -> 'booking'` carries the
155
+ * availability and the id of a slots Table, so it is the SAME object a form is and
156
+ * this is the same list `forms()` is, asked for the booking half. The numbers are
157
+ * the store's own: a screen that counted appointments in the browser would drift
158
+ * from the index that actually protects a slot.
159
+ */
160
+ interface BookingSummary {
161
+ form_id: string;
162
+ /** The Table the appointments land in — a booking is an ordinary record in it. */
163
+ table_id: string;
164
+ title: string | null;
165
+ slug: string;
166
+ published_at: string | null;
167
+ closed_at: string | null;
168
+ /** How long one appointment is. The offer is the store's, never the browser's. */
169
+ slot_minutes: number;
170
+ /** The organization's own zone, which is what the visitor's times are drawn in. */
171
+ timezone: string;
172
+ /** The ONE slots Table `custom.booking_declare` finds-or-makes for this page. */
173
+ slot_table_id: string;
174
+ booked: number;
175
+ cancelled: number;
176
+ /** Booked and still ahead of now — the number that answers "what is coming". */
177
+ upcoming: number;
178
+ /** Slots a visitor is holding right now, before they have given their details. */
179
+ held: number;
180
+ /** The next appointment, or null when there is none. */
181
+ next_at: string | null;
182
+ /** draft · open · closed — the store's own word, never derived on a screen. */
183
+ state: string;
184
+ }
185
+ /**
186
+ * ONE WINDOW OF AN ORGANIZATION'S WEEK, in the shape `custom._booking_availability`
187
+ * normalises to and `custom._booking_slots` generates from. `weekday` is 0 for Sunday
188
+ * and 6 for Saturday — the database's own numbering, so a picker and the store cannot
189
+ * disagree about which day Monday is. A window may name ONE member, which is the "with
190
+ * whom" of an appointment; naming somebody who is not a member is refused BY NAME.
191
+ */
192
+ interface BookingWindow {
193
+ weekday: number;
194
+ /** "09:00" */
195
+ from: string;
196
+ /** "17:00" — later in the day than `from`, or the store refuses it by name. */
197
+ to: string;
198
+ member_user_id?: string | null;
199
+ }
200
+ /**
201
+ * WHAT IS ON OFFER. Every field is the store's to default: a page declared with an
202
+ * empty availability comes back with the organization's timezone, a 30-minute slot and
203
+ * Monday-to-Friday nine-to-five, because a booking page that offered nothing would look
204
+ * broken rather than unconfigured. A screen shows what came BACK, never what it sent.
205
+ */
206
+ interface BookingAvailability {
207
+ timezone: string;
208
+ slot_minutes: number;
209
+ /** Dead time kept after each appointment, so two never touch. */
210
+ buffer_minutes: number;
211
+ /** How far ahead of now the earliest bookable slot is. */
212
+ lead_minutes: number;
213
+ /** Most appointments in one day, across every window. */
214
+ max_per_day: number;
215
+ /** How many days ahead the page offers. */
216
+ days: number;
217
+ windows: BookingWindow[];
218
+ }
219
+ /**
220
+ * WHAT `custom.booking_declare` ANSWERS. `availability` is the NORMALISED offer —
221
+ * show that, not the draft — and `questions_filled_in` is how many questions the store
222
+ * took over (`slot`, `status`, `booked_with`), which a visitor is never asked.
223
+ *
224
+ * It does NOT publish. `anonPublish` is still the one act that opens the link, exactly
225
+ * as it is for a form, so there is one act and one word for opening a public surface.
226
+ */
227
+ interface BookingDeclared {
228
+ form_id: string;
229
+ slot_table_id: string;
230
+ availability: BookingAvailability;
231
+ questions_asked: number;
232
+ questions_filled_in: number;
233
+ ms: number;
234
+ }
235
+ /**
236
+ * THE VISITOR'S OWN LINK to a booking page. The page id IS the capability, exactly
237
+ * as it is for a form; `custom.anon_submission.booking_ref` is the separate secret
238
+ * that lets ONE visitor manage the appointment they made.
239
+ */
240
+ declare function bookingPath(formId: string): string;
241
+ /**
242
+ * THE PUBLIC LINK, and the one place its shape is written down.
243
+ *
244
+ * The form's own id IS the capability — 122 bits of UUIDv4, exactly as
245
+ * Typeform's form id in `/to/<id>` is and as an unguessable meeting slug is
246
+ * here. There is no second secret to keep, and revoking it is closing the form.
247
+ */
248
+ declare function publicFormPath(formId: string): string;
249
+
250
+ export { type BookingSummary as B, type FormSummary as F, type RuleExpression as R, type BookingAvailability as a, type BookingDeclared as b, type FormRoute as c, type FormResults as d, type BookingWindow as e, type Rule as f, type RuleAnswer as g, bookingPath as h, publicFormPath as p };
@@ -0,0 +1,250 @@
1
+ import { U as Uuid, e as RuleNodeKind, f as RuleUse, T as Timestamp } from './record-BQi92d4-.cjs';
2
+
3
+ /**
4
+ * A rule expression as `custom.rule_eval` ACTUALLY evaluates it — read off the
5
+ * door's own body, not invented here. A leaf is the node's name carrying its
6
+ * payload (`{"const": 3}`, `{"field": "<uuid>"}`); an operator is
7
+ * `{"op": "eq", "args": [...]}`.
8
+ *
9
+ * `field` / `parent_field` name a Field BY ID (REC-17 — the door refuses
10
+ * `field_name`, `field_key` and `field_label` by name), and `merge_field` is
11
+ * the resolver's seam, storable today and refused `0A000` until W5-MERGE-B.
12
+ *
13
+ * `p_values` is keyed by the Field's KEY: the door resolves the id to a key
14
+ * (`custom.rule_field_key`) and then reads `p_values -> key`.
15
+ */
16
+ type RuleExpression = {
17
+ const: unknown;
18
+ } | {
19
+ field: Uuid;
20
+ } | {
21
+ parent_field: Uuid;
22
+ } | {
23
+ merge_field: string;
24
+ } | {
25
+ op: RuleNodeKind;
26
+ args: RuleExpression[];
27
+ };
28
+ /** REC-15. One Rule, four uses; a Rule may serve more than one. */
29
+ interface Rule {
30
+ id: Uuid;
31
+ organization_id: Uuid;
32
+ name: string;
33
+ kind: string | null;
34
+ /** The Table this Rule is scoped to. */
35
+ scope_table_id: Uuid | null;
36
+ uses: RuleUse[];
37
+ validates: boolean;
38
+ computes: boolean;
39
+ defines_membership: boolean;
40
+ /**
41
+ * REC-16. An applicability Rule reads the record's own Values and its
42
+ * parent's, ONE level up, and no further.
43
+ */
44
+ decides_applicability: boolean;
45
+ applies_to_types: string[];
46
+ use_types: string[];
47
+ expr: RuleExpression;
48
+ /** Which Field this Rule's answer is about (REC-17: by id). */
49
+ target_field_id: Uuid | null;
50
+ /** What a person reads when this Rule refuses. */
51
+ message: string | null;
52
+ sort: number | null;
53
+ created_by: Uuid | null;
54
+ updated_by: Uuid | null;
55
+ created_at: Timestamp;
56
+ updated_at: Timestamp;
57
+ /** REC-19. Rules have versions, and History knows which one produced a Value. */
58
+ version: number;
59
+ metadata: Record<string, unknown>;
60
+ visibility: string;
61
+ }
62
+ /** What the store answers when a Rule is run: the answer and the version that gave it. */
63
+ interface RuleAnswer {
64
+ rule_id: Uuid;
65
+ rule_name: string;
66
+ rule_version: number;
67
+ applies: boolean;
68
+ answer: unknown;
69
+ }
70
+ /** One form as `custom.forms` reports it to its owner. */
71
+ interface FormSummary {
72
+ form_id: string;
73
+ table_id: string;
74
+ title: string | null;
75
+ slug: string;
76
+ published_at: string | null;
77
+ closed_at: string | null;
78
+ submission_cap: number | null;
79
+ /** Every answer that arrived, rejected ones excluded from `in_table` and `held`. */
80
+ responses: number;
81
+ /** Answers that became records — the only number that means "it is in the table". */
82
+ in_table: number;
83
+ /** Answers waiting for a person, because the form's accept Rule did not clear them. */
84
+ held: number;
85
+ /** Answers the accept Rule or the decoy turned away. */
86
+ rejected: number;
87
+ /** draft · open · closed · full — the store's own word, never derived on a screen. */
88
+ state: "draft" | "open" | "closed" | "full";
89
+ quarantine_rule_id: string | null;
90
+ notify_rule_id: string | null;
91
+ presentation: Record<string, unknown>;
92
+ }
93
+ /**
94
+ * THE ROUTE THROUGH A FORM, AS THE STORE WALKED IT (lane TYPEFORM-DUP) — `custom._form_route`,
95
+ * reached by the owner's preview (`custom.form_preview_route`) and the stranger's page
96
+ * (`custom.form_public_route`). One row per question in order (`asked` false only when a condition
97
+ * hid it or a logic jump carried the person past it); the ending reached (null = the thank-you
98
+ * screen); the score (null when no question carries points).
99
+ */
100
+ interface FormRoute {
101
+ asks: Array<{
102
+ field_key: string;
103
+ asked: boolean;
104
+ decided: boolean;
105
+ said: string | null;
106
+ }>;
107
+ ending: string | null;
108
+ score: number | null;
109
+ }
110
+ /** A form's results for its owner — `custom.form_results`. Every number is the store's. */
111
+ interface FormResults {
112
+ form_id: string;
113
+ /** Visits to the public link (one per page open, counted through the app's own route). */
114
+ views: number;
115
+ /** Visits that answered at least one question. */
116
+ starts: number;
117
+ /** Submissions that arrived (the decoy's excluded). */
118
+ completions: number;
119
+ /** completions / starts, as a percentage with one decimal; null before anybody started. */
120
+ completion_rate: number | null;
121
+ questions: Array<{
122
+ field_key: string;
123
+ /** Visits that were shown this question. */
124
+ reached: number;
125
+ /** Visits whose last question was this one and that never sent: the drop-off. */
126
+ left: number;
127
+ /** Submissions that answered it. */
128
+ answered: number;
129
+ /** The twelve most common answers (a list answer counts each of its parts). */
130
+ answers: Array<{
131
+ value: string;
132
+ count: number;
133
+ }>;
134
+ }>;
135
+ endings: Array<{
136
+ ending: string | null;
137
+ count: number;
138
+ }>;
139
+ hidden: Array<{
140
+ key: string;
141
+ value: string;
142
+ count: number;
143
+ }>;
144
+ score: {
145
+ count: number;
146
+ average: number;
147
+ min: number;
148
+ max: number;
149
+ } | null;
150
+ }
151
+ /**
152
+ * ONE BOOKING PAGE, AS ITS OWNER SEES IT — `custom.bookings` (PRODUCTS row 14).
153
+ *
154
+ * A booking page is an `anon_form` whose `presentation -> 'booking'` carries the
155
+ * availability and the id of a slots Table, so it is the SAME object a form is and
156
+ * this is the same list `forms()` is, asked for the booking half. The numbers are
157
+ * the store's own: a screen that counted appointments in the browser would drift
158
+ * from the index that actually protects a slot.
159
+ */
160
+ interface BookingSummary {
161
+ form_id: string;
162
+ /** The Table the appointments land in — a booking is an ordinary record in it. */
163
+ table_id: string;
164
+ title: string | null;
165
+ slug: string;
166
+ published_at: string | null;
167
+ closed_at: string | null;
168
+ /** How long one appointment is. The offer is the store's, never the browser's. */
169
+ slot_minutes: number;
170
+ /** The organization's own zone, which is what the visitor's times are drawn in. */
171
+ timezone: string;
172
+ /** The ONE slots Table `custom.booking_declare` finds-or-makes for this page. */
173
+ slot_table_id: string;
174
+ booked: number;
175
+ cancelled: number;
176
+ /** Booked and still ahead of now — the number that answers "what is coming". */
177
+ upcoming: number;
178
+ /** Slots a visitor is holding right now, before they have given their details. */
179
+ held: number;
180
+ /** The next appointment, or null when there is none. */
181
+ next_at: string | null;
182
+ /** draft · open · closed — the store's own word, never derived on a screen. */
183
+ state: string;
184
+ }
185
+ /**
186
+ * ONE WINDOW OF AN ORGANIZATION'S WEEK, in the shape `custom._booking_availability`
187
+ * normalises to and `custom._booking_slots` generates from. `weekday` is 0 for Sunday
188
+ * and 6 for Saturday — the database's own numbering, so a picker and the store cannot
189
+ * disagree about which day Monday is. A window may name ONE member, which is the "with
190
+ * whom" of an appointment; naming somebody who is not a member is refused BY NAME.
191
+ */
192
+ interface BookingWindow {
193
+ weekday: number;
194
+ /** "09:00" */
195
+ from: string;
196
+ /** "17:00" — later in the day than `from`, or the store refuses it by name. */
197
+ to: string;
198
+ member_user_id?: string | null;
199
+ }
200
+ /**
201
+ * WHAT IS ON OFFER. Every field is the store's to default: a page declared with an
202
+ * empty availability comes back with the organization's timezone, a 30-minute slot and
203
+ * Monday-to-Friday nine-to-five, because a booking page that offered nothing would look
204
+ * broken rather than unconfigured. A screen shows what came BACK, never what it sent.
205
+ */
206
+ interface BookingAvailability {
207
+ timezone: string;
208
+ slot_minutes: number;
209
+ /** Dead time kept after each appointment, so two never touch. */
210
+ buffer_minutes: number;
211
+ /** How far ahead of now the earliest bookable slot is. */
212
+ lead_minutes: number;
213
+ /** Most appointments in one day, across every window. */
214
+ max_per_day: number;
215
+ /** How many days ahead the page offers. */
216
+ days: number;
217
+ windows: BookingWindow[];
218
+ }
219
+ /**
220
+ * WHAT `custom.booking_declare` ANSWERS. `availability` is the NORMALISED offer —
221
+ * show that, not the draft — and `questions_filled_in` is how many questions the store
222
+ * took over (`slot`, `status`, `booked_with`), which a visitor is never asked.
223
+ *
224
+ * It does NOT publish. `anonPublish` is still the one act that opens the link, exactly
225
+ * as it is for a form, so there is one act and one word for opening a public surface.
226
+ */
227
+ interface BookingDeclared {
228
+ form_id: string;
229
+ slot_table_id: string;
230
+ availability: BookingAvailability;
231
+ questions_asked: number;
232
+ questions_filled_in: number;
233
+ ms: number;
234
+ }
235
+ /**
236
+ * THE VISITOR'S OWN LINK to a booking page. The page id IS the capability, exactly
237
+ * as it is for a form; `custom.anon_submission.booking_ref` is the separate secret
238
+ * that lets ONE visitor manage the appointment they made.
239
+ */
240
+ declare function bookingPath(formId: string): string;
241
+ /**
242
+ * THE PUBLIC LINK, and the one place its shape is written down.
243
+ *
244
+ * The form's own id IS the capability — 122 bits of UUIDv4, exactly as
245
+ * Typeform's form id in `/to/<id>` is and as an unguessable meeting slug is
246
+ * here. There is no second secret to keep, and revoking it is closing the form.
247
+ */
248
+ declare function publicFormPath(formId: string): string;
249
+
250
+ export { type BookingSummary as B, type FormSummary as F, type RuleExpression as R, type BookingAvailability as a, type BookingDeclared as b, type FormRoute as c, type FormResults as d, type BookingWindow as e, type Rule as f, type RuleAnswer as g, bookingPath as h, publicFormPath as p };