@superpanel-sdk/runtime 0.2.3 → 0.7.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 (319) hide show
  1. package/README.md +30 -10
  2. package/dist/builder/codegen/emit.d.ts +25 -12
  3. package/dist/builder/codegen/emit.js +339 -78
  4. package/dist/builder/codegen/generate.d.ts +21 -2
  5. package/dist/builder/codegen/generate.js +147 -34
  6. package/dist/builder/company-import-graph.d.ts +2 -0
  7. package/dist/builder/company-import-graph.js +40 -8
  8. package/dist/builder/company-imports.d.ts +29 -0
  9. package/dist/builder/company-imports.js +122 -0
  10. package/dist/builder/compile/compile-sequence.d.ts +61 -8
  11. package/dist/builder/compile/compile-sequence.js +334 -80
  12. package/dist/builder/compile/function-code.d.ts +19 -3
  13. package/dist/builder/compile/function-code.js +123 -45
  14. package/dist/builder/compile/registry.d.ts +7 -3
  15. package/dist/builder/compile/registry.js +30 -27
  16. package/dist/builder/errors.d.ts +9 -0
  17. package/dist/builder/errors.js +17 -0
  18. package/dist/builder/function-params.d.ts +10 -0
  19. package/dist/builder/function-params.js +203 -0
  20. package/dist/builder/load.d.ts +70 -10
  21. package/dist/builder/load.js +258 -67
  22. package/dist/builder/paths.d.ts +9 -1
  23. package/dist/builder/paths.js +32 -2
  24. package/dist/builder/schedules.d.ts +25 -0
  25. package/dist/builder/schedules.js +101 -0
  26. package/dist/builder/slot-schema-validation.d.ts +4 -0
  27. package/dist/builder/slot-schema-validation.js +10 -0
  28. package/dist/builder/typecheck.d.ts +8 -0
  29. package/dist/builder/typecheck.js +102 -0
  30. package/dist/builder/types.d.ts +127 -19
  31. package/dist/builder/types.js +21 -1
  32. package/dist/cli/auth/auth.d.ts +37 -0
  33. package/dist/cli/auth/auth.js +211 -0
  34. package/dist/cli/auth/backend-url.d.ts +5 -0
  35. package/dist/cli/auth/backend-url.js +25 -0
  36. package/dist/cli/auth/clipboard.d.ts +9 -0
  37. package/dist/cli/auth/clipboard.js +38 -0
  38. package/dist/cli/auth/http.d.ts +20 -0
  39. package/dist/cli/auth/http.js +27 -0
  40. package/dist/cli/auth/index.d.ts +10 -0
  41. package/dist/cli/auth/index.js +27 -0
  42. package/dist/cli/auth/progress.d.ts +12 -0
  43. package/dist/cli/auth/progress.js +15 -0
  44. package/dist/cli/auth/serve-login.d.ts +8 -0
  45. package/dist/cli/auth/serve-login.js +24 -0
  46. package/dist/cli/calls/index.d.ts +177 -0
  47. package/dist/cli/calls/index.js +96 -0
  48. package/dist/cli/compile/index.js +3 -0
  49. package/dist/cli/config.d.ts +10 -0
  50. package/dist/cli/config.js +52 -0
  51. package/dist/cli/debug/index.d.ts +31 -0
  52. package/dist/cli/debug/index.js +119 -0
  53. package/dist/cli/exec/index.d.ts +39 -0
  54. package/dist/cli/exec/index.js +138 -0
  55. package/dist/cli/exec/session.d.ts +48 -0
  56. package/dist/cli/exec/session.js +82 -0
  57. package/dist/cli/exec/trace.d.ts +18 -0
  58. package/dist/cli/exec/trace.js +52 -0
  59. package/dist/cli/index.js +112 -9
  60. package/dist/cli/logs/index.d.ts +47 -0
  61. package/dist/cli/logs/index.js +113 -0
  62. package/dist/cli/mobile/index.d.ts +12 -0
  63. package/dist/cli/mobile/index.js +405 -0
  64. package/dist/cli/serve/index.d.ts +109 -3
  65. package/dist/cli/serve/index.js +506 -118
  66. package/dist/cli/turns/index.d.ts +105 -0
  67. package/dist/cli/turns/index.js +128 -0
  68. package/dist/cli/turns/run.d.ts +13 -0
  69. package/dist/cli/turns/run.js +57 -0
  70. package/dist/cli/turns/shadow.d.ts +112 -0
  71. package/dist/cli/turns/shadow.js +54 -0
  72. package/dist/cli/type-gen/index.js +9 -9
  73. package/dist/compiler.d.ts +7 -0
  74. package/dist/compiler.js +7 -0
  75. package/dist/compute-host/compute-host.d.ts +14 -23
  76. package/dist/compute-host/compute-host.js +18 -30
  77. package/dist/compute-host/index.d.ts +2 -4
  78. package/dist/compute-host/index.js +1 -2
  79. package/dist/compute-host/source-compute-host.d.ts +10 -10
  80. package/dist/compute-host/source-compute-host.js +33 -40
  81. package/dist/core/case-orchestrator/contact-hours.d.ts +70 -0
  82. package/dist/core/case-orchestrator/contact-hours.js +127 -0
  83. package/dist/core/case-orchestrator/index.d.ts +3 -0
  84. package/dist/core/case-orchestrator/index.js +3 -0
  85. package/dist/core/case-orchestrator/render.d.ts +75 -0
  86. package/dist/core/case-orchestrator/render.js +244 -0
  87. package/dist/core/case-orchestrator/time.d.ts +11 -0
  88. package/dist/core/case-orchestrator/time.js +29 -0
  89. package/dist/core/case-orchestrator/types.d.ts +708 -0
  90. package/dist/core/case-orchestrator/types.js +42 -0
  91. package/dist/core/context/call.d.ts +291 -0
  92. package/dist/core/context/call.js +94 -0
  93. package/dist/core/context/channels.d.ts +60 -0
  94. package/dist/core/context/channels.js +35 -0
  95. package/dist/core/context/contact.d.ts +96 -6
  96. package/dist/core/context/contact.js +48 -2
  97. package/dist/core/context/email-message.d.ts +198 -0
  98. package/dist/core/context/email-message.js +86 -0
  99. package/dist/core/context/email.d.ts +109 -0
  100. package/dist/core/context/email.js +90 -0
  101. package/dist/core/context/exchanges.d.ts +167 -0
  102. package/dist/core/context/exchanges.js +81 -0
  103. package/dist/core/context/instances.d.ts +307 -0
  104. package/dist/core/context/instances.js +137 -0
  105. package/dist/core/context/kv.d.ts +113 -0
  106. package/dist/core/context/kv.js +60 -0
  107. package/dist/core/context/platform-registry.d.ts +544 -4
  108. package/dist/core/context/platform-registry.js +14 -2
  109. package/dist/core/context/platform.d.ts +2 -1
  110. package/dist/core/context/sms.d.ts +177 -0
  111. package/dist/core/context/sms.js +77 -0
  112. package/dist/core/context/types.d.ts +79 -48
  113. package/dist/core/context/types.js +1 -7
  114. package/dist/core/conversation/index.d.ts +85 -0
  115. package/dist/core/conversation/index.js +133 -0
  116. package/dist/core/functions/errors.d.ts +74 -0
  117. package/dist/core/functions/errors.js +26 -0
  118. package/dist/core/functions/events.d.ts +192 -0
  119. package/dist/core/functions/events.js +23 -0
  120. package/dist/core/functions/schedules.d.ts +50 -0
  121. package/dist/core/functions/schedules.js +20 -0
  122. package/dist/core/functions/types.d.ts +29 -73
  123. package/dist/core/functions/types.js +1 -4
  124. package/dist/core/office-hours/index.d.ts +39 -0
  125. package/dist/core/office-hours/index.js +187 -0
  126. package/dist/core/page/define.d.ts +904 -0
  127. package/dist/core/page/define.js +518 -0
  128. package/dist/core/page/envelope.d.ts +55 -0
  129. package/dist/core/page/envelope.js +4 -0
  130. package/dist/core/page/fns.d.ts +448 -0
  131. package/dist/core/page/fns.js +539 -0
  132. package/dist/core/page/memory-reader.d.ts +27 -0
  133. package/dist/core/page/memory-reader.js +299 -0
  134. package/dist/core/page/ops.d.ts +58 -0
  135. package/dist/core/page/ops.js +220 -0
  136. package/dist/core/page/page-host.d.ts +20 -0
  137. package/dist/core/page/page-host.js +57 -0
  138. package/dist/core/page/records-query.d.ts +234 -0
  139. package/dist/core/page/records-query.js +780 -0
  140. package/dist/core/page/render.d.ts +295 -0
  141. package/dist/core/page/render.js +1060 -0
  142. package/dist/core/page/sandbox.d.ts +85 -0
  143. package/dist/core/page/sandbox.js +357 -0
  144. package/dist/core/page/time-format.d.ts +46 -0
  145. package/dist/core/page/time-format.js +125 -0
  146. package/dist/core/page/timeline.d.ts +40 -0
  147. package/dist/core/page/timeline.js +2 -0
  148. package/dist/core/page/typed.d.ts +648 -0
  149. package/dist/core/page/typed.js +2 -0
  150. package/dist/core/page/workspace.d.ts +57 -0
  151. package/dist/core/page/workspace.js +266 -0
  152. package/dist/core/party/index.d.ts +3 -0
  153. package/dist/core/party/index.js +3 -0
  154. package/dist/core/party/schema.d.ts +208 -0
  155. package/dist/core/party/schema.js +113 -0
  156. package/dist/core/party/types.d.ts +35 -0
  157. package/dist/core/party/types.js +15 -0
  158. package/dist/core/sequence/define.d.ts +56 -0
  159. package/dist/core/sequence/define.js +10 -0
  160. package/dist/core/sequence/index.d.ts +63 -0
  161. package/dist/core/sequence/index.js +231 -0
  162. package/dist/core/slot/binding.d.ts +40 -0
  163. package/dist/core/slot/binding.js +2 -0
  164. package/dist/core/slot/company-metadata.d.ts +102 -0
  165. package/dist/core/slot/company-metadata.js +536 -0
  166. package/dist/core/slot/compile-schema.d.ts +19 -13
  167. package/dist/core/slot/compile-schema.js +51 -248
  168. package/dist/core/slot/contact-timezone.d.ts +110 -0
  169. package/dist/core/slot/contact-timezone.js +186 -0
  170. package/dist/core/slot/field.d.ts +2 -25
  171. package/dist/core/slot/field.js +0 -71
  172. package/dist/core/slot/id-ref.d.ts +17 -2
  173. package/dist/core/slot/id-ref.js +16 -8
  174. package/dist/core/slot/index.d.ts +12 -13
  175. package/dist/core/slot/index.js +11 -12
  176. package/dist/core/slot/naming.d.ts +15 -0
  177. package/dist/core/slot/naming.js +96 -0
  178. package/dist/core/slot/platform-fields.d.ts +119 -0
  179. package/dist/core/slot/platform-fields.js +121 -0
  180. package/dist/core/slot/ref.d.ts +16 -0
  181. package/dist/core/slot/ref.js +14 -0
  182. package/dist/core/slot/row.d.ts +2 -9
  183. package/dist/core/slot/row.js +13 -23
  184. package/dist/core/slot/schema-compat.d.ts +17 -0
  185. package/dist/core/slot/schema-compat.js +103 -0
  186. package/dist/core/slot/schema.d.ts +353 -76
  187. package/dist/core/slot/schema.js +163 -10
  188. package/dist/core/slot/types.d.ts +30 -103
  189. package/dist/core/slot/value.d.ts +28 -3
  190. package/dist/core/slot/value.js +93 -57
  191. package/dist/dev-overlay/protocol.d.ts +74 -8
  192. package/dist/fn-context/build-context.d.ts +3 -1
  193. package/dist/fn-context/build-context.js +26 -10
  194. package/dist/fn-context/fake/empty-api.js +9 -28
  195. package/dist/fn-context/fake/index.d.ts +13 -4
  196. package/dist/fn-context/fake/index.js +29 -2
  197. package/dist/fn-context/fn-params.d.ts +3 -0
  198. package/dist/fn-context/fn-params.js +10 -0
  199. package/dist/fn-context/index.d.ts +5 -5
  200. package/dist/fn-context/index.js +4 -4
  201. package/dist/fn-context/log.js +2 -2
  202. package/dist/fn-context/make-ctx.d.ts +11 -0
  203. package/dist/fn-context/make-ctx.js +20 -9
  204. package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +32 -0
  205. package/dist/fn-context/rpc/case-orchestrator-tools.js +12 -0
  206. package/dist/fn-context/rpc/errors.d.ts +13 -0
  207. package/dist/fn-context/rpc/errors.js +22 -0
  208. package/dist/fn-context/rpc/index.d.ts +4 -2
  209. package/dist/fn-context/rpc/index.js +4 -2
  210. package/dist/fn-context/rpc/integration/index.d.ts +15 -5
  211. package/dist/fn-context/rpc/integration/index.js +1 -1
  212. package/dist/fn-context/rpc/integration/list-surfaces.d.ts +21 -0
  213. package/dist/fn-context/rpc/integration/{list-bindings.js → list-surfaces.js} +4 -4
  214. package/dist/fn-context/rpc/log.d.ts +11 -1
  215. package/dist/fn-context/rpc/platform.d.ts +13 -3
  216. package/dist/fn-context/rpc/platform.js +1 -1
  217. package/dist/fn-context/rpc/records.d.ts +85 -0
  218. package/dist/fn-context/rpc/records.js +24 -0
  219. package/dist/fn-context/rpc/trpc-client.d.ts +44 -2
  220. package/dist/fn-context/rpc/trpc-client.js +222 -12
  221. package/dist/fn-context/rpc/trpc-init.d.ts +21 -3
  222. package/dist/fn-context/rpc/trpc-init.js +10 -4
  223. package/dist/fn-context/rpc/trpc-router-factory.d.ts +111 -7
  224. package/dist/fn-context/rpc/trpc-router-factory.js +2 -0
  225. package/dist/fn-context/run-scope.d.ts +4 -0
  226. package/dist/fn-context/run-scope.js +9 -0
  227. package/dist/fn-context/types.d.ts +52 -5
  228. package/dist/index.d.ts +36 -46
  229. package/dist/index.js +30 -33
  230. package/dist/logger.d.ts +11 -0
  231. package/dist/logger.js +49 -0
  232. package/dist/platform.d.ts +75 -0
  233. package/dist/platform.js +57 -0
  234. package/dist/testing-compile-child.d.ts +2 -0
  235. package/dist/testing-compile-child.js +20 -0
  236. package/dist/testing.d.ts +368 -0
  237. package/dist/testing.js +439 -0
  238. package/dist/voice-service/actions.d.ts +50 -6
  239. package/dist/voice-service/index.d.ts +2 -0
  240. package/dist/voice-service/index.js +2 -0
  241. package/dist/voice-service/protocol.d.ts +604 -0
  242. package/dist/voice-service/protocol.js +67 -0
  243. package/dist/voice-service/types.d.ts +55 -8
  244. package/dist/worker.d.ts +11 -0
  245. package/dist/worker.js +11 -0
  246. package/package.json +38 -15
  247. package/dist/builder/compile/compile-agenda.d.ts +0 -15
  248. package/dist/builder/compile/compile-agenda.js +0 -64
  249. package/dist/builder/merge.d.ts +0 -4
  250. package/dist/builder/merge.js +0 -19
  251. package/dist/compute-host/read-only-cache.d.ts +0 -20
  252. package/dist/compute-host/read-only-cache.js +0 -61
  253. package/dist/core/context/db.d.ts +0 -69
  254. package/dist/core/context/db.js +0 -44
  255. package/dist/core/context/docusign.d.ts +0 -134
  256. package/dist/core/context/docusign.js +0 -108
  257. package/dist/core/context/filevine.d.ts +0 -323
  258. package/dist/core/context/filevine.js +0 -254
  259. package/dist/core/context/http.d.ts +0 -9
  260. package/dist/core/context/http.js +0 -4
  261. package/dist/core/context/hubspot.d.ts +0 -250
  262. package/dist/core/context/hubspot.js +0 -191
  263. package/dist/core/context/twilio.d.ts +0 -50
  264. package/dist/core/context/twilio.js +0 -42
  265. package/dist/core/functions/define/case-context.d.ts +0 -14
  266. package/dist/core/functions/define/case-context.js +0 -15
  267. package/dist/core/functions/define/compute.d.ts +0 -7
  268. package/dist/core/functions/define/compute.js +0 -17
  269. package/dist/core/functions/define/custom.d.ts +0 -4
  270. package/dist/core/functions/define/custom.js +0 -8
  271. package/dist/core/functions/define/system.d.ts +0 -7
  272. package/dist/core/functions/define/system.js +0 -12
  273. package/dist/core/functions/func-ref.d.ts +0 -16
  274. package/dist/core/functions/func-ref.js +0 -20
  275. package/dist/core/slot/deps.d.ts +0 -15
  276. package/dist/core/slot/deps.js +0 -88
  277. package/dist/core/slot/derived.d.ts +0 -32
  278. package/dist/core/slot/derived.js +0 -115
  279. package/dist/core/slot/platform-session-fields.d.ts +0 -38
  280. package/dist/core/slot/platform-session-fields.js +0 -48
  281. package/dist/core/slot/sf-schema.d.ts +0 -23
  282. package/dist/core/slot/sf-schema.js +0 -125
  283. package/dist/core/slot/sf-validate.d.ts +0 -14
  284. package/dist/core/slot/sf-validate.js +0 -132
  285. package/dist/core/slot/snapshot.d.ts +0 -18
  286. package/dist/core/slot/snapshot.js +0 -138
  287. package/dist/core/slot/write.d.ts +0 -48
  288. package/dist/core/slot/write.js +0 -426
  289. package/dist/core/stage/builders.d.ts +0 -54
  290. package/dist/core/stage/builders.js +0 -31
  291. package/dist/core/stage/condition.d.ts +0 -17
  292. package/dist/core/stage/condition.js +0 -198
  293. package/dist/core/stage/drive.d.ts +0 -43
  294. package/dist/core/stage/drive.js +0 -78
  295. package/dist/core/stage/finish-when.d.ts +0 -20
  296. package/dist/core/stage/finish-when.js +0 -82
  297. package/dist/core/stage/flatten.d.ts +0 -27
  298. package/dist/core/stage/flatten.js +0 -466
  299. package/dist/core/stage/index.d.ts +0 -15
  300. package/dist/core/stage/index.js +0 -13
  301. package/dist/core/stage/interrupts.d.ts +0 -28
  302. package/dist/core/stage/interrupts.js +0 -120
  303. package/dist/core/stage/ivr-fields.d.ts +0 -9
  304. package/dist/core/stage/ivr-fields.js +0 -75
  305. package/dist/core/stage/simulate.d.ts +0 -24
  306. package/dist/core/stage/simulate.js +0 -33
  307. package/dist/core/stage/transfer-fields.d.ts +0 -19
  308. package/dist/core/stage/transfer-fields.js +0 -129
  309. package/dist/core/stage/transfer-spec.d.ts +0 -48
  310. package/dist/core/stage/transfer-spec.js +0 -113
  311. package/dist/core/stage/types.d.ts +0 -208
  312. package/dist/core/stage/types.js +0 -2
  313. package/dist/core/stage/validate.d.ts +0 -11
  314. package/dist/core/stage/validate.js +0 -330
  315. package/dist/core/stage/walk.d.ts +0 -39
  316. package/dist/core/stage/walk.js +0 -119
  317. package/dist/fn-context/rpc/integration/list-bindings.d.ts +0 -21
  318. package/dist/fn-context/system-args.d.ts +0 -6
  319. package/dist/fn-context/system-args.js +0 -14
@@ -0,0 +1,536 @@
1
+ import { nameProblem } from './naming.js';
2
+ import { formatFieldPath } from './path.js';
3
+ import { PLATFORM_CONTACT_FIELDS, PLATFORM_SESSION_FIELDS } from './platform-fields.js';
4
+ import { isReservedTableName } from './row.js';
5
+ import { OPTION_DATA_TYPES, REMOVED_ENUM_KEY, REMOVED_IDENTIFIER_KEY, REMOVED_NULLABLE_KEY, REMOVED_SOURCE_KEY, ROW_ID_FIELD, SCALAR_DATA_TYPES, sessionSchemaSchema } from './schema.js';
6
+ export { PLATFORM_CONTACT_FIELDS, PLATFORM_SESSION_FIELDS } from './platform-fields.js';
7
+ /** The one table every company has: the only thing the platform contacts (14-sequence-instance §5). */
8
+ export const CONTACT_TABLE = 'contact';
9
+ /** The conversation's table: its fields are the company's `schema/session.ts`; no company table has this name. */
10
+ export const SESSION_TABLE = 'session';
11
+ export const CONTACT_OPT_OUT_FIELDS = ['opted_out', 'call_opted_out', 'sms_opted_out', 'email_opted_out'];
12
+ /** Platform limits (14-sequence-instance §16.1). */
13
+ export const LIMITS = {
14
+ /** Longest parent chain: a table's parent's parent … at most this many hops to a table without one. */
15
+ parentDepth: 5,
16
+ /** An instance's `variables`, serialized, bytes. */
17
+ variablesBytes: 64 * 1024,
18
+ /** Company tables per company and environment (18-record-search-index §4.7). */
19
+ tables: 100,
20
+ /** Fields per table, platform fields included. */
21
+ fieldsPerTable: 300,
22
+ /** `options` of one `select` / `multi_select` field (a longer list is a table and a lookupRef). */
23
+ options: 200,
24
+ /** Characters of one option: a short code, not a sentence (its meaning goes in `extraction`). */
25
+ optionChars: 60,
26
+ /**
27
+ * A `string` value, UTF-8 bytes, as written and lower-cased: its index entries keep it whole, and a
28
+ * B-tree entry holds at most 2688 bytes of it; the rest is room for the entry's other columns (34 §2).
29
+ */
30
+ stringBytes: 2500,
31
+ /** A `text` value, UTF-8 bytes: the storage's bound, not a business one (34 §2). */
32
+ textBytes: 64 * 1024,
33
+ /** One row's stored data, serialized, UTF-8 bytes. */
34
+ rowDataBytes: 256 * 1024,
35
+ };
36
+ /**
37
+ * The policy ids a run can name, per layer: the values of the platform's run variables
38
+ * `responsePolicy`, `slotFillingPolicy` and `voice` (14 §4.4). Customers write them, so an id is only
39
+ * ever added; removing or renaming one breaks the companies that use it.
40
+ */
41
+ export const POLICY_IDS = {
42
+ response: ['default'],
43
+ slotFilling: ['default'],
44
+ voice: ['default'],
45
+ };
46
+ /** Session fields with the platform's only: what a company without fields of its own declares. */
47
+ export const PLATFORM_SESSION_SCHEMA = { fields: { ...PLATFORM_SESSION_FIELDS } };
48
+ /** Each table's platform fields, with the name its issue codes use (`missing-platform-<name>-field`). */
49
+ export const PLATFORM_TABLE_FIELDS = {
50
+ contact: { name: 'contact', fields: PLATFORM_CONTACT_FIELDS },
51
+ };
52
+ /**
53
+ * A company table other than `contact`: one the company defines whole. Every company table (contact
54
+ * included) is stored as `Record` rows; `session` is the sequence's, stored on the session.
55
+ */
56
+ export function isCustomTable(tableName) {
57
+ return tableName !== CONTACT_TABLE && tableName !== SESSION_TABLE && !isReservedTableName(tableName);
58
+ }
59
+ /** A table whose rows are `Record` rows: every company table, contact included. */
60
+ export function isRecordTable(tableName) {
61
+ return tableName !== SESSION_TABLE && !isReservedTableName(tableName);
62
+ }
63
+ /** A table's parent: the field name and the table it points at; null when it has none. */
64
+ export function parentOf(table) {
65
+ if (!table)
66
+ return null;
67
+ for (const [field, def] of Object.entries(table.fields)) {
68
+ const ref = def.ref;
69
+ if (ref?.kind === 'parent')
70
+ return { field, table: ref.table };
71
+ }
72
+ return null;
73
+ }
74
+ /**
75
+ * Whether `fieldName` is the table's parent. Its value is the row's owner: filled by the platform or
76
+ * given once on insert, never written after, and stored as the row's parent edge in `RecordRef`, not
77
+ * in its data.
78
+ */
79
+ export function isParentField(table, fieldName) {
80
+ return parentOf(table)?.field === fieldName;
81
+ }
82
+ /**
83
+ * Why `schema/session.ts` is not a session schema (11-remove-sequence-schema §3.1): its fields are
84
+ * simple values, with no `ref` (the session is related to no other table).
85
+ */
86
+ export function sessionSchemaIssues(session) {
87
+ const issues = [];
88
+ const fields = session.fields;
89
+ if (fields && typeof fields === 'object') {
90
+ for (const [fieldName, field] of Object.entries(fields)) {
91
+ const path = formatFieldPath(SESSION_TABLE, fieldName);
92
+ if (fieldName === ROW_ID_FIELD) {
93
+ issues.push({ code: 'invalid-session-field', message: `schema/session.ts: ${path}: the name is reserved`, path });
94
+ continue;
95
+ }
96
+ if (!field || typeof field !== 'object')
97
+ continue;
98
+ if (Object.hasOwn(field, REMOVED_SOURCE_KEY))
99
+ issues.push(sourceRemovedIssue(path, 'schema/session.ts: '));
100
+ if (Object.hasOwn(field, REMOVED_NULLABLE_KEY))
101
+ issues.push(nullableRemovedIssue(path, 'schema/session.ts: '));
102
+ if (Object.hasOwn(field, REMOVED_IDENTIFIER_KEY))
103
+ issues.push(identifierRemovedIssue(path, 'schema/session.ts: '));
104
+ issues.push(...optionIssues(path, field, 'schema/session.ts: '));
105
+ if ('unique' in field) {
106
+ issues.push({ code: 'invalid-session-field', message: `schema/session.ts: ${path}: a session field cannot be unique (there is one session row per conversation)`, path });
107
+ }
108
+ if ('ref' in field) {
109
+ issues.push({
110
+ code: 'invalid-session-field',
111
+ message: `schema/session.ts: ${path}: a session field has no ref (the session is related to no other table)`,
112
+ path,
113
+ });
114
+ }
115
+ if (field.dataType === 'contact_schedule') {
116
+ issues.push({
117
+ code: 'invalid-session-field',
118
+ message: `schema/session.ts: ${path}: a session field is a simple value (${SCALAR_DATA_TYPES.join(', ')})`,
119
+ path,
120
+ });
121
+ }
122
+ }
123
+ }
124
+ if (issues.length > 0)
125
+ return issues;
126
+ for (const issue of sessionSchemaSchema.safeParse(session).error?.issues ?? []) {
127
+ const [, fieldName, ...rest] = issue.path.map(String);
128
+ const path = fieldName ? formatFieldPath(SESSION_TABLE, fieldName) : SESSION_TABLE;
129
+ issues.push({
130
+ code: 'invalid-session-field',
131
+ message: `schema/session.ts: ${[path, ...rest].join('.')}: ${issue.message}`,
132
+ path,
133
+ });
134
+ }
135
+ return issues;
136
+ }
137
+ /**
138
+ * A ref's `relatedName` (13-data-model-v1 §23.4 items 3 and 6): a name like any other, and one the
139
+ * target table does not already use: not one of its fields, not another ref's `relatedName` to it.
140
+ * The way back is a key of the target row, beside its fields.
141
+ */
142
+ function relatedNameIssues(company) {
143
+ const issues = [];
144
+ const taken = new Map();
145
+ for (const [tableName, table] of Object.entries(company)) {
146
+ if (tableName === SESSION_TABLE || isReservedTableName(tableName))
147
+ continue;
148
+ for (const [fieldName, field] of Object.entries(table.fields ?? {})) {
149
+ const name = field?.ref?.relatedName;
150
+ if (name === undefined)
151
+ continue;
152
+ const path = formatFieldPath(tableName, fieldName);
153
+ const target = field.ref.table;
154
+ const problem = typeof name === 'string' ? nameProblem(name) : { code: 'invalid-name', reason: 'must be a string' };
155
+ if (problem) {
156
+ issues.push({ code: problem.code, message: `${path}: relatedName ${JSON.stringify(name)} is not a relation name: ${problem.reason}`, path });
157
+ continue;
158
+ }
159
+ const targetTable = Object.hasOwn(company, target) ? company[target] : undefined;
160
+ // The row id is the platform's, on every table: a field of it all the same.
161
+ if (targetTable && (name === ROW_ID_FIELD || Object.hasOwn(targetTable.fields ?? {}, name))) {
162
+ issues.push({ code: 'related-name-conflict', message: `${path}: relatedName ${name} is already a field of ${target}`, path });
163
+ continue;
164
+ }
165
+ const names = taken.get(target) ?? new Map();
166
+ const other = names.get(name);
167
+ if (other) {
168
+ issues.push({ code: 'related-name-conflict', message: `${path}: relatedName ${name} is already ${other}'s way back to ${target}`, path });
169
+ continue;
170
+ }
171
+ names.set(name, path);
172
+ taken.set(target, names);
173
+ }
174
+ }
175
+ return issues;
176
+ }
177
+ /**
178
+ * Names the schema may not use (13-data-model-v1 §23.4 item 6): every table name, field name and
179
+ * session field name is checked once here, for the whole company, not per sequence.
180
+ */
181
+ function schemaNameIssues(company, session) {
182
+ const issues = [];
183
+ const check = (name, path, what) => {
184
+ const problem = nameProblem(name);
185
+ if (problem)
186
+ issues.push({ code: problem.code, message: `${path}: not a ${what} name: ${problem.reason}`, path });
187
+ };
188
+ for (const [tableName, table] of Object.entries(company)) {
189
+ if (tableName === SESSION_TABLE || isReservedTableName(tableName))
190
+ continue;
191
+ check(tableName, tableName, 'table');
192
+ for (const [fieldName, field] of Object.entries(table.fields ?? {})) {
193
+ const path = formatFieldPath(tableName, fieldName);
194
+ check(fieldName, path, 'field');
195
+ // A ref is the related row, its `.value` the id: named for the row (`injury`), not `injury_id` (§23.4 item 1).
196
+ if (field?.ref && fieldName.endsWith('_id')) {
197
+ const noun = fieldName.slice(0, -'_id'.length);
198
+ issues.push({
199
+ code: 'ref-name-id-suffix',
200
+ message: `${path}: a ref is named for the row it points at, without _id (e.g. ${noun}: ${field.ref.kind}Ref('${field.ref.table}'))`,
201
+ path,
202
+ });
203
+ }
204
+ }
205
+ }
206
+ issues.push(...relatedNameIssues(company));
207
+ const sessionFields = session.fields;
208
+ if (sessionFields && typeof sessionFields === 'object') {
209
+ for (const fieldName of Object.keys(sessionFields)) {
210
+ if (fieldName === ROW_ID_FIELD)
211
+ continue; // `invalid-session-field` reports it
212
+ check(fieldName, formatFieldPath(SESSION_TABLE, fieldName), 'session field');
213
+ }
214
+ }
215
+ return issues;
216
+ }
217
+ /**
218
+ * Whether the company schema is one: its tables (`schema/index.ts`) and its session fields
219
+ * (`schema/session.ts`, the platform's only when the file is missing). `session` is reserved: no
220
+ * company table has the name. What a build stores is `compileSlotSchema`'s output.
221
+ */
222
+ export function validateCompanySchema(company, session = PLATFORM_SESSION_SCHEMA) {
223
+ const issues = [];
224
+ if (Object.hasOwn(company, SESSION_TABLE)) {
225
+ issues.push({
226
+ code: 'reserved-table-name',
227
+ message: "Table name is reserved: session is the conversation's; define its fields in schema/session.ts",
228
+ path: SESSION_TABLE,
229
+ });
230
+ }
231
+ for (const tableName of Object.keys(company)) {
232
+ if (!isReservedTableName(tableName))
233
+ continue;
234
+ issues.push({ code: 'reserved-table-name', message: `Table name is reserved: ${tableName}`, path: tableName });
235
+ }
236
+ issues.push(...sessionSchemaIssues(session));
237
+ issues.push(...schemaNameIssues(company, session));
238
+ if (!Object.hasOwn(company, CONTACT_TABLE)) {
239
+ issues.push({
240
+ code: 'missing-contact-table',
241
+ message: 'the company schema must define the contact table (spread PLATFORM_CONTACT_FIELDS into it)',
242
+ path: CONTACT_TABLE,
243
+ });
244
+ return { ok: false, issues };
245
+ }
246
+ validatePlatformFields(company, CONTACT_TABLE, issues);
247
+ validatePlatformSessionFields(session, issues);
248
+ validateRelationships(company, issues);
249
+ issues.push(...fieldRuleIssues(company));
250
+ return issues.length === 0 ? { ok: true } : { ok: false, issues };
251
+ }
252
+ /**
253
+ * Relationship rules (14-sequence-instance §16.1): a table has at most one parent, a required system
254
+ * ref to another company table (not session, not itself); the parents form no cycle and no chain
255
+ * longer than {@link LIMITS.parentDepth}; `contact` has no parent (it belongs to no one thing). A
256
+ * ref no longer takes `unique` (13-data-model-v1 §22.4): a schema written before says so instead of
257
+ * silently getting a list.
258
+ */
259
+ function validateRelationships(company, issues) {
260
+ const parentTargets = new Map();
261
+ for (const [tableName, table] of Object.entries(company)) {
262
+ if (tableName === SESSION_TABLE || isReservedTableName(tableName))
263
+ continue;
264
+ const parents = [];
265
+ for (const [fieldName, field] of Object.entries(table.fields)) {
266
+ if (!field.ref)
267
+ continue;
268
+ const path = formatFieldPath(tableName, fieldName);
269
+ const { ref } = field;
270
+ if ('unique' in ref) {
271
+ issues.push({
272
+ code: 'unique-removed',
273
+ message: `${path}: refs no longer take unique; a parent row has any number of rows under it (fields of one per parent belong on the parent table)`,
274
+ path,
275
+ });
276
+ }
277
+ if (ref.kind !== 'parent')
278
+ continue;
279
+ parents.push(fieldName);
280
+ if (tableName === CONTACT_TABLE) {
281
+ issues.push({
282
+ code: 'contact-parent-forbidden',
283
+ message: `${path}: a contact belongs to no one row, so it has no parent; use lookupRef('${ref.table}') instead`,
284
+ path,
285
+ });
286
+ continue;
287
+ }
288
+ if (ref.table === SESSION_TABLE || ref.table === tableName) {
289
+ issues.push({
290
+ code: 'parent-target-invalid',
291
+ message: `${path}: a parent must point at another company table, got ${ref.table}`,
292
+ path,
293
+ });
294
+ }
295
+ else {
296
+ parentTargets.set(tableName, ref.table);
297
+ }
298
+ }
299
+ if (parents.length > 1) {
300
+ issues.push({
301
+ code: 'multiple-parents',
302
+ message: `${tableName} has more than one parent (${parents.join(', ')}); keep one and make the others lookups (lookupRef)`,
303
+ path: tableName,
304
+ });
305
+ }
306
+ }
307
+ for (const tableName of parentTargets.keys()) {
308
+ const seen = [tableName];
309
+ let next = parentTargets.get(tableName);
310
+ while (next !== undefined) {
311
+ if (seen.includes(next)) {
312
+ issues.push({
313
+ code: 'parent-cycle',
314
+ message: `${tableName}: its parents form a cycle (${[...seen, next].join(' → ')})`,
315
+ path: tableName,
316
+ });
317
+ break;
318
+ }
319
+ seen.push(next);
320
+ next = parentTargets.get(next);
321
+ }
322
+ if (next === undefined && seen.length - 1 > LIMITS.parentDepth) {
323
+ issues.push({
324
+ code: 'parent-chain-too-long',
325
+ message: `${tableName}: its parent chain has ${seen.length - 1} levels (${seen.join(' → ')}); at most ${LIMITS.parentDepth}`,
326
+ path: tableName,
327
+ });
328
+ }
329
+ }
330
+ }
331
+ /** The issue for a field that still names its `source` (19-page-writable-cells). */
332
+ export function sourceRemovedIssue(path, prefix = '') {
333
+ return {
334
+ code: 'source-removed',
335
+ message: `${prefix}${path}: remove source; a page decides what the AI may write (field(...) opens a cell, anything else on the page is read-only)`,
336
+ path,
337
+ };
338
+ }
339
+ /** The issue for a field that still names `nullable`, which no write checked. */
340
+ export function nullableRemovedIssue(path, prefix = '') {
341
+ return {
342
+ code: 'nullable-removed',
343
+ message: `${prefix}${path}: remove nullable; every field starts empty and can be cleared (a page's required says when one must be filled)`,
344
+ path,
345
+ };
346
+ }
347
+ /** The issue for a field that still names `identifier`, which nothing used. */
348
+ export function identifierRemovedIssue(path, prefix = '') {
349
+ return {
350
+ code: 'identifier-removed',
351
+ message: `${prefix}${path}: remove identifier; resolve.ts decides who a conversation is with (ctx.api.contact.find looks up phone and email)`,
352
+ path,
353
+ };
354
+ }
355
+ /**
356
+ * A field's choices (27 §2–§3): no `enum` (now a `select`); `options` on a `select` / `multi_select`
357
+ * only, and there required: 1 to `LIMITS.options` distinct short codes.
358
+ */
359
+ export function optionIssues(path, field, prefix = '') {
360
+ const issues = [];
361
+ if (Object.hasOwn(field, REMOVED_ENUM_KEY)) {
362
+ issues.push({
363
+ code: 'enum-removed',
364
+ message: `${prefix}${path}: enum is removed; a field of a known set of values is dataType 'select' (one of them) or 'multi_select' (any of them) with options: [...]`,
365
+ path,
366
+ });
367
+ }
368
+ const options = field.options;
369
+ const takes = OPTION_DATA_TYPES.has(field.dataType);
370
+ if (!takes) {
371
+ if (options !== undefined) {
372
+ issues.push({ code: 'options-on-wrong-type', message: `${prefix}${path}: options are on a select or multi_select field only (this one is ${String(field.dataType)})`, path });
373
+ }
374
+ return issues;
375
+ }
376
+ if (!Array.isArray(options) || options.length === 0) {
377
+ issues.push({ code: 'missing-options', message: `${prefix}${path}: a ${String(field.dataType)} field needs options: [...] (at least one)`, path });
378
+ return issues;
379
+ }
380
+ if (options.length > LIMITS.options) {
381
+ issues.push({ code: 'too-many-options', message: `${prefix}${path}: ${options.length} options; at most ${LIMITS.options} (make it a table and a lookupRef instead)`, path });
382
+ }
383
+ const bad = options.filter((v) => typeof v !== 'string' || v.length === 0);
384
+ if (bad.length) {
385
+ issues.push({ code: 'invalid-option', message: `${prefix}${path}: options are non-empty strings (${bad.map((v) => JSON.stringify(v)).join(', ')})`, path });
386
+ }
387
+ const long = options.filter((v) => typeof v === 'string' && v.length > LIMITS.optionChars);
388
+ if (long.length) {
389
+ issues.push({
390
+ code: 'option-too-long',
391
+ message: `${prefix}${path}: options are short codes, at most ${LIMITS.optionChars} characters (${long.map((v) => JSON.stringify(v.slice(0, 30) + '…')).join(', ')}); say what each means in extraction`,
392
+ path,
393
+ });
394
+ }
395
+ const seen = new Set();
396
+ const repeated = options.filter((v) => (seen.has(v) ? true : (seen.add(v), false)));
397
+ if (repeated.length) {
398
+ issues.push({ code: 'duplicate-option', message: `${prefix}${path}: options repeat ${[...new Set(repeated)].map((v) => JSON.stringify(v)).join(', ')}`, path });
399
+ }
400
+ return issues;
401
+ }
402
+ /** The issue for a table that writes the row id, which is the platform's. */
403
+ export function idIsPlatformIssue(path) {
404
+ return {
405
+ code: 'id-is-platform',
406
+ message: `${path}: remove id; every table has it (with createdAt and updatedAt), the platform's`,
407
+ path,
408
+ };
409
+ }
410
+ /** Types a `unique` field may have: values compared as one stored scalar (18-record-search-index §4.5). */
411
+ const UNIQUE_DATA_TYPES = new Set(['string', 'phone', 'email', 'number']);
412
+ /**
413
+ * Field and size rules (18-record-search-index §4.2, §4.5, §4.7): no `id` (the platform's), no
414
+ * `source`, `nullable`, `identifier` or `enum`; the table and field limits, a field's options; `unique` only on a plain
415
+ * value of a type compared as stored.
416
+ */
417
+ function fieldRuleIssues(company) {
418
+ const issues = [];
419
+ const tables = Object.entries(company).filter(([tableName]) => tableName !== SESSION_TABLE && !isReservedTableName(tableName));
420
+ if (tables.length > LIMITS.tables) {
421
+ issues.push({ code: 'too-many-tables', message: `the company schema has ${tables.length} tables; at most ${LIMITS.tables}`, path: '' });
422
+ }
423
+ for (const [tableName, table] of tables) {
424
+ const fields = Object.entries(table.fields ?? {});
425
+ // The platform's row id counts too.
426
+ const count = fields.filter(([name]) => name !== ROW_ID_FIELD).length + 1;
427
+ if (count > LIMITS.fieldsPerTable) {
428
+ issues.push({ code: 'too-many-fields', message: `${tableName} has ${count} fields with its id; at most ${LIMITS.fieldsPerTable}`, path: tableName });
429
+ }
430
+ for (const [fieldName, field] of fields) {
431
+ if (!field || typeof field !== 'object')
432
+ continue;
433
+ const path = formatFieldPath(tableName, fieldName);
434
+ if (fieldName === ROW_ID_FIELD) {
435
+ issues.push(idIsPlatformIssue(path));
436
+ continue;
437
+ }
438
+ if (Object.hasOwn(field, REMOVED_SOURCE_KEY))
439
+ issues.push(sourceRemovedIssue(path));
440
+ if (Object.hasOwn(field, REMOVED_NULLABLE_KEY))
441
+ issues.push(nullableRemovedIssue(path));
442
+ if (Object.hasOwn(field, REMOVED_IDENTIFIER_KEY))
443
+ issues.push(identifierRemovedIssue(path));
444
+ issues.push(...optionIssues(path, field));
445
+ if (field.unique !== undefined) {
446
+ if (field.unique !== true || !UNIQUE_DATA_TYPES.has(field.dataType) || field.ref) {
447
+ issues.push({
448
+ code: 'invalid-unique',
449
+ message: `${path}: unique is true or absent, on a string, phone, email or number field that is not a ref`,
450
+ path,
451
+ });
452
+ }
453
+ }
454
+ }
455
+ }
456
+ return issues;
457
+ }
458
+ /** Every platform field of `tableName` is in the company schema, defined as the runtime defines it. */
459
+ function validatePlatformFields(company, tableName, issues) {
460
+ const platform = PLATFORM_TABLE_FIELDS[tableName];
461
+ for (const [name, required] of Object.entries(platform.fields)) {
462
+ const path = `${tableName}.${name}`;
463
+ const actual = company[tableName]?.fields[name];
464
+ if (!actual) {
465
+ issues.push({ code: `missing-platform-${platform.name}-field`, message: `${path} is required`, path });
466
+ continue;
467
+ }
468
+ const differing = differingProperties(actual, required);
469
+ if (differing.length > 0) {
470
+ issues.push({
471
+ code: `invalid-platform-${platform.name}-field`,
472
+ message: `${path} must match the runtime field definition; it differs in: ${differing.join(', ')}`,
473
+ path,
474
+ });
475
+ }
476
+ }
477
+ }
478
+ /** Every platform session field is in `schema/session.ts`, defined as the runtime defines it (24 §5.2). */
479
+ function validatePlatformSessionFields(session, issues) {
480
+ for (const [name, required] of Object.entries(PLATFORM_SESSION_FIELDS)) {
481
+ const path = `${SESSION_TABLE}.${name}`;
482
+ const actual = session.fields?.[name];
483
+ if (!actual) {
484
+ issues.push({ code: 'missing-platform-session-field', message: `${path} is required: spread PLATFORM_SESSION_FIELDS into schema/session.ts`, path });
485
+ continue;
486
+ }
487
+ const differing = differingProperties(actual, required);
488
+ if (differing.length > 0) {
489
+ issues.push({ code: 'invalid-platform-session-field', message: `${path} must match the runtime field definition; it differs in: ${differing.join(', ')}`, path });
490
+ }
491
+ }
492
+ }
493
+ /** The company table a sequence names as its business root, checked (14 §4.5). */
494
+ export function subjectTableIssues(company, subject) {
495
+ if (typeof subject !== 'string' || subject.length === 0) {
496
+ return [
497
+ {
498
+ code: 'missing-subject',
499
+ message: "the sequence must declare its business root: export default defineSequence({ subject: '<table>' }) in index.ts",
500
+ path: 'subject',
501
+ },
502
+ ];
503
+ }
504
+ if (subject === SESSION_TABLE || isReservedTableName(subject) || !Object.hasOwn(company, subject)) {
505
+ return [{ code: 'unknown-subject', message: `subject is not a company table: ${subject}`, path: 'subject' }];
506
+ }
507
+ return [];
508
+ }
509
+ /**
510
+ * The properties where an authored required field departs from its runtime definition, by value:
511
+ * key order never matters, and an `undefined` property or `deprecated: false` reads as absent
512
+ * (both mean the default). `deprecated: true` is a difference: a required field cannot be retired.
513
+ */
514
+ function differingProperties(actual, required) {
515
+ const authored = presentProperties(actual);
516
+ const canonical = presentProperties(required);
517
+ const keys = [...new Set([...Object.keys(authored), ...Object.keys(canonical)])].sort();
518
+ return keys.filter((key) => !sameValue(authored[key], canonical[key]));
519
+ }
520
+ function presentProperties(field) {
521
+ return Object.fromEntries(Object.entries(field).filter(([key, value]) => value !== undefined && !(key === 'deprecated' && value === false)));
522
+ }
523
+ /** Deep equality of plain JSON values, ignoring object key order and `undefined` properties. */
524
+ function sameValue(a, b) {
525
+ if (a === b)
526
+ return true;
527
+ if (Array.isArray(a) || Array.isArray(b)) {
528
+ return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, i) => sameValue(item, b[i]));
529
+ }
530
+ if (!a || !b || typeof a !== 'object' || typeof b !== 'object')
531
+ return false;
532
+ const left = Object.entries(a).filter(([, value]) => value !== undefined);
533
+ const right = new Map(Object.entries(b).filter(([, value]) => value !== undefined));
534
+ return left.length === right.size && left.every(([key, value]) => right.has(key) && sameValue(value, right.get(key)));
535
+ }
536
+ //# sourceMappingURL=company-metadata.js.map
@@ -1,24 +1,30 @@
1
- import type { CompanySchema, EffectiveSchema, SequenceSlots } from './schema.js';
2
- import type { FuncMap } from '../functions/types.js';
3
- import type { CompiledSlotSchema, RuntimeTableDef, ValidationResult } from './types.js';
4
- import { type FieldPath } from './path.js';
1
+ import type { CompanyFieldDef, CompanySchema, SessionSchema } from './schema.js';
2
+ import type { CompiledSlotSchema, RuntimeFieldDef, RuntimeTableDef, ValidationResult } from './types.js';
3
+ export declare function companyFieldToRuntime(field: CompanyFieldDef): RuntimeFieldDef;
5
4
  /**
6
- * Inherit every company table, then apply sequence overlays + session.
5
+ * The company schema as the platform reads it (28 §2): every company table and field, and the
6
+ * company's session fields (`schema/session.ts`). One for the whole company: every sequence, page and
7
+ * function reads it; a sequence only names its `subject` (checked by `subjectTableIssues`).
7
8
  */
8
- export declare function compileSlotSchema(company: CompanySchema, sequenceSlots: SequenceSlots, options?: {
9
- computeFns?: ReadonlySet<string>;
10
- functions?: FuncMap;
9
+ export declare function compileSlotSchema(company: CompanySchema, options?: {
10
+ /** The company's session fields (`schema/session.ts`); none when omitted. */
11
+ session?: SessionSchema;
11
12
  }): {
12
13
  schema: CompiledSlotSchema;
13
14
  validation: ValidationResult;
14
15
  };
15
16
  /** Validate field paths exist on a compiled schema. */
16
17
  export declare function validateFieldRefs(schema: CompiledSlotSchema, refs: Iterable<string>): ValidationResult;
18
+ /** A way back to a table (13-data-model-v1 §23.4 item 3): the rows of `table` whose ref `field` points at it. */
19
+ export type TableRelation = {
20
+ name: string;
21
+ table: string;
22
+ field: string;
23
+ };
24
+ /** The ways back to `tableName`: every ref of this schema that points at it and has a `relatedName`. */
25
+ export declare function relationsOf(schema: CompiledSlotSchema, tableName: string): TableRelation[];
26
+ /** A table's own field by name; undefined for any other key, a name every object has (`toString`) included. */
27
+ export declare function getTableField(table: Pick<RuntimeTableDef, 'fields'>, fieldName: string): RuntimeFieldDef | undefined;
17
28
  export declare function getCompiledTable(schema: CompiledSlotSchema, tableName: string): RuntimeTableDef | undefined;
18
29
  export declare function compiledTableEntries(schema: CompiledSlotSchema): Array<[string, RuntimeTableDef]>;
19
- /** Snapshot / SF presentation: single → field dict, multi → row array. */
20
- export declare function isSnapshotSingleRow(table: RuntimeTableDef): boolean;
21
- /** Effective schema for Slots codegen (multi → array, single → dict). */
22
- export declare function toEffectiveSchema(compiled: CompiledSlotSchema): EffectiveSchema;
23
- export declare function listConversationFields(schema: CompiledSlotSchema): FieldPath[];
24
30
  //# sourceMappingURL=compile-schema.d.ts.map