@atproto/pds 0.5.5 → 0.5.6

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 (147) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/account-manager/account-manager.d.ts +51 -13
  3. package/dist/account-manager/account-manager.d.ts.map +1 -1
  4. package/dist/account-manager/account-manager.js +86 -26
  5. package/dist/account-manager/account-manager.js.map +1 -1
  6. package/dist/account-manager/db/migrations/005-oauth-account-management.d.ts.map +1 -1
  7. package/dist/account-manager/db/migrations/005-oauth-account-management.js +3 -4
  8. package/dist/account-manager/db/migrations/005-oauth-account-management.js.map +1 -1
  9. package/dist/account-manager/db/schema/authorization-request.d.ts +2 -2
  10. package/dist/account-manager/db/schema/authorization-request.d.ts.map +1 -1
  11. package/dist/account-manager/db/schema/authorization-request.js.map +1 -1
  12. package/dist/account-manager/db/schema/authorized-client.d.ts +2 -2
  13. package/dist/account-manager/db/schema/authorized-client.d.ts.map +1 -1
  14. package/dist/account-manager/db/schema/authorized-client.js.map +1 -1
  15. package/dist/account-manager/db/schema/token.d.ts +2 -2
  16. package/dist/account-manager/db/schema/token.d.ts.map +1 -1
  17. package/dist/account-manager/db/schema/token.js.map +1 -1
  18. package/dist/account-manager/helpers/account-device.d.ts +23 -196
  19. package/dist/account-manager/helpers/account-device.d.ts.map +1 -1
  20. package/dist/account-manager/helpers/account-device.js +3 -3
  21. package/dist/account-manager/helpers/account-device.js.map +1 -1
  22. package/dist/account-manager/helpers/account.d.ts +14 -4
  23. package/dist/account-manager/helpers/account.d.ts.map +1 -1
  24. package/dist/account-manager/helpers/account.js +17 -11
  25. package/dist/account-manager/helpers/account.js.map +1 -1
  26. package/dist/account-manager/helpers/auth.js +1 -1
  27. package/dist/account-manager/helpers/auth.js.map +1 -1
  28. package/dist/account-manager/helpers/authorization-request.d.ts +83 -5
  29. package/dist/account-manager/helpers/authorization-request.d.ts.map +1 -1
  30. package/dist/account-manager/helpers/authorization-request.js +8 -8
  31. package/dist/account-manager/helpers/authorization-request.js.map +1 -1
  32. package/dist/account-manager/helpers/authorized-client.d.ts +5 -4
  33. package/dist/account-manager/helpers/authorized-client.d.ts.map +1 -1
  34. package/dist/account-manager/helpers/authorized-client.js +3 -0
  35. package/dist/account-manager/helpers/authorized-client.js.map +1 -1
  36. package/dist/account-manager/helpers/device.d.ts +9 -3
  37. package/dist/account-manager/helpers/device.d.ts.map +1 -1
  38. package/dist/account-manager/helpers/device.js +4 -4
  39. package/dist/account-manager/helpers/device.js.map +1 -1
  40. package/dist/account-manager/helpers/invite.d.ts +35 -2
  41. package/dist/account-manager/helpers/invite.d.ts.map +1 -1
  42. package/dist/account-manager/helpers/lexicon.d.ts.map +1 -1
  43. package/dist/account-manager/helpers/lexicon.js +6 -0
  44. package/dist/account-manager/helpers/lexicon.js.map +1 -1
  45. package/dist/account-manager/helpers/password.d.ts +1 -0
  46. package/dist/account-manager/helpers/password.d.ts.map +1 -1
  47. package/dist/account-manager/helpers/password.js +3 -0
  48. package/dist/account-manager/helpers/password.js.map +1 -1
  49. package/dist/account-manager/helpers/token.d.ts +72 -1031
  50. package/dist/account-manager/helpers/token.d.ts.map +1 -1
  51. package/dist/account-manager/helpers/token.js +13 -10
  52. package/dist/account-manager/helpers/token.js.map +1 -1
  53. package/dist/account-manager/helpers/used-refresh-token.d.ts +6 -2
  54. package/dist/account-manager/helpers/used-refresh-token.d.ts.map +1 -1
  55. package/dist/account-manager/oauth-store.d.ts +17 -13
  56. package/dist/account-manager/oauth-store.d.ts.map +1 -1
  57. package/dist/account-manager/oauth-store.js +89 -39
  58. package/dist/account-manager/oauth-store.js.map +1 -1
  59. package/dist/actor-store/blob/reader.d.ts.map +1 -1
  60. package/dist/actor-store/blob/reader.js +2 -3
  61. package/dist/actor-store/blob/reader.js.map +1 -1
  62. package/dist/actor-store/record/reader.js +3 -3
  63. package/dist/actor-store/record/reader.js.map +1 -1
  64. package/dist/actor-store/repo/sql-repo-reader.d.ts +5 -1
  65. package/dist/actor-store/repo/sql-repo-reader.d.ts.map +1 -1
  66. package/dist/actor-store/repo/sql-repo-reader.js.map +1 -1
  67. package/dist/api/com/atproto/admin/updateSubjectStatus.d.ts.map +1 -1
  68. package/dist/api/com/atproto/admin/updateSubjectStatus.js +12 -4
  69. package/dist/api/com/atproto/admin/updateSubjectStatus.js.map +1 -1
  70. package/dist/api/com/atproto/server/activateAccount.d.ts.map +1 -1
  71. package/dist/api/com/atproto/server/activateAccount.js +25 -31
  72. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  73. package/dist/api/com/atproto/server/deactivateAccount.d.ts.map +1 -1
  74. package/dist/api/com/atproto/server/deactivateAccount.js +3 -4
  75. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  76. package/dist/api/com/atproto/server/deleteAccount.d.ts.map +1 -1
  77. package/dist/api/com/atproto/server/deleteAccount.js +51 -37
  78. package/dist/api/com/atproto/server/deleteAccount.js.map +1 -1
  79. package/dist/api/com/atproto/server/util.d.ts +25 -6
  80. package/dist/api/com/atproto/server/util.d.ts.map +1 -1
  81. package/dist/api/com/atproto/server/util.js.map +1 -1
  82. package/dist/config/config.d.ts +2 -1
  83. package/dist/config/config.d.ts.map +1 -1
  84. package/dist/config/config.js +4 -1
  85. package/dist/config/config.js.map +1 -1
  86. package/dist/context.d.ts.map +1 -1
  87. package/dist/context.js +1 -1
  88. package/dist/context.js.map +1 -1
  89. package/dist/db/migrator.d.ts +4 -3
  90. package/dist/db/migrator.d.ts.map +1 -1
  91. package/dist/db/migrator.js +1 -1
  92. package/dist/db/migrator.js.map +1 -1
  93. package/dist/db/pagination.d.ts +2 -1
  94. package/dist/db/pagination.d.ts.map +1 -1
  95. package/dist/db/pagination.js +2 -2
  96. package/dist/db/pagination.js.map +1 -1
  97. package/dist/db/util.d.ts +3 -3
  98. package/dist/db/util.d.ts.map +1 -1
  99. package/dist/db/util.js.map +1 -1
  100. package/dist/mailer/index.d.ts +2 -0
  101. package/dist/mailer/index.d.ts.map +1 -1
  102. package/dist/mailer/index.js +2 -0
  103. package/dist/mailer/index.js.map +1 -1
  104. package/dist/scripts/sequencer-recovery/recovery-db.js.map +1 -1
  105. package/dist/sequencer/events.d.ts.map +1 -1
  106. package/dist/sequencer/events.js +6 -13
  107. package/dist/sequencer/events.js.map +1 -1
  108. package/dist/sequencer/sequencer.d.ts +1 -1
  109. package/dist/sequencer/sequencer.d.ts.map +1 -1
  110. package/dist/sequencer/sequencer.js.map +1 -1
  111. package/package.json +13 -13
  112. package/src/account-manager/account-manager.ts +135 -36
  113. package/src/account-manager/db/migrations/005-oauth-account-management.ts +6 -5
  114. package/src/account-manager/db/schema/authorization-request.ts +2 -1
  115. package/src/account-manager/db/schema/authorized-client.ts +6 -2
  116. package/src/account-manager/db/schema/token.ts +2 -2
  117. package/src/account-manager/helpers/account-device.ts +5 -11
  118. package/src/account-manager/helpers/account.ts +39 -16
  119. package/src/account-manager/helpers/auth.ts +2 -2
  120. package/src/account-manager/helpers/authorization-request.ts +12 -8
  121. package/src/account-manager/helpers/authorized-client.ts +12 -6
  122. package/src/account-manager/helpers/device.ts +4 -4
  123. package/src/account-manager/helpers/lexicon.ts +8 -3
  124. package/src/account-manager/helpers/password.ts +6 -0
  125. package/src/account-manager/helpers/token.ts +17 -11
  126. package/src/account-manager/oauth-store.ts +129 -61
  127. package/src/actor-store/blob/reader.ts +8 -5
  128. package/src/actor-store/record/reader.ts +3 -3
  129. package/src/actor-store/repo/sql-repo-reader.ts +1 -1
  130. package/src/api/com/atproto/admin/updateSubjectStatus.ts +16 -4
  131. package/src/api/com/atproto/server/activateAccount.ts +27 -49
  132. package/src/api/com/atproto/server/deactivateAccount.ts +3 -7
  133. package/src/api/com/atproto/server/deleteAccount.ts +60 -43
  134. package/src/api/com/atproto/server/util.ts +24 -7
  135. package/src/config/config.ts +7 -2
  136. package/src/context.ts +2 -3
  137. package/src/db/migrator.ts +2 -1
  138. package/src/db/pagination.ts +7 -7
  139. package/src/db/util.ts +5 -2
  140. package/src/mailer/index.ts +4 -2
  141. package/src/scripts/sequencer-recovery/recovery-db.ts +1 -1
  142. package/src/sequencer/events.ts +8 -13
  143. package/src/sequencer/sequencer.ts +1 -3
  144. package/tests/account-manager.test.ts +79 -0
  145. package/tests/account-status.test.ts +206 -0
  146. package/tests/db.test.ts +3 -3
  147. package/tests/oauth.test.ts +91 -0
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport * as plc from '@did-plc/lib'\nimport express from 'express'\nimport { Redis } from 'ioredis'\nimport * as nodemailer from 'nodemailer'\nimport * as ui8 from 'uint8arrays'\nimport * as undici from 'undici'\nimport { KmsKeypair, S3BlobStore } from '@atproto/aws'\nimport * as crypto from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport {\n AccessTokenMode,\n JoseKey,\n LexResolver,\n OAuthProvider,\n OAuthVerifier,\n} from '@atproto/oauth-provider'\nimport { BlobStore } from '@atproto/repo'\nimport {\n createServiceAuthHeaders,\n createServiceJwt,\n} from '@atproto/xrpc-server'\nimport {\n Fetch,\n isUnicastIp,\n safeFetchWrap,\n unicastLookup,\n} from '@atproto-labs/fetch-node'\nimport { AccountManager } from './account-manager/account-manager.js'\nimport { OAuthStore } from './account-manager/oauth-store.js'\nimport { ScopeReferenceGetter } from './account-manager/scope-reference-getter.js'\nimport { ActorStore } from './actor-store/actor-store.js'\nimport { authPassthru, forwardedFor } from './api/proxy.js'\nimport {\n AuthVerifier,\n createPublicKeyObject,\n createSecretKeyObject,\n} from './auth-verifier.js'\nimport { BackgroundQueue } from './background.js'\nimport { BskyAppView } from './bsky-app-view.js'\nimport { ServerConfig, ServerSecrets } from './config/index.js'\nimport { Crawlers } from './crawlers.js'\nimport { DidSqliteCache } from './did-cache/index.js'\nimport { DiskBlobStore } from './disk-blobstore.js'\nimport { ImageUrlBuilder } from './image/image-url-builder.js'\nimport { fetchLogger, lexiconResolverLogger, oauthLogger } from './logger.js'\nimport { ServerMailer } from './mailer/index.js'\nimport { ModerationMailer } from './mailer/moderation.js'\nimport { LocalViewer, LocalViewerCreator } from './read-after-write/viewer.js'\nimport { getRedisClient } from './redis.js'\nimport { Sequencer } from './sequencer/index.js'\n\nexport type AppContextOptions = {\n actorStore: ActorStore\n blobstore: (did: string) => BlobStore\n localViewer: LocalViewerCreator\n mailer: ServerMailer\n moderationMailer: ModerationMailer\n didCache: DidSqliteCache\n idResolver: IdResolver\n plcClient: plc.Client\n accountManager: AccountManager\n sequencer: Sequencer\n backgroundQueue: BackgroundQueue\n redisScratch?: Redis\n crawlers: Crawlers\n bskyAppView?: BskyAppView\n moderationClient?: Client\n reportingClient?: Client\n entrywayClient?: Client\n entrywayAdminClient?: Client\n proxyAgent: undici.Dispatcher\n safeFetch: Fetch\n oauthProvider?: OAuthProvider\n authVerifier: AuthVerifier\n plcRotationKey: crypto.Keypair\n cfg: ServerConfig\n}\n\nexport class AppContext {\n public actorStore: ActorStore\n public blobstore: (did: string) => BlobStore\n public localViewer: LocalViewerCreator\n public mailer: ServerMailer\n public moderationMailer: ModerationMailer\n public didCache: DidSqliteCache\n public idResolver: IdResolver\n public plcClient: plc.Client\n public accountManager: AccountManager\n public sequencer: Sequencer\n public backgroundQueue: BackgroundQueue\n public redisScratch?: Redis\n public crawlers: Crawlers\n public bskyAppView?: BskyAppView\n public moderationClient: Client | undefined\n public reportingClient: Client | undefined\n public entrywayClient: Client | undefined\n public entrywayAdminClient: Client | undefined\n public proxyAgent: undici.Dispatcher\n public safeFetch: Fetch\n public authVerifier: AuthVerifier\n public oauthProvider?: OAuthProvider\n public plcRotationKey: crypto.Keypair\n public cfg: ServerConfig\n\n constructor(opts: AppContextOptions) {\n this.actorStore = opts.actorStore\n this.blobstore = opts.blobstore\n this.localViewer = opts.localViewer\n this.mailer = opts.mailer\n this.moderationMailer = opts.moderationMailer\n this.didCache = opts.didCache\n this.idResolver = opts.idResolver\n this.plcClient = opts.plcClient\n this.accountManager = opts.accountManager\n this.sequencer = opts.sequencer\n this.backgroundQueue = opts.backgroundQueue\n this.redisScratch = opts.redisScratch\n this.crawlers = opts.crawlers\n this.bskyAppView = opts.bskyAppView\n this.moderationClient = opts.moderationClient\n this.reportingClient = opts.reportingClient\n this.entrywayClient = opts.entrywayClient\n this.entrywayAdminClient = opts.entrywayAdminClient\n this.proxyAgent = opts.proxyAgent\n this.safeFetch = opts.safeFetch\n this.authVerifier = opts.authVerifier\n this.oauthProvider = opts.oauthProvider\n this.plcRotationKey = opts.plcRotationKey\n this.cfg = opts.cfg\n }\n\n static async fromConfig(\n cfg: ServerConfig,\n secrets: ServerSecrets,\n overrides?: Partial<AppContextOptions>,\n ): Promise<AppContext> {\n const blobstore =\n cfg.blobstore.provider === 's3'\n ? S3BlobStore.creator({\n bucket: cfg.blobstore.bucket,\n region: cfg.blobstore.region,\n endpoint: cfg.blobstore.endpoint,\n forcePathStyle: cfg.blobstore.forcePathStyle,\n credentials: cfg.blobstore.credentials,\n uploadTimeoutMs: cfg.blobstore.uploadTimeoutMs,\n })\n : DiskBlobStore.creator(\n cfg.blobstore.location,\n cfg.blobstore.tempLocation,\n )\n\n const mailTransport =\n cfg.email !== null\n ? nodemailer.createTransport(cfg.email.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const mailer = new ServerMailer(mailTransport, cfg.email, cfg.branding)\n\n const modMailTransport =\n cfg.moderationEmail !== null\n ? nodemailer.createTransport(cfg.moderationEmail.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const moderationMailer = new ModerationMailer(modMailTransport, cfg)\n\n const didCache = new DidSqliteCache(\n cfg.db.didCacheDbLoc,\n cfg.identity.cacheStaleTTL,\n cfg.identity.cacheMaxTTL,\n cfg.db.disableWalAutoCheckpoint,\n )\n await didCache.migrateOrThrow()\n\n const idResolver = new IdResolver({\n plcUrl: cfg.identity.plcUrl,\n didCache,\n timeout: cfg.identity.resolverTimeout,\n backupNameservers: cfg.identity.handleBackupNameservers,\n })\n const plcClient = new plc.Client(cfg.identity.plcUrl)\n\n const backgroundQueue = new BackgroundQueue()\n const crawlers = new Crawlers(\n backgroundQueue,\n cfg.service.hostname,\n cfg.crawlers,\n )\n const sequencer = new Sequencer(\n cfg.db.sequencerDbLoc,\n crawlers,\n undefined,\n cfg.db.disableWalAutoCheckpoint,\n )\n const redisScratch = cfg.redis\n ? getRedisClient(cfg.redis.address, cfg.redis.password)\n : undefined\n\n const bskyAppView = cfg.bskyAppView\n ? new BskyAppView({\n ...cfg.bskyAppView,\n validateResponse: cfg.service.devMode,\n })\n : undefined\n\n const moderationClient = cfg.modService\n ? new Client(\n { service: cfg.modService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const reportingClient = cfg.reportService\n ? new Client(\n { service: cfg.reportService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayClient = cfg.entryway\n ? new Client(\n { service: cfg.entryway.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayAdminClient =\n cfg.entryway && secrets.entrywayAdminToken\n ? new Client(\n { service: cfg.entryway.url },\n {\n headers: {\n authorization: basicAuthHeader(\n 'admin',\n secrets.entrywayAdminToken,\n ),\n },\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n\n const jwtSecretKey = createSecretKeyObject(secrets.jwtSecret)\n const jwtPublicKey = cfg.entryway\n ? createPublicKeyObject(cfg.entryway.jwtPublicKeyHex)\n : null\n\n const imageUrlBuilder = new ImageUrlBuilder(\n cfg.service.hostname,\n bskyAppView,\n )\n\n const actorStore = new ActorStore(cfg.actorStore, {\n blobstore,\n backgroundQueue,\n })\n\n const plcRotationKey =\n secrets.plcRotationKey.provider === 'kms'\n ? await KmsKeypair.load({\n keyId: secrets.plcRotationKey.keyId,\n })\n : await crypto.Secp256k1Keypair.import(\n secrets.plcRotationKey.privateKeyHex,\n )\n\n const accountManager = new AccountManager(\n idResolver,\n jwtSecretKey,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n cfg.service.did,\n cfg.identity.serviceHandleDomains,\n cfg.db,\n )\n await accountManager.migrateOrThrow()\n\n const localViewer = LocalViewer.creator(\n accountManager,\n imageUrlBuilder,\n bskyAppView,\n )\n\n // An agent for performing HTTP requests based on user provided URLs.\n const proxyAgentBase = new undici.Agent({\n allowH2: cfg.proxy.allowHTTP2, // This is experimental\n headersTimeout: cfg.proxy.headersTimeout,\n maxResponseSize: cfg.proxy.maxResponseSize,\n bodyTimeout: cfg.proxy.bodyTimeout,\n factory: cfg.proxy.disableSsrfProtection\n ? undefined\n : (origin, opts) => {\n const { protocol, hostname } =\n origin instanceof URL ? origin : new URL(origin)\n if (protocol !== 'https:') {\n throw new Error(`Forbidden protocol \"${protocol}\"`)\n }\n if (isUnicastIp(hostname) === false) {\n throw new Error('Hostname resolved to non-unicast address')\n }\n return new undici.Pool(origin, opts)\n },\n connect: {\n lookup: cfg.proxy.disableSsrfProtection ? undefined : unicastLookup,\n },\n })\n const proxyAgent =\n cfg.proxy.maxRetries > 0\n ? new undici.RetryAgent(proxyAgentBase, {\n statusCodes: [], // Only retry on socket errors\n methods: ['GET', 'HEAD'],\n maxRetries: cfg.proxy.maxRetries,\n })\n : proxyAgentBase\n\n /**\n * A fetch() function that protects against SSRF attacks, large responses &\n * known bad domains. This function can safely be used to fetch user\n * provided URLs (unless \"disableSsrfProtection\" is true, of course).\n *\n * @note **DO NOT** wrap `safeFetch` with any logging or other transforms as\n * this might prevent the use of explicit `redirect: \"follow\"` init from\n * working. See {@link safeFetchWrap}.\n */\n const safeFetch = safeFetchWrap({\n allowIpHost: false,\n allowImplicitRedirect: false,\n responseMaxSize: cfg.fetch.maxResponseSize,\n ssrfProtection: !cfg.fetch.disableSsrfProtection,\n\n fetch: function (input, init) {\n const method =\n init?.method ?? (input instanceof Request ? input.method : 'GET')\n const uri = input instanceof Request ? input.url : String(input)\n\n fetchLogger.info({ method, uri }, 'fetch')\n\n return globalThis.fetch.call(this, input, init)\n },\n })\n\n const oauthProvider = cfg.oauth.provider\n ? new OAuthProvider({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtSecretKey, undefined, 'HS256')],\n store: new OAuthStore(\n accountManager,\n actorStore,\n imageUrlBuilder,\n backgroundQueue,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n cfg.service.publicUrl,\n cfg.identity.recoveryDidKey,\n ),\n redis: redisScratch,\n dpopSecret: secrets.dpopSecret,\n inviteCodeRequired: cfg.invites.required,\n availableUserDomains: cfg.identity.serviceHandleDomains,\n hcaptcha: cfg.oauth.provider.hcaptcha,\n branding: cfg.oauth.provider.branding,\n safeFetch,\n lexResolver: new LexResolver({\n fetch: safeFetch,\n plcDirectoryUrl: cfg.identity.plcUrl,\n hooks: {\n onResolveAuthority: ({ nsid }) => {\n lexiconResolverLogger.debug(\n { nsid: nsid.toString() },\n 'Resolving lexicon DID authority',\n )\n // Override the lexicon did resolution to point to a custom PDS\n return cfg.lexicon.didAuthority\n },\n onResolveAuthorityResult({ nsid, did }) {\n lexiconResolverLogger.info(\n { nsid: nsid.toString(), did },\n 'Resolved lexicon DID',\n )\n },\n onResolveAuthorityError({ nsid, err }) {\n lexiconResolverLogger.error(\n { nsid: nsid.toString(), err },\n 'Lexicon DID resolution error',\n )\n },\n onFetchResult({ uri, cid }) {\n lexiconResolverLogger.info(\n { uri: uri.toString(), cid: cid.toString() },\n 'Fetched lexicon',\n )\n },\n onFetchError({ err, uri }) {\n lexiconResolverLogger.error(\n { uri: uri.toString(), err },\n 'Lexicon fetch error',\n )\n },\n },\n }),\n metadata: {\n protected_resources: [new URL(cfg.oauth.issuer).origin],\n },\n // If the PDS is both an authorization server & resource server (no\n // entryway), we can afford to check the token validity on every\n // request. This allows revoked tokens to be rejected immediately.\n // This also allows JWT to be shorter since some claims (notably the\n // \"scope\" claim) do not need to be included in the token.\n accessTokenMode: AccessTokenMode.stateful,\n\n getClientInfo(clientId) {\n return {\n isTrusted: cfg.oauth.provider?.trustedClients?.includes(clientId),\n }\n },\n })\n : undefined\n\n const scopeRefGetter = entrywayClient\n ? new ScopeReferenceGetter(entrywayClient, redisScratch)\n : undefined\n\n const oauthVerifier: OAuthVerifier =\n oauthProvider ?? // OAuthProvider extends OAuthVerifier\n new OAuthVerifier({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtPublicKey!, undefined, 'ES256K')],\n dpopSecret: secrets.dpopSecret,\n redis: redisScratch,\n onDecodeToken: async ({ payload, dpopProof }) => {\n // @TODO drop this once oauth provider no longer accepts DPoP proof with\n // query or fragment in \"htu\" claim.\n if (dpopProof?.htu.match(/[?#]/)) {\n oauthLogger.info(\n { htu: dpopProof.htu, client_id: payload.client_id },\n 'DPoP proof \"htu\" contains query or fragment',\n )\n }\n\n if (scopeRefGetter) {\n payload.scope = await scopeRefGetter.dereference(payload.scope)\n }\n\n return payload\n },\n })\n\n const authVerifier = new AuthVerifier(\n accountManager,\n idResolver,\n oauthVerifier,\n {\n publicUrl: cfg.service.publicUrl,\n jwtKey: jwtPublicKey ?? jwtSecretKey,\n adminPass: secrets.adminPassword,\n dids: {\n pds: cfg.service.did,\n entryway: cfg.entryway?.did,\n modService: cfg.modService?.did,\n },\n },\n )\n\n return new AppContext({\n actorStore,\n blobstore,\n localViewer,\n mailer,\n moderationMailer,\n didCache,\n idResolver,\n plcClient,\n accountManager,\n sequencer,\n backgroundQueue,\n redisScratch,\n crawlers,\n bskyAppView,\n moderationClient,\n reportingClient,\n entrywayClient,\n entrywayAdminClient,\n proxyAgent,\n safeFetch,\n authVerifier,\n oauthProvider,\n plcRotationKey,\n cfg,\n ...(overrides ?? {}),\n })\n }\n\n async appviewAuthHeaders(did: string, lxm: string) {\n assert(this.bskyAppView)\n return this.serviceAuthHeaders(did, this.bskyAppView.did, lxm)\n }\n\n async entrywayAuthHeaders(req: express.Request, did: string, lxm: string) {\n assert(this.cfg.entryway)\n const headers = await this.serviceAuthHeaders(\n did,\n this.cfg.entryway.did,\n lxm,\n )\n return forwardedFor(req, headers)\n }\n\n entrywayPassthruHeaders(req: express.Request) {\n return forwardedFor(req, authPassthru(req))\n }\n\n async serviceAuthHeaders(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceAuthHeaders({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async serviceAuthJwt(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceJwt({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n}\n\nconst basicAuthHeader = (username: string, password: string) => {\n const encoded = ui8.toString(\n ui8.fromString(`${username}:${password}`, 'utf8'),\n 'base64pad',\n )\n return `Basic ${encoded}`\n}\n\nexport default AppContext\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport * as plc from '@did-plc/lib'\nimport express from 'express'\nimport { Redis } from 'ioredis'\nimport * as nodemailer from 'nodemailer'\nimport * as ui8 from 'uint8arrays'\nimport * as undici from 'undici'\nimport { KmsKeypair, S3BlobStore } from '@atproto/aws'\nimport * as crypto from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport {\n AccessTokenMode,\n JoseKey,\n LexResolver,\n OAuthProvider,\n OAuthVerifier,\n} from '@atproto/oauth-provider'\nimport { BlobStore } from '@atproto/repo'\nimport {\n createServiceAuthHeaders,\n createServiceJwt,\n} from '@atproto/xrpc-server'\nimport {\n Fetch,\n isUnicastIp,\n safeFetchWrap,\n unicastLookup,\n} from '@atproto-labs/fetch-node'\nimport { AccountManager } from './account-manager/account-manager.js'\nimport { OAuthStore } from './account-manager/oauth-store.js'\nimport { ScopeReferenceGetter } from './account-manager/scope-reference-getter.js'\nimport { ActorStore } from './actor-store/actor-store.js'\nimport { authPassthru, forwardedFor } from './api/proxy.js'\nimport {\n AuthVerifier,\n createPublicKeyObject,\n createSecretKeyObject,\n} from './auth-verifier.js'\nimport { BackgroundQueue } from './background.js'\nimport { BskyAppView } from './bsky-app-view.js'\nimport { ServerConfig, ServerSecrets } from './config/index.js'\nimport { Crawlers } from './crawlers.js'\nimport { DidSqliteCache } from './did-cache/index.js'\nimport { DiskBlobStore } from './disk-blobstore.js'\nimport { ImageUrlBuilder } from './image/image-url-builder.js'\nimport { fetchLogger, lexiconResolverLogger, oauthLogger } from './logger.js'\nimport { ServerMailer } from './mailer/index.js'\nimport { ModerationMailer } from './mailer/moderation.js'\nimport { LocalViewer, LocalViewerCreator } from './read-after-write/viewer.js'\nimport { getRedisClient } from './redis.js'\nimport { Sequencer } from './sequencer/index.js'\n\nexport type AppContextOptions = {\n actorStore: ActorStore\n blobstore: (did: string) => BlobStore\n localViewer: LocalViewerCreator\n mailer: ServerMailer\n moderationMailer: ModerationMailer\n didCache: DidSqliteCache\n idResolver: IdResolver\n plcClient: plc.Client\n accountManager: AccountManager\n sequencer: Sequencer\n backgroundQueue: BackgroundQueue\n redisScratch?: Redis\n crawlers: Crawlers\n bskyAppView?: BskyAppView\n moderationClient?: Client\n reportingClient?: Client\n entrywayClient?: Client\n entrywayAdminClient?: Client\n proxyAgent: undici.Dispatcher\n safeFetch: Fetch\n oauthProvider?: OAuthProvider\n authVerifier: AuthVerifier\n plcRotationKey: crypto.Keypair\n cfg: ServerConfig\n}\n\nexport class AppContext {\n public actorStore: ActorStore\n public blobstore: (did: string) => BlobStore\n public localViewer: LocalViewerCreator\n public mailer: ServerMailer\n public moderationMailer: ModerationMailer\n public didCache: DidSqliteCache\n public idResolver: IdResolver\n public plcClient: plc.Client\n public accountManager: AccountManager\n public sequencer: Sequencer\n public backgroundQueue: BackgroundQueue\n public redisScratch?: Redis\n public crawlers: Crawlers\n public bskyAppView?: BskyAppView\n public moderationClient: Client | undefined\n public reportingClient: Client | undefined\n public entrywayClient: Client | undefined\n public entrywayAdminClient: Client | undefined\n public proxyAgent: undici.Dispatcher\n public safeFetch: Fetch\n public authVerifier: AuthVerifier\n public oauthProvider?: OAuthProvider\n public plcRotationKey: crypto.Keypair\n public cfg: ServerConfig\n\n constructor(opts: AppContextOptions) {\n this.actorStore = opts.actorStore\n this.blobstore = opts.blobstore\n this.localViewer = opts.localViewer\n this.mailer = opts.mailer\n this.moderationMailer = opts.moderationMailer\n this.didCache = opts.didCache\n this.idResolver = opts.idResolver\n this.plcClient = opts.plcClient\n this.accountManager = opts.accountManager\n this.sequencer = opts.sequencer\n this.backgroundQueue = opts.backgroundQueue\n this.redisScratch = opts.redisScratch\n this.crawlers = opts.crawlers\n this.bskyAppView = opts.bskyAppView\n this.moderationClient = opts.moderationClient\n this.reportingClient = opts.reportingClient\n this.entrywayClient = opts.entrywayClient\n this.entrywayAdminClient = opts.entrywayAdminClient\n this.proxyAgent = opts.proxyAgent\n this.safeFetch = opts.safeFetch\n this.authVerifier = opts.authVerifier\n this.oauthProvider = opts.oauthProvider\n this.plcRotationKey = opts.plcRotationKey\n this.cfg = opts.cfg\n }\n\n static async fromConfig(\n cfg: ServerConfig,\n secrets: ServerSecrets,\n overrides?: Partial<AppContextOptions>,\n ): Promise<AppContext> {\n const blobstore =\n cfg.blobstore.provider === 's3'\n ? S3BlobStore.creator({\n bucket: cfg.blobstore.bucket,\n region: cfg.blobstore.region,\n endpoint: cfg.blobstore.endpoint,\n forcePathStyle: cfg.blobstore.forcePathStyle,\n credentials: cfg.blobstore.credentials,\n uploadTimeoutMs: cfg.blobstore.uploadTimeoutMs,\n })\n : DiskBlobStore.creator(\n cfg.blobstore.location,\n cfg.blobstore.tempLocation,\n )\n\n const mailTransport =\n cfg.email !== null\n ? nodemailer.createTransport(cfg.email.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const mailer = new ServerMailer(mailTransport, cfg.email, cfg.branding)\n\n const modMailTransport =\n cfg.moderationEmail !== null\n ? nodemailer.createTransport(cfg.moderationEmail.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const moderationMailer = new ModerationMailer(modMailTransport, cfg)\n\n const didCache = new DidSqliteCache(\n cfg.db.didCacheDbLoc,\n cfg.identity.cacheStaleTTL,\n cfg.identity.cacheMaxTTL,\n cfg.db.disableWalAutoCheckpoint,\n )\n await didCache.migrateOrThrow()\n\n const idResolver = new IdResolver({\n plcUrl: cfg.identity.plcUrl,\n didCache,\n timeout: cfg.identity.resolverTimeout,\n backupNameservers: cfg.identity.handleBackupNameservers,\n })\n const plcClient = new plc.Client(cfg.identity.plcUrl)\n\n const backgroundQueue = new BackgroundQueue()\n const crawlers = new Crawlers(\n backgroundQueue,\n cfg.service.hostname,\n cfg.crawlers,\n )\n const sequencer = new Sequencer(\n cfg.db.sequencerDbLoc,\n crawlers,\n undefined,\n cfg.db.disableWalAutoCheckpoint,\n )\n const redisScratch = cfg.redis\n ? getRedisClient(cfg.redis.address, cfg.redis.password)\n : undefined\n\n const bskyAppView = cfg.bskyAppView\n ? new BskyAppView({\n ...cfg.bskyAppView,\n validateResponse: cfg.service.devMode,\n })\n : undefined\n\n const moderationClient = cfg.modService\n ? new Client(\n { service: cfg.modService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const reportingClient = cfg.reportService\n ? new Client(\n { service: cfg.reportService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayClient = cfg.entryway\n ? new Client(\n { service: cfg.entryway.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayAdminClient =\n cfg.entryway && secrets.entrywayAdminToken\n ? new Client(\n { service: cfg.entryway.url },\n {\n headers: {\n authorization: basicAuthHeader(\n 'admin',\n secrets.entrywayAdminToken,\n ),\n },\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n\n const jwtSecretKey = createSecretKeyObject(secrets.jwtSecret)\n const jwtPublicKey = cfg.entryway\n ? createPublicKeyObject(cfg.entryway.jwtPublicKeyHex)\n : null\n\n const imageUrlBuilder = new ImageUrlBuilder(\n cfg.service.hostname,\n bskyAppView,\n )\n\n const actorStore = new ActorStore(cfg.actorStore, {\n blobstore,\n backgroundQueue,\n })\n\n const plcRotationKey =\n secrets.plcRotationKey.provider === 'kms'\n ? await KmsKeypair.load({\n keyId: secrets.plcRotationKey.keyId,\n })\n : await crypto.Secp256k1Keypair.import(\n secrets.plcRotationKey.privateKeyHex,\n )\n\n const accountManager = new AccountManager(\n cfg,\n actorStore,\n idResolver,\n jwtSecretKey,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n )\n await accountManager.migrateOrThrow()\n\n const localViewer = LocalViewer.creator(\n accountManager,\n imageUrlBuilder,\n bskyAppView,\n )\n\n // An agent for performing HTTP requests based on user provided URLs.\n const proxyAgentBase = new undici.Agent({\n allowH2: cfg.proxy.allowHTTP2, // This is experimental\n headersTimeout: cfg.proxy.headersTimeout,\n maxResponseSize: cfg.proxy.maxResponseSize,\n bodyTimeout: cfg.proxy.bodyTimeout,\n factory: cfg.proxy.disableSsrfProtection\n ? undefined\n : (origin, opts) => {\n const { protocol, hostname } =\n origin instanceof URL ? origin : new URL(origin)\n if (protocol !== 'https:') {\n throw new Error(`Forbidden protocol \"${protocol}\"`)\n }\n if (isUnicastIp(hostname) === false) {\n throw new Error('Hostname resolved to non-unicast address')\n }\n return new undici.Pool(origin, opts)\n },\n connect: {\n lookup: cfg.proxy.disableSsrfProtection ? undefined : unicastLookup,\n },\n })\n const proxyAgent =\n cfg.proxy.maxRetries > 0\n ? new undici.RetryAgent(proxyAgentBase, {\n statusCodes: [], // Only retry on socket errors\n methods: ['GET', 'HEAD'],\n maxRetries: cfg.proxy.maxRetries,\n })\n : proxyAgentBase\n\n /**\n * A fetch() function that protects against SSRF attacks, large responses &\n * known bad domains. This function can safely be used to fetch user\n * provided URLs (unless \"disableSsrfProtection\" is true, of course).\n *\n * @note **DO NOT** wrap `safeFetch` with any logging or other transforms as\n * this might prevent the use of explicit `redirect: \"follow\"` init from\n * working. See {@link safeFetchWrap}.\n */\n const safeFetch = safeFetchWrap({\n allowIpHost: false,\n allowImplicitRedirect: false,\n responseMaxSize: cfg.fetch.maxResponseSize,\n ssrfProtection: !cfg.fetch.disableSsrfProtection,\n\n fetch: function (input, init) {\n const method =\n init?.method ?? (input instanceof Request ? input.method : 'GET')\n const uri = input instanceof Request ? input.url : String(input)\n\n fetchLogger.info({ method, uri }, 'fetch')\n\n return globalThis.fetch.call(this, input, init)\n },\n })\n\n const oauthProvider = cfg.oauth.provider\n ? new OAuthProvider({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtSecretKey, undefined, 'HS256')],\n store: new OAuthStore(\n accountManager,\n actorStore,\n imageUrlBuilder,\n backgroundQueue,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n cfg.service.publicUrl,\n cfg.identity.recoveryDidKey,\n ),\n redis: redisScratch,\n dpopSecret: secrets.dpopSecret,\n inviteCodeRequired: cfg.invites.required,\n availableUserDomains: cfg.identity.serviceHandleDomains,\n hcaptcha: cfg.oauth.provider.hcaptcha,\n branding: cfg.oauth.provider.branding,\n safeFetch,\n lexResolver: new LexResolver({\n fetch: safeFetch,\n plcDirectoryUrl: cfg.identity.plcUrl,\n hooks: {\n onResolveAuthority: ({ nsid }) => {\n lexiconResolverLogger.debug(\n { nsid: nsid.toString() },\n 'Resolving lexicon DID authority',\n )\n // Override the lexicon did resolution to point to a custom PDS\n return cfg.lexicon.didAuthority\n },\n onResolveAuthorityResult({ nsid, did }) {\n lexiconResolverLogger.info(\n { nsid: nsid.toString(), did },\n 'Resolved lexicon DID',\n )\n },\n onResolveAuthorityError({ nsid, err }) {\n lexiconResolverLogger.error(\n { nsid: nsid.toString(), err },\n 'Lexicon DID resolution error',\n )\n },\n onFetchResult({ uri, cid }) {\n lexiconResolverLogger.info(\n { uri: uri.toString(), cid: cid.toString() },\n 'Fetched lexicon',\n )\n },\n onFetchError({ err, uri }) {\n lexiconResolverLogger.error(\n { uri: uri.toString(), err },\n 'Lexicon fetch error',\n )\n },\n },\n }),\n metadata: {\n protected_resources: [new URL(cfg.oauth.issuer).origin],\n },\n // If the PDS is both an authorization server & resource server (no\n // entryway), we can afford to check the token validity on every\n // request. This allows revoked tokens to be rejected immediately.\n // This also allows JWT to be shorter since some claims (notably the\n // \"scope\" claim) do not need to be included in the token.\n accessTokenMode: AccessTokenMode.stateful,\n\n getClientInfo(clientId) {\n return {\n isTrusted: cfg.oauth.provider?.trustedClients?.includes(clientId),\n }\n },\n })\n : undefined\n\n const scopeRefGetter = entrywayClient\n ? new ScopeReferenceGetter(entrywayClient, redisScratch)\n : undefined\n\n const oauthVerifier: OAuthVerifier =\n oauthProvider ?? // OAuthProvider extends OAuthVerifier\n new OAuthVerifier({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtPublicKey!, undefined, 'ES256K')],\n dpopSecret: secrets.dpopSecret,\n redis: redisScratch,\n onDecodeToken: async ({ payload, dpopProof }) => {\n // @TODO drop this once oauth provider no longer accepts DPoP proof with\n // query or fragment in \"htu\" claim.\n if (dpopProof?.htu.match(/[?#]/)) {\n oauthLogger.info(\n { htu: dpopProof.htu, client_id: payload.client_id },\n 'DPoP proof \"htu\" contains query or fragment',\n )\n }\n\n if (scopeRefGetter) {\n payload.scope = await scopeRefGetter.dereference(payload.scope)\n }\n\n return payload\n },\n })\n\n const authVerifier = new AuthVerifier(\n accountManager,\n idResolver,\n oauthVerifier,\n {\n publicUrl: cfg.service.publicUrl,\n jwtKey: jwtPublicKey ?? jwtSecretKey,\n adminPass: secrets.adminPassword,\n dids: {\n pds: cfg.service.did,\n entryway: cfg.entryway?.did,\n modService: cfg.modService?.did,\n },\n },\n )\n\n return new AppContext({\n actorStore,\n blobstore,\n localViewer,\n mailer,\n moderationMailer,\n didCache,\n idResolver,\n plcClient,\n accountManager,\n sequencer,\n backgroundQueue,\n redisScratch,\n crawlers,\n bskyAppView,\n moderationClient,\n reportingClient,\n entrywayClient,\n entrywayAdminClient,\n proxyAgent,\n safeFetch,\n authVerifier,\n oauthProvider,\n plcRotationKey,\n cfg,\n ...(overrides ?? {}),\n })\n }\n\n async appviewAuthHeaders(did: string, lxm: string) {\n assert(this.bskyAppView)\n return this.serviceAuthHeaders(did, this.bskyAppView.did, lxm)\n }\n\n async entrywayAuthHeaders(req: express.Request, did: string, lxm: string) {\n assert(this.cfg.entryway)\n const headers = await this.serviceAuthHeaders(\n did,\n this.cfg.entryway.did,\n lxm,\n )\n return forwardedFor(req, headers)\n }\n\n entrywayPassthruHeaders(req: express.Request) {\n return forwardedFor(req, authPassthru(req))\n }\n\n async serviceAuthHeaders(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceAuthHeaders({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async serviceAuthJwt(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceJwt({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n}\n\nconst basicAuthHeader = (username: string, password: string) => {\n const encoded = ui8.toString(\n ui8.fromString(`${username}:${password}`, 'utf8'),\n 'base64pad',\n )\n return `Basic ${encoded}`\n}\n\nexport default AppContext\n"]}
@@ -1,8 +1,9 @@
1
- import { Kysely, Migration, Migrator as KyselyMigrator } from 'kysely';
1
+ import { Kysely } from 'kysely';
2
+ import { Migration, Migrator as KyselyMigrator } from 'kysely/migration';
2
3
  export declare class Migrator<T> extends KyselyMigrator {
3
4
  db: Kysely<T>;
4
5
  constructor(db: Kysely<T>, migrations: Record<string, Migration>);
5
- migrateToOrThrow(migration: string): Promise<import("kysely").MigrationResult[]>;
6
- migrateToLatestOrThrow(): Promise<import("kysely").MigrationResult[]>;
6
+ migrateToOrThrow(migration: string): Promise<import("kysely/migration").MigrationResult[]>;
7
+ migrateToLatestOrThrow(): Promise<import("kysely/migration").MigrationResult[]>;
7
8
  }
8
9
  //# sourceMappingURL=migrator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../src/db/migrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,QAAQ,CAAA;AAEtE,qBAAa,QAAQ,CAAC,CAAC,CAAE,SAAQ,cAAc;IAEpC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IADtB,YACS,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAUtC;IAEK,gBAAgB,CAAC,SAAS,EAAE,MAAM,+CASvC;IAEK,sBAAsB,gDAS3B;CACF"}
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../src/db/migrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAExE,qBAAa,QAAQ,CAAC,CAAC,CAAE,SAAQ,cAAc;IAEpC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IADtB,YACS,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAUtC;IAEK,gBAAgB,CAAC,SAAS,EAAE,MAAM,yDASvC;IAEK,sBAAsB,0DAS3B;CACF"}
@@ -1,4 +1,4 @@
1
- import { Migrator as KyselyMigrator } from 'kysely';
1
+ import { Migrator as KyselyMigrator } from 'kysely/migration';
2
2
  export class Migrator extends KyselyMigrator {
3
3
  constructor(db, migrations) {
4
4
  super({
@@ -1 +1 @@
1
- {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../../src/db/migrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,QAAQ,IAAI,cAAc,EAAE,MAAM,QAAQ,CAAA;AAEtE,MAAM,OAAO,QAAY,SAAQ,cAAc;IAC7C,YACS,EAAa,EACpB,UAAqC;QAErC,KAAK,CAAC;YACJ,EAAE;YACF,QAAQ,EAAE;gBACR,KAAK,CAAC,aAAa;oBACjB,OAAO,UAAU,CAAA;gBACnB,CAAC;aACF;SACF,CAAC,CAAA;kBAVK,EAAE;IAWX,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QAC1D,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,sBAAsB;QAC1B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;QACvD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF","sourcesContent":["import { Kysely, Migration, Migrator as KyselyMigrator } from 'kysely'\n\nexport class Migrator<T> extends KyselyMigrator {\n constructor(\n public db: Kysely<T>,\n migrations: Record<string, Migration>,\n ) {\n super({\n db,\n provider: {\n async getMigrations() {\n return migrations\n },\n },\n })\n }\n\n async migrateToOrThrow(migration: string) {\n const { error, results } = await this.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n const { error, results } = await this.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n"]}
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../../src/db/migrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,QAAQ,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAExE,MAAM,OAAO,QAAY,SAAQ,cAAc;IAC7C,YACS,EAAa,EACpB,UAAqC;QAErC,KAAK,CAAC;YACJ,EAAE;YACF,QAAQ,EAAE;gBACR,KAAK,CAAC,aAAa;oBACjB,OAAO,UAAU,CAAA;gBACnB,CAAC;aACF;SACF,CAAC,CAAA;kBAVK,EAAE;IAWX,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QAC1D,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,sBAAsB;QAC1B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;QACvD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF","sourcesContent":["import { Kysely } from 'kysely'\nimport { Migration, Migrator as KyselyMigrator } from 'kysely/migration'\n\nexport class Migrator<T> extends KyselyMigrator {\n constructor(\n public db: Kysely<T>,\n migrations: Record<string, Migration>,\n ) {\n super({\n db,\n provider: {\n async getMigrations() {\n return migrations\n },\n },\n })\n }\n\n async migrateToOrThrow(migration: string) {\n const { error, results } = await this.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n const { error, results } = await this.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { SqlBool } from 'kysely';
1
2
  import { AnyQb, DbRef } from './util.js';
2
3
  export type Cursor = {
3
4
  primary: string;
@@ -33,7 +34,7 @@ export declare abstract class GenericKeyset<R, LR extends LabeledResult> {
33
34
  unpack(cursorStr?: string): LR | undefined;
34
35
  packCursor(cursor?: Cursor): string | undefined;
35
36
  unpackCursor(cursorStr?: string): Cursor | undefined;
36
- getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean): import("kysely").RawBuilder<unknown> | undefined;
37
+ getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean): import("kysely").RawBuilder<SqlBool> | undefined;
37
38
  }
38
39
  type CreatedAtCidResult = {
39
40
  createdAt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/db/pagination.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,MAAM,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,8BAAsB,aAAa,CAAC,CAAC,EAAE,EAAE,SAAS,aAAa;IAEpD,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAFzB,YACS,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,KAAK,EACrB;IACJ,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAA;IACnC,QAAQ,CAAC,qBAAqB,CAAC,OAAO,EAAE,EAAE,GAAG,MAAM,CAAA;IACnD,QAAQ,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,CAAA;IAClD,cAAc,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,GAAG,SAAS,CAInD;IACD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,SAAS,CAIrC;IACD,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,EAAE,GAAG,SAAS,CAIzC;IACD,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9C;IACD,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWnD;IACD,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,oDAiBlE;CACF;AAED,KAAK,kBAAkB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5D,KAAK,oBAAoB,GAAG,MAAM,CAAA;AAElC,qBAAa,aAAa,CACxB,aAAa,GAAG,kBAAkB,CAClC,SAAQ,aAAa,CAAC,aAAa,EAAE,oBAAoB,CAAC;IAC1D,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,oBAAoB,CAAA;IAIxD,qBAAqB,CAAC,OAAO,EAAE,oBAAoB;QAE/C,OAAO;QACP,SAAS;MAEZ;IACD,qBAAqB,CAAC,MAAM,EAAE,MAAM;QAMhC,OAAO;QACP,SAAS;MAEZ;CACF;AAED,eAAO,MAAM,QAAQ,GACnB,EAAE,SAAS,KAAK,EAChB,CAAC,SAAS,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,MAEjC,EAAE,QACA;IACJ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IAC1B,MAAM,EAAE,CAAC,CAAA;IACT,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,KACA,EAQF,CAAA"}
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/db/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAO,MAAM,QAAQ,CAAA;AAErC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,MAAM,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,8BAAsB,aAAa,CAAC,CAAC,EAAE,EAAE,SAAS,aAAa;IAEpD,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAFzB,YACS,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,KAAK,EACrB;IACJ,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAA;IACnC,QAAQ,CAAC,qBAAqB,CAAC,OAAO,EAAE,EAAE,GAAG,MAAM,CAAA;IACnD,QAAQ,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,CAAA;IAClD,cAAc,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,GAAG,SAAS,CAInD;IACD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,SAAS,CAIrC;IACD,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,EAAE,GAAG,SAAS,CAIzC;IACD,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9C;IACD,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWnD;IACD,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,oDAiBlE;CACF;AAED,KAAK,kBAAkB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5D,KAAK,oBAAoB,GAAG,MAAM,CAAA;AAElC,qBAAa,aAAa,CACxB,aAAa,GAAG,kBAAkB,CAClC,SAAQ,aAAa,CAAC,aAAa,EAAE,oBAAoB,CAAC;IAC1D,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,oBAAoB,CAAA;IAIxD,qBAAqB,CAAC,OAAO,EAAE,oBAAoB;QAE/C,OAAO;QACP,SAAS;MAEZ;IACD,qBAAqB,CAAC,MAAM,EAAE,MAAM;QAMhC,OAAO;QACP,SAAS;MAEZ;CACF;AAED,eAAO,MAAM,QAAQ,GACnB,EAAE,SAAS,KAAK,EAChB,CAAC,SAAS,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,MAEjC,EAAE,QACA;IACJ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IAC1B,MAAM,EAAE,CAAC,CAAA;IACT,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,KACA,EAQF,CAAA"}
@@ -103,9 +103,9 @@ export const paginate = (qb, opts) => {
103
103
  const { limit, cursor, keyset, direction = 'desc', tryIndex } = opts;
104
104
  const keysetSql = keyset.getSql(keyset.unpack(cursor), direction, tryIndex);
105
105
  return qb
106
- .if(!!limit, (q) => q.limit(limit))
106
+ .$if(!!limit, (q) => q.limit(limit))
107
107
  .orderBy(keyset.primary, direction)
108
108
  .orderBy(keyset.secondary, direction)
109
- .if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb));
109
+ .$if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb));
110
110
  };
111
111
  //# sourceMappingURL=pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/db/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { AnyQb, DbRef } from './util.js'\n\nexport type Cursor = { primary: string; secondary: string }\nexport type LabeledResult = {\n primary: string | number\n secondary: string | number\n}\n\n/**\n * The GenericKeyset is an abstract class that sets-up the interface and partial implementation\n * of a keyset-paginated cursor with two parts. There are three types involved:\n * - Result: a raw result (i.e. a row from the db) containing data that will make-up a cursor.\n * - E.g. { createdAt: '2022-01-01T12:00:00Z', cid: 'bafyx' }\n * - LabeledResult: a Result processed such that the \"primary\" and \"secondary\" parts of the cursor are labeled.\n * - E.g. { primary: '2022-01-01T12:00:00Z', secondary: 'bafyx' }\n * - Cursor: the two string parts that make-up the packed/string cursor.\n * - E.g. packed cursor '1641038400000::bafyx' in parts { primary: '1641038400000', secondary: 'bafyx' }\n *\n * These types relate as such. Implementers define the relations marked with a *:\n * Result -*-> LabeledResult <-*-> Cursor <--> packed/string cursor\n * ↳ SQL Condition\n */\nexport abstract class GenericKeyset<R, LR extends LabeledResult> {\n constructor(\n public primary: DbRef,\n public secondary: DbRef,\n ) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): Cursor\n abstract cursorToLabeledResult(cursor: Cursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: Cursor): string | undefined {\n if (!cursor) return\n return `${cursor.primary}::${cursor.secondary}`\n }\n unpackCursor(cursorStr?: string): Cursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('::')\n const [primary, secondary, ...others] = result\n if (!primary || !secondary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n secondary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean) {\n if (labeled === undefined) return\n if (tryIndex) {\n // The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.\n if (direction === 'asc') {\n return sql`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`\n } else {\n return sql`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`\n }\n } else {\n // @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the \"or\" usage.\n if (direction === 'asc') {\n return sql`((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`\n } else {\n return sql`((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`\n }\n }\n }\n}\n\ntype CreatedAtCidResult = { createdAt: string; cid: string }\ntype TimeCidLabeledResult = Cursor\n\nexport class TimeCidKeyset<\n TimeCidResult = CreatedAtCidResult,\n> extends GenericKeyset<TimeCidResult, TimeCidLabeledResult> {\n labelResult(result: TimeCidResult): TimeCidLabeledResult\n labelResult<TimeCidResult extends CreatedAtCidResult>(result: TimeCidResult) {\n return { primary: result.createdAt, secondary: result.cid }\n }\n labeledResultToCursor(labeled: TimeCidLabeledResult) {\n return {\n primary: new Date(labeled.primary).getTime().toString(),\n secondary: labeled.secondary,\n }\n }\n cursorToLabeledResult(cursor: Cursor) {\n const primaryDate = new Date(parseInt(cursor.primary, 10))\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n secondary: cursor.secondary,\n }\n }\n}\n\nexport const paginate = <\n QB extends AnyQb,\n K extends GenericKeyset<unknown, any>,\n>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n keyset: K\n tryIndex?: boolean\n },\n): QB => {\n const { limit, cursor, keyset, direction = 'desc', tryIndex } = opts\n const keysetSql = keyset.getSql(keyset.unpack(cursor), direction, tryIndex)\n return qb\n .if(!!limit, (q) => q.limit(limit as number))\n .orderBy(keyset.primary, direction)\n .orderBy(keyset.secondary, direction)\n .if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb)) as QB\n}\n"]}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/db/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import { SqlBool, sql } from 'kysely'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { AnyQb, DbRef } from './util.js'\n\nexport type Cursor = { primary: string; secondary: string }\nexport type LabeledResult = {\n primary: string | number\n secondary: string | number\n}\n\n/**\n * The GenericKeyset is an abstract class that sets-up the interface and partial implementation\n * of a keyset-paginated cursor with two parts. There are three types involved:\n * - Result: a raw result (i.e. a row from the db) containing data that will make-up a cursor.\n * - E.g. { createdAt: '2022-01-01T12:00:00Z', cid: 'bafyx' }\n * - LabeledResult: a Result processed such that the \"primary\" and \"secondary\" parts of the cursor are labeled.\n * - E.g. { primary: '2022-01-01T12:00:00Z', secondary: 'bafyx' }\n * - Cursor: the two string parts that make-up the packed/string cursor.\n * - E.g. packed cursor '1641038400000::bafyx' in parts { primary: '1641038400000', secondary: 'bafyx' }\n *\n * These types relate as such. Implementers define the relations marked with a *:\n * Result -*-> LabeledResult <-*-> Cursor <--> packed/string cursor\n * ↳ SQL Condition\n */\nexport abstract class GenericKeyset<R, LR extends LabeledResult> {\n constructor(\n public primary: DbRef,\n public secondary: DbRef,\n ) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): Cursor\n abstract cursorToLabeledResult(cursor: Cursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: Cursor): string | undefined {\n if (!cursor) return\n return `${cursor.primary}::${cursor.secondary}`\n }\n unpackCursor(cursorStr?: string): Cursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('::')\n const [primary, secondary, ...others] = result\n if (!primary || !secondary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n secondary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean) {\n if (labeled === undefined) return\n if (tryIndex) {\n // The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`\n }\n } else {\n // @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the \"or\" usage.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`\n }\n }\n }\n}\n\ntype CreatedAtCidResult = { createdAt: string; cid: string }\ntype TimeCidLabeledResult = Cursor\n\nexport class TimeCidKeyset<\n TimeCidResult = CreatedAtCidResult,\n> extends GenericKeyset<TimeCidResult, TimeCidLabeledResult> {\n labelResult(result: TimeCidResult): TimeCidLabeledResult\n labelResult<TimeCidResult extends CreatedAtCidResult>(result: TimeCidResult) {\n return { primary: result.createdAt, secondary: result.cid }\n }\n labeledResultToCursor(labeled: TimeCidLabeledResult) {\n return {\n primary: new Date(labeled.primary).getTime().toString(),\n secondary: labeled.secondary,\n }\n }\n cursorToLabeledResult(cursor: Cursor) {\n const primaryDate = new Date(parseInt(cursor.primary, 10))\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n secondary: cursor.secondary,\n }\n }\n}\n\nexport const paginate = <\n QB extends AnyQb,\n K extends GenericKeyset<unknown, any>,\n>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n keyset: K\n tryIndex?: boolean\n },\n): QB => {\n const { limit, cursor, keyset, direction = 'desc', tryIndex } = opts\n const keysetSql = keyset.getSql(keyset.unpack(cursor), direction, tryIndex)\n return qb\n .$if(!!limit, (q) => q.limit(limit as number))\n .orderBy(keyset.primary, direction)\n .orderBy(keyset.secondary, direction)\n .$if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb)) as QB\n}\n"]}
package/dist/db/util.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { DummyDriver, DynamicModule, Kysely, RawBuilder, ReferenceExpression, SelectQueryBuilder, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from 'kysely';
2
- export declare const notSoftDeletedClause: (alias: DbRef) => RawBuilder<unknown>;
1
+ import { DummyDriver, DynamicModule, Kysely, RawBuilder, ReferenceExpression, SelectQueryBuilder, SqlBool, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from 'kysely';
2
+ export declare const notSoftDeletedClause: (alias: DbRef) => RawBuilder<SqlBool>;
3
3
  export declare const softDeleted: (repoOrRecord: {
4
4
  takedownRef: string | null;
5
5
  }) => boolean;
@@ -15,7 +15,7 @@ export declare const dummyDialect: {
15
15
  };
16
16
  export declare const retrySqlite: <T>(fn: () => Promise<T>) => Promise<T>;
17
17
  export type Ref = ReferenceExpression<any, any>;
18
- export type DbRef = RawBuilder | ReturnType<DynamicModule['ref']>;
18
+ export type DbRef = RawBuilder<unknown> | ReturnType<DynamicModule<unknown>['ref']>;
19
19
  export type AnyQb = SelectQueryBuilder<any, any, any>;
20
20
  export declare const isErrUniqueViolation: (err: unknown) => boolean;
21
21
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/db/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,QAAQ,CAAA;AAIf,eAAO,MAAM,oBAAoB,UAAW,KAAK,wBAEhD,CAAA;AAED,eAAO,MAAM,WAAW,iBAAkB;IAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,YAEvE,CAAA;AAED,eAAO,MAAM,QAAQ,oBAAwB,CAAA;AAC7C,eAAO,MAAM,aAAa,QAAS,KAAK,uBAAwC,CAAA;AAGhF,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,4BAE3C,CAAA;AAGD,eAAO,MAAM,UAAU,SAAU,OAAO,EAAE,wBAEzC,CAAA;AAED,eAAO,MAAM,YAAY;;;;;CAaxB,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAM9D,CAAA;AAmCD,MAAM,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AAE/C,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;AAEjE,MAAM,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAErD,eAAO,MAAM,oBAAoB,QAAS,OAAO,YAMhD,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/db/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,QAAQ,CAAA;AAIf,eAAO,MAAM,oBAAoB,UAAW,KAAK,wBAEhD,CAAA;AAED,eAAO,MAAM,WAAW,iBAAkB;IAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,YAEvE,CAAA;AAED,eAAO,MAAM,QAAQ,oBAAwB,CAAA;AAC7C,eAAO,MAAM,aAAa,QAAS,KAAK,uBAAwC,CAAA;AAGhF,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,4BAE3C,CAAA;AAGD,eAAO,MAAM,UAAU,SAAU,OAAO,EAAE,wBAEzC,CAAA;AAED,eAAO,MAAM,YAAY;;;;;CAaxB,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAM9D,CAAA;AAmCD,MAAM,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AAE/C,MAAM,MAAM,KAAK,GACb,UAAU,CAAC,OAAO,CAAC,GACnB,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;AAE7C,MAAM,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAErD,eAAO,MAAM,oBAAoB,QAAS,OAAO,YAMhD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/db/util.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DummyDriver,\n DynamicModule,\n Kysely,\n RawBuilder,\n ReferenceExpression,\n SelectQueryBuilder,\n SqliteAdapter,\n SqliteIntrospector,\n SqliteQueryCompiler,\n sql,\n} from 'kysely'\nimport { retry } from '@atproto/common'\n\n// Applies to repo_root or record table\nexport const notSoftDeletedClause = (alias: DbRef) => {\n return sql`${alias}.\"takedownRef\" is null`\n}\n\nexport const softDeleted = (repoOrRecord: { takedownRef: string | null }) => {\n return repoOrRecord.takedownRef !== null\n}\n\nexport const countAll = sql<number>`count(*)`\nexport const countDistinct = (ref: DbRef) => sql<number>`count(distinct ${ref})`\n\n// For use with doUpdateSet()\nexport const excluded = <T, S>(db: Kysely<S>, col) => {\n return sql<T>`${db.dynamic.ref(`excluded.${col}`)}`\n}\n\n// Can be useful for large where-in clauses, to get the db to use a hash lookup on the list\nexport const valuesList = (vals: unknown[]) => {\n return sql`(values (${sql.join(vals, sql`), (`)}))`\n}\n\nexport const dummyDialect = {\n createAdapter() {\n return new SqliteAdapter()\n },\n createDriver() {\n return new DummyDriver()\n },\n createIntrospector(db) {\n return new SqliteIntrospector(db)\n },\n createQueryCompiler() {\n return new SqliteQueryCompiler()\n },\n}\n\nexport const retrySqlite = <T>(fn: () => Promise<T>): Promise<T> => {\n return retry(fn, {\n retryable: retryableSqlite,\n getWaitMs: getWaitMsSqlite,\n maxRetries: 60, // a safety measure: getWaitMsSqlite() times out before this after 5000ms of waiting.\n })\n}\n\nconst retryableSqlite = (err: unknown) => {\n return typeof err?.['code'] === 'string' && RETRY_ERRORS.has(err['code'])\n}\n\n// based on sqlite's backoff strategy https://github.com/sqlite/sqlite/blob/91c8e65dd4bf17d21fbf8f7073565fe1a71c8948/src/main.c#L1704-L1713\nconst getWaitMsSqlite = (n: number, timeout = 5000) => {\n if (n < 0) return null\n let delay: number\n let prior: number\n if (n < DELAYS.length) {\n delay = DELAYS[n]\n prior = TOTALS[n]\n } else {\n delay = last(DELAYS)\n prior = last(TOTALS) + delay * (n - (DELAYS.length - 1))\n }\n if (prior + delay > timeout) {\n delay = timeout - prior\n if (delay <= 0) return null\n }\n return delay\n}\n\nconst last = <T>(arr: T[]) => arr[arr.length - 1]\nconst DELAYS = [1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100]\nconst TOTALS = [0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228]\nconst RETRY_ERRORS = new Set([\n 'SQLITE_BUSY',\n 'SQLITE_BUSY_SNAPSHOT',\n 'SQLITE_BUSY_RECOVERY',\n 'SQLITE_BUSY_TIMEOUT',\n])\n\nexport type Ref = ReferenceExpression<any, any>\n\nexport type DbRef = RawBuilder | ReturnType<DynamicModule['ref']>\n\nexport type AnyQb = SelectQueryBuilder<any, any, any>\n\nexport const isErrUniqueViolation = (err: unknown) => {\n const code = err?.['code']\n return (\n code === '23505' || // postgres, see https://www.postgresql.org/docs/current/errcodes-appendix.html\n code === 'SQLITE_CONSTRAINT_UNIQUE' // sqlite, see https://www.sqlite.org/rescode.html#constraint_unique\n )\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/db/util.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DummyDriver,\n DynamicModule,\n Kysely,\n RawBuilder,\n ReferenceExpression,\n SelectQueryBuilder,\n SqlBool,\n SqliteAdapter,\n SqliteIntrospector,\n SqliteQueryCompiler,\n sql,\n} from 'kysely'\nimport { retry } from '@atproto/common'\n\n// Applies to repo_root or record table\nexport const notSoftDeletedClause = (alias: DbRef) => {\n return sql<SqlBool>`${alias}.\"takedownRef\" is null`\n}\n\nexport const softDeleted = (repoOrRecord: { takedownRef: string | null }) => {\n return repoOrRecord.takedownRef !== null\n}\n\nexport const countAll = sql<number>`count(*)`\nexport const countDistinct = (ref: DbRef) => sql<number>`count(distinct ${ref})`\n\n// For use with doUpdateSet()\nexport const excluded = <T, S>(db: Kysely<S>, col) => {\n return sql<T>`${db.dynamic.ref(`excluded.${col}`)}`\n}\n\n// Can be useful for large where-in clauses, to get the db to use a hash lookup on the list\nexport const valuesList = (vals: unknown[]) => {\n return sql`(values (${sql.join(vals, sql`), (`)}))`\n}\n\nexport const dummyDialect = {\n createAdapter() {\n return new SqliteAdapter()\n },\n createDriver() {\n return new DummyDriver()\n },\n createIntrospector(db) {\n return new SqliteIntrospector(db)\n },\n createQueryCompiler() {\n return new SqliteQueryCompiler()\n },\n}\n\nexport const retrySqlite = <T>(fn: () => Promise<T>): Promise<T> => {\n return retry(fn, {\n retryable: retryableSqlite,\n getWaitMs: getWaitMsSqlite,\n maxRetries: 60, // a safety measure: getWaitMsSqlite() times out before this after 5000ms of waiting.\n })\n}\n\nconst retryableSqlite = (err: unknown) => {\n return typeof err?.['code'] === 'string' && RETRY_ERRORS.has(err['code'])\n}\n\n// based on sqlite's backoff strategy https://github.com/sqlite/sqlite/blob/91c8e65dd4bf17d21fbf8f7073565fe1a71c8948/src/main.c#L1704-L1713\nconst getWaitMsSqlite = (n: number, timeout = 5000) => {\n if (n < 0) return null\n let delay: number\n let prior: number\n if (n < DELAYS.length) {\n delay = DELAYS[n]\n prior = TOTALS[n]\n } else {\n delay = last(DELAYS)\n prior = last(TOTALS) + delay * (n - (DELAYS.length - 1))\n }\n if (prior + delay > timeout) {\n delay = timeout - prior\n if (delay <= 0) return null\n }\n return delay\n}\n\nconst last = <T>(arr: T[]) => arr[arr.length - 1]\nconst DELAYS = [1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100]\nconst TOTALS = [0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228]\nconst RETRY_ERRORS = new Set([\n 'SQLITE_BUSY',\n 'SQLITE_BUSY_SNAPSHOT',\n 'SQLITE_BUSY_RECOVERY',\n 'SQLITE_BUSY_TIMEOUT',\n])\n\nexport type Ref = ReferenceExpression<any, any>\n\nexport type DbRef =\n | RawBuilder<unknown>\n | ReturnType<DynamicModule<unknown>['ref']>\n\nexport type AnyQb = SelectQueryBuilder<any, any, any>\n\nexport const isErrUniqueViolation = (err: unknown) => {\n const code = err?.['code']\n return (\n code === '23505' || // postgres, see https://www.postgresql.org/docs/current/errcodes-appendix.html\n code === 'SQLITE_CONSTRAINT_UNIQUE' // sqlite, see https://www.sqlite.org/rescode.html#constraint_unique\n )\n}\n"]}
@@ -8,9 +8,11 @@ export declare class ServerMailer {
8
8
  sendResetPassword(params: {
9
9
  handle: string;
10
10
  token: string;
11
+ locale?: string;
11
12
  }, mailOpts: SendMailOptions): Promise<void>;
12
13
  sendAccountDelete(params: {
13
14
  token: string;
15
+ locale?: string;
14
16
  }, mailOpts: SendMailOptions): Promise<void>;
15
17
  sendConfirmEmail(params: {
16
18
  token: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mailer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAahE,qBAAa,YAAY;aAIL,WAAW,EAAE,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,YACkB,WAAW,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW,GAAG,IAAI,EAC1C,QAAQ,EAAE,cAAc,EAczB;IAEK,iBAAiB,CACrB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EACzC,QAAQ,EAAE,eAAe,iBAM1B;IAEK,iBAAiB,CACrB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EACzB,QAAQ,EAAE,eAAe,iBAM1B;IAEK,gBAAgB,CACpB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1C,QAAQ,EAAE,eAAe,iBAO1B;IAEK,eAAe,CACnB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1C,QAAQ,EAAE,eAAe,iBAO1B;IAEK,gBAAgB,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,QAAQ,EAAE,eAAe,iBAK1E;YAEa,YAAY;CAsB3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mailer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAahE,qBAAa,YAAY;aAIL,WAAW,EAAE,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,YACkB,WAAW,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW,GAAG,IAAI,EAC1C,QAAQ,EAAE,cAAc,EAczB;IAEK,iBAAiB,CACrB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1D,QAAQ,EAAE,eAAe,iBAO1B;IAEK,iBAAiB,CACrB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1C,QAAQ,EAAE,eAAe,iBAO1B;IAEK,gBAAgB,CACpB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1C,QAAQ,EAAE,eAAe,iBAO1B;IAEK,eAAe,CACnB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1C,QAAQ,EAAE,eAAe,iBAO1B;IAEK,gBAAgB,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,QAAQ,EAAE,eAAe,iBAK1E;YAEa,YAAY;CAsB3B"}
@@ -22,12 +22,14 @@ export class ServerMailer {
22
22
  };
23
23
  }
24
24
  async sendResetPassword(params, mailOpts) {
25
+ // @TODO (later) handle locale in the template
25
26
  await this.sendTemplate('resetPassword', params, {
26
27
  subject: 'Password Reset Requested',
27
28
  ...mailOpts,
28
29
  });
29
30
  }
30
31
  async sendAccountDelete(params, mailOpts) {
32
+ // @TODO (later) handle locale in the template
31
33
  await this.sendTemplate('deleteAccount', params, {
32
34
  subject: 'Account Deletion Requested',
33
35
  ...mailOpts,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mailer/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { SendMailOptions, Transporter } from 'nodemailer'\nimport { htmlToText } from 'nodemailer-html-to-text'\nimport { BrandingConfig, EmailConfig } from '../config/index.js'\nimport { mailerLogger } from '../logger.js'\nimport * as templates from './templates.js'\n\n// @TODO Add support for i18n\n\nconst DEFAULT_LOGO_URL =\n 'https://bsky.social/about/images/email/email_logo_default.png'\nconst DEFAULT_MARK_URL =\n 'https://bsky.social/about/images/email/email_mark_dark.png'\nconst DEFAULT_HOME_URL = 'https://bsky.app'\nconst DEFAULT_PRIMARY_COLOR = '#067df7'\n\nexport class ServerMailer {\n private readonly config: templates.Config\n\n constructor(\n public readonly transporter: Transporter,\n private readonly email: EmailConfig | null,\n branding: BrandingConfig,\n ) {\n transporter.use('compile', htmlToText())\n\n this.config = {\n serviceName: branding.name ?? 'Bluesky',\n homeUrl:\n branding.links?.find((link) => link.rel === 'canonical')?.href ??\n DEFAULT_HOME_URL,\n logoUrl: branding.logo ?? DEFAULT_LOGO_URL,\n markUrl: branding.logo ?? DEFAULT_MARK_URL,\n primaryColor: branding.colors?.primary ?? DEFAULT_PRIMARY_COLOR,\n showBskyAppEmailConfirmationLink: email?.disableConfirmationLink !== true,\n }\n }\n\n async sendResetPassword(\n params: { handle: string; token: string },\n mailOpts: SendMailOptions,\n ) {\n await this.sendTemplate('resetPassword', params, {\n subject: 'Password Reset Requested',\n ...mailOpts,\n })\n }\n\n async sendAccountDelete(\n params: { token: string },\n mailOpts: SendMailOptions,\n ) {\n await this.sendTemplate('deleteAccount', params, {\n subject: 'Account Deletion Requested',\n ...mailOpts,\n })\n }\n\n async sendConfirmEmail(\n params: { token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('confirmEmail', params, {\n subject: 'Email Confirmation',\n ...mailOpts,\n })\n }\n\n async sendUpdateEmail(\n params: { token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('updateEmail', params, {\n subject: 'Email Update Requested',\n ...mailOpts,\n })\n }\n\n async sendPlcOperation(params: { token: string }, mailOpts: SendMailOptions) {\n await this.sendTemplate('plcOperation', params, {\n subject: 'PLC Update Operation Requested',\n ...mailOpts,\n })\n }\n\n private async sendTemplate<K extends keyof typeof templates>(\n templateName: K,\n params: Parameters<(typeof templates)[K]>[0],\n mailOpts: SendMailOptions,\n ) {\n const html = templates[templateName]({\n ...params,\n config: this.config,\n } as any)\n const res = await this.transporter.sendMail({\n ...mailOpts,\n from: mailOpts.from ?? this.email?.fromAddress,\n html,\n })\n if (!this.email?.smtpUrl) {\n mailerLogger.debug(\n 'No SMTP URL has been configured. Intended to send email:\\n' +\n JSON.stringify(res, null, 2),\n )\n }\n return res\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mailer/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { SendMailOptions, Transporter } from 'nodemailer'\nimport { htmlToText } from 'nodemailer-html-to-text'\nimport { BrandingConfig, EmailConfig } from '../config/index.js'\nimport { mailerLogger } from '../logger.js'\nimport * as templates from './templates.js'\n\n// @TODO Add support for i18n\n\nconst DEFAULT_LOGO_URL =\n 'https://bsky.social/about/images/email/email_logo_default.png'\nconst DEFAULT_MARK_URL =\n 'https://bsky.social/about/images/email/email_mark_dark.png'\nconst DEFAULT_HOME_URL = 'https://bsky.app'\nconst DEFAULT_PRIMARY_COLOR = '#067df7'\n\nexport class ServerMailer {\n private readonly config: templates.Config\n\n constructor(\n public readonly transporter: Transporter,\n private readonly email: EmailConfig | null,\n branding: BrandingConfig,\n ) {\n transporter.use('compile', htmlToText())\n\n this.config = {\n serviceName: branding.name ?? 'Bluesky',\n homeUrl:\n branding.links?.find((link) => link.rel === 'canonical')?.href ??\n DEFAULT_HOME_URL,\n logoUrl: branding.logo ?? DEFAULT_LOGO_URL,\n markUrl: branding.logo ?? DEFAULT_MARK_URL,\n primaryColor: branding.colors?.primary ?? DEFAULT_PRIMARY_COLOR,\n showBskyAppEmailConfirmationLink: email?.disableConfirmationLink !== true,\n }\n }\n\n async sendResetPassword(\n params: { handle: string; token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('resetPassword', params, {\n subject: 'Password Reset Requested',\n ...mailOpts,\n })\n }\n\n async sendAccountDelete(\n params: { token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('deleteAccount', params, {\n subject: 'Account Deletion Requested',\n ...mailOpts,\n })\n }\n\n async sendConfirmEmail(\n params: { token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('confirmEmail', params, {\n subject: 'Email Confirmation',\n ...mailOpts,\n })\n }\n\n async sendUpdateEmail(\n params: { token: string; locale?: string },\n mailOpts: SendMailOptions,\n ) {\n // @TODO (later) handle locale in the template\n await this.sendTemplate('updateEmail', params, {\n subject: 'Email Update Requested',\n ...mailOpts,\n })\n }\n\n async sendPlcOperation(params: { token: string }, mailOpts: SendMailOptions) {\n await this.sendTemplate('plcOperation', params, {\n subject: 'PLC Update Operation Requested',\n ...mailOpts,\n })\n }\n\n private async sendTemplate<K extends keyof typeof templates>(\n templateName: K,\n params: Parameters<(typeof templates)[K]>[0],\n mailOpts: SendMailOptions,\n ) {\n const html = templates[templateName]({\n ...params,\n config: this.config,\n } as any)\n const res = await this.transporter.sendMail({\n ...mailOpts,\n from: mailOpts.from ?? this.email?.fromAddress,\n html,\n })\n if (!this.email?.smtpUrl) {\n mailerLogger.debug(\n 'No SMTP URL has been configured. Intended to send email:\\n' +\n JSON.stringify(res, null, 2),\n )\n }\n return res\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"recovery-db.js","sourceRoot":"","sources":["../../../src/scripts/sequencer-recovery/recovery-db.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAoBtD,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,YAAoB,EACC,EAAE;IACvB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAA;IAC9E,OAAO,uBAAuB,CAAC,aAAa,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,QAAgB,EAChB,wBAAwB,GAAG,KAAK,EACX,EAAE;IACvB,MAAM,OAAO,GAA2B,wBAAwB;QAC9D,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,EAAE;QAC7B,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;IAChD,MAAM,QAAQ,CAAC,sBAAsB,EAAE,CAAA;IACvC,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,MAAM,UAAU,GAAG;IACjB,KAAK,EAAE;QACL,EAAE,EAAE,KAAK,EAAE,EAAmB,EAAE,EAAE;YAChC,MAAM,EAAE,CAAC,MAAM;iBACZ,WAAW,CAAC,aAAa,CAAC;iBAC1B,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;iBACtD,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;iBACtD,OAAO,EAAE,CAAA;YAEZ,MAAM,EAAE,CAAC,MAAM;iBACZ,WAAW,CAAC,QAAQ,CAAC;iBACrB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;iBACtD,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;iBAC7B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;iBAClD,OAAO,EAAE,CAAA;QACd,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAmB,EAAE,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAA;YAClD,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAA;QAC/C,CAAC;KACF;CACF,CAAA","sourcesContent":["import path from 'node:path'\nimport { Kysely } from 'kysely'\nimport { DidString } from '@atproto/syntax'\nimport { Database, Migrator } from '../../db/index.js'\n\nexport interface NewAccount {\n did: DidString\n published: 0 | 1\n}\n\nexport interface Failed {\n did: DidString\n error: string | null\n fixed: 0 | 1\n}\n\nexport type RecoveryDbSchema = {\n new_account: NewAccount\n failed: Failed\n}\n\nexport type RecoveryDb = Database<RecoveryDbSchema>\n\nexport const getRecoveryDbFromSequencerLoc = (\n sequencerLoc: string,\n): Promise<RecoveryDb> => {\n const recoveryDbLoc = path.join(path.dirname(sequencerLoc), 'recovery.sqlite')\n return getAndMigrateRecoveryDb(recoveryDbLoc)\n}\n\nexport const getAndMigrateRecoveryDb = async (\n location: string,\n disableWalAutoCheckpoint = false,\n): Promise<RecoveryDb> => {\n const pragmas: Record<string, string> = disableWalAutoCheckpoint\n ? { wal_autocheckpoint: '0' }\n : {}\n const db = Database.sqlite(location, pragmas)\n const migrator = new Migrator(db.db, migrations)\n await migrator.migrateToLatestOrThrow()\n return db\n}\n\nconst migrations = {\n '001': {\n up: async (db: Kysely<unknown>) => {\n await db.schema\n .createTable('new_account')\n .addColumn('did', 'varchar', (col) => col.primaryKey())\n .addColumn('published', 'int2', (col) => col.notNull())\n .execute()\n\n await db.schema\n .createTable('failed')\n .addColumn('did', 'varchar', (col) => col.primaryKey())\n .addColumn('error', 'varchar')\n .addColumn('fixed', 'int2', (col) => col.notNull())\n .execute()\n },\n down: async (db: Kysely<unknown>) => {\n await db.schema.dropTable('new_account').execute()\n await db.schema.dropTable('failed').execute()\n },\n },\n}\n"]}
1
+ {"version":3,"file":"recovery-db.js","sourceRoot":"","sources":["../../../src/scripts/sequencer-recovery/recovery-db.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAoBtD,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,YAAoB,EACC,EAAE;IACvB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAA;IAC9E,OAAO,uBAAuB,CAAC,aAAa,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,QAAgB,EAChB,wBAAwB,GAAG,KAAK,EACX,EAAE;IACvB,MAAM,OAAO,GAA2B,wBAAwB;QAC9D,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,EAAE;QAC7B,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAmB,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC/D,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;IAChD,MAAM,QAAQ,CAAC,sBAAsB,EAAE,CAAA;IACvC,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,MAAM,UAAU,GAAG;IACjB,KAAK,EAAE;QACL,EAAE,EAAE,KAAK,EAAE,EAAmB,EAAE,EAAE;YAChC,MAAM,EAAE,CAAC,MAAM;iBACZ,WAAW,CAAC,aAAa,CAAC;iBAC1B,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;iBACtD,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;iBACtD,OAAO,EAAE,CAAA;YAEZ,MAAM,EAAE,CAAC,MAAM;iBACZ,WAAW,CAAC,QAAQ,CAAC;iBACrB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;iBACtD,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;iBAC7B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;iBAClD,OAAO,EAAE,CAAA;QACd,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAmB,EAAE,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAA;YAClD,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAA;QAC/C,CAAC;KACF;CACF,CAAA","sourcesContent":["import path from 'node:path'\nimport { Kysely } from 'kysely'\nimport { DidString } from '@atproto/syntax'\nimport { Database, Migrator } from '../../db/index.js'\n\nexport interface NewAccount {\n did: DidString\n published: 0 | 1\n}\n\nexport interface Failed {\n did: DidString\n error: string | null\n fixed: 0 | 1\n}\n\nexport type RecoveryDbSchema = {\n new_account: NewAccount\n failed: Failed\n}\n\nexport type RecoveryDb = Database<RecoveryDbSchema>\n\nexport const getRecoveryDbFromSequencerLoc = (\n sequencerLoc: string,\n): Promise<RecoveryDb> => {\n const recoveryDbLoc = path.join(path.dirname(sequencerLoc), 'recovery.sqlite')\n return getAndMigrateRecoveryDb(recoveryDbLoc)\n}\n\nexport const getAndMigrateRecoveryDb = async (\n location: string,\n disableWalAutoCheckpoint = false,\n): Promise<RecoveryDb> => {\n const pragmas: Record<string, string> = disableWalAutoCheckpoint\n ? { wal_autocheckpoint: '0' }\n : {}\n const db = Database.sqlite<RecoveryDbSchema>(location, pragmas)\n const migrator = new Migrator(db.db, migrations)\n await migrator.migrateToLatestOrThrow()\n return db\n}\n\nconst migrations = {\n '001': {\n up: async (db: Kysely<unknown>) => {\n await db.schema\n .createTable('new_account')\n .addColumn('did', 'varchar', (col) => col.primaryKey())\n .addColumn('published', 'int2', (col) => col.notNull())\n .execute()\n\n await db.schema\n .createTable('failed')\n .addColumn('did', 'varchar', (col) => col.primaryKey())\n .addColumn('error', 'varchar')\n .addColumn('fixed', 'int2', (col) => col.notNull())\n .execute()\n },\n down: async (db: Kysely<unknown>) => {\n await db.schema.dropTable('new_account').execute()\n await db.schema.dropTable('failed').execute()\n },\n },\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EACL,cAAc,EACd,SAAS,EACT,YAAY,EAGb,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,eAAO,MAAM,eAAe,QACrB,MAAM,cACC,iBAAiB,KAC5B,OAAO,CAAC,aAAa,CAyBvB,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB,SAAS,QACR,WAAW,KAChB,OAAO,CAAC,aAAa,CAavB,CAAA;AAED,eAAO,MAAM,qBAAqB,eACpB,iBAAiB,KAC5B,WAaF,CAAA;AAED,eAAO,MAAM,oBAAoB,QAC1B,SAAS,WACL,YAAY,KACpB,OAAO,CAAC,aAAa,CAavB,CAAA;AAED,eAAO,MAAM,mBAAmB,QACzB,SAAS,UACN,aAAa,KACpB,OAAO,CAAC,aAAa,CAevB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAUtB,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAIrD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWpB,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD,eAAO,MAAM,OAAO;;;;;;;;;;;;EAIlB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAE7C,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD,eAAO,MAAM,UAAU;;;;;;;;;;;;EAWrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,SAAS,CAAA;CACf,CAAA;AACD,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,OAAO,CAAA;CACb,CAAA;AACD,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,UAAU,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,WAAW,CAAA;CACjB,CAAA;AACD,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,UAAU,CAAA;CAChB,CAAA;AACD,MAAM,MAAM,MAAM,GACd,cAAc,GACd,YAAY,GACZ,gBAAgB,GAChB,eAAe,CAAA"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EACL,cAAc,EACd,SAAS,EACT,YAAY,EAGb,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,eAAO,MAAM,eAAe,QACrB,MAAM,cACC,iBAAiB,KAC5B,OAAO,CAAC,aAAa,CAyBvB,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB,SAAS,QACR,WAAW,KAChB,OAAO,CAAC,aAAa,CAavB,CAAA;AAED,eAAO,MAAM,qBAAqB,eACpB,iBAAiB,KAC5B,WAaF,CAAA;AAED,eAAO,MAAM,oBAAoB,QAC1B,SAAS,WACL,YAAY,KACpB,OAAO,CAAC,aAAa,CAWvB,CAAA;AAED,eAAO,MAAM,mBAAmB,QACzB,SAAS,UACN,aAAa,KACpB,OAAO,CAAC,aAAa,CAYvB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAUtB,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAIrD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWpB,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD,eAAO,MAAM,OAAO;;;;;;;;;;;;EAIlB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAE7C,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD,eAAO,MAAM,UAAU;;;;;;;;;;;;EAWrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,SAAS,CAAA;CACf,CAAA;AACD,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,OAAO,CAAA;CACb,CAAA;AACD,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,UAAU,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,WAAW,CAAA;CACjB,CAAA;AACD,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,UAAU,CAAA;CAChB,CAAA;AACD,MAAM,MAAM,MAAM,GACd,cAAc,GACd,YAAY,GACZ,gBAAgB,GAChB,eAAe,CAAA"}
@@ -55,12 +55,9 @@ export const syncEvtDataFromCommit = (commitData) => {
55
55
  };
56
56
  };
57
57
  export const formatSeqIdentityEvt = async (did, handle) => {
58
- const evt = {
59
- did,
60
- };
61
- if (handle) {
62
- evt.handle = handle;
63
- }
58
+ const evt = handle //
59
+ ? { did, handle }
60
+ : { did };
64
61
  return {
65
62
  did,
66
63
  eventType: 'identity',
@@ -69,13 +66,9 @@ export const formatSeqIdentityEvt = async (did, handle) => {
69
66
  };
70
67
  };
71
68
  export const formatSeqAccountEvt = async (did, status) => {
72
- const evt = {
73
- did,
74
- active: status === 'active',
75
- };
76
- if (status !== AccountStatus.Active) {
77
- evt.status = status;
78
- }
69
+ const evt = status === AccountStatus.Active
70
+ ? { did, active: true }
71
+ : { did, active: false, status };
79
72
  return {
80
73
  did,
81
74
  eventType: 'account',
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAIL,WAAW,EACX,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AAIrE,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,GAAW,EACX,UAA6B,EACL,EAAE;IAC1B,MAAM,YAAY,GAAG,IAAI,QAAQ,EAAE,CAAA;IACnC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACzC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;IAE9C,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,UAAU,CAAC,GAAG;QACtB,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,MAAM,EAAE,MAAM,eAAe,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC;QAC3D,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,SAAS;QAC1C,yCAAyC;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,EAAE;KACV,CAAA;IAED,OAAO;QACL,GAAG;QACH,SAAS,EAAE,QAAiB;QAC5B,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,GAAc,EACd,IAAiB,EACO,EAAE;IAC1B,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3D,MAAM,GAAG,GAAY;QACnB,GAAG;QACH,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM;KACP,CAAA;IACD,OAAO;QACL,GAAG;QACH,SAAS,EAAE,MAAM;QACjB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,UAA6B,EAChB,EAAE;IACf,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC;QAC5D,UAAU,CAAC,GAAG;KACf,CAAC,CAAA;IACF,MAAM,CACJ,CAAC,OAAO,CAAC,MAAM,EACf,wDAAwD,CACzD,CAAA;IACD,OAAO;QACL,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,MAAM;KACP,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,GAAc,EACd,MAAqB,EACG,EAAE;IAC1B,MAAM,GAAG,GAAgB;QACvB,GAAG;KACJ,CAAA;IACD,IAAI,MAAM,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,GAAG,MAAM,CAAA;IACrB,CAAC;IACD,OAAO;QACL,GAAG;QACH,SAAS,EAAE,UAAU;QACrB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,GAAc,EACd,MAAqB,EACG,EAAE;IAC1B,MAAM,GAAG,GAAe;QACtB,GAAG;QACH,MAAM,EAAE,MAAM,KAAK,QAAQ;KAC5B,CAAA;IACD,IAAI,MAAM,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QACpC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAA;IACrB,CAAC;IAED,OAAO;QACL,GAAG;QACH,SAAS,EAAE,SAAS;QACpB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC;QACd,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;KACpB,CAAC;IACF,wEAAwE;IACxE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;IAC1B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAA;AAGF,6EAA6E;AAC7E,oCAAoC;AACpC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,GAAG;IAClB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,MAAM,CAAC,KAAK;IACpB,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,KAAK;IACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;CAChB,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE;CACrD,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,MAAM,EAAE,CAAC;SACN,IAAI,CAAC;QACJ,aAAa,CAAC,SAAS;QACvB,aAAa,CAAC,SAAS;QACvB,aAAa,CAAC,OAAO;QACrB,aAAa,CAAC,WAAW;KAC1B,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAA","sourcesContent":["import assert from 'node:assert'\nimport { z } from 'zod'\nimport { schema } from '@atproto/common'\nimport {\n DatetimeString,\n DidString,\n HandleString,\n isDidString,\n isHandleString,\n} from '@atproto/lex'\nimport { encode as cborEncode } from '@atproto/lex-cbor'\nimport { BlockMap, blocksToCarFile } from '@atproto/repo'\nimport { AccountStatus } from '../account-manager/account-manager.js'\nimport { CommitDataWithOps, SyncEvtData } from '../repo/index.js'\nimport { RepoSeqInsert } from './db/index.js'\n\nexport const formatSeqCommit = async (\n did: string,\n commitData: CommitDataWithOps,\n): Promise<RepoSeqInsert> => {\n const blocksToSend = new BlockMap()\n blocksToSend.addMap(commitData.newBlocks)\n blocksToSend.addMap(commitData.relevantBlocks)\n\n const evt = {\n repo: did,\n commit: commitData.cid,\n rev: commitData.rev,\n since: commitData.since,\n blocks: await blocksToCarFile(commitData.cid, blocksToSend),\n ops: commitData.ops,\n prevData: commitData.prevData ?? undefined,\n // deprecated (but still required) fields\n rebase: false,\n tooBig: false,\n blobs: [],\n }\n\n return {\n did,\n eventType: 'append' as const,\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const formatSeqSyncEvt = async (\n did: DidString,\n data: SyncEvtData,\n): Promise<RepoSeqInsert> => {\n const blocks = await blocksToCarFile(data.cid, data.blocks)\n const evt: SyncEvt = {\n did,\n rev: data.rev,\n blocks,\n }\n return {\n did,\n eventType: 'sync',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const syncEvtDataFromCommit = (\n commitData: CommitDataWithOps,\n): SyncEvtData => {\n const { blocks, missing } = commitData.relevantBlocks.getMany([\n commitData.cid,\n ])\n assert(\n !missing.length,\n 'commit block was not found, could not build sync event',\n )\n return {\n rev: commitData.rev,\n cid: commitData.cid,\n blocks,\n }\n}\n\nexport const formatSeqIdentityEvt = async (\n did: DidString,\n handle?: HandleString,\n): Promise<RepoSeqInsert> => {\n const evt: IdentityEvt = {\n did,\n }\n if (handle) {\n evt.handle = handle\n }\n return {\n did,\n eventType: 'identity',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const formatSeqAccountEvt = async (\n did: DidString,\n status: AccountStatus,\n): Promise<RepoSeqInsert> => {\n const evt: AccountEvt = {\n did,\n active: status === 'active',\n }\n if (status !== AccountStatus.Active) {\n evt.status = status\n }\n\n return {\n did,\n eventType: 'account',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const commitEvtOp = z.object({\n action: z.union([\n z.literal('create'),\n z.literal('update'),\n z.literal('delete'),\n ]),\n // @TODO should we validate that the \"path\" is a valid \"<nsid>/<rkey>\" ?\n path: z.string(),\n cid: schema.cid.nullable(),\n prev: schema.cid.optional(),\n})\nexport type CommitEvtOp = z.infer<typeof commitEvtOp>\n\n// @TODO This runtime code is only used to generate \"types\". We should either\n// make use of it or only use types.\nexport const commitEvt = z.object({\n rebase: z.boolean(),\n tooBig: z.boolean(),\n repo: z.string().refine(isDidString),\n commit: schema.cid,\n rev: z.string(),\n since: z.string().nullable(),\n blocks: schema.bytes,\n ops: z.array(commitEvtOp),\n blobs: z.array(schema.cid),\n prevData: schema.cid.optional(),\n})\nexport type CommitEvt = z.infer<typeof commitEvt>\n\nexport const syncEvt = z.object({\n did: z.string().refine(isDidString),\n blocks: schema.bytes,\n rev: z.string(),\n})\nexport type SyncEvt = z.infer<typeof syncEvt>\n\nexport const identityEvt = z.object({\n did: z.string().refine(isDidString),\n handle: z.string().refine(isHandleString).optional(),\n})\nexport type IdentityEvt = z.infer<typeof identityEvt>\n\nexport const accountEvt = z.object({\n did: z.string().refine(isDidString),\n active: z.boolean(),\n status: z\n .enum([\n AccountStatus.Takendown,\n AccountStatus.Suspended,\n AccountStatus.Deleted,\n AccountStatus.Deactivated,\n ])\n .optional(),\n})\nexport type AccountEvt = z.infer<typeof accountEvt>\n\ntype TypedCommitEvt = {\n type: 'commit'\n seq: number\n time: DatetimeString\n evt: CommitEvt\n}\ntype TypedSyncEvt = {\n type: 'sync'\n seq: number\n time: DatetimeString\n evt: SyncEvt\n}\ntype TypedIdentityEvt = {\n type: 'identity'\n seq: number\n time: DatetimeString\n evt: IdentityEvt\n}\ntype TypedAccountEvt = {\n type: 'account'\n seq: number\n time: DatetimeString\n evt: AccountEvt\n}\nexport type SeqEvt =\n | TypedCommitEvt\n | TypedSyncEvt\n | TypedIdentityEvt\n | TypedAccountEvt\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { z } from 'zod'\nimport { schema } from '@atproto/common'\nimport {\n DatetimeString,\n DidString,\n HandleString,\n isDidString,\n isHandleString,\n} from '@atproto/lex'\nimport { encode as cborEncode } from '@atproto/lex-cbor'\nimport { BlockMap, blocksToCarFile } from '@atproto/repo'\nimport { AccountStatus } from '../account-manager/account-manager.js'\nimport { CommitDataWithOps, SyncEvtData } from '../repo/index.js'\nimport { RepoSeqInsert } from './db/index.js'\n\nexport const formatSeqCommit = async (\n did: string,\n commitData: CommitDataWithOps,\n): Promise<RepoSeqInsert> => {\n const blocksToSend = new BlockMap()\n blocksToSend.addMap(commitData.newBlocks)\n blocksToSend.addMap(commitData.relevantBlocks)\n\n const evt = {\n repo: did,\n commit: commitData.cid,\n rev: commitData.rev,\n since: commitData.since,\n blocks: await blocksToCarFile(commitData.cid, blocksToSend),\n ops: commitData.ops,\n prevData: commitData.prevData ?? undefined,\n // deprecated (but still required) fields\n rebase: false,\n tooBig: false,\n blobs: [],\n }\n\n return {\n did,\n eventType: 'append' as const,\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const formatSeqSyncEvt = async (\n did: DidString,\n data: SyncEvtData,\n): Promise<RepoSeqInsert> => {\n const blocks = await blocksToCarFile(data.cid, data.blocks)\n const evt: SyncEvt = {\n did,\n rev: data.rev,\n blocks,\n }\n return {\n did,\n eventType: 'sync',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const syncEvtDataFromCommit = (\n commitData: CommitDataWithOps,\n): SyncEvtData => {\n const { blocks, missing } = commitData.relevantBlocks.getMany([\n commitData.cid,\n ])\n assert(\n !missing.length,\n 'commit block was not found, could not build sync event',\n )\n return {\n rev: commitData.rev,\n cid: commitData.cid,\n blocks,\n }\n}\n\nexport const formatSeqIdentityEvt = async (\n did: DidString,\n handle?: HandleString,\n): Promise<RepoSeqInsert> => {\n const evt: IdentityEvt = handle //\n ? { did, handle }\n : { did }\n\n return {\n did,\n eventType: 'identity',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const formatSeqAccountEvt = async (\n did: DidString,\n status: AccountStatus,\n): Promise<RepoSeqInsert> => {\n const evt: AccountEvt =\n status === AccountStatus.Active\n ? { did, active: true }\n : { did, active: false, status }\n\n return {\n did,\n eventType: 'account',\n event: cborEncode(evt),\n sequencedAt: new Date().toISOString(),\n }\n}\n\nexport const commitEvtOp = z.object({\n action: z.union([\n z.literal('create'),\n z.literal('update'),\n z.literal('delete'),\n ]),\n // @TODO should we validate that the \"path\" is a valid \"<nsid>/<rkey>\" ?\n path: z.string(),\n cid: schema.cid.nullable(),\n prev: schema.cid.optional(),\n})\nexport type CommitEvtOp = z.infer<typeof commitEvtOp>\n\n// @TODO This runtime code is only used to generate \"types\". We should either\n// make use of it or only use types.\nexport const commitEvt = z.object({\n rebase: z.boolean(),\n tooBig: z.boolean(),\n repo: z.string().refine(isDidString),\n commit: schema.cid,\n rev: z.string(),\n since: z.string().nullable(),\n blocks: schema.bytes,\n ops: z.array(commitEvtOp),\n blobs: z.array(schema.cid),\n prevData: schema.cid.optional(),\n})\nexport type CommitEvt = z.infer<typeof commitEvt>\n\nexport const syncEvt = z.object({\n did: z.string().refine(isDidString),\n blocks: schema.bytes,\n rev: z.string(),\n})\nexport type SyncEvt = z.infer<typeof syncEvt>\n\nexport const identityEvt = z.object({\n did: z.string().refine(isDidString),\n handle: z.string().refine(isHandleString).optional(),\n})\nexport type IdentityEvt = z.infer<typeof identityEvt>\n\nexport const accountEvt = z.object({\n did: z.string().refine(isDidString),\n active: z.boolean(),\n status: z\n .enum([\n AccountStatus.Takendown,\n AccountStatus.Suspended,\n AccountStatus.Deleted,\n AccountStatus.Deactivated,\n ])\n .optional(),\n})\nexport type AccountEvt = z.infer<typeof accountEvt>\n\ntype TypedCommitEvt = {\n type: 'commit'\n seq: number\n time: DatetimeString\n evt: CommitEvt\n}\ntype TypedSyncEvt = {\n type: 'sync'\n seq: number\n time: DatetimeString\n evt: SyncEvt\n}\ntype TypedIdentityEvt = {\n type: 'identity'\n seq: number\n time: DatetimeString\n evt: IdentityEvt\n}\ntype TypedAccountEvt = {\n type: 'account'\n seq: number\n time: DatetimeString\n evt: AccountEvt\n}\nexport type SeqEvt =\n | TypedCommitEvt\n | TypedSyncEvt\n | TypedIdentityEvt\n | TypedAccountEvt\n"]}
@@ -29,7 +29,7 @@ export declare class Sequencer extends Sequencer_base {
29
29
  }): Promise<SeqEvt[]>;
30
30
  private pollDb;
31
31
  private exponentialBackoff;
32
- protected sequenceEvts(events: readonly RepoSeqInsert[]): Promise<number[]>;
32
+ sequenceEvts(events: readonly RepoSeqInsert[]): Promise<number[]>;
33
33
  sequenceCommit(did: DidString, commitData: CommitDataWithOps): Promise<void>;
34
34
  sequenceSync(did: DidString, data: SyncEvtData): Promise<void>;
35
35
  sequenceIdentity(did: DidString, handle?: HandleString): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}