@yolk-sdk/emulators 0.1.0-canary.96

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 (333) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2135 -0
  3. package/dist/anthropic.d.mts +269 -0
  4. package/dist/anthropic.d.mts.map +1 -0
  5. package/dist/anthropic.mjs +177 -0
  6. package/dist/anthropic.mjs.map +1 -0
  7. package/dist/chat-completions.d.mts +288 -0
  8. package/dist/chat-completions.d.mts.map +1 -0
  9. package/dist/chat-completions.mjs +451 -0
  10. package/dist/chat-completions.mjs.map +1 -0
  11. package/dist/codex.d.mts +265 -0
  12. package/dist/codex.d.mts.map +1 -0
  13. package/dist/codex.mjs +199 -0
  14. package/dist/codex.mjs.map +1 -0
  15. package/dist/dropbox/api.d.mts +63 -0
  16. package/dist/dropbox/api.d.mts.map +1 -0
  17. package/dist/dropbox/api.mjs +565 -0
  18. package/dist/dropbox/api.mjs.map +1 -0
  19. package/dist/dropbox/state.d.mts +136 -0
  20. package/dist/dropbox/state.d.mts.map +1 -0
  21. package/dist/dropbox/state.mjs +209 -0
  22. package/dist/dropbox/state.mjs.map +1 -0
  23. package/dist/dropbox.d.mts +79 -0
  24. package/dist/dropbox.d.mts.map +1 -0
  25. package/dist/dropbox.mjs +124 -0
  26. package/dist/dropbox.mjs.map +1 -0
  27. package/dist/email-fixtures.d.mts +36 -0
  28. package/dist/email-fixtures.d.mts.map +1 -0
  29. package/dist/email-fixtures.mjs +1080 -0
  30. package/dist/email-fixtures.mjs.map +1 -0
  31. package/dist/email.d.mts +160 -0
  32. package/dist/email.d.mts.map +1 -0
  33. package/dist/email.mjs +608 -0
  34. package/dist/email.mjs.map +1 -0
  35. package/dist/emulator-compose.d.mts +40 -0
  36. package/dist/emulator-compose.d.mts.map +1 -0
  37. package/dist/emulator-compose.mjs +91 -0
  38. package/dist/emulator-compose.mjs.map +1 -0
  39. package/dist/emulator-http.d.mts +53 -0
  40. package/dist/emulator-http.d.mts.map +1 -0
  41. package/dist/emulator-http.mjs +117 -0
  42. package/dist/emulator-http.mjs.map +1 -0
  43. package/dist/emulator-kernel.d.mts +176 -0
  44. package/dist/emulator-kernel.d.mts.map +1 -0
  45. package/dist/emulator-kernel.mjs +413 -0
  46. package/dist/emulator-kernel.mjs.map +1 -0
  47. package/dist/fixture-route.d.mts +129 -0
  48. package/dist/fixture-route.d.mts.map +1 -0
  49. package/dist/fixture-route.mjs +257 -0
  50. package/dist/fixture-route.mjs.map +1 -0
  51. package/dist/fortnox/api.d.mts +92 -0
  52. package/dist/fortnox/api.d.mts.map +1 -0
  53. package/dist/fortnox/api.mjs +750 -0
  54. package/dist/fortnox/api.mjs.map +1 -0
  55. package/dist/fortnox/state.d.mts +533 -0
  56. package/dist/fortnox/state.d.mts.map +1 -0
  57. package/dist/fortnox/state.mjs +612 -0
  58. package/dist/fortnox/state.mjs.map +1 -0
  59. package/dist/fortnox.d.mts +128 -0
  60. package/dist/fortnox.d.mts.map +1 -0
  61. package/dist/fortnox.mjs +403 -0
  62. package/dist/fortnox.mjs.map +1 -0
  63. package/dist/gateway-evaluate-recordings.d.mts +12 -0
  64. package/dist/gateway-evaluate-recordings.d.mts.map +1 -0
  65. package/dist/gateway-evaluate-recordings.mjs +128 -0
  66. package/dist/gateway-evaluate-recordings.mjs.map +1 -0
  67. package/dist/gateway.d.mts +272 -0
  68. package/dist/gateway.d.mts.map +1 -0
  69. package/dist/gateway.mjs +400 -0
  70. package/dist/gateway.mjs.map +1 -0
  71. package/dist/github/api.d.mts +63 -0
  72. package/dist/github/api.d.mts.map +1 -0
  73. package/dist/github/api.mjs +527 -0
  74. package/dist/github/api.mjs.map +1 -0
  75. package/dist/github/state.d.mts +272 -0
  76. package/dist/github/state.d.mts.map +1 -0
  77. package/dist/github/state.mjs +303 -0
  78. package/dist/github/state.mjs.map +1 -0
  79. package/dist/github.d.mts +77 -0
  80. package/dist/github.d.mts.map +1 -0
  81. package/dist/github.mjs +180 -0
  82. package/dist/github.mjs.map +1 -0
  83. package/dist/google/calendar.d.mts +10 -0
  84. package/dist/google/calendar.d.mts.map +1 -0
  85. package/dist/google/calendar.mjs +252 -0
  86. package/dist/google/calendar.mjs.map +1 -0
  87. package/dist/google/drive.d.mts +8 -0
  88. package/dist/google/drive.d.mts.map +1 -0
  89. package/dist/google/drive.mjs +252 -0
  90. package/dist/google/drive.mjs.map +1 -0
  91. package/dist/google/gmail.d.mts +10 -0
  92. package/dist/google/gmail.d.mts.map +1 -0
  93. package/dist/google/gmail.mjs +591 -0
  94. package/dist/google/gmail.mjs.map +1 -0
  95. package/dist/google/shared.d.mts +107 -0
  96. package/dist/google/shared.d.mts.map +1 -0
  97. package/dist/google/shared.mjs +146 -0
  98. package/dist/google/shared.mjs.map +1 -0
  99. package/dist/google/state.d.mts +385 -0
  100. package/dist/google/state.d.mts.map +1 -0
  101. package/dist/google/state.mjs +496 -0
  102. package/dist/google/state.mjs.map +1 -0
  103. package/dist/google.d.mts +75 -0
  104. package/dist/google.d.mts.map +1 -0
  105. package/dist/google.mjs +210 -0
  106. package/dist/google.mjs.map +1 -0
  107. package/dist/linkedin-search/api.d.mts +45 -0
  108. package/dist/linkedin-search/api.d.mts.map +1 -0
  109. package/dist/linkedin-search/api.mjs +181 -0
  110. package/dist/linkedin-search/api.mjs.map +1 -0
  111. package/dist/linkedin-search/state.d.mts +123 -0
  112. package/dist/linkedin-search/state.d.mts.map +1 -0
  113. package/dist/linkedin-search/state.mjs +261 -0
  114. package/dist/linkedin-search/state.mjs.map +1 -0
  115. package/dist/linkedin-search.d.mts +69 -0
  116. package/dist/linkedin-search.d.mts.map +1 -0
  117. package/dist/linkedin-search.mjs +158 -0
  118. package/dist/linkedin-search.mjs.map +1 -0
  119. package/dist/mcp/api.d.mts +44 -0
  120. package/dist/mcp/api.d.mts.map +1 -0
  121. package/dist/mcp/api.mjs +557 -0
  122. package/dist/mcp/api.mjs.map +1 -0
  123. package/dist/mcp/recordings.d.mts +40 -0
  124. package/dist/mcp/recordings.d.mts.map +1 -0
  125. package/dist/mcp/recordings.mjs +2390 -0
  126. package/dist/mcp/recordings.mjs.map +1 -0
  127. package/dist/mcp/state.d.mts +71 -0
  128. package/dist/mcp/state.d.mts.map +1 -0
  129. package/dist/mcp/state.mjs +83 -0
  130. package/dist/mcp/state.mjs.map +1 -0
  131. package/dist/mcp.d.mts +84 -0
  132. package/dist/mcp.d.mts.map +1 -0
  133. package/dist/mcp.mjs +241 -0
  134. package/dist/mcp.mjs.map +1 -0
  135. package/dist/messages.d.mts +183 -0
  136. package/dist/messages.d.mts.map +1 -0
  137. package/dist/messages.mjs +532 -0
  138. package/dist/messages.mjs.map +1 -0
  139. package/dist/microsoft/api.d.mts +47 -0
  140. package/dist/microsoft/api.d.mts.map +1 -0
  141. package/dist/microsoft/api.mjs +178 -0
  142. package/dist/microsoft/api.mjs.map +1 -0
  143. package/dist/microsoft/calendar.d.mts +30 -0
  144. package/dist/microsoft/calendar.d.mts.map +1 -0
  145. package/dist/microsoft/calendar.mjs +271 -0
  146. package/dist/microsoft/calendar.mjs.map +1 -0
  147. package/dist/microsoft/drive.d.mts +36 -0
  148. package/dist/microsoft/drive.d.mts.map +1 -0
  149. package/dist/microsoft/drive.mjs +298 -0
  150. package/dist/microsoft/drive.mjs.map +1 -0
  151. package/dist/microsoft/graph.d.mts +198 -0
  152. package/dist/microsoft/graph.d.mts.map +1 -0
  153. package/dist/microsoft/graph.mjs +264 -0
  154. package/dist/microsoft/graph.mjs.map +1 -0
  155. package/dist/microsoft/mail.d.mts +48 -0
  156. package/dist/microsoft/mail.d.mts.map +1 -0
  157. package/dist/microsoft/mail.mjs +488 -0
  158. package/dist/microsoft/mail.mjs.map +1 -0
  159. package/dist/microsoft/state.d.mts +480 -0
  160. package/dist/microsoft/state.d.mts.map +1 -0
  161. package/dist/microsoft/state.mjs +625 -0
  162. package/dist/microsoft/state.mjs.map +1 -0
  163. package/dist/microsoft.d.mts +168 -0
  164. package/dist/microsoft.d.mts.map +1 -0
  165. package/dist/microsoft.mjs +483 -0
  166. package/dist/microsoft.mjs.map +1 -0
  167. package/dist/node.d.mts +47 -0
  168. package/dist/node.d.mts.map +1 -0
  169. package/dist/node.mjs +178 -0
  170. package/dist/node.mjs.map +1 -0
  171. package/dist/notion/api.d.mts +51 -0
  172. package/dist/notion/api.d.mts.map +1 -0
  173. package/dist/notion/api.mjs +507 -0
  174. package/dist/notion/api.mjs.map +1 -0
  175. package/dist/notion/state.d.mts +329 -0
  176. package/dist/notion/state.d.mts.map +1 -0
  177. package/dist/notion/state.mjs +432 -0
  178. package/dist/notion/state.mjs.map +1 -0
  179. package/dist/notion.d.mts +72 -0
  180. package/dist/notion.d.mts.map +1 -0
  181. package/dist/notion.mjs +127 -0
  182. package/dist/notion.mjs.map +1 -0
  183. package/dist/openai.d.mts +165 -0
  184. package/dist/openai.d.mts.map +1 -0
  185. package/dist/openai.mjs +141 -0
  186. package/dist/openai.mjs.map +1 -0
  187. package/dist/opencode-recordings.d.mts +7 -0
  188. package/dist/opencode-recordings.d.mts.map +1 -0
  189. package/dist/opencode-recordings.mjs +222 -0
  190. package/dist/opencode-recordings.mjs.map +1 -0
  191. package/dist/opencode.d.mts +70 -0
  192. package/dist/opencode.d.mts.map +1 -0
  193. package/dist/opencode.mjs +217 -0
  194. package/dist/opencode.mjs.map +1 -0
  195. package/dist/r2-fixtures.d.mts +36 -0
  196. package/dist/r2-fixtures.d.mts.map +1 -0
  197. package/dist/r2-fixtures.mjs +245 -0
  198. package/dist/r2-fixtures.mjs.map +1 -0
  199. package/dist/r2-guard.d.mts +43 -0
  200. package/dist/r2-guard.d.mts.map +1 -0
  201. package/dist/r2-guard.mjs +215 -0
  202. package/dist/r2-guard.mjs.map +1 -0
  203. package/dist/r2.d.mts +166 -0
  204. package/dist/r2.d.mts.map +1 -0
  205. package/dist/r2.mjs +517 -0
  206. package/dist/r2.mjs.map +1 -0
  207. package/dist/responses.d.mts +231 -0
  208. package/dist/responses.d.mts.map +1 -0
  209. package/dist/responses.mjs +556 -0
  210. package/dist/responses.mjs.map +1 -0
  211. package/dist/route-evidence.d.mts +45 -0
  212. package/dist/route-evidence.d.mts.map +1 -0
  213. package/dist/route-evidence.mjs +56 -0
  214. package/dist/route-evidence.mjs.map +1 -0
  215. package/dist/router.d.mts +93 -0
  216. package/dist/router.d.mts.map +1 -0
  217. package/dist/router.mjs +259 -0
  218. package/dist/router.mjs.map +1 -0
  219. package/dist/stateful-core.d.mts +17 -0
  220. package/dist/stateful-core.d.mts.map +1 -0
  221. package/dist/stateful-core.mjs +41 -0
  222. package/dist/stateful-core.mjs.map +1 -0
  223. package/dist/stateful-emulator.d.mts +565 -0
  224. package/dist/stateful-emulator.d.mts.map +1 -0
  225. package/dist/stateful-emulator.mjs +1228 -0
  226. package/dist/stateful-emulator.mjs.map +1 -0
  227. package/dist/stateful-secrets.d.mts +84 -0
  228. package/dist/stateful-secrets.d.mts.map +1 -0
  229. package/dist/stateful-secrets.mjs +216 -0
  230. package/dist/stateful-secrets.mjs.map +1 -0
  231. package/dist/subscription-usage-recordings.d.mts +9 -0
  232. package/dist/subscription-usage-recordings.d.mts.map +1 -0
  233. package/dist/subscription-usage-recordings.mjs +53 -0
  234. package/dist/subscription-usage-recordings.mjs.map +1 -0
  235. package/dist/subscription-usage.d.mts +53 -0
  236. package/dist/subscription-usage.d.mts.map +1 -0
  237. package/dist/subscription-usage.mjs +21 -0
  238. package/dist/subscription-usage.mjs.map +1 -0
  239. package/dist/telegram/api.d.mts +34 -0
  240. package/dist/telegram/api.d.mts.map +1 -0
  241. package/dist/telegram/api.mjs +257 -0
  242. package/dist/telegram/api.mjs.map +1 -0
  243. package/dist/telegram/state.d.mts +128 -0
  244. package/dist/telegram/state.d.mts.map +1 -0
  245. package/dist/telegram/state.mjs +154 -0
  246. package/dist/telegram/state.mjs.map +1 -0
  247. package/dist/telegram.d.mts +62 -0
  248. package/dist/telegram.d.mts.map +1 -0
  249. package/dist/telegram.mjs +127 -0
  250. package/dist/telegram.mjs.map +1 -0
  251. package/dist/todoist/api.d.mts +55 -0
  252. package/dist/todoist/api.d.mts.map +1 -0
  253. package/dist/todoist/api.mjs +415 -0
  254. package/dist/todoist/api.mjs.map +1 -0
  255. package/dist/todoist/state.d.mts +275 -0
  256. package/dist/todoist/state.d.mts.map +1 -0
  257. package/dist/todoist/state.mjs +345 -0
  258. package/dist/todoist/state.mjs.map +1 -0
  259. package/dist/todoist.d.mts +68 -0
  260. package/dist/todoist.d.mts.map +1 -0
  261. package/dist/todoist.mjs +181 -0
  262. package/dist/todoist.mjs.map +1 -0
  263. package/dist/xai.d.mts +267 -0
  264. package/dist/xai.d.mts.map +1 -0
  265. package/dist/xai.mjs +252 -0
  266. package/dist/xai.mjs.map +1 -0
  267. package/package.json +157 -0
  268. package/src/anthropic.ts +289 -0
  269. package/src/chat-completions.ts +924 -0
  270. package/src/codex.ts +296 -0
  271. package/src/dropbox/api.ts +1084 -0
  272. package/src/dropbox/state.ts +364 -0
  273. package/src/dropbox.ts +203 -0
  274. package/src/email-fixtures.ts +1297 -0
  275. package/src/email.ts +1108 -0
  276. package/src/emulator-compose.ts +147 -0
  277. package/src/emulator-http.ts +184 -0
  278. package/src/emulator-kernel.ts +844 -0
  279. package/src/fixture-route.ts +561 -0
  280. package/src/fortnox/api.ts +1352 -0
  281. package/src/fortnox/state.ts +798 -0
  282. package/src/fortnox.ts +801 -0
  283. package/src/gateway-evaluate-recordings.ts +153 -0
  284. package/src/gateway.ts +530 -0
  285. package/src/github/api.ts +986 -0
  286. package/src/github/state.ts +439 -0
  287. package/src/github.ts +271 -0
  288. package/src/google/calendar.ts +486 -0
  289. package/src/google/drive.ts +471 -0
  290. package/src/google/gmail.ts +1011 -0
  291. package/src/google/shared.ts +321 -0
  292. package/src/google/state.ts +686 -0
  293. package/src/google.ts +298 -0
  294. package/src/linkedin-search/api.ts +363 -0
  295. package/src/linkedin-search/state.ts +373 -0
  296. package/src/linkedin-search.ts +241 -0
  297. package/src/mcp/api.ts +995 -0
  298. package/src/mcp/recordings.ts +2665 -0
  299. package/src/mcp/state.ts +125 -0
  300. package/src/mcp.ts +319 -0
  301. package/src/messages.ts +844 -0
  302. package/src/microsoft/api.ts +426 -0
  303. package/src/microsoft/calendar.ts +491 -0
  304. package/src/microsoft/drive.ts +541 -0
  305. package/src/microsoft/graph.ts +550 -0
  306. package/src/microsoft/mail.ts +833 -0
  307. package/src/microsoft/state.ts +822 -0
  308. package/src/microsoft.ts +982 -0
  309. package/src/node.ts +293 -0
  310. package/src/notion/api.ts +976 -0
  311. package/src/notion/state.ts +512 -0
  312. package/src/notion.ts +210 -0
  313. package/src/openai.ts +198 -0
  314. package/src/opencode-recordings.ts +257 -0
  315. package/src/opencode.ts +271 -0
  316. package/src/r2-fixtures.ts +295 -0
  317. package/src/r2-guard.ts +323 -0
  318. package/src/r2.ts +890 -0
  319. package/src/responses.ts +901 -0
  320. package/src/route-evidence.ts +90 -0
  321. package/src/router.ts +490 -0
  322. package/src/stateful-core.ts +70 -0
  323. package/src/stateful-emulator.ts +2571 -0
  324. package/src/stateful-secrets.ts +299 -0
  325. package/src/subscription-usage-recordings.ts +77 -0
  326. package/src/subscription-usage.ts +68 -0
  327. package/src/telegram/api.ts +437 -0
  328. package/src/telegram/state.ts +229 -0
  329. package/src/telegram.ts +227 -0
  330. package/src/todoist/api.ts +736 -0
  331. package/src/todoist/state.ts +456 -0
  332. package/src/todoist.ts +316 -0
  333. package/src/xai.ts +341 -0
@@ -0,0 +1,432 @@
1
+ import { Result } from "effect";
2
+ import * as Schema from "effect/Schema";
3
+ //#region src/notion/state.ts
4
+ /**
5
+ * Notion emulator state: the typed bot user, pages, blocks, paginated property items, databases,
6
+ * and data sources, the seed input, the default seed, and the profiles (internal; re-exported by
7
+ * `src/notion.ts`).
8
+ *
9
+ * Entity shapes and the default entities follow the synthetic Notion conformance fixtures (API
10
+ * version 2025-09-03), copied as data (the same ids, titles, properties, timestamps, and URLs as
11
+ * the fixtures and `notionConformanceFixtureSeeds`), never imported from SDK code. Pages a fixture
12
+ * only names by id (the blocks page, the write case's parent page, the database's parent page, and
13
+ * the second data source row the query fixture's `next_cursor` names) are `impliedPages`: their ids
14
+ * resolve where a fixture names them, but no content is invented for them, so any answer that
15
+ * would render one is not emulated.
16
+ *
17
+ * Minted page ids never repeat seeded ones: the page counter starts above the highest seeded id
18
+ * in the minted form (`1f0000e0-0000-4000-8000-NNNNNNNNNNNN`).
19
+ *
20
+ * Pages and other objects are stored with their wire fields (`properties`, `parent`, rich text)
21
+ * as JSON, answered as stored. A page's `properties` value is what the page object answers; the
22
+ * items the property endpoint pages through are stored separately (`propertyItems`), as the
23
+ * fixtures show them (the page object of the property page carries only the first segment).
24
+ *
25
+ * @experimental
26
+ */
27
+ /** A Notion id as stored and answered: a lower-case dashed UUID. */
28
+ const notionIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
29
+ const NotionId = Schema.String.check(Schema.isPattern(notionIdPattern));
30
+ const Timestamp = Schema.String;
31
+ const JsonObject = Schema.Record(Schema.String, Schema.Json);
32
+ /** The integration's bot user (`GET /v1/users/me`). */
33
+ const NotionEmulatorBotUser = Schema.Struct({
34
+ id: NotionId,
35
+ name: Schema.String,
36
+ avatarUrl: Schema.NullOr(Schema.String),
37
+ workspaceName: Schema.String
38
+ });
39
+ /** A page parent as Notion answers it. */
40
+ const NotionEmulatorParent = Schema.Union([
41
+ Schema.Struct({
42
+ type: Schema.Literal("workspace"),
43
+ workspace: Schema.Literal(true)
44
+ }),
45
+ Schema.Struct({
46
+ type: Schema.Literal("page_id"),
47
+ page_id: NotionId
48
+ }),
49
+ Schema.Struct({
50
+ type: Schema.Literal("data_source_id"),
51
+ data_source_id: NotionId,
52
+ database_id: NotionId
53
+ })
54
+ ]);
55
+ /** A stored page. `times` is `null` where the fixture omits both timestamps (data source rows). */
56
+ const NotionEmulatorPage = Schema.Struct({
57
+ id: NotionId,
58
+ times: Schema.NullOr(Schema.Struct({
59
+ created: Timestamp,
60
+ lastEdited: Timestamp
61
+ })),
62
+ parent: NotionEmulatorParent,
63
+ archived: Schema.Boolean,
64
+ inTrash: Schema.Boolean,
65
+ /** The page object's `properties`, answered as stored. */
66
+ properties: JsonObject,
67
+ url: Schema.String
68
+ });
69
+ /** A stored block, a child of a page. */
70
+ const NotionEmulatorBlock = Schema.Struct({
71
+ id: NotionId,
72
+ pageId: NotionId,
73
+ createdTime: Timestamp,
74
+ lastEditedTime: Timestamp,
75
+ hasChildren: Schema.Boolean,
76
+ archived: Schema.Boolean,
77
+ inTrash: Schema.Boolean,
78
+ /** Block type, for example `paragraph`. */
79
+ type: Schema.String,
80
+ /** The type-specific value (`paragraph: { rich_text, color }`). */
81
+ value: JsonObject
82
+ });
83
+ /**
84
+ * The items of one paginated page property, as the property endpoint pages through them. Each
85
+ * item answers `{ object: "property_item", id, type, [type]: value }`.
86
+ */
87
+ const NotionEmulatorPropertyItems = Schema.Struct({
88
+ pageId: NotionId,
89
+ /** The property id exactly as the page object returns it (for example `Syn%3Ap`). */
90
+ propertyId: Schema.String,
91
+ type: Schema.String,
92
+ values: Schema.Array(Schema.Json)
93
+ });
94
+ const NotionEmulatorDatabase = Schema.Struct({
95
+ id: NotionId,
96
+ title: Schema.Array(Schema.Json),
97
+ description: Schema.Array(Schema.Json),
98
+ parent: Schema.Struct({
99
+ type: Schema.Literal("page_id"),
100
+ page_id: NotionId
101
+ }),
102
+ isInline: Schema.Boolean,
103
+ inTrash: Schema.Boolean,
104
+ archived: Schema.Boolean,
105
+ createdTime: Timestamp,
106
+ lastEditedTime: Timestamp,
107
+ url: Schema.String
108
+ });
109
+ /** A data source of a database: its schema; its rows are pages with a `data_source_id` parent. */
110
+ const NotionEmulatorDataSource = Schema.Struct({
111
+ id: NotionId,
112
+ databaseId: NotionId,
113
+ /** Rich text title; its plain text is the name the database lists. */
114
+ title: Schema.Array(Schema.Json),
115
+ properties: JsonObject,
116
+ archived: Schema.Boolean,
117
+ inTrash: Schema.Boolean
118
+ });
119
+ /**
120
+ * A page a fixture names by id but never shows (no title, properties, or timestamps): accepted
121
+ * where a fixture names it (a block parent, a create parent, a database parent, a query row), never
122
+ * rendered. `parent` is set only for a data source row.
123
+ */
124
+ const NotionEmulatorImpliedPage = Schema.Struct({
125
+ id: NotionId,
126
+ parent: Schema.NullOr(NotionEmulatorParent)
127
+ });
128
+ const Counter = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));
129
+ const Counters = Schema.Struct({
130
+ /** Next number in created page ids (`1f0000e0-0000-4000-8000-000000000001`). */
131
+ nextPageNumber: Counter });
132
+ /** The whole emulator state (JSON-compatible; what `snapshot()` returns). */
133
+ const NotionEmulatorStateSchema = Schema.Struct({
134
+ botUser: NotionEmulatorBotUser,
135
+ pages: Schema.Array(NotionEmulatorPage),
136
+ impliedPages: Schema.Array(NotionEmulatorImpliedPage),
137
+ blocks: Schema.Array(NotionEmulatorBlock),
138
+ propertyItems: Schema.Array(NotionEmulatorPropertyItems),
139
+ databases: Schema.Array(NotionEmulatorDatabase),
140
+ dataSources: Schema.Array(NotionEmulatorDataSource),
141
+ counters: Counters
142
+ });
143
+ /** Account-variance profiles for the default seed. */
144
+ const NotionEmulatorProfile = Schema.Literals(["default", "empty"]);
145
+ /**
146
+ * A typed seed. Start from `profile` (default `'default'`, the fixture entities); every other key,
147
+ * when given, replaces that part of the profile.
148
+ */
149
+ const NotionEmulatorSeed = Schema.Struct({
150
+ profile: Schema.optionalKey(NotionEmulatorProfile),
151
+ botUser: Schema.optionalKey(NotionEmulatorBotUser),
152
+ pages: Schema.optionalKey(Schema.Array(NotionEmulatorPage)),
153
+ impliedPages: Schema.optionalKey(Schema.Array(NotionEmulatorImpliedPage)),
154
+ blocks: Schema.optionalKey(Schema.Array(NotionEmulatorBlock)),
155
+ propertyItems: Schema.optionalKey(Schema.Array(NotionEmulatorPropertyItems)),
156
+ databases: Schema.optionalKey(Schema.Array(NotionEmulatorDatabase)),
157
+ dataSources: Schema.optionalKey(Schema.Array(NotionEmulatorDataSource))
158
+ });
159
+ const strict = { onExcessProperty: "error" };
160
+ const decodeSeedInput = Schema.decodeUnknownResult(NotionEmulatorSeed, strict);
161
+ const decodeStateInput = Schema.decodeUnknownResult(NotionEmulatorStateSchema, strict);
162
+ const issueMessage = (issue) => new Schema.SchemaError(issue).message;
163
+ /** A plain rich text item as the fixtures write it (no annotations). */
164
+ const plainRichText = (text) => ({
165
+ type: "text",
166
+ text: {
167
+ content: text,
168
+ link: null
169
+ },
170
+ plain_text: text,
171
+ href: null
172
+ });
173
+ /** A page `title` property as the fixtures write it. */
174
+ const titleProperty = (items) => ({
175
+ id: "title",
176
+ type: "title",
177
+ title: [...items]
178
+ });
179
+ const seededAt = "2026-09-20T09:00:00.000Z";
180
+ const workspace = {
181
+ type: "workspace",
182
+ workspace: true
183
+ };
184
+ const annotations = (bold) => ({
185
+ bold,
186
+ italic: false,
187
+ strikethrough: false,
188
+ underline: false,
189
+ code: false,
190
+ color: "default"
191
+ });
192
+ const workspacePage = (id, title, url, extra = {}) => ({
193
+ id,
194
+ times: {
195
+ created: seededAt,
196
+ lastEdited: seededAt
197
+ },
198
+ parent: workspace,
199
+ archived: false,
200
+ inTrash: false,
201
+ properties: {
202
+ ...extra,
203
+ title: titleProperty(title)
204
+ },
205
+ url
206
+ });
207
+ const searchPage = (index) => workspacePage(`1f0000a0-0000-4000-8000-00000000000${index}`, [plainRichText(`yolk-search-probe ${index}`)], `https://www.notion.so/yolk-search-probe-${index}-1f0000a0000040008000000000000${index}`);
208
+ /** A rich text item with annotations, as the title fixture writes it. */
209
+ const annotatedRichText = (text, bold) => ({
210
+ type: "text",
211
+ text: {
212
+ content: text,
213
+ link: null
214
+ },
215
+ annotations: annotations(bold),
216
+ plain_text: text,
217
+ href: null
218
+ });
219
+ const titlePage = workspacePage("1f000000-0000-4000-8000-000000000001", [annotatedRichText("Synthetic ", false), annotatedRichText("Title Page", true)], "https://www.notion.so/Synthetic-Title-Page-1f000000000040008000000000000001");
220
+ const blocksPageId = "1f000000-0000-4000-8000-000000000002";
221
+ const propertyPageId = "1f000000-0000-4000-8000-000000000003";
222
+ const propertyId = "Syn%3Ap";
223
+ const segment = (index) => plainRichText(`Synthetic segment ${index} `);
224
+ const propertyPage = workspacePage(propertyPageId, [plainRichText("Synthetic Property Page")], "https://www.notion.so/Synthetic-Property-Page-1f000000000040008000000000000003", { Notes: {
225
+ id: propertyId,
226
+ type: "rich_text",
227
+ rich_text: [segment(1)]
228
+ } });
229
+ const parentPageId = "1f000000-0000-4000-8000-000000000005";
230
+ const databaseId = "1f000000-0000-4000-8000-000000000004";
231
+ const dataSourceId = "1f0000d0-0000-4000-8000-000000000001";
232
+ const databaseParentId = "1f0000d0-0000-4000-8000-0000000000aa";
233
+ const rowParent = {
234
+ type: "data_source_id",
235
+ data_source_id: dataSourceId,
236
+ database_id: databaseId
237
+ };
238
+ /** The query fixture's row (its row object carries no timestamps). */
239
+ const firstRow = {
240
+ id: "1f0000d0-0000-4000-8000-000000000101",
241
+ times: null,
242
+ parent: rowParent,
243
+ archived: false,
244
+ inTrash: false,
245
+ properties: {
246
+ Name: {
247
+ id: "title",
248
+ type: "title",
249
+ title: [plainRichText("Synthetic task 1")]
250
+ },
251
+ Done: {
252
+ id: "Syn%3Ad",
253
+ type: "checkbox",
254
+ checkbox: false
255
+ }
256
+ },
257
+ url: "https://www.notion.so/Synthetic-task-1-1f0000d0000040008000000000000101"
258
+ };
259
+ const paragraph = (index) => ({
260
+ id: `1f0000c0-0000-4000-8000-00000000000${index}`,
261
+ pageId: blocksPageId,
262
+ createdTime: seededAt,
263
+ lastEditedTime: seededAt,
264
+ hasChildren: false,
265
+ archived: false,
266
+ inTrash: false,
267
+ type: "paragraph",
268
+ value: {
269
+ rich_text: [plainRichText(`Synthetic paragraph ${index}`)],
270
+ color: "default"
271
+ }
272
+ });
273
+ const defaultBotUser = {
274
+ id: "1f0000b0-0000-4000-8000-000000000001",
275
+ name: "Synthetic Integration",
276
+ avatarUrl: null,
277
+ workspaceName: "Synthetic Workspace"
278
+ };
279
+ const tasksTitle = [plainRichText("Synthetic Tasks")];
280
+ const profileEntities = (profile) => profile === "default" ? {
281
+ botUser: defaultBotUser,
282
+ pages: [
283
+ searchPage(1),
284
+ searchPage(2),
285
+ titlePage,
286
+ propertyPage,
287
+ firstRow
288
+ ],
289
+ impliedPages: [
290
+ {
291
+ id: blocksPageId,
292
+ parent: null
293
+ },
294
+ {
295
+ id: parentPageId,
296
+ parent: null
297
+ },
298
+ {
299
+ id: databaseParentId,
300
+ parent: null
301
+ },
302
+ {
303
+ id: "1f0000d0-0000-4000-8000-000000000102",
304
+ parent: rowParent
305
+ }
306
+ ],
307
+ blocks: [
308
+ paragraph(1),
309
+ paragraph(2),
310
+ paragraph(3)
311
+ ],
312
+ propertyItems: [{
313
+ pageId: propertyPageId,
314
+ propertyId,
315
+ type: "rich_text",
316
+ values: [
317
+ segment(1),
318
+ segment(2),
319
+ segment(3)
320
+ ]
321
+ }],
322
+ databases: [{
323
+ id: databaseId,
324
+ title: tasksTitle,
325
+ description: [],
326
+ parent: {
327
+ type: "page_id",
328
+ page_id: databaseParentId
329
+ },
330
+ isInline: false,
331
+ inTrash: false,
332
+ archived: false,
333
+ createdTime: seededAt,
334
+ lastEditedTime: seededAt,
335
+ url: "https://www.notion.so/1f000000000040008000000000000004"
336
+ }],
337
+ dataSources: [{
338
+ id: dataSourceId,
339
+ databaseId,
340
+ title: tasksTitle,
341
+ properties: {
342
+ Name: {
343
+ id: "title",
344
+ name: "Name",
345
+ type: "title",
346
+ title: {}
347
+ },
348
+ Done: {
349
+ id: "Syn%3Ad",
350
+ name: "Done",
351
+ type: "checkbox",
352
+ checkbox: {}
353
+ }
354
+ },
355
+ archived: false,
356
+ inTrash: false
357
+ }]
358
+ } : {
359
+ botUser: defaultBotUser,
360
+ pages: [],
361
+ impliedPages: [],
362
+ blocks: [],
363
+ propertyItems: [],
364
+ databases: [],
365
+ dataSources: []
366
+ };
367
+ const duplicate = (values) => values.find((value, index) => values.indexOf(value) !== index);
368
+ /** The minted page id form (`1f0000e0-0000-4000-8000-000000000001`). */
369
+ const mintedPageIdPattern = /^1f0000e0-0000-4000-8000-(\d{12})$/;
370
+ /** Integrity problems a decoded seed can still have (duplicates, dangling references). */
371
+ const seedProblem = (entities) => {
372
+ const pageIds = entities.pages.map((page) => page.id);
373
+ const knownPageIds = [...pageIds, ...entities.impliedPages.map((page) => page.id)];
374
+ const databaseIds = entities.databases.map((database) => database.id);
375
+ const dataSourceIds = entities.dataSources.map((source) => source.id);
376
+ const duplicates = [
377
+ ["object id", duplicate([
378
+ ...knownPageIds,
379
+ ...databaseIds,
380
+ ...dataSourceIds
381
+ ])],
382
+ ["block id", duplicate(entities.blocks.map((block) => block.id))],
383
+ ["property item list", duplicate(entities.propertyItems.map((items) => `${items.pageId} ${items.propertyId}`))]
384
+ ];
385
+ for (const [label, value] of duplicates) if (value !== void 0) return `duplicate ${label} ${value}`;
386
+ for (const page of [...entities.pages, ...entities.impliedPages]) {
387
+ const parent = page.parent;
388
+ if (parent?.type === "page_id" && !knownPageIds.includes(parent.page_id)) return `page ${page.id} references missing parent page ${parent.page_id}`;
389
+ if (parent?.type === "data_source_id" && !entities.dataSources.some((source) => source.id === parent.data_source_id && source.databaseId === parent.database_id)) return `page ${page.id} references missing data source ${parent.data_source_id}`;
390
+ }
391
+ const block = entities.blocks.find((candidate) => !knownPageIds.includes(candidate.pageId));
392
+ if (block !== void 0) return `block ${block.id} references missing page ${block.pageId}`;
393
+ const items = entities.propertyItems.find((candidate) => !pageIds.includes(candidate.pageId));
394
+ if (items !== void 0) return `property items reference missing page ${items.pageId}`;
395
+ const database = entities.databases.find((candidate) => !knownPageIds.includes(candidate.parent.page_id));
396
+ if (database !== void 0) return `database ${database.id} references missing parent page ${database.parent.page_id}`;
397
+ const source = entities.dataSources.find((candidate) => !databaseIds.includes(candidate.databaseId));
398
+ return source === void 0 ? void 0 : `data source ${source.id} references missing database ${source.databaseId}`;
399
+ };
400
+ /** Build the emulator state for a decoded seed; a string is an integrity problem. */
401
+ const stateFromSeed = (seed) => {
402
+ const profile = profileEntities(seed.profile ?? "default");
403
+ const entities = {
404
+ botUser: seed.botUser ?? profile.botUser,
405
+ pages: seed.pages ?? profile.pages,
406
+ impliedPages: seed.impliedPages ?? profile.impliedPages,
407
+ blocks: seed.blocks ?? profile.blocks,
408
+ propertyItems: seed.propertyItems ?? profile.propertyItems,
409
+ databases: seed.databases ?? profile.databases,
410
+ dataSources: seed.dataSources ?? profile.dataSources
411
+ };
412
+ const problem = seedProblem(entities);
413
+ const highest = Math.max(0, ...[...entities.pages, ...entities.impliedPages].map((page) => Number(mintedPageIdPattern.exec(page.id)?.[1] ?? 0)));
414
+ return problem ?? {
415
+ ...entities,
416
+ counters: { nextPageNumber: highest + 1 }
417
+ };
418
+ };
419
+ /** Decode and build a seed; a string is the reason it is invalid. */
420
+ const buildSeedState = (input) => {
421
+ const decoded = decodeSeedInput(input);
422
+ return Result.isFailure(decoded) ? issueMessage(decoded.failure.issue) : stateFromSeed(decoded.success);
423
+ };
424
+ /** Decode a full state (a restored snapshot); a string is the reason it is invalid. */
425
+ const decodeState = (input) => {
426
+ const decoded = decodeStateInput(input);
427
+ return Result.isFailure(decoded) ? issueMessage(decoded.failure.issue) : { ...decoded.success };
428
+ };
429
+ //#endregion
430
+ export { NotionEmulatorBlock, NotionEmulatorBotUser, NotionEmulatorDataSource, NotionEmulatorDatabase, NotionEmulatorImpliedPage, NotionEmulatorPage, NotionEmulatorParent, NotionEmulatorProfile, NotionEmulatorPropertyItems, NotionEmulatorSeed, NotionEmulatorStateSchema, buildSeedState, decodeState, notionIdPattern, plainRichText, titleProperty };
431
+
432
+ //# sourceMappingURL=state.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.mjs","names":[],"sources":["../../src/notion/state.ts"],"sourcesContent":["/**\n * Notion emulator state: the typed bot user, pages, blocks, paginated property items, databases,\n * and data sources, the seed input, the default seed, and the profiles (internal; re-exported by\n * `src/notion.ts`).\n *\n * Entity shapes and the default entities follow the synthetic Notion conformance fixtures (API\n * version 2025-09-03), copied as data (the same ids, titles, properties, timestamps, and URLs as\n * the fixtures and `notionConformanceFixtureSeeds`), never imported from SDK code. Pages a fixture\n * only names by id (the blocks page, the write case's parent page, the database's parent page, and\n * the second data source row the query fixture's `next_cursor` names) are `impliedPages`: their ids\n * resolve where a fixture names them, but no content is invented for them, so any answer that\n * would render one is not emulated.\n *\n * Minted page ids never repeat seeded ones: the page counter starts above the highest seeded id\n * in the minted form (`1f0000e0-0000-4000-8000-NNNNNNNNNNNN`).\n *\n * Pages and other objects are stored with their wire fields (`properties`, `parent`, rich text)\n * as JSON, answered as stored. A page's `properties` value is what the page object answers; the\n * items the property endpoint pages through are stored separately (`propertyItems`), as the\n * fixtures show them (the page object of the property page carries only the first segment).\n *\n * @experimental\n */\nimport { Result } from 'effect'\nimport * as Schema from 'effect/Schema'\n\n/** A Notion id as stored and answered: a lower-case dashed UUID. */\nexport const notionIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/\n\nconst NotionId = Schema.String.check(Schema.isPattern(notionIdPattern))\n\nconst Timestamp = Schema.String\n\nconst JsonObject = Schema.Record(Schema.String, Schema.Json)\n\n/** The integration's bot user (`GET /v1/users/me`). */\nexport const NotionEmulatorBotUser = Schema.Struct({\n id: NotionId,\n name: Schema.String,\n avatarUrl: Schema.NullOr(Schema.String),\n workspaceName: Schema.String\n})\n\nexport type NotionEmulatorBotUser = typeof NotionEmulatorBotUser.Type\n\n/** A page parent as Notion answers it. */\nexport const NotionEmulatorParent = Schema.Union([\n Schema.Struct({ type: Schema.Literal('workspace'), workspace: Schema.Literal(true) }),\n Schema.Struct({ type: Schema.Literal('page_id'), page_id: NotionId }),\n Schema.Struct({\n type: Schema.Literal('data_source_id'),\n data_source_id: NotionId,\n database_id: NotionId\n })\n])\n\nexport type NotionEmulatorParent = typeof NotionEmulatorParent.Type\n\n/** A stored page. `times` is `null` where the fixture omits both timestamps (data source rows). */\nexport const NotionEmulatorPage = Schema.Struct({\n id: NotionId,\n times: Schema.NullOr(Schema.Struct({ created: Timestamp, lastEdited: Timestamp })),\n parent: NotionEmulatorParent,\n archived: Schema.Boolean,\n inTrash: Schema.Boolean,\n /** The page object's `properties`, answered as stored. */\n properties: JsonObject,\n url: Schema.String\n})\n\nexport type NotionEmulatorPage = typeof NotionEmulatorPage.Type\n\n/** A stored block, a child of a page. */\nexport const NotionEmulatorBlock = Schema.Struct({\n id: NotionId,\n pageId: NotionId,\n createdTime: Timestamp,\n lastEditedTime: Timestamp,\n hasChildren: Schema.Boolean,\n archived: Schema.Boolean,\n inTrash: Schema.Boolean,\n /** Block type, for example `paragraph`. */\n type: Schema.String,\n /** The type-specific value (`paragraph: { rich_text, color }`). */\n value: JsonObject\n})\n\nexport type NotionEmulatorBlock = typeof NotionEmulatorBlock.Type\n\n/**\n * The items of one paginated page property, as the property endpoint pages through them. Each\n * item answers `{ object: \"property_item\", id, type, [type]: value }`.\n */\nexport const NotionEmulatorPropertyItems = Schema.Struct({\n pageId: NotionId,\n /** The property id exactly as the page object returns it (for example `Syn%3Ap`). */\n propertyId: Schema.String,\n type: Schema.String,\n values: Schema.Array(Schema.Json)\n})\n\nexport type NotionEmulatorPropertyItems = typeof NotionEmulatorPropertyItems.Type\n\nexport const NotionEmulatorDatabase = Schema.Struct({\n id: NotionId,\n title: Schema.Array(Schema.Json),\n description: Schema.Array(Schema.Json),\n parent: Schema.Struct({ type: Schema.Literal('page_id'), page_id: NotionId }),\n isInline: Schema.Boolean,\n inTrash: Schema.Boolean,\n archived: Schema.Boolean,\n createdTime: Timestamp,\n lastEditedTime: Timestamp,\n url: Schema.String\n})\n\nexport type NotionEmulatorDatabase = typeof NotionEmulatorDatabase.Type\n\n/** A data source of a database: its schema; its rows are pages with a `data_source_id` parent. */\nexport const NotionEmulatorDataSource = Schema.Struct({\n id: NotionId,\n databaseId: NotionId,\n /** Rich text title; its plain text is the name the database lists. */\n title: Schema.Array(Schema.Json),\n properties: JsonObject,\n archived: Schema.Boolean,\n inTrash: Schema.Boolean\n})\n\nexport type NotionEmulatorDataSource = typeof NotionEmulatorDataSource.Type\n\n/**\n * A page a fixture names by id but never shows (no title, properties, or timestamps): accepted\n * where a fixture names it (a block parent, a create parent, a database parent, a query row), never\n * rendered. `parent` is set only for a data source row.\n */\nexport const NotionEmulatorImpliedPage = Schema.Struct({\n id: NotionId,\n parent: Schema.NullOr(NotionEmulatorParent)\n})\n\nexport type NotionEmulatorImpliedPage = typeof NotionEmulatorImpliedPage.Type\n\nconst Counter = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))\n\nconst Counters = Schema.Struct({\n /** Next number in created page ids (`1f0000e0-0000-4000-8000-000000000001`). */\n nextPageNumber: Counter\n})\n\n/** The whole emulator state (JSON-compatible; what `snapshot()` returns). */\nexport const NotionEmulatorStateSchema = Schema.Struct({\n botUser: NotionEmulatorBotUser,\n pages: Schema.Array(NotionEmulatorPage),\n impliedPages: Schema.Array(NotionEmulatorImpliedPage),\n blocks: Schema.Array(NotionEmulatorBlock),\n propertyItems: Schema.Array(NotionEmulatorPropertyItems),\n databases: Schema.Array(NotionEmulatorDatabase),\n dataSources: Schema.Array(NotionEmulatorDataSource),\n counters: Counters\n})\n\n/**\n * The emulator state. The container is mutable (routes replace whole lists); every entity is\n * replaced, never edited in place.\n */\nexport type NotionEmulatorState = {\n botUser: NotionEmulatorBotUser\n pages: ReadonlyArray<NotionEmulatorPage>\n impliedPages: ReadonlyArray<NotionEmulatorImpliedPage>\n blocks: ReadonlyArray<NotionEmulatorBlock>\n propertyItems: ReadonlyArray<NotionEmulatorPropertyItems>\n databases: ReadonlyArray<NotionEmulatorDatabase>\n dataSources: ReadonlyArray<NotionEmulatorDataSource>\n counters: typeof Counters.Type\n}\n\n/** Account-variance profiles for the default seed. */\nexport const NotionEmulatorProfile = Schema.Literals(['default', 'empty'])\n\nexport type NotionEmulatorProfile = typeof NotionEmulatorProfile.Type\n\n/**\n * A typed seed. Start from `profile` (default `'default'`, the fixture entities); every other key,\n * when given, replaces that part of the profile.\n */\nexport const NotionEmulatorSeed = Schema.Struct({\n profile: Schema.optionalKey(NotionEmulatorProfile),\n botUser: Schema.optionalKey(NotionEmulatorBotUser),\n pages: Schema.optionalKey(Schema.Array(NotionEmulatorPage)),\n impliedPages: Schema.optionalKey(Schema.Array(NotionEmulatorImpliedPage)),\n blocks: Schema.optionalKey(Schema.Array(NotionEmulatorBlock)),\n propertyItems: Schema.optionalKey(Schema.Array(NotionEmulatorPropertyItems)),\n databases: Schema.optionalKey(Schema.Array(NotionEmulatorDatabase)),\n dataSources: Schema.optionalKey(Schema.Array(NotionEmulatorDataSource))\n})\n\nexport type NotionEmulatorSeed = typeof NotionEmulatorSeed.Type\n\nconst strict = { onExcessProperty: 'error' } as const\n\nconst decodeSeedInput = Schema.decodeUnknownResult(NotionEmulatorSeed, strict)\n\nconst decodeStateInput = Schema.decodeUnknownResult(NotionEmulatorStateSchema, strict)\n\nconst issueMessage = (issue: Schema.SchemaError['issue']): string =>\n new Schema.SchemaError(issue).message\n\n/** A plain rich text item as the fixtures write it (no annotations). */\nexport const plainRichText = (text: string): Schema.JsonObject => ({\n type: 'text',\n text: { content: text, link: null },\n plain_text: text,\n href: null\n})\n\n/** A page `title` property as the fixtures write it. */\nexport const titleProperty = (items: ReadonlyArray<Schema.Json>): Schema.JsonObject => ({\n id: 'title',\n type: 'title',\n title: [...items]\n})\n\n// Default entities, copied from the fixtures: the bot user, the two search pages, the title page\n// with its two annotated title items, the three paragraph blocks, the property page with its\n// `Notes` property and three rich-text segments, the database, its data source, and its first row.\n// Implied (named by a fixture, never shown): the blocks page, the write case's parent page, the\n// database's parent page, and the second row.\n\nconst seededAt = '2026-09-20T09:00:00.000Z'\n\nconst workspace: NotionEmulatorParent = { type: 'workspace', workspace: true }\n\nconst annotations = (bold: boolean): Schema.JsonObject => ({\n bold,\n italic: false,\n strikethrough: false,\n underline: false,\n code: false,\n color: 'default'\n})\n\nconst workspacePage = (\n id: string,\n title: ReadonlyArray<Schema.Json>,\n url: string,\n extra: Schema.JsonObject = {}\n): NotionEmulatorPage => ({\n id,\n times: { created: seededAt, lastEdited: seededAt },\n parent: workspace,\n archived: false,\n inTrash: false,\n properties: { ...extra, title: titleProperty(title) },\n url\n})\n\nconst searchPage = (index: number): NotionEmulatorPage =>\n workspacePage(\n `1f0000a0-0000-4000-8000-00000000000${index}`,\n [plainRichText(`yolk-search-probe ${index}`)],\n // The search fixture's URL carries a shortened id (30 hex digits); copied as is.\n `https://www.notion.so/yolk-search-probe-${index}-1f0000a0000040008000000000000${index}`\n )\n\n/** A rich text item with annotations, as the title fixture writes it. */\nconst annotatedRichText = (text: string, bold: boolean): Schema.JsonObject => ({\n type: 'text',\n text: { content: text, link: null },\n annotations: annotations(bold),\n plain_text: text,\n href: null\n})\n\nconst titlePage = workspacePage(\n '1f000000-0000-4000-8000-000000000001',\n [annotatedRichText('Synthetic ', false), annotatedRichText('Title Page', true)],\n 'https://www.notion.so/Synthetic-Title-Page-1f000000000040008000000000000001'\n)\n\nconst blocksPageId = '1f000000-0000-4000-8000-000000000002'\n\nconst propertyPageId = '1f000000-0000-4000-8000-000000000003'\n\nconst propertyId = 'Syn%3Ap'\n\nconst segment = (index: number) => plainRichText(`Synthetic segment ${index} `)\n\nconst propertyPage = workspacePage(\n propertyPageId,\n [plainRichText('Synthetic Property Page')],\n 'https://www.notion.so/Synthetic-Property-Page-1f000000000040008000000000000003',\n { Notes: { id: propertyId, type: 'rich_text', rich_text: [segment(1)] } }\n)\n\nconst parentPageId = '1f000000-0000-4000-8000-000000000005'\n\nconst databaseId = '1f000000-0000-4000-8000-000000000004'\n\nconst dataSourceId = '1f0000d0-0000-4000-8000-000000000001'\n\nconst databaseParentId = '1f0000d0-0000-4000-8000-0000000000aa'\n\nconst rowParent: NotionEmulatorParent = {\n type: 'data_source_id',\n data_source_id: dataSourceId,\n database_id: databaseId\n}\n\n/** The query fixture's row (its row object carries no timestamps). */\nconst firstRow: NotionEmulatorPage = {\n id: '1f0000d0-0000-4000-8000-000000000101',\n times: null,\n parent: rowParent,\n archived: false,\n inTrash: false,\n properties: {\n Name: { id: 'title', type: 'title', title: [plainRichText('Synthetic task 1')] },\n Done: { id: 'Syn%3Ad', type: 'checkbox', checkbox: false }\n },\n url: 'https://www.notion.so/Synthetic-task-1-1f0000d0000040008000000000000101'\n}\n\nconst paragraph = (index: number): NotionEmulatorBlock => ({\n id: `1f0000c0-0000-4000-8000-00000000000${index}`,\n pageId: blocksPageId,\n createdTime: seededAt,\n lastEditedTime: seededAt,\n hasChildren: false,\n archived: false,\n inTrash: false,\n type: 'paragraph',\n value: { rich_text: [plainRichText(`Synthetic paragraph ${index}`)], color: 'default' }\n})\n\nconst defaultBotUser: NotionEmulatorBotUser = {\n id: '1f0000b0-0000-4000-8000-000000000001',\n name: 'Synthetic Integration',\n avatarUrl: null,\n workspaceName: 'Synthetic Workspace'\n}\n\nconst tasksTitle = [plainRichText('Synthetic Tasks')]\n\ntype ProfileEntities = Omit<NotionEmulatorState, 'counters'>\n\nconst profileEntities = (profile: NotionEmulatorProfile): ProfileEntities =>\n profile === 'default'\n ? {\n botUser: defaultBotUser,\n pages: [searchPage(1), searchPage(2), titlePage, propertyPage, firstRow],\n impliedPages: [\n { id: blocksPageId, parent: null },\n { id: parentPageId, parent: null },\n { id: databaseParentId, parent: null },\n { id: '1f0000d0-0000-4000-8000-000000000102', parent: rowParent }\n ],\n blocks: [paragraph(1), paragraph(2), paragraph(3)],\n propertyItems: [\n {\n pageId: propertyPageId,\n propertyId,\n type: 'rich_text',\n values: [segment(1), segment(2), segment(3)]\n }\n ],\n databases: [\n {\n id: databaseId,\n title: tasksTitle,\n description: [],\n parent: { type: 'page_id', page_id: databaseParentId },\n isInline: false,\n inTrash: false,\n archived: false,\n createdTime: seededAt,\n lastEditedTime: seededAt,\n url: 'https://www.notion.so/1f000000000040008000000000000004'\n }\n ],\n dataSources: [\n {\n id: dataSourceId,\n databaseId,\n title: tasksTitle,\n properties: {\n Name: { id: 'title', name: 'Name', type: 'title', title: {} },\n Done: { id: 'Syn%3Ad', name: 'Done', type: 'checkbox', checkbox: {} }\n },\n archived: false,\n inTrash: false\n }\n ]\n }\n : {\n botUser: defaultBotUser,\n pages: [],\n impliedPages: [],\n blocks: [],\n propertyItems: [],\n databases: [],\n dataSources: []\n }\n\nconst duplicate = (values: ReadonlyArray<string>): string | undefined =>\n values.find((value, index) => values.indexOf(value) !== index)\n\n/** The minted page id form (`1f0000e0-0000-4000-8000-000000000001`). */\nconst mintedPageIdPattern = /^1f0000e0-0000-4000-8000-(\\d{12})$/\n\n/** Integrity problems a decoded seed can still have (duplicates, dangling references). */\nconst seedProblem = (entities: ProfileEntities): string | undefined => {\n const pageIds = entities.pages.map(page => page.id)\n const knownPageIds = [...pageIds, ...entities.impliedPages.map(page => page.id)]\n const databaseIds = entities.databases.map(database => database.id)\n const dataSourceIds = entities.dataSources.map(source => source.id)\n\n const duplicates: ReadonlyArray<readonly [string, string | undefined]> = [\n ['object id', duplicate([...knownPageIds, ...databaseIds, ...dataSourceIds])],\n ['block id', duplicate(entities.blocks.map(block => block.id))],\n [\n 'property item list',\n duplicate(entities.propertyItems.map(items => `${items.pageId} ${items.propertyId}`))\n ]\n ]\n\n for (const [label, value] of duplicates) {\n if (value !== undefined) return `duplicate ${label} ${value}`\n }\n\n for (const page of [...entities.pages, ...entities.impliedPages]) {\n const parent = page.parent\n\n if (parent?.type === 'page_id' && !knownPageIds.includes(parent.page_id)) {\n return `page ${page.id} references missing parent page ${parent.page_id}`\n }\n\n if (\n parent?.type === 'data_source_id' &&\n !entities.dataSources.some(\n source => source.id === parent.data_source_id && source.databaseId === parent.database_id\n )\n ) {\n return `page ${page.id} references missing data source ${parent.data_source_id}`\n }\n }\n\n const block = entities.blocks.find(candidate => !knownPageIds.includes(candidate.pageId))\n\n if (block !== undefined) return `block ${block.id} references missing page ${block.pageId}`\n\n const items = entities.propertyItems.find(candidate => !pageIds.includes(candidate.pageId))\n\n if (items !== undefined) return `property items reference missing page ${items.pageId}`\n\n const database = entities.databases.find(\n candidate => !knownPageIds.includes(candidate.parent.page_id)\n )\n\n if (database !== undefined) {\n return `database ${database.id} references missing parent page ${database.parent.page_id}`\n }\n\n const source = entities.dataSources.find(candidate => !databaseIds.includes(candidate.databaseId))\n\n return source === undefined\n ? undefined\n : `data source ${source.id} references missing database ${source.databaseId}`\n}\n\n/** Build the emulator state for a decoded seed; a string is an integrity problem. */\nconst stateFromSeed = (seed: NotionEmulatorSeed): NotionEmulatorState | string => {\n const profile = profileEntities(seed.profile ?? 'default')\n\n const entities: ProfileEntities = {\n botUser: seed.botUser ?? profile.botUser,\n pages: seed.pages ?? profile.pages,\n impliedPages: seed.impliedPages ?? profile.impliedPages,\n blocks: seed.blocks ?? profile.blocks,\n propertyItems: seed.propertyItems ?? profile.propertyItems,\n databases: seed.databases ?? profile.databases,\n dataSources: seed.dataSources ?? profile.dataSources\n }\n\n const problem = seedProblem(entities)\n\n // Minted ids start above every seeded id in the minted form, so none repeats.\n const highest = Math.max(\n 0,\n ...[...entities.pages, ...entities.impliedPages].map(page =>\n Number(mintedPageIdPattern.exec(page.id)?.[1] ?? 0)\n )\n )\n\n return problem ?? { ...entities, counters: { nextPageNumber: highest + 1 } }\n}\n\n/** Decode and build a seed; a string is the reason it is invalid. */\nexport const buildSeedState = (input: unknown): NotionEmulatorState | string => {\n const decoded = decodeSeedInput(input)\n\n return Result.isFailure(decoded)\n ? issueMessage(decoded.failure.issue)\n : stateFromSeed(decoded.success)\n}\n\n/** Decode a full state (a restored snapshot); a string is the reason it is invalid. */\nexport const decodeState = (input: unknown): NotionEmulatorState | string => {\n const decoded = decodeStateInput(input)\n\n return Result.isFailure(decoded) ? issueMessage(decoded.failure.issue) : { ...decoded.success }\n}\n"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { EmulatorEvidence, EmulatorRouteEvidence, emulatorEvidenceHeader } from "./route-evidence.mjs";
2
+ import { StatefulCoverage, StatefulEmulatorApi, StatefulFault, StatefulFaultMatch, StatefulFaultState, StatefulInputKind, StatefulLedgerEntry } from "./stateful-emulator.mjs";
3
+ import { NotionEmulatorBlock, NotionEmulatorBotUser, NotionEmulatorDataSource, NotionEmulatorDatabase, NotionEmulatorImpliedPage, NotionEmulatorPage, NotionEmulatorParent, NotionEmulatorProfile, NotionEmulatorPropertyItems, NotionEmulatorSeed, NotionEmulatorState, NotionEmulatorStateSchema } from "./notion/state.mjs";
4
+ import { NotionEmulatorDrills, notionEmulatorBasePath, notionEmulatorOrigin, notionEmulatorVersion } from "./notion/api.mjs";
5
+
6
+ //#region src/notion.d.ts
7
+ /**
8
+ * Route evidence manifest: every emulated route, whether it writes, and the conformance cases
9
+ * whose (currently synthetic, unverified) wire claims it follows. Kept in sync with the handlers
10
+ * by construction (both come from one route table).
11
+ */
12
+ declare const notionEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence>;
13
+ /**
14
+ * Optional fault filter; an omitted field matches every request. `method` is the HTTP method;
15
+ * `path` is the raw request path (ending in `*`, a prefix); `route` is a route template of the
16
+ * manifest (another value is rejected when the fault is added).
17
+ */
18
+ declare const NotionFaultMatch: import("effect/Schema").Struct<{
19
+ readonly method: import("effect/Schema").optionalKey<import("effect/Schema").String>;
20
+ readonly path: import("effect/Schema").optionalKey<import("effect/Schema").String>;
21
+ readonly route: import("effect/Schema").optionalKey<import("effect/Schema").String>;
22
+ }>;
23
+ type NotionFaultMatch = typeof StatefulFaultMatch.Type;
24
+ /**
25
+ * A status fault (400-599): answer matching requests with this status, headers, and body instead
26
+ * of the route's write, so nothing is written. The body defaults to
27
+ * `{ error: { type: 'emulator_fault', message } }`; `count` limits how many requests it answers.
28
+ * Only a request the emulator would answer reaches a fault: a request that is not emulated, by
29
+ * its shape or by the state, never uses one up.
30
+ */
31
+ declare const NotionFault: import("effect/Schema").Struct<{
32
+ readonly kind: import("effect/Schema").Literal<"status">;
33
+ readonly status: import("effect/Schema").Int;
34
+ readonly headers: import("effect/Schema").optionalKey<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
35
+ readonly body: import("effect/Schema").optionalKey<import("effect/Schema").Codec<import("effect/Schema").Json, import("effect/Schema").Json, never, never>>;
36
+ readonly match: import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
37
+ readonly method: import("effect/Schema").optionalKey<import("effect/Schema").String>;
38
+ readonly path: import("effect/Schema").optionalKey<import("effect/Schema").String>;
39
+ readonly route: import("effect/Schema").optionalKey<import("effect/Schema").String>;
40
+ }>>;
41
+ readonly count: import("effect/Schema").optionalKey<import("effect/Schema").Int>;
42
+ }>;
43
+ type NotionFault = StatefulFault;
44
+ type NotionFaultState = StatefulFaultState;
45
+ type NotionLedgerEntry = StatefulLedgerEntry;
46
+ type NotionCoverage = StatefulCoverage;
47
+ declare const NotionEmulatorInputInvalid_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
48
+ readonly _tag: "NotionEmulatorInputInvalid";
49
+ } & Readonly<A>;
50
+ /** Invalid emulator input from the JS API: a seed, a fault, or an option. A programmer error. */
51
+ declare class NotionEmulatorInputInvalid extends NotionEmulatorInputInvalid_base<{
52
+ readonly input: StatefulInputKind;
53
+ readonly reason: string;
54
+ }> {
55
+ get message(): string;
56
+ }
57
+ type NotionEmulatorOptions = {
58
+ /** Typed seed; defaults to the fixture entities (`profile: 'default'`). */readonly seed?: NotionEmulatorSeed; /** Clock in epoch milliseconds (created page timestamps). Defaults to `Date.now`. */
59
+ readonly now?: () => number; /** Drill knobs (tests only): make the emulator disagree with one conformance claim. */
60
+ readonly drills?: NotionEmulatorDrills;
61
+ };
62
+ type NotionEmulator = StatefulEmulatorApi<NotionEmulatorState, NotionEmulatorSeed>;
63
+ /**
64
+ * Create a stateful Notion emulator on the `@emulators/core` custom runtime. Each call has its
65
+ * own state, ledger, and faults. Rejects with `NotionEmulatorInputInvalid` for an invalid seed or
66
+ * option. Every request needs `Notion-Version: 2025-09-03` (else not emulated). See
67
+ * `src/stateful-emulator.ts` for the request precedence.
68
+ */
69
+ declare const makeNotionEmulator: (options?: NotionEmulatorOptions) => Promise<NotionEmulator>;
70
+ //#endregion
71
+ export { type EmulatorEvidence, type EmulatorRouteEvidence, NotionCoverage, NotionEmulator, NotionEmulatorBlock, NotionEmulatorBotUser, NotionEmulatorDataSource, NotionEmulatorDatabase, type NotionEmulatorDrills, NotionEmulatorImpliedPage, NotionEmulatorInputInvalid, NotionEmulatorOptions, NotionEmulatorPage, NotionEmulatorParent, NotionEmulatorProfile, NotionEmulatorPropertyItems, NotionEmulatorSeed, type NotionEmulatorState, NotionEmulatorStateSchema, NotionFault, NotionFaultMatch, NotionFaultState, NotionLedgerEntry, emulatorEvidenceHeader, makeNotionEmulator, notionEmulatorBasePath, notionEmulatorOrigin, notionEmulatorRoutes, notionEmulatorVersion };
72
+ //# sourceMappingURL=notion.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion.d.mts","names":[],"sources":["../src/notion.ts"],"mappings":";;;;;;;;AA0FsE;AAQtE;;cARa,oBAAA,EAAsB,aAAa,CAAC,qBAAA;;;;;;cAQpC,gBAAA,0BAAgB,MAAA;EAAA;;;;KAEjB,gBAAA,UAA0B,kBAAA,CAAmB,IAAI;;;AAA7D;;;;AAA6D;cAShD,WAAA,0BAAW,MAAA;EAAA;;;;;;;;;;;KAEZ,WAAA,GAAc,aAAa;AAAA,KAE3B,gBAAA,GAAmB,kBAAkB;AAAA,KAErC,iBAAA,GAAoB,mBAAmB;AAAA,KAEvC,cAAA,GAAiB,gBAAgB;AAAA,cAAA,+BAAA;;;;cAGhC,0BAAA,SAAmC,+BAAA;EAAA,SACrC,KAAA,EAAO,iBAAA;EAAA,SACP,MAAA;AAAA;EAAA,IAEI,OAAA,CAAA;AAAA;AAAA,KAKH,qBAAA;sFAED,IAAA,GAAO,kBAAA;WAEP,GAAA;WAEA,MAAA,GAAS,oBAAoB;AAAA;AAAA,KAG5B,cAAA,GAAiB,mBAAA,CAAoB,mBAAA,EAAqB,kBAAA;;AA3BtE;;;;AAAuC;cAsC1B,kBAAA,GACX,OAAA,GAAS,qBAAA,KACR,OAAA,CAAQ,cAAA"}