@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 @@
1
+ {"version":3,"file":"state.mjs","names":[],"sources":["../../src/microsoft/state.ts"],"sourcesContent":["/**\n * Microsoft Graph emulator state: the typed entities, the seed input, the default seed, and the\n * profiles (internal; re-exported by `src/microsoft.ts`).\n *\n * Entity shapes and the default entities follow the synthetic Microsoft conformance fixtures,\n * copied as data (the same mailbox, calendar, event, message, folder, drive, and item ids as\n * `microsoftConformanceFixtureSeeds`), never imported from SDK code. Where no fixture records a\n * value, the default is synthesized and says so below: the user id, the well-known mail folders\n * other than Drafts and Deleted Items, the attachment message itself, and the drive root and\n * `Sources` folder have no fixture.\n *\n * @experimental\n */\nimport { Result, Struct } from 'effect'\nimport * as Schema from 'effect/Schema'\n\nconst Timestamp = Schema.String\n\n/** A recipient as stored: `name` falls back to the address when Graph has none. */\nexport const MicrosoftEmulatorRecipient = Schema.Struct({\n name: Schema.NullOr(Schema.String),\n address: Schema.String\n})\n\nexport type MicrosoftEmulatorRecipient = typeof MicrosoftEmulatorRecipient.Type\n\n/** The mailbox owner every `/users/{userId}` route answers for (id, `mail`, or UPN). */\nexport const MicrosoftEmulatorUser = Schema.Struct({\n id: Schema.String,\n displayName: Schema.String,\n mail: Schema.String,\n userPrincipalName: Schema.String\n})\n\nexport type MicrosoftEmulatorUser = typeof MicrosoftEmulatorUser.Type\n\nconst WellKnownFolder = Schema.Literals(['inbox', 'drafts', 'deleteditems'])\n\n/** A mail folder; `wellKnownName` lets routes address it by name (`deleteditems`). */\nexport const MicrosoftEmulatorMailFolder = Schema.Struct({\n id: Schema.String,\n displayName: Schema.String,\n wellKnownName: Schema.NullOr(WellKnownFolder)\n})\n\nexport type MicrosoftEmulatorMailFolder = typeof MicrosoftEmulatorMailFolder.Type\n\nconst BodyContentType = Schema.Literals(['text', 'html'])\n\nconst messageFields = {\n /** The immutable id (`Prefer: IdType=\"ImmutableId\"`): stable across moves. */\n id: Schema.String,\n parentFolderId: Schema.String,\n subject: Schema.String,\n bodyContentType: BodyContentType,\n bodyContent: Schema.String,\n from: Schema.NullOr(MicrosoftEmulatorRecipient),\n sender: Schema.NullOr(MicrosoftEmulatorRecipient),\n toRecipients: Schema.Array(MicrosoftEmulatorRecipient),\n ccRecipients: Schema.Array(MicrosoftEmulatorRecipient),\n bccRecipients: Schema.Array(MicrosoftEmulatorRecipient),\n replyTo: Schema.Array(MicrosoftEmulatorRecipient),\n isRead: Schema.Boolean,\n isDraft: Schema.Boolean,\n importance: Schema.Literals(['low', 'normal', 'high']),\n flagStatus: Schema.Literals(['notFlagged', 'flagged', 'complete']),\n categories: Schema.Array(Schema.String),\n /** Answered as stored (not derived from the attachments; no fixture shows the rule). */\n hasAttachments: Schema.Boolean,\n createdDateTime: Timestamp,\n lastModifiedDateTime: Timestamp,\n receivedDateTime: Timestamp,\n sentDateTime: Timestamp,\n conversationId: Schema.String,\n internetMessageId: Schema.String,\n changeKey: Schema.String\n}\n\n/** A stored message. Every message is addressed by its immutable id. */\nexport const MicrosoftEmulatorMessage = Schema.Struct(messageFields)\n\nexport type MicrosoftEmulatorMessage = typeof MicrosoftEmulatorMessage.Type\n\nconst attachmentFields = {\n id: Schema.String,\n /** Immutable id of the owning message. */\n messageId: Schema.String,\n name: Schema.String,\n contentType: Schema.String,\n size: Schema.Int,\n isInline: Schema.Boolean,\n contentId: Schema.NullOr(Schema.String),\n contentLocation: Schema.NullOr(Schema.String),\n contentBytes: Schema.String,\n lastModifiedDateTime: Timestamp\n}\n\n/** A stored file attachment (`#microsoft.graph.fileAttachment`). */\nexport const MicrosoftEmulatorAttachment = Schema.Struct(attachmentFields)\n\nexport type MicrosoftEmulatorAttachment = typeof MicrosoftEmulatorAttachment.Type\n\nexport const MicrosoftEmulatorCalendar = Schema.Struct({\n id: Schema.String,\n name: Schema.String\n})\n\nexport type MicrosoftEmulatorCalendar = typeof MicrosoftEmulatorCalendar.Type\n\n/** Graph local date-time in UTC with seven fractional digits (`2026-09-23T12:00:00.0000000`). */\nexport const microsoftEmulatorDateTimePattern = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{7}$/\n\nconst UtcDateTime = Schema.String.check(Schema.isPattern(microsoftEmulatorDateTimePattern))\n\nconst eventFields = {\n id: Schema.String,\n calendarId: Schema.String,\n subject: Schema.String,\n bodyContentType: BodyContentType,\n bodyContent: Schema.String,\n /** Start in UTC, seven fractional digits. */\n start: UtcDateTime,\n /** End in UTC, seven fractional digits. */\n end: UtcDateTime,\n isCancelled: Schema.Boolean,\n isReminderOn: Schema.Boolean,\n showAs: Schema.Literals(['free', 'tentative', 'busy', 'oof', 'workingElsewhere', 'unknown']),\n changeKey: Schema.String,\n createdDateTime: Timestamp,\n lastModifiedDateTime: Timestamp\n}\n\n/** A stored single-instance calendar event (no attendees, no recurrence). */\nexport const MicrosoftEmulatorEvent = Schema.Struct(eventFields)\n\nexport type MicrosoftEmulatorEvent = typeof MicrosoftEmulatorEvent.Type\n\n/** The one emulated drive. */\nexport const MicrosoftEmulatorDrive = Schema.Struct({\n id: Schema.String,\n driveType: Schema.Literals(['business', 'personal']),\n rootId: Schema.String\n})\n\nexport type MicrosoftEmulatorDrive = typeof MicrosoftEmulatorDrive.Type\n\nconst driveItemFields = {\n id: Schema.String,\n /** `null` only for the drive root. */\n parentId: Schema.NullOr(Schema.String),\n name: Schema.String,\n kind: Schema.Literals(['folder', 'file']),\n /** File size in bytes; folders report the sum of their contents instead. */\n size: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n mimeType: Schema.NullOr(Schema.String),\n quickXorHash: Schema.NullOr(Schema.String),\n createdDateTime: Timestamp,\n lastModifiedDateTime: Timestamp\n}\n\n/** A stored drive item (file or folder). Deleted items are removed (no recycle bin). */\nexport const MicrosoftEmulatorDriveItem = Schema.Struct(driveItemFields)\n\nexport type MicrosoftEmulatorDriveItem = typeof MicrosoftEmulatorDriveItem.Type\n\nconst Counter = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))\n\nconst Counters = Schema.Struct({\n /** Next number in created event ids (`AAMkAGI2-synthetic-event-0101=`). */\n nextEventNumber: Counter,\n /** Next number in created message immutable ids. */\n nextMessageNumber: Counter,\n /** Next change key number (message and event writes). */\n nextChangeKeyNumber: Counter,\n /** Next number in created drive item ids. */\n nextItemNumber: Counter\n})\n\n/** The whole emulator state (JSON-compatible; what `snapshot()` returns). */\nexport const MicrosoftEmulatorStateSchema = Schema.Struct({\n user: MicrosoftEmulatorUser,\n mailFolders: Schema.Array(MicrosoftEmulatorMailFolder),\n messages: Schema.Array(MicrosoftEmulatorMessage),\n attachments: Schema.Array(MicrosoftEmulatorAttachment),\n calendars: Schema.Array(MicrosoftEmulatorCalendar),\n events: Schema.Array(MicrosoftEmulatorEvent),\n drive: MicrosoftEmulatorDrive,\n driveItems: Schema.Array(MicrosoftEmulatorDriveItem),\n counters: Counters\n})\n\n/**\n * The emulator state. The container is mutable (route handlers replace whole entity lists);\n * every entity is replaced, never edited in place.\n */\nexport type MicrosoftEmulatorState = {\n user: MicrosoftEmulatorUser\n mailFolders: ReadonlyArray<MicrosoftEmulatorMailFolder>\n messages: ReadonlyArray<MicrosoftEmulatorMessage>\n attachments: ReadonlyArray<MicrosoftEmulatorAttachment>\n calendars: ReadonlyArray<MicrosoftEmulatorCalendar>\n events: ReadonlyArray<MicrosoftEmulatorEvent>\n drive: MicrosoftEmulatorDrive\n driveItems: ReadonlyArray<MicrosoftEmulatorDriveItem>\n counters: typeof Counters.Type\n}\n\n/** A seeded message: `id`, `parentFolderId`, and `subject` are required. */\nexport const MicrosoftEmulatorMessageSeed = Schema.Struct(\n Struct.mapOmit(messageFields, ['id', 'parentFolderId', 'subject'], Schema.optionalKey)\n)\n\nexport type MicrosoftEmulatorMessageSeed = typeof MicrosoftEmulatorMessageSeed.Type\n\n/** A seeded attachment: `id`, `messageId`, and `name` are required. */\nexport const MicrosoftEmulatorAttachmentSeed = Schema.Struct(\n Struct.mapOmit(attachmentFields, ['id', 'messageId', 'name'], Schema.optionalKey)\n)\n\nexport type MicrosoftEmulatorAttachmentSeed = typeof MicrosoftEmulatorAttachmentSeed.Type\n\n/**\n * A seeded event: `id`, `calendarId`, `subject`, `start`, and `end` are required. `start` and\n * `end` are UTC: either an ISO instant ending in `Z` or a seven-digit local date-time.\n */\nexport const MicrosoftEmulatorEventSeed = Schema.Struct({\n ...Struct.mapOmit(\n eventFields,\n ['id', 'calendarId', 'subject', 'start', 'end'],\n Schema.optionalKey\n ),\n start: Schema.String,\n end: Schema.String\n})\n\nexport type MicrosoftEmulatorEventSeed = typeof MicrosoftEmulatorEventSeed.Type\n\n/** A seeded drive item: `id`, `parentId`, `name`, and `kind` are required. */\nexport const MicrosoftEmulatorDriveItemSeed = Schema.Struct(\n Struct.mapOmit(driveItemFields, ['id', 'parentId', 'name', 'kind'], Schema.optionalKey)\n)\n\nexport type MicrosoftEmulatorDriveItemSeed = typeof MicrosoftEmulatorDriveItemSeed.Type\n\n/** Account-variance profiles for the default seed. */\nexport const MicrosoftEmulatorProfile = Schema.Literals(['default', 'empty'])\n\nexport type MicrosoftEmulatorProfile = typeof MicrosoftEmulatorProfile.Type\n\n/**\n * A typed seed. Start from `profile` (default `'default'`, the fixture entities); every other\n * key, when given, replaces that part of the profile.\n */\nexport const MicrosoftEmulatorSeed = Schema.Struct({\n profile: Schema.optionalKey(MicrosoftEmulatorProfile),\n user: Schema.optionalKey(MicrosoftEmulatorUser),\n mailFolders: Schema.optionalKey(Schema.Array(MicrosoftEmulatorMailFolder)),\n messages: Schema.optionalKey(Schema.Array(MicrosoftEmulatorMessageSeed)),\n attachments: Schema.optionalKey(Schema.Array(MicrosoftEmulatorAttachmentSeed)),\n calendars: Schema.optionalKey(Schema.Array(MicrosoftEmulatorCalendar)),\n events: Schema.optionalKey(Schema.Array(MicrosoftEmulatorEventSeed)),\n drive: Schema.optionalKey(MicrosoftEmulatorDrive),\n driveItems: Schema.optionalKey(Schema.Array(MicrosoftEmulatorDriveItemSeed))\n})\n\nexport type MicrosoftEmulatorSeed = typeof MicrosoftEmulatorSeed.Type\n\nconst strict = { onExcessProperty: 'error' } as const\n\nconst decodeSeedInput = Schema.decodeUnknownResult(MicrosoftEmulatorSeed, strict)\n\nconst decodeStateInput = Schema.decodeUnknownResult(MicrosoftEmulatorStateSchema, strict)\n\nconst issueMessage = (issue: Schema.SchemaError['issue']): string =>\n new Schema.SchemaError(issue).message\n\n// Instants: 100-nanosecond ticks since the epoch (BigInt, so seven fractional digits stay exact).\n\nconst ticksPerMilli = BigInt(10_000)\n\nconst ticksPerSecond = BigInt(10_000_000)\n\nconst instantPattern =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,7}))?(Z|[+-]\\d{2}:\\d{2})?$/\n\n/**\n * Ticks of an ISO-8601 date-time. `zone` `'required'` needs `Z` or an offset; `'forbidden'`\n * needs none (a Graph local date-time, read as UTC); `'optional'` reads a missing one as UTC.\n */\nexport const parseInstant = (\n value: string,\n zone: 'required' | 'forbidden' | 'optional'\n): bigint | undefined => {\n const match = instantPattern.exec(value)\n\n if (match === null) return undefined\n\n const [, year, month, day, hour, minute, second, fraction = '', offset] = match\n\n if (\n (zone === 'required' && offset === undefined) ||\n (zone === 'forbidden' && offset !== undefined)\n ) {\n return undefined\n }\n\n const wholeMillis = Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second)\n )\n\n const check = new Date(wholeMillis)\n\n // Reject rollovers such as 2026-02-30 or 25:00.\n if (\n !Number.isFinite(wholeMillis) ||\n check.getUTCFullYear() !== Number(year) ||\n check.getUTCMonth() !== Number(month) - 1 ||\n check.getUTCDate() !== Number(day) ||\n check.getUTCHours() !== Number(hour) ||\n check.getUTCMinutes() !== Number(minute)\n ) {\n return undefined\n }\n\n const offsetMinutes =\n offset === undefined || offset === 'Z'\n ? 0\n : (offset.startsWith('-') ? -1 : 1) *\n (Number(offset.slice(1, 3)) * 60 + Number(offset.slice(4, 6)))\n\n return (\n BigInt(wholeMillis - offsetMinutes * 60_000) * ticksPerMilli + BigInt(fraction.padEnd(7, '0'))\n )\n}\n\nconst pad = (value: number, width: number): string => String(value).padStart(width, '0')\n\n/** A UTC local date-time with `digits` fractional digits (Graph uses seven). */\nexport const formatLocalDateTime = (ticks: bigint, digits: number): string => {\n const millis = Number(ticks / ticksPerMilli)\n const date = new Date(millis)\n const fraction = pad(Number(((ticks % ticksPerSecond) + ticksPerSecond) % ticksPerSecond), 7)\n\n const whole = `${pad(date.getUTCFullYear(), 4)}-${pad(date.getUTCMonth() + 1, 2)}-${pad(\n date.getUTCDate(),\n 2\n )}T${pad(date.getUTCHours(), 2)}:${pad(date.getUTCMinutes(), 2)}:${pad(date.getUTCSeconds(), 2)}`\n\n return digits === 0 ? whole : `${whole}.${fraction.slice(0, digits)}`\n}\n\n// Default entities. Fixture-derived: the mailbox, the calendar and its two events, the attachment\n// message's two attachments, the paging folder's three messages, the Drafts and Deleted Items\n// folder ids, the drive, the `Conformance` parent folder with its existing file, and the copy\n// source file. Synthesized: the user id, the Inbox folder, the attachment message's own fields,\n// the drive root, the `Sources` folder, and every default the `*FromSeed` builders fill in.\n\nconst ada: MicrosoftEmulatorUser = {\n id: '00000000-0000-4000-8000-00000000ada1',\n displayName: 'Ada Example',\n mail: 'ada@example.test',\n userPrincipalName: 'ada@example.test'\n}\n\nconst grace: MicrosoftEmulatorRecipient = { name: 'Grace Example', address: 'grace@example.test' }\n\nconst adaRecipient: MicrosoftEmulatorRecipient = {\n name: 'Ada Example',\n address: 'ada@example.test'\n}\n\nconst inboxId = 'AAMkAGI2-synthetic-inbox-folder='\n\nconst pagingFolderId = 'AAMkAGI2-synthetic-folder-0001='\n\nconst defaultMailFolders: ReadonlyArray<MicrosoftEmulatorMailFolder> = [\n { id: inboxId, displayName: 'Inbox', wellKnownName: 'inbox' },\n { id: 'AAMkAGI2-synthetic-drafts-folder=', displayName: 'Drafts', wellKnownName: 'drafts' },\n {\n id: 'AAMkAGI2-synthetic-deleteditems-folder=',\n displayName: 'Deleted Items',\n wellKnownName: 'deleteditems'\n },\n { id: pagingFolderId, displayName: 'Synthetic updates', wellKnownName: null }\n]\n\nconst pagingMessage = (number: number, hour: number): MicrosoftEmulatorMessageSeed => {\n const id = `AAMkAGI2-synthetic-message-${pad(number, 4)}=`\n const at = `2026-09-22T${pad(hour, 2)}:00:00Z`\n\n return {\n id,\n parentFolderId: pagingFolderId,\n subject: `Synthetic update ${number - 100}`,\n bodyContent: 'Synthetic message body.',\n from: grace,\n sender: grace,\n toRecipients: [adaRecipient],\n isRead: true,\n isDraft: false,\n receivedDateTime: at,\n sentDateTime: at,\n createdDateTime: at,\n lastModifiedDateTime: at,\n conversationId: `AAQkAGI2-synthetic-conversation-${pad(number, 4)}=`,\n internetMessageId: `<synthetic-${pad(number, 4)}@example.test>`,\n changeKey: `CQAAABYAAAAsynthetic${pad(number, 4)}`\n }\n}\n\nconst attachmentMessageId = 'AAMkAGI2-synthetic-message-0001='\n\nconst defaultMessages: ReadonlyArray<MicrosoftEmulatorMessageSeed> = [\n {\n id: attachmentMessageId,\n parentFolderId: inboxId,\n subject: 'Synthetic message with attachments',\n bodyContentType: 'html',\n bodyContent: '<p>Synthetic body <img src=\"cid:image001.png@01DD2E00.00000000\"></p>',\n from: grace,\n sender: grace,\n toRecipients: [adaRecipient],\n isRead: false,\n isDraft: false,\n // Synthesized (no fixture lists this message): it has a regular (non-inline) attachment.\n hasAttachments: true,\n receivedDateTime: '2026-09-22T08:15:00Z',\n sentDateTime: '2026-09-22T08:15:00Z',\n createdDateTime: '2026-09-22T08:15:00Z',\n lastModifiedDateTime: '2026-09-22T08:15:00Z',\n conversationId: 'AAQkAGI2-synthetic-conversation-0001=',\n internetMessageId: '<synthetic-0001@example.test>',\n changeKey: 'CQAAABYAAAAsynthetic0001'\n },\n pagingMessage(101, 9),\n pagingMessage(102, 8),\n pagingMessage(103, 7)\n]\n\nconst defaultAttachments: ReadonlyArray<MicrosoftEmulatorAttachmentSeed> = [\n {\n id: 'AAMkAGI2-synthetic-attachment-0001=',\n messageId: attachmentMessageId,\n name: 'image001.png',\n contentType: 'image/png',\n size: 1024,\n isInline: true,\n contentId: 'image001.png@01DD2E00.00000000',\n contentBytes: 'iVBORw0KGgo=',\n lastModifiedDateTime: '2026-09-22T08:15:00Z'\n },\n {\n id: 'AAMkAGI2-synthetic-attachment-0002=',\n messageId: attachmentMessageId,\n name: 'synthetic-report.pdf',\n contentType: 'application/pdf',\n size: 2048,\n isInline: false,\n contentId: null,\n contentBytes: 'JVBERi0xLjQK',\n lastModifiedDateTime: '2026-09-22T08:15:00Z'\n }\n]\n\nconst calendarId = 'AAMkAGI2-synthetic-calendar-0001='\n\nconst defaultCalendars: ReadonlyArray<MicrosoftEmulatorCalendar> = [\n { id: calendarId, name: 'Calendar' }\n]\n\nconst defaultEvents: ReadonlyArray<MicrosoftEmulatorEventSeed> = [\n {\n id: 'AAMkAGI2-synthetic-event-0001=',\n calendarId,\n subject: 'Synthetic planning session',\n start: '2026-09-23T12:00:00Z',\n end: '2026-09-23T13:00:00Z',\n changeKey: 'DwAAABYAAAAsynthetic0001'\n },\n {\n id: 'AAMkAGI2-synthetic-event-0002=',\n calendarId,\n subject: 'Synthetic review',\n start: '2026-09-24T08:30:00Z',\n end: '2026-09-24T09:00:00Z',\n changeKey: 'DwAAABYAAAAsynthetic0002'\n }\n]\n\nconst defaultDrive: MicrosoftEmulatorDrive = {\n id: 'b!synthetic-drive-0001',\n driveType: 'business',\n rootId: '01SYNTHETICROOTFOLDER00000000001'\n}\n\nconst quickXorHash = 'AAAAAAAAAAAAAAAAAAAAAAAAAAA='\n\nconst conformanceFolderId = '01SYNTHETICPARENTFOLDER0000000001'\n\nconst sourcesFolderId = '01SYNTHETICSOURCEPARENT000000001'\n\nconst rootItem: MicrosoftEmulatorDriveItemSeed = {\n id: defaultDrive.rootId,\n parentId: null,\n name: 'root',\n kind: 'folder'\n}\n\nconst defaultDriveItems: ReadonlyArray<MicrosoftEmulatorDriveItemSeed> = [\n rootItem,\n { id: conformanceFolderId, parentId: defaultDrive.rootId, name: 'Conformance', kind: 'folder' },\n {\n id: '01SYNTHETICEXISTINGFILE000000001',\n parentId: conformanceFolderId,\n name: 'synthetic-existing.txt',\n kind: 'file',\n size: 12,\n mimeType: 'text/plain',\n quickXorHash\n },\n { id: sourcesFolderId, parentId: defaultDrive.rootId, name: 'Sources', kind: 'folder' },\n {\n id: '01SYNTHETICSOURCEFILE00000000001',\n parentId: sourcesFolderId,\n name: 'synthetic-notes.txt',\n kind: 'file',\n size: 24,\n mimeType: 'text/plain',\n quickXorHash\n }\n]\n\ntype ProfileEntities = {\n readonly user: MicrosoftEmulatorUser\n readonly mailFolders: ReadonlyArray<MicrosoftEmulatorMailFolder>\n readonly messages: ReadonlyArray<MicrosoftEmulatorMessageSeed>\n readonly attachments: ReadonlyArray<MicrosoftEmulatorAttachmentSeed>\n readonly calendars: ReadonlyArray<MicrosoftEmulatorCalendar>\n readonly events: ReadonlyArray<MicrosoftEmulatorEventSeed>\n readonly drive: MicrosoftEmulatorDrive\n readonly driveItems: ReadonlyArray<MicrosoftEmulatorDriveItemSeed>\n}\n\nconst profileEntities = (profile: MicrosoftEmulatorProfile): ProfileEntities => {\n switch (profile) {\n case 'default':\n return {\n user: ada,\n mailFolders: defaultMailFolders,\n messages: defaultMessages,\n attachments: defaultAttachments,\n calendars: defaultCalendars,\n events: defaultEvents,\n drive: defaultDrive,\n driveItems: defaultDriveItems\n }\n case 'empty':\n return {\n user: ada,\n mailFolders: defaultMailFolders.filter(folder => folder.wellKnownName !== null),\n messages: [],\n attachments: [],\n calendars: defaultCalendars,\n events: [],\n drive: defaultDrive,\n driveItems: [rootItem]\n }\n }\n}\n\nconst defaultTimestamp = '2026-09-29T10:00:00Z'\n\nconst messageFromSeed = (\n seed: MicrosoftEmulatorMessageSeed,\n user: MicrosoftEmulatorUser\n): MicrosoftEmulatorMessage => {\n const owner: MicrosoftEmulatorRecipient = { name: user.displayName, address: user.mail }\n const created = seed.createdDateTime ?? defaultTimestamp\n\n return {\n id: seed.id,\n parentFolderId: seed.parentFolderId,\n subject: seed.subject,\n bodyContentType: seed.bodyContentType ?? 'text',\n bodyContent: seed.bodyContent ?? '',\n from: seed.from === undefined ? owner : seed.from,\n sender: seed.sender === undefined ? owner : seed.sender,\n toRecipients: seed.toRecipients ?? [],\n ccRecipients: seed.ccRecipients ?? [],\n bccRecipients: seed.bccRecipients ?? [],\n replyTo: seed.replyTo ?? [],\n isRead: seed.isRead ?? true,\n isDraft: seed.isDraft ?? false,\n importance: seed.importance ?? 'normal',\n flagStatus: seed.flagStatus ?? 'notFlagged',\n categories: seed.categories ?? [],\n hasAttachments: seed.hasAttachments ?? false,\n createdDateTime: created,\n lastModifiedDateTime: seed.lastModifiedDateTime ?? created,\n receivedDateTime: seed.receivedDateTime ?? created,\n sentDateTime: seed.sentDateTime ?? created,\n conversationId: seed.conversationId ?? `AAQkAGI2-synthetic-conversation-${seed.id}`,\n internetMessageId: seed.internetMessageId ?? `<${seed.id}@example.test>`,\n changeKey: seed.changeKey ?? 'CQAAABYAAAAsynthetic0000'\n }\n}\n\n/** Decoded size of a base64 string (no validation beyond the padding count). */\nconst base64Size = (value: string): number =>\n Math.max(0, Math.floor((value.length * 3) / 4) - (value.match(/=+$/)?.[0].length ?? 0))\n\nconst attachmentFromSeed = (seed: MicrosoftEmulatorAttachmentSeed): MicrosoftEmulatorAttachment => {\n const contentBytes = seed.contentBytes ?? ''\n\n return {\n id: seed.id,\n messageId: seed.messageId,\n name: seed.name,\n contentType: seed.contentType ?? 'application/octet-stream',\n size: seed.size ?? base64Size(contentBytes),\n isInline: seed.isInline ?? false,\n contentId: seed.contentId ?? null,\n contentLocation: seed.contentLocation ?? null,\n contentBytes,\n lastModifiedDateTime: seed.lastModifiedDateTime ?? defaultTimestamp\n }\n}\n\n/** A seeded start/end as a seven-digit UTC local date-time, or `undefined` when unreadable. */\nconst seedDateTime = (value: string): string | undefined => {\n const ticks = value.endsWith('Z')\n ? parseInstant(value, 'required')\n : parseInstant(value, 'forbidden')\n\n return ticks === undefined ? undefined : formatLocalDateTime(ticks, 7)\n}\n\nconst eventFromSeed = (\n seed: MicrosoftEmulatorEventSeed,\n start: string,\n end: string\n): MicrosoftEmulatorEvent => ({\n id: seed.id,\n calendarId: seed.calendarId,\n subject: seed.subject,\n bodyContentType: seed.bodyContentType ?? 'text',\n bodyContent: seed.bodyContent ?? '',\n start,\n end,\n isCancelled: seed.isCancelled ?? false,\n isReminderOn: seed.isReminderOn ?? false,\n showAs: seed.showAs ?? 'busy',\n changeKey: seed.changeKey ?? 'DwAAABYAAAAsynthetic0000',\n createdDateTime: seed.createdDateTime ?? defaultTimestamp,\n lastModifiedDateTime: seed.lastModifiedDateTime ?? seed.createdDateTime ?? defaultTimestamp\n})\n\nconst driveItemFromSeed = (seed: MicrosoftEmulatorDriveItemSeed): MicrosoftEmulatorDriveItem => ({\n id: seed.id,\n parentId: seed.parentId,\n name: seed.name,\n kind: seed.kind,\n size: seed.kind === 'folder' ? 0 : (seed.size ?? 0),\n mimeType: seed.kind === 'folder' ? null : (seed.mimeType ?? 'application/octet-stream'),\n quickXorHash: seed.kind === 'folder' ? null : (seed.quickXorHash ?? null),\n createdDateTime: seed.createdDateTime ?? defaultTimestamp,\n lastModifiedDateTime: seed.lastModifiedDateTime ?? seed.createdDateTime ?? defaultTimestamp\n})\n\nconst duplicate = (values: ReadonlyArray<string>): string | undefined =>\n values.find((value, index) => values.indexOf(value) !== index)\n\n/** Integrity problems a decoded seed can still have (duplicates, dangling references, cycles). */\nconst seedProblem = (entities: ProfileEntities): string | undefined => {\n const folderIds = entities.mailFolders.map(folder => folder.id)\n const messageIds = entities.messages.map(message => message.id)\n const calendarIds = entities.calendars.map(calendar => calendar.id)\n const itemIds = entities.driveItems.map(item => item.id)\n\n const duplicates: ReadonlyArray<readonly [string, string | undefined]> = [\n ['mail folder id', duplicate(folderIds)],\n [\n 'well-known folder',\n duplicate(entities.mailFolders.flatMap(folder => folder.wellKnownName ?? []))\n ],\n ['message id', duplicate(messageIds)],\n ['attachment id', duplicate(entities.attachments.map(attachment => attachment.id))],\n ['calendar id', duplicate(calendarIds)],\n ['event id', duplicate(entities.events.map(event => event.id))],\n ['drive item id', duplicate(itemIds)]\n ]\n\n for (const [label, value] of duplicates) {\n if (value !== undefined) return `duplicate ${label} ${value}`\n }\n\n for (const wellKnown of ['drafts', 'deleteditems'] as const) {\n if (!entities.mailFolders.some(folder => folder.wellKnownName === wellKnown)) {\n return `the mail folders need a ${wellKnown} folder`\n }\n }\n\n const message = entities.messages.find(candidate => !folderIds.includes(candidate.parentFolderId))\n\n if (message !== undefined) {\n return `message ${message.id} references missing folder ${message.parentFolderId}`\n }\n\n const attachment = entities.attachments.find(\n candidate => !messageIds.includes(candidate.messageId)\n )\n\n if (attachment !== undefined) {\n return `attachment ${attachment.id} references missing message ${attachment.messageId}`\n }\n\n const event = entities.events.find(candidate => !calendarIds.includes(candidate.calendarId))\n\n if (event !== undefined) {\n return `event ${event.id} references missing calendar ${event.calendarId}`\n }\n\n const roots = entities.driveItems.filter(item => item.parentId === null)\n\n if (roots.length !== 1 || roots[0]?.id !== entities.drive.rootId || roots[0].kind !== 'folder') {\n return `the drive items need exactly one root folder with id ${entities.drive.rootId}`\n }\n\n const byId = new Map(entities.driveItems.map(item => [item.id, item]))\n\n for (const item of entities.driveItems) {\n let parentId = item.parentId\n let steps = 0\n\n while (parentId !== null) {\n const parent = byId.get(parentId)\n\n if (parent === undefined || parent.kind !== 'folder') {\n return `drive item ${item.id} has a missing or non-folder parent ${parentId}`\n }\n\n steps += 1\n\n if (steps > entities.driveItems.length) return `drive item ${item.id} is in a parent cycle`\n\n parentId = parent.parentId\n }\n }\n\n return undefined\n}\n\n/** Build the emulator state for a decoded seed; a string is an integrity problem. */\nconst stateFromSeed = (seed: MicrosoftEmulatorSeed): MicrosoftEmulatorState | string => {\n const profile = profileEntities(seed.profile ?? 'default')\n\n const entities: ProfileEntities = {\n user: seed.user ?? profile.user,\n mailFolders: seed.mailFolders ?? profile.mailFolders,\n messages: seed.messages ?? profile.messages,\n attachments: seed.attachments ?? profile.attachments,\n calendars: seed.calendars ?? profile.calendars,\n events: seed.events ?? profile.events,\n drive: seed.drive ?? profile.drive,\n driveItems: seed.driveItems ?? profile.driveItems\n }\n\n const problem = seedProblem(entities)\n\n if (problem !== undefined) return problem\n\n const events: Array<MicrosoftEmulatorEvent> = []\n\n for (const event of entities.events) {\n const start = seedDateTime(event.start)\n const end = seedDateTime(event.end)\n\n if (start === undefined || end === undefined || end < start) {\n return `event ${event.id} needs readable UTC start and end, with end not before start`\n }\n\n events.push(eventFromSeed(event, start, end))\n }\n\n return {\n user: entities.user,\n mailFolders: entities.mailFolders,\n messages: entities.messages.map(message => messageFromSeed(message, entities.user)),\n attachments: entities.attachments.map(attachmentFromSeed),\n calendars: entities.calendars,\n events,\n drive: entities.drive,\n driveItems: entities.driveItems.map(driveItemFromSeed),\n counters: {\n nextEventNumber: 101,\n nextMessageNumber: 1,\n nextChangeKeyNumber: 1001,\n nextItemNumber: 1\n }\n }\n}\n\n/** Decode and build a seed; a string is the reason it is invalid. */\nexport const buildSeedState = (input: unknown): MicrosoftEmulatorState | 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): MicrosoftEmulatorState | 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,168 @@
1
+ import { EmulatorEvidence, EmulatorRouteEvidence, emulatorEvidenceHeader } from "./route-evidence.mjs";
2
+ import { MicrosoftEmulatorAttachment, MicrosoftEmulatorAttachmentSeed, MicrosoftEmulatorCalendar, MicrosoftEmulatorDrive, MicrosoftEmulatorDriveItem, MicrosoftEmulatorDriveItemSeed, MicrosoftEmulatorEvent, MicrosoftEmulatorEventSeed, MicrosoftEmulatorMailFolder, MicrosoftEmulatorMessage, MicrosoftEmulatorMessageSeed, MicrosoftEmulatorProfile, MicrosoftEmulatorRecipient, MicrosoftEmulatorSeed, MicrosoftEmulatorState, MicrosoftEmulatorStateSchema, MicrosoftEmulatorUser } from "./microsoft/state.mjs";
3
+ import { MicrosoftEmulatorDrills, microsoftEmulatorBasePath, microsoftEmulatorErrorCodes } from "./microsoft/graph.mjs";
4
+ import * as Schema from "effect/Schema";
5
+
6
+ //#region src/microsoft.d.ts
7
+ /** Origin the connector calls; also the origin of `@odata.nextLink` values. */
8
+ declare const microsoftEmulatorDefaultOrigin = "https://graph.microsoft.com";
9
+ /**
10
+ * Origin of OneDrive `webUrl` values and copy monitor URLs (the fixtures' synthetic SharePoint
11
+ * host). Route it to the same emulator as the Graph origin.
12
+ */
13
+ declare const microsoftEmulatorDefaultSharePointOrigin = "https://synthetic-my.sharepoint.com";
14
+ /**
15
+ * Route evidence manifest: every emulated route, whether it writes, and the conformance cases
16
+ * whose (currently synthetic, unverified) wire claims it follows. Kept in sync with the handlers
17
+ * by construction (both come from one route table). The monitor route lives on the SharePoint
18
+ * origin; every other route on the Graph origin.
19
+ */
20
+ declare const microsoftEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence>;
21
+ /** Optional fault filter; an omitted field matches every request. `path` ending in `*` is a prefix. */
22
+ declare const MicrosoftFaultMatch: Schema.Struct<{
23
+ readonly method: Schema.optionalKey<Schema.String>;
24
+ readonly path: Schema.optionalKey<Schema.String>;
25
+ }>;
26
+ type MicrosoftFaultMatch = typeof MicrosoftFaultMatch.Type;
27
+ /**
28
+ * A wire fault: answer matching requests with this status, headers, and body (for example 429
29
+ * with `retry-after`) instead of the route's successful answer, so nothing is written. A request
30
+ * the route refuses is answered by the route and uses up no fault. The body defaults to a Graph
31
+ * error envelope. `count` limits how many requests it answers (omitted: all). `match.path` is
32
+ * the raw request path (`/v1.0/users/ada%40example.test/...`).
33
+ *
34
+ * The shared emulator rules apply: statuses that cannot carry a body (1xx, 204, 205) and
35
+ * redirects (3xx) are rejected, as are invalid header names or values, a `location` header, and
36
+ * framing headers (`content-length`, `transfer-encoding`, `connection`, `keep-alive`, `upgrade`).
37
+ */
38
+ declare const MicrosoftFault: Schema.Struct<{
39
+ readonly kind: Schema.Literal<"status">;
40
+ readonly status: Schema.Int;
41
+ readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
42
+ readonly body: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
43
+ readonly match: Schema.optionalKey<Schema.Struct<{
44
+ readonly method: Schema.optionalKey<Schema.String>;
45
+ readonly path: Schema.optionalKey<Schema.String>;
46
+ }>>;
47
+ readonly count: Schema.optionalKey<Schema.Int>;
48
+ }>;
49
+ type MicrosoftFault = typeof MicrosoftFault.Type;
50
+ declare const MicrosoftEmulatorInputInvalid_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 & {
51
+ readonly _tag: "MicrosoftEmulatorInputInvalid";
52
+ } & Readonly<A>;
53
+ /** Invalid emulator input from the JS API: a seed, a fault, or an option. A programmer error. */
54
+ declare class MicrosoftEmulatorInputInvalid extends MicrosoftEmulatorInputInvalid_base<{
55
+ readonly input: 'seed' | 'fault' | 'option';
56
+ readonly reason: string;
57
+ }> {
58
+ get message(): string;
59
+ }
60
+ type MicrosoftLedgerEntry = {
61
+ /** 1-based arrival order since the last ledger clear or reset. */readonly seq: number;
62
+ readonly method: string; /** Raw request path, for example `/v1.0/users/ada%40example.test/messages`. */
63
+ readonly path: string; /** Path template of the matched route, for example `/v1.0/users/{userId}/messages`. */
64
+ readonly route?: string; /** Query parameters; the values of credential-named keys (`access_token`) are `<redacted>`. */
65
+ readonly query: Readonly<Record<string, string>>;
66
+ /**
67
+ * Parsed JSON request body, when there was one, with every credential-named key's value
68
+ * (for example a `$batch` subrequest's `Authorization` header) replaced by `<redacted>`.
69
+ */
70
+ readonly body?: Schema.Json; /** The `Prefer` header, when sent (never a credential). */
71
+ readonly prefer?: string;
72
+ readonly status: number; /** Evidence of the matched route; `unknown-route` for requests that failed closed. */
73
+ readonly evidence: EmulatorEvidence | 'unknown-route'; /** Set when a fault answered the request. */
74
+ readonly fault?: 'status';
75
+ /**
76
+ * Set when the emulator could not build or produce the response, or a route handler threw; the
77
+ * request was answered with a 500 Graph error envelope (still evidence-tagged) and no fault was
78
+ * used up.
79
+ */
80
+ readonly responseError?: string;
81
+ };
82
+ type MicrosoftFaultState = {
83
+ readonly id: number;
84
+ readonly fault: MicrosoftFault; /** Remaining matching requests; `undefined` for an unlimited fault. */
85
+ readonly remaining: number | undefined;
86
+ readonly applied: number;
87
+ };
88
+ type MicrosoftRouteCoverage = EmulatorRouteEvidence & {
89
+ /** Ledger requests answered by this route since the last ledger clear or reset. */readonly requests: number;
90
+ };
91
+ type MicrosoftCoverage = {
92
+ readonly routes: ReadonlyArray<MicrosoftRouteCoverage>; /** Ledger requests to unknown routes (failed closed). */
93
+ readonly unknownRouteRequests: number;
94
+ };
95
+ /** A copy monitor as reported by `/_emulate/state` and `monitors()`. */
96
+ type MicrosoftCopyMonitorState = {
97
+ readonly id: string;
98
+ readonly sourceId: string;
99
+ readonly destinationParentId: string;
100
+ readonly pollsLeft: number;
101
+ readonly status: 'inProgress' | 'completed';
102
+ readonly resourceId?: string;
103
+ };
104
+ type MicrosoftEmulatorOptions = {
105
+ /** Typed seed; defaults to the fixture entities (`profile: 'default'`). */readonly seed?: MicrosoftEmulatorSeed; /** Clock in epoch milliseconds. Defaults to `Date.now`. */
106
+ readonly now?: () => number; /** Origin of `@odata.nextLink` values. Defaults to `https://graph.microsoft.com`. */
107
+ readonly baseUrl?: string; /** Origin of `webUrl` values and monitor URLs. Defaults to `https://synthetic-my.sharepoint.com`. */
108
+ readonly sharePointOrigin?: string;
109
+ /**
110
+ * In-progress monitor answers before a copy completes (integer 0-100, default 0: the first poll
111
+ * completes, as the copy fixture records).
112
+ */
113
+ readonly copyInProgressPolls?: number;
114
+ /**
115
+ * How long (ms, integer 0-10000, default 25) the first committed message write holds its
116
+ * message (a refused or faulted write holds nothing); an overlapping write to that message gets
117
+ * 409. Non-overlapping writes both apply (an emulator extrapolation). `0` only rejects writes
118
+ * that overlap the handler itself.
119
+ */
120
+ readonly conflictWindowMs?: number; /** Drill knobs (tests only): make the emulator disagree with one conformance claim. */
121
+ readonly drills?: MicrosoftEmulatorDrills;
122
+ };
123
+ type MicrosoftEmulator = {
124
+ /** The fetch handler (Graph routes, the copy monitor, and `/_emulate/*`). Never rejects. */readonly fetch: (request: Request) => Promise<Response>; /** Origin of `@odata.nextLink` values. */
125
+ readonly baseUrl: string; /** Origin of `webUrl` values and monitor URLs; route it to this emulator too. */
126
+ readonly sharePointOrigin: string;
127
+ readonly ledger: {
128
+ readonly entries: () => ReadonlyArray<MicrosoftLedgerEntry>;
129
+ readonly clear: () => void;
130
+ };
131
+ readonly faults: {
132
+ /** Add a fault; throws `MicrosoftEmulatorInputInvalid` for an invalid fault. */readonly add: (fault: MicrosoftFault) => MicrosoftFaultState;
133
+ readonly list: () => ReadonlyArray<MicrosoftFaultState>;
134
+ readonly clear: () => void;
135
+ }; /** The copy monitors created since the last reset or seed. */
136
+ readonly monitors: () => ReadonlyArray<MicrosoftCopyMonitorState>; /** Restore the current seed and clear the ledger, faults, and copy monitors. */
137
+ readonly reset: () => Promise<void>;
138
+ /**
139
+ * Replace the state with a new seed, which becomes what `reset` restores (monitors are
140
+ * cleared). Rejects with `MicrosoftEmulatorInputInvalid` for an invalid seed.
141
+ */
142
+ readonly seed: (seed: MicrosoftEmulatorSeed) => Promise<void>; /** A deep copy of the current state (entities and counters). */
143
+ readonly snapshot: () => MicrosoftEmulatorState;
144
+ readonly coverage: () => MicrosoftCoverage; /** Close the core runtime. Later requests answer 503. Idempotent. */
145
+ readonly close: () => Promise<void>;
146
+ };
147
+ /**
148
+ * Create a stateful Microsoft Graph emulator on the `@emulators/core` custom runtime. Each call
149
+ * has its own state, ledger, faults, and copy monitors. Rejects with
150
+ * `MicrosoftEmulatorInputInvalid` for an invalid seed or option.
151
+ *
152
+ * Graph routes need `Authorization: Bearer <non-empty>` (missing: 401 Graph error envelope); the
153
+ * token is never checked, stored, forwarded to the core, or ledgered. The copy monitor needs no
154
+ * credential. Precedence per request: route match (unknown routes fail closed with a 404 Graph
155
+ * error envelope), authorization, JSON body parsing, then the stateful route's plan (its query
156
+ * allowlist and `If-Match` refusal, then its handler on drafts of the state and copy monitors),
157
+ * then the first matching fault, then the commit. A request the route refuses (any answer that is
158
+ * not 2xx, such as a 404 for an unknown id, a 400 not emulated, or a 409 conflict) uses up no
159
+ * fault; a faulted request writes nothing and holds no message. A handler that throws answers a 500
160
+ * Graph error envelope with `responseError` in the ledger, even when the clock throws; unknown
161
+ * routes (404) and a closed emulator (503) keep their status when the clock throws too. Every
162
+ * response from an unverified route carries `x-emulator-evidence: unverified`. Ledgered bodies and
163
+ * query parameters have credential-named keys redacted.
164
+ */
165
+ declare const makeMicrosoftEmulator: (options?: MicrosoftEmulatorOptions) => Promise<MicrosoftEmulator>;
166
+ //#endregion
167
+ export { type EmulatorEvidence, type EmulatorRouteEvidence, MicrosoftCopyMonitorState, MicrosoftCoverage, MicrosoftEmulator, MicrosoftEmulatorAttachment, MicrosoftEmulatorAttachmentSeed, MicrosoftEmulatorCalendar, type MicrosoftEmulatorDrills, MicrosoftEmulatorDrive, MicrosoftEmulatorDriveItem, MicrosoftEmulatorDriveItemSeed, MicrosoftEmulatorEvent, MicrosoftEmulatorEventSeed, MicrosoftEmulatorInputInvalid, MicrosoftEmulatorMailFolder, MicrosoftEmulatorMessage, MicrosoftEmulatorMessageSeed, MicrosoftEmulatorOptions, MicrosoftEmulatorProfile, MicrosoftEmulatorRecipient, MicrosoftEmulatorSeed, type MicrosoftEmulatorState, MicrosoftEmulatorStateSchema, MicrosoftEmulatorUser, MicrosoftFault, MicrosoftFaultMatch, MicrosoftFaultState, MicrosoftLedgerEntry, MicrosoftRouteCoverage, emulatorEvidenceHeader, makeMicrosoftEmulator, microsoftEmulatorBasePath, microsoftEmulatorDefaultOrigin, microsoftEmulatorDefaultSharePointOrigin, microsoftEmulatorErrorCodes, microsoftEmulatorRoutes };
168
+ //# sourceMappingURL=microsoft.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft.d.mts","names":[],"sources":["../src/microsoft.ts"],"mappings":";;;;;;;cAmFa,8BAAA;AAA8B;AAM3C;;;AAN2C,cAM9B,wCAAA;AAAwC;AAQrD;;;;AAAyE;AARpB,cAQxC,uBAAA,EAAyB,aAAa,CAAC,qBAAA;;cAOvC,mBAAA,EAAmB,MAAA,CAAA,MAAA;EAAA;;;KAKpB,mBAAA,UAA6B,mBAAA,CAAoB,IAAI;;;;;;;;;;;;cAapD,cAAA,EAAc,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;KASf,cAAA,UAAwB,cAAA,CAAe,IAAI;AAAA,cAAA,kCAAA;;;;cAG1C,6BAAA,SAAsC,kCAAA;EAAA,SAGxC,KAAA;EAAA,SACA,MAAA;AAAA;EAAA,IAEI,OAAA,CAAA;AAAA;AAAA,KAKH,oBAAA;6EAED,GAAA;EAAA,SACA,MAAA;WAEA,IAAA;WAEA,KAAA;WAEA,KAAA,EAAO,QAAA,CAAS,MAAA;EAhCA;;;;EAAA,SAqChB,IAAA,GAAO,MAAA,CAAO,IAAA;WAEd,MAAA;EAAA,SACA,MAAA;WAEA,QAAA,EAAU,gBAAA;WAEV,KAAA;;;;;;WAMA,aAAA;AAAA;AAAA,KAGC,mBAAA;EAAA,SACD,EAAA;EAAA,SACA,KAAA,EAAO,cAAc;WAErB,SAAA;EAAA,SACA,OAAA;AAAA;AAAA,KAGC,sBAAA,GAAyB,qBAAqB;8FAE/C,QAAQ;AAAA;AAAA,KAGP,iBAAA;EAAA,SACD,MAAA,EAAQ,aAAa,CAAC,sBAAA;WAEtB,oBAAA;AAAA;;KAIC,yBAAA;EAAA,SACD,EAAA;EAAA,SACA,QAAA;EAAA,SACA,mBAAA;EAAA,SACA,SAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,wBAAA;sFAED,IAAA,GAAO,qBAAA;WAEP,GAAA;WAEA,OAAA,WA/EC;EAAA,SAiFD,gBAAA;;;AAjF4C;AAAA;WAsF5C,mBAAA;;;;;;;WAOA,gBAAA;WAEA,MAAA,GAAS,uBAAuB;AAAA;AAAA,KAG/B,iBAAA;uGAED,KAAA,GAAQ,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;WAErC,OAAA;WAEA,gBAAA;EAAA,SACA,MAAA;IAAA,SACE,OAAA,QAAe,aAAA,CAAc,oBAAA;IAAA,SAC7B,KAAA;EAAA;EAAA,SAEF,MAAA;6FAEE,GAAA,GAAM,KAAA,EAAO,cAAA,KAAmB,mBAAA;IAAA,SAChC,IAAA,QAAY,aAAA,CAAc,mBAAA;IAAA,SAC1B,KAAA;EAAA,GA9GA;EAAA,SAiHF,QAAA,QAAgB,aAAA,CAAc,yBAAA;WAE9B,KAAA,QAAa,OAAA;EAnH2B;;;;EAAA,SAwHxC,IAAA,GAAO,IAAA,EAAM,qBAAA,KAA0B,OAAA,QAlH5B;EAAA,SAoHX,QAAA,QAAgB,sBAAA;EAAA,SAChB,QAAA,QAAgB,iBAAA;WAEhB,KAAA,QAAa,OAAA;AAAA;;;;;;;;;;;;;;;;;;;cAuKX,qBAAA,GACX,OAAA,GAAS,wBAAA,KACR,OAAA,CAAQ,iBAAA"}