comisai 1.0.11 → 1.0.13

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 (255) hide show
  1. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +1 -0
  2. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +9 -9
  3. package/node_modules/@comis/agent/package.json +1 -1
  4. package/node_modules/@comis/channels/package.json +1 -1
  5. package/node_modules/@comis/cli/package.json +1 -1
  6. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +2 -0
  7. package/node_modules/@comis/core/package.json +1 -1
  8. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +12 -1
  9. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +1 -0
  10. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +1 -0
  11. package/node_modules/@comis/daemon/package.json +1 -1
  12. package/node_modules/@comis/gateway/package.json +1 -1
  13. package/node_modules/@comis/infra/package.json +1 -1
  14. package/node_modules/@comis/memory/package.json +1 -1
  15. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +6 -0
  16. package/node_modules/@comis/scheduler/dist/cron/cron-types.js +2 -0
  17. package/node_modules/@comis/scheduler/package.json +1 -1
  18. package/node_modules/@comis/shared/package.json +1 -1
  19. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  20. package/node_modules/@comis/skills/package.json +1 -1
  21. package/package.json +18 -18
  22. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  24. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  26. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  28. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  30. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  32. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  34. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  36. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  38. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  40. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  42. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  44. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  46. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  48. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  50. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  52. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  54. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  58. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  60. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  62. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  64. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  66. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  68. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  70. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  72. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  74. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  76. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  78. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  80. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  82. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  84. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  86. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  88. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  90. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  92. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  94. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  96. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  98. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  100. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  102. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  104. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  106. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  108. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  110. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  112. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  114. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  116. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  118. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  120. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  122. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  124. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  126. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  128. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  130. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  132. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  134. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  136. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  138. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  140. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  142. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  144. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  146. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  148. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  150. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  152. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  154. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  156. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  158. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  160. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  162. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  164. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  166. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  168. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  170. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  172. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  174. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  176. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  177. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  178. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  180. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  181. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  182. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  183. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  184. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  186. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  188. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  190. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  191. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  192. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  193. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  194. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  196. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  198. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  200. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  202. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  204. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  206. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  207. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  208. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  210. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  212. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  214. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  215. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  216. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  217. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  218. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  220. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  222. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  224. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  226. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  227. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  228. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  230. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  232. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  234. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  236. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  237. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  238. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  240. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  241. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  242. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  243. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  244. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  245. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  246. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  248. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  250. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  252. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  253. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  254. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  255. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1,8 +0,0 @@
1
- /**
2
- * Tests for SqliteSecretStore — SecretStorePort implementation with
3
- * AES-256-GCM encrypted BLOB storage in SQLite.
4
- *
5
- * Uses real crypto (no mocks) and temp files for persistence testing.
6
- * Each test gets a unique temp DB path cleaned up in afterEach.
7
- */
8
- export {};
@@ -1,245 +0,0 @@
1
- /**
2
- * Tests for SqliteSecretStore — SecretStorePort implementation with
3
- * AES-256-GCM encrypted BLOB storage in SQLite.
4
- *
5
- * Uses real crypto (no mocks) and temp files for persistence testing.
6
- * Each test gets a unique temp DB path cleaned up in afterEach.
7
- */
8
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
9
- import Database from "better-sqlite3";
10
- import { randomBytes } from "node:crypto";
11
- import * as fs from "node:fs";
12
- import * as os from "node:os";
13
- import { createSecretsCrypto } from "@comis/core";
14
- import { createSqliteSecretStore } from "./sqlite-secret-store.js";
15
- function makeCrypto() {
16
- return createSecretsCrypto(randomBytes(32));
17
- }
18
- function tempDbPath() {
19
- const dir = os.tmpdir();
20
- const name = `comis-test-secrets-${randomBytes(8).toString("hex")}.db`;
21
- return `${dir}/${name}`;
22
- }
23
- /** Unwrap a Result or fail the test. */
24
- function unwrap(result) {
25
- if (!result.ok) {
26
- throw new Error(`Expected ok result, got error: ${result.error.message}`);
27
- }
28
- return result.value;
29
- }
30
- describe("createSqliteSecretStore", () => {
31
- let dbPath;
32
- let crypto;
33
- beforeEach(() => {
34
- dbPath = tempDbPath();
35
- crypto = makeCrypto();
36
- });
37
- afterEach(() => {
38
- // Clean up temp database files
39
- for (const suffix of ["", "-wal", "-shm"]) {
40
- try {
41
- fs.unlinkSync(dbPath + suffix);
42
- }
43
- catch {
44
- // File may not exist
45
- }
46
- }
47
- });
48
- describe("set + getDecrypted round-trip", () => {
49
- it("stores and retrieves a secret", () => {
50
- const store = createSqliteSecretStore(dbPath, crypto);
51
- const setResult = store.set("API_KEY", "sk-secret-123");
52
- expect(setResult.ok).toBe(true);
53
- const plaintext = unwrap(store.getDecrypted("API_KEY"));
54
- expect(plaintext).toBe("sk-secret-123");
55
- store.close();
56
- });
57
- });
58
- describe("UPSERT behavior", () => {
59
- it("preserves created_at on update, changes updated_at", () => {
60
- const store = createSqliteSecretStore(dbPath, crypto);
61
- store.set("MY_SECRET", "original-value");
62
- // Get metadata before update
63
- const beforeItems = unwrap(store.list());
64
- const beforeMeta = beforeItems.find((m) => m.name === "MY_SECRET");
65
- expect(beforeMeta).toBeDefined();
66
- const createdBefore = beforeMeta.createdAt;
67
- // Small delay to ensure timestamp difference
68
- const now = Date.now();
69
- while (Date.now() === now) {
70
- // busy-wait for at least 1ms
71
- }
72
- store.set("MY_SECRET", "updated-value");
73
- const afterItems = unwrap(store.list());
74
- const afterMeta = afterItems.find((m) => m.name === "MY_SECRET");
75
- expect(afterMeta).toBeDefined();
76
- // created_at preserved
77
- expect(afterMeta.createdAt).toBe(createdBefore);
78
- // updated_at changed
79
- expect(afterMeta.updatedAt).toBeGreaterThanOrEqual(createdBefore);
80
- // Value updated
81
- const plaintext = unwrap(store.getDecrypted("MY_SECRET"));
82
- expect(plaintext).toBe("updated-value");
83
- store.close();
84
- });
85
- });
86
- describe("getDecrypted", () => {
87
- it("returns ok(undefined) for missing secret", () => {
88
- const store = createSqliteSecretStore(dbPath, crypto);
89
- const plaintext = unwrap(store.getDecrypted("NONEXISTENT"));
90
- expect(plaintext).toBeUndefined();
91
- store.close();
92
- });
93
- });
94
- describe("decryptAll", () => {
95
- it("returns all stored secrets as Map", () => {
96
- const store = createSqliteSecretStore(dbPath, crypto);
97
- store.set("KEY_A", "value-a");
98
- store.set("KEY_B", "value-b");
99
- store.set("KEY_C", "value-c");
100
- const map = unwrap(store.decryptAll());
101
- expect(map.size).toBe(3);
102
- expect(map.get("KEY_A")).toBe("value-a");
103
- expect(map.get("KEY_B")).toBe("value-b");
104
- expect(map.get("KEY_C")).toBe("value-c");
105
- store.close();
106
- });
107
- it("returns empty Map on empty store", () => {
108
- const store = createSqliteSecretStore(dbPath, crypto);
109
- const map = unwrap(store.decryptAll());
110
- expect(map.size).toBe(0);
111
- store.close();
112
- });
113
- it("excludes canary from results", () => {
114
- const store = createSqliteSecretStore(dbPath, crypto);
115
- store.set("USER_SECRET", "my-value");
116
- const map = unwrap(store.decryptAll());
117
- // Should only contain user secret, not canary
118
- expect(map.has("__comis_canary__")).toBe(false);
119
- expect(map.size).toBe(1);
120
- expect(map.get("USER_SECRET")).toBe("my-value");
121
- store.close();
122
- });
123
- });
124
- describe("exists", () => {
125
- it("returns true for stored secret, false for missing", () => {
126
- const store = createSqliteSecretStore(dbPath, crypto);
127
- expect(store.exists("ABSENT")).toBe(false);
128
- store.set("PRESENT", "value");
129
- expect(store.exists("PRESENT")).toBe(true);
130
- store.close();
131
- });
132
- });
133
- describe("list", () => {
134
- it("returns metadata without secret values", () => {
135
- const store = createSqliteSecretStore(dbPath, crypto);
136
- store.set("DB_PASSWORD", "secret123", {
137
- provider: "postgres",
138
- description: "Main database password",
139
- });
140
- const items = unwrap(store.list());
141
- expect(items).toHaveLength(1);
142
- const item = items[0];
143
- expect(item.name).toBe("DB_PASSWORD");
144
- expect(item.provider).toBe("postgres");
145
- expect(item.description).toBe("Main database password");
146
- expect(item.usageCount).toBe(0);
147
- expect(item.createdAt).toBeTypeOf("number");
148
- expect(item.updatedAt).toBeTypeOf("number");
149
- // No secret value in metadata
150
- expect(item).not.toHaveProperty("ciphertext");
151
- expect(item).not.toHaveProperty("iv");
152
- expect(item).not.toHaveProperty("authTag");
153
- expect(item).not.toHaveProperty("salt");
154
- expect(item).not.toHaveProperty("plaintext");
155
- store.close();
156
- });
157
- it("excludes canary from list results", () => {
158
- const store = createSqliteSecretStore(dbPath, crypto);
159
- store.set("VISIBLE_SECRET", "hello");
160
- const items = unwrap(store.list());
161
- const names = items.map((i) => i.name);
162
- expect(names).not.toContain("__comis_canary__");
163
- expect(names).toContain("VISIBLE_SECRET");
164
- store.close();
165
- });
166
- });
167
- describe("delete", () => {
168
- it("returns ok(true) for existing secret", () => {
169
- const store = createSqliteSecretStore(dbPath, crypto);
170
- store.set("TO_DELETE", "value");
171
- const deleted = unwrap(store.delete("TO_DELETE"));
172
- expect(deleted).toBe(true);
173
- // Confirm deleted
174
- expect(store.exists("TO_DELETE")).toBe(false);
175
- store.close();
176
- });
177
- it("returns ok(false) for non-existent secret", () => {
178
- const store = createSqliteSecretStore(dbPath, crypto);
179
- const deleted = unwrap(store.delete("DOES_NOT_EXIST"));
180
- expect(deleted).toBe(false);
181
- store.close();
182
- });
183
- });
184
- describe("recordUsage", () => {
185
- it("increments usage_count and updates last_used_at", () => {
186
- const store = createSqliteSecretStore(dbPath, crypto);
187
- store.set("TRACKED", "value");
188
- // Initial state
189
- const beforeItems = unwrap(store.list());
190
- const before = beforeItems.find((m) => m.name === "TRACKED");
191
- expect(before.usageCount).toBe(0);
192
- expect(before.lastUsedAt).toBeUndefined();
193
- // Record usage
194
- store.recordUsage("TRACKED");
195
- const afterItems = unwrap(store.list());
196
- const after = afterItems.find((m) => m.name === "TRACKED");
197
- expect(after.usageCount).toBe(1);
198
- expect(after.lastUsedAt).toBeTypeOf("number");
199
- // Record again
200
- store.recordUsage("TRACKED");
201
- const finalItems = unwrap(store.list());
202
- const final = finalItems.find((m) => m.name === "TRACKED");
203
- expect(final.usageCount).toBe(2);
204
- store.close();
205
- });
206
- });
207
- describe("close", () => {
208
- it("does not throw", () => {
209
- const store = createSqliteSecretStore(dbPath, crypto);
210
- expect(() => store.close()).not.toThrow();
211
- });
212
- });
213
- describe("WAL mode", () => {
214
- it("enables WAL journal mode", () => {
215
- const store = createSqliteSecretStore(dbPath, crypto);
216
- // Open a new connection to verify WAL mode persists
217
- const db = new Database(dbPath);
218
- const row = db.prepare("PRAGMA journal_mode").get();
219
- expect(row.journal_mode).toBe("wal");
220
- db.close();
221
- store.close();
222
- });
223
- });
224
- describe("file permissions", () => {
225
- it("sets 0o600 on secrets.db", () => {
226
- const store = createSqliteSecretStore(dbPath, crypto);
227
- const stat = fs.statSync(dbPath);
228
- // Check file mode (lower 9 bits)
229
- const mode = stat.mode & 0o777;
230
- expect(mode).toBe(0o600);
231
- store.close();
232
- });
233
- });
234
- describe("persistence", () => {
235
- it("survives close and reopen", () => {
236
- const store1 = createSqliteSecretStore(dbPath, crypto);
237
- store1.set("PERSIST_KEY", "persist-value");
238
- store1.close();
239
- const store2 = createSqliteSecretStore(dbPath, crypto);
240
- const plaintext = unwrap(store2.getDecrypted("PERSIST_KEY"));
241
- expect(plaintext).toBe("persist-value");
242
- store2.close();
243
- });
244
- });
245
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,71 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { checkAborted } from "./abort.js";
3
- describe("checkAborted", () => {
4
- it("returns ok when signal is undefined", () => {
5
- const result = checkAborted(undefined);
6
- expect(result.ok).toBe(true);
7
- if (result.ok) {
8
- expect(result.value).toBeUndefined();
9
- }
10
- });
11
- it("returns ok when signal is not aborted", () => {
12
- const controller = new AbortController();
13
- const result = checkAborted(controller.signal);
14
- expect(result.ok).toBe(true);
15
- if (result.ok) {
16
- expect(result.value).toBeUndefined();
17
- }
18
- });
19
- it("returns err when signal is aborted", () => {
20
- const controller = new AbortController();
21
- controller.abort("custom reason");
22
- const result = checkAborted(controller.signal);
23
- expect(result.ok).toBe(false);
24
- if (!result.ok) {
25
- expect(result.error).toBeInstanceOf(Error);
26
- expect(result.error.message).toBe("custom reason");
27
- }
28
- });
29
- it("preserves Error reason directly when signal.reason is an Error", () => {
30
- const controller = new AbortController();
31
- const originalError = new Error("specific abort reason");
32
- controller.abort(originalError);
33
- const result = checkAborted(controller.signal);
34
- expect(result.ok).toBe(false);
35
- if (!result.ok) {
36
- expect(result.error).toBe(originalError);
37
- expect(result.error.message).toBe("specific abort reason");
38
- }
39
- });
40
- it("wraps string reason in Error", () => {
41
- const controller = new AbortController();
42
- controller.abort("string reason");
43
- const result = checkAborted(controller.signal);
44
- expect(result.ok).toBe(false);
45
- if (!result.ok) {
46
- expect(result.error).toBeInstanceOf(Error);
47
- expect(result.error.message).toBe("string reason");
48
- }
49
- });
50
- it("defaults to 'Aborted' when no reason is set", () => {
51
- const controller = new AbortController();
52
- controller.abort();
53
- const result = checkAborted(controller.signal);
54
- expect(result.ok).toBe(false);
55
- if (!result.ok) {
56
- expect(result.error).toBeInstanceOf(Error);
57
- // AbortController.abort() without args sets reason to a DOMException
58
- // in Node.js, but our function handles the general case
59
- expect(result.error.message).toBeTruthy();
60
- }
61
- });
62
- it("returns err immediately for pre-aborted signal (AbortSignal.abort())", () => {
63
- const signal = AbortSignal.abort("pre-aborted");
64
- const result = checkAborted(signal);
65
- expect(result.ok).toBe(false);
66
- if (!result.ok) {
67
- expect(result.error).toBeInstanceOf(Error);
68
- expect(result.error.message).toBe("pre-aborted");
69
- }
70
- });
71
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,178 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { ok, err, tryCatch, fromPromise } from "./result.js";
3
- describe("Result<T, E>", () => {
4
- describe("ok()", () => {
5
- it("returns { ok: true, value: T }", () => {
6
- const result = ok(42);
7
- expect(result).toEqual({ ok: true, value: 42 });
8
- });
9
- it("allows access to .value when narrowed via ok === true", () => {
10
- const result = ok(42);
11
- if (result.ok) {
12
- // TypeScript narrows to { ok: true, value: number }
13
- expect(result.value).toBe(42);
14
- }
15
- else {
16
- throw new Error("Should not reach here");
17
- }
18
- });
19
- it("works with complex types", () => {
20
- const result = ok({ name: "test", count: 3 });
21
- expect(result.ok).toBe(true);
22
- if (result.ok) {
23
- expect(result.value.name).toBe("test");
24
- expect(result.value.count).toBe(3);
25
- }
26
- });
27
- });
28
- describe("err()", () => {
29
- it("returns { ok: false, error: E }", () => {
30
- const error = new Error("fail");
31
- const result = err(error);
32
- expect(result).toEqual({ ok: false, error });
33
- });
34
- it("allows access to .error when narrowed via ok === false", () => {
35
- const result = err(new Error("fail"));
36
- if (!result.ok) {
37
- // TypeScript narrows to { ok: false, error: Error }
38
- expect(result.error.message).toBe("fail");
39
- }
40
- else {
41
- throw new Error("Should not reach here");
42
- }
43
- });
44
- it("works with custom error types", () => {
45
- const result = err({ code: "NOT_FOUND", message: "not found" });
46
- expect(result.ok).toBe(false);
47
- if (!result.ok) {
48
- expect(result.error.code).toBe("NOT_FOUND");
49
- }
50
- });
51
- });
52
- describe("tryCatch()", () => {
53
- it("returns ok(value) when function succeeds", () => {
54
- const result = tryCatch(() => 42);
55
- expect(result).toEqual({ ok: true, value: 42 });
56
- });
57
- it("returns err(Error) when function throws Error", () => {
58
- const result = tryCatch(() => {
59
- throw new Error("boom");
60
- });
61
- expect(result.ok).toBe(false);
62
- if (!result.ok) {
63
- expect(result.error).toBeInstanceOf(Error);
64
- expect(result.error.message).toBe("boom");
65
- }
66
- });
67
- it("wraps non-Error thrown values in Error", () => {
68
- const result = tryCatch(() => {
69
- throw "string error";
70
- });
71
- expect(result.ok).toBe(false);
72
- if (!result.ok) {
73
- expect(result.error).toBeInstanceOf(Error);
74
- expect(result.error.message).toBe("string error");
75
- }
76
- });
77
- it("wraps thrown numbers in Error", () => {
78
- const result = tryCatch(() => {
79
- throw 404;
80
- });
81
- expect(result.ok).toBe(false);
82
- if (!result.ok) {
83
- expect(result.error).toBeInstanceOf(Error);
84
- expect(result.error.message).toBe("404");
85
- }
86
- });
87
- it("handles malicious object with toString() that throws", () => {
88
- const malicious = {
89
- toString() {
90
- throw new Error("toString attack");
91
- },
92
- };
93
- const result = tryCatch(() => {
94
- throw malicious;
95
- });
96
- expect(result.ok).toBe(false);
97
- if (!result.ok) {
98
- expect(result.error).toBeInstanceOf(Error);
99
- expect(result.error.message).toBe("[non-stringifiable value]");
100
- }
101
- });
102
- });
103
- describe("fromPromise()", () => {
104
- it("returns ok(value) when promise resolves", async () => {
105
- const result = await fromPromise(Promise.resolve(42));
106
- expect(result).toEqual({ ok: true, value: 42 });
107
- });
108
- it("returns err(Error) when promise rejects with Error", async () => {
109
- const result = await fromPromise(Promise.reject(new Error("boom")));
110
- expect(result.ok).toBe(false);
111
- if (!result.ok) {
112
- expect(result.error).toBeInstanceOf(Error);
113
- expect(result.error.message).toBe("boom");
114
- }
115
- });
116
- it("wraps non-Error rejection in Error", async () => {
117
- const result = await fromPromise(Promise.reject("string"));
118
- expect(result.ok).toBe(false);
119
- if (!result.ok) {
120
- expect(result.error).toBeInstanceOf(Error);
121
- expect(result.error.message).toBe("string");
122
- }
123
- });
124
- it("wraps null rejection in Error", async () => {
125
- const result = await fromPromise(Promise.reject(null));
126
- expect(result.ok).toBe(false);
127
- if (!result.ok) {
128
- expect(result.error).toBeInstanceOf(Error);
129
- expect(result.error.message).toBe("null");
130
- }
131
- });
132
- it("handles malicious object with toString() that throws", async () => {
133
- const malicious = {
134
- toString() {
135
- throw new Error("toString attack");
136
- },
137
- };
138
- const result = await fromPromise(Promise.reject(malicious));
139
- expect(result.ok).toBe(false);
140
- if (!result.ok) {
141
- expect(result.error).toBeInstanceOf(Error);
142
- expect(result.error.message).toBe("[non-stringifiable value]");
143
- }
144
- });
145
- it("wraps undefined rejection in Error", async () => {
146
- const result = await fromPromise(Promise.reject(undefined));
147
- expect(result.ok).toBe(false);
148
- if (!result.ok) {
149
- expect(result.error).toBeInstanceOf(Error);
150
- expect(result.error.message).toBe("undefined");
151
- }
152
- });
153
- });
154
- describe("tryCatch() - undefined edge cases", () => {
155
- it("wraps thrown undefined in Error", () => {
156
- const result = tryCatch(() => {
157
- throw undefined;
158
- });
159
- expect(result.ok).toBe(false);
160
- if (!result.ok) {
161
- expect(result.error).toBeInstanceOf(Error);
162
- expect(result.error.message).toBe("undefined");
163
- }
164
- });
165
- it("wraps thrown void (undefined) in Error", () => {
166
- // eslint-disable-next-line @typescript-eslint/no-throw-literal
167
- const result = tryCatch(() => {
168
- // This explicitly tests the edge case of a void throw
169
- throw void 0;
170
- });
171
- expect(result.ok).toBe(false);
172
- if (!result.ok) {
173
- expect(result.error).toBeInstanceOf(Error);
174
- expect(result.error.message).toBe("undefined");
175
- }
176
- });
177
- });
178
- });
@@ -1,50 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { suppressError } from "./suppress-error.js";
3
- describe("suppressError()", () => {
4
- it("does not throw when promise rejects", () => {
5
- expect(() => {
6
- suppressError(Promise.reject(new Error("test")), "cleanup");
7
- }).not.toThrow();
8
- });
9
- it("logs the error reason at debug level when no logger provided", async () => {
10
- const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => { });
11
- suppressError(Promise.reject(new Error("test error")), "cleanup task");
12
- // Wait for the microtask queue to flush
13
- await new Promise((resolve) => setTimeout(resolve, 10));
14
- expect(debugSpy).toHaveBeenCalledWith("Suppressed error (cleanup task): test error");
15
- expect(debugSpy).toHaveBeenCalledTimes(1);
16
- debugSpy.mockRestore();
17
- });
18
- it("uses custom logger when provided", async () => {
19
- const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => { });
20
- const customLogger = vi.fn();
21
- suppressError(Promise.reject(new Error("custom error")), "custom task", customLogger);
22
- await new Promise((resolve) => setTimeout(resolve, 10));
23
- expect(customLogger).toHaveBeenCalledTimes(1);
24
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (custom task): custom error");
25
- // console.debug should NOT be called when custom logger is provided
26
- expect(debugSpy).not.toHaveBeenCalled();
27
- debugSpy.mockRestore();
28
- });
29
- it("passes formatted error message string to custom logger", async () => {
30
- const customLogger = vi.fn();
31
- suppressError(Promise.reject(new Error("something broke")), "retry cleanup", customLogger);
32
- await new Promise((resolve) => setTimeout(resolve, 10));
33
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (retry cleanup): something broke");
34
- });
35
- it("handles non-Error rejection with custom logger", async () => {
36
- const customLogger = vi.fn();
37
- suppressError(Promise.reject("plain string rejection"), "string reject", customLogger);
38
- await new Promise((resolve) => setTimeout(resolve, 10));
39
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (string reject): plain string rejection");
40
- });
41
- it("does not cause unhandled rejection", async () => {
42
- const unhandledHandler = vi.fn();
43
- process.on("unhandledRejection", unhandledHandler);
44
- suppressError(Promise.reject(new Error("should be caught")), "test");
45
- // Wait enough for unhandledRejection to fire if it were going to
46
- await new Promise((resolve) => setTimeout(resolve, 50));
47
- expect(unhandledHandler).not.toHaveBeenCalled();
48
- process.removeListener("unhandledRejection", unhandledHandler);
49
- });
50
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,75 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { withTimeout, TimeoutError } from "./timeout.js";
3
- describe("TimeoutError", () => {
4
- it("has name set to 'TimeoutError'", () => {
5
- const error = new TimeoutError(5000);
6
- expect(error.name).toBe("TimeoutError");
7
- });
8
- it("is instanceof Error", () => {
9
- const error = new TimeoutError(5000);
10
- expect(error).toBeInstanceOf(Error);
11
- });
12
- it("has correct timeoutMs property", () => {
13
- const error = new TimeoutError(3000);
14
- expect(error.timeoutMs).toBe(3000);
15
- });
16
- it("formats message with label", () => {
17
- const error = new TimeoutError(5000, "MCP connect");
18
- expect(error.message).toBe("MCP connect timed out after 5000ms");
19
- });
20
- it("formats message without label", () => {
21
- const error = new TimeoutError(5000);
22
- expect(error.message).toBe("Operation timed out after 5000ms");
23
- });
24
- });
25
- describe("withTimeout", () => {
26
- it("resolves when promise completes before timeout", async () => {
27
- const result = await withTimeout(Promise.resolve(42), 1000);
28
- expect(result).toBe(42);
29
- });
30
- it("rejects with TimeoutError when timeout fires first", async () => {
31
- const neverResolves = new Promise(() => { });
32
- await expect(withTimeout(neverResolves, 10, "test op")).rejects.toThrow(TimeoutError);
33
- });
34
- it("TimeoutError has correct timeoutMs on rejection", async () => {
35
- const neverResolves = new Promise(() => { });
36
- try {
37
- await withTimeout(neverResolves, 25, "test op");
38
- throw new Error("Should not reach here");
39
- }
40
- catch (e) {
41
- expect(e).toBeInstanceOf(TimeoutError);
42
- expect(e.timeoutMs).toBe(25);
43
- }
44
- });
45
- it("timer is cleaned up on success", async () => {
46
- vi.useFakeTimers();
47
- try {
48
- const promise = Promise.resolve("ok");
49
- await withTimeout(promise, 60_000);
50
- // After resolution, advancing time should not cause issues
51
- // (timer was cleared, no pending timers)
52
- expect(vi.getTimerCount()).toBe(0);
53
- }
54
- finally {
55
- vi.useRealTimers();
56
- }
57
- });
58
- it("propagates original error when promise rejects before timeout", async () => {
59
- const originalError = new Error("original failure");
60
- const failing = Promise.reject(originalError);
61
- await expect(withTimeout(failing, 5000)).rejects.toThrow("original failure");
62
- await expect(withTimeout(Promise.reject(originalError), 5000)).rejects.not.toBeInstanceOf(TimeoutError);
63
- });
64
- it("no unhandled rejection when original promise rejects after timeout", async () => {
65
- // Create a promise that rejects after a short delay
66
- const delayedReject = new Promise((_resolve, reject) => {
67
- setTimeout(() => reject(new Error("late rejection")), 50);
68
- });
69
- // The timeout fires first (10ms < 50ms)
70
- await expect(withTimeout(delayedReject, 10, "test")).rejects.toThrow(TimeoutError);
71
- // Wait for the delayed rejection to fire -- if unhandled rejection
72
- // suppression is missing, this would crash the test runner
73
- await new Promise((r) => setTimeout(r, 100));
74
- });
75
- });
@@ -1 +0,0 @@
1
- export {};