memory.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { CredentialProvider } from '@deepseek-ai/dsh-credentials'
  2. import type {
  3. CredentialInfo,
  4. CredentialKey,
  5. CredentialRecord,
  6. CredentialRecordEntry,
  7. CredentialRecordInfo,
  8. CredentialRef,
  9. ResolvedCredential,
  10. } from '@deepseek-ai/dsh-credentials'
  11. /**
  12. * In-memory credentials provider for the authorization suite. Only the record
  13. * half is exercised — the seam's whole interest in this service is whether a
  14. * flow left a record behind — so the reference half answers "nothing stored".
  15. */
  16. // TODO: near-duplicate of the record half of
  17. // packages/credentials/credentials/tests/memory.ts; fold both into a shared
  18. // test-support double when a third suite needs one.
  19. export class MemoryCredentials extends CredentialProvider {
  20. private readonly records = new Map<CredentialKey, CredentialRecord>()
  21. override resolve(_ref: CredentialRef): Promise<ResolvedCredential | undefined> {
  22. return Promise.resolve(undefined)
  23. }
  24. override describe(_ref: CredentialRef): Promise<CredentialInfo> {
  25. return Promise.resolve({ configured: false, writable: true })
  26. }
  27. override set(_ref: CredentialRef, _value: string): Promise<void> {
  28. return Promise.resolve()
  29. }
  30. override unset(_ref: CredentialRef): Promise<void> {
  31. return Promise.resolve()
  32. }
  33. override readRecord(key: CredentialKey): Promise<CredentialRecord | undefined> {
  34. return Promise.resolve(this.records.get(key))
  35. }
  36. override describeRecord(key: CredentialKey): Promise<CredentialRecordInfo> {
  37. const stored = this.records.get(key)
  38. return Promise.resolve(stored === undefined
  39. ? { configured: false, writable: true }
  40. : { configured: true, kind: stored.kind, writable: true })
  41. }
  42. override listRecords(): Promise<readonly CredentialRecordEntry[]> {
  43. return Promise.resolve([...this.records].map(([key, record]) => ({ key, kind: record.kind })))
  44. }
  45. override async modifyRecord(
  46. key: CredentialKey,
  47. mutate: (current: CredentialRecord | undefined) => Promise<CredentialRecord | undefined>,
  48. ): Promise<CredentialRecord | undefined> {
  49. const current = this.records.get(key)
  50. const next = await mutate(current)
  51. if (next === undefined) return current
  52. this.records.set(key, next)
  53. this.ctx.emit('credentials/record-updated', key)
  54. return next
  55. }
  56. override deleteRecord(key: CredentialKey): Promise<void> {
  57. if (this.records.delete(key)) this.ctx.emit('credentials/record-updated', key)
  58. return Promise.resolve()
  59. }
  60. }