@atproto/bsky 0.0.215 → 0.0.217
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.
- package/CHANGELOG.md +13 -0
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +6 -4
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +2 -0
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +10 -3
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +9 -2
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +2 -2
- package/dist/context.js.map +1 -1
- package/dist/feature-gates/gates.d.ts +5 -0
- package/dist/feature-gates/gates.d.ts.map +1 -0
- package/dist/feature-gates/gates.js +6 -0
- package/dist/feature-gates/gates.js.map +1 -0
- package/dist/feature-gates/index.d.ts +24 -0
- package/dist/feature-gates/index.d.ts.map +1 -0
- package/dist/feature-gates/index.js +135 -0
- package/dist/feature-gates/index.js.map +1 -0
- package/dist/feature-gates/metrics.d.ts +32 -0
- package/dist/feature-gates/metrics.d.ts.map +1 -0
- package/dist/feature-gates/metrics.js +100 -0
- package/dist/feature-gates/metrics.js.map +1 -0
- package/dist/feature-gates/metrics.test.d.ts +2 -0
- package/dist/feature-gates/metrics.test.d.ts.map +1 -0
- package/dist/feature-gates/metrics.test.js +152 -0
- package/dist/feature-gates/metrics.test.js.map +1 -0
- package/dist/feature-gates/types.d.ts +49 -0
- package/dist/feature-gates/types.d.ts.map +1 -0
- package/dist/feature-gates/types.js +3 -0
- package/dist/feature-gates/types.js.map +1 -0
- package/dist/feature-gates/utils.d.ts +21 -0
- package/dist/feature-gates/utils.d.ts.map +1 -0
- package/dist/feature-gates/utils.js +85 -0
- package/dist/feature-gates/utils.js.map +1 -0
- package/dist/hydration/hydrator.d.ts +8 -3
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +9 -5
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +2 -2
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +4 -4
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +116 -100
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +59 -51
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts +3 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/{getSuggestedOnboardingUsersSkeleton.d.ts → getOnboardingSuggestedUsersSkeleton.d.ts} +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/{getSuggestedOnboardingUsersSkeleton.d.ts.map → getOnboardingSuggestedUsersSkeleton.d.ts.map} +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/{getSuggestedOnboardingUsersSkeleton.js → getOnboardingSuggestedUsersSkeleton.js} +2 -2
- package/dist/lexicon/types/app/bsky/unspecced/{getSuggestedOnboardingUsersSkeleton.js.map → getOnboardingSuggestedUsersSkeleton.js.map} +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts +3 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.js.map +1 -1
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +3 -4
- package/dist/views/index.js.map +1 -1
- package/package.json +9 -9
- package/src/api/app/bsky/feed/searchPosts.ts +10 -8
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +3 -1
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +3 -3
- package/src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts +14 -7
- package/src/api/app/bsky/unspecced/getSuggestedUsers.ts +13 -6
- package/src/config.ts +8 -0
- package/src/context.ts +4 -4
- package/src/feature-gates/README.md +47 -0
- package/src/feature-gates/gates.ts +9 -0
- package/src/feature-gates/index.ts +146 -0
- package/src/feature-gates/metrics.test.ts +196 -0
- package/src/feature-gates/metrics.ts +107 -0
- package/src/feature-gates/types.ts +52 -0
- package/src/feature-gates/utils.ts +90 -0
- package/src/hydration/hydrator.ts +12 -6
- package/src/index.ts +8 -7
- package/src/lexicon/index.ts +13 -13
- package/src/lexicon/lexicons.ts +63 -55
- package/src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts +3 -1
- package/src/lexicon/types/app/bsky/unspecced/{getSuggestedOnboardingUsersSkeleton.ts → getOnboardingSuggestedUsersSkeleton.ts} +1 -1
- package/src/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.ts +3 -1
- package/src/views/index.ts +5 -8
- package/tests/views/get-suggested-onboarding-users.test.ts +1 -1
- package/tests/views/thread.test.ts +2 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/feature-gates.d.ts +0 -44
- package/dist/feature-gates.d.ts.map +0 -1
- package/dist/feature-gates.js +0 -133
- package/dist/feature-gates.js.map +0 -1
- package/src/feature-gates.ts +0 -136
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { noUndefinedVals } from '@atproto/common'\nimport { subLogger as log } from './logger'\n\ntype LiveNowConfig = {\n did: string\n domains: string[]\n}[]\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: string\n alternateAudienceDids: string[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: string\n adminPasswords: string[]\n labelsFromIssuerDids?: string[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid)\n\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return this.cfg.labelsFromIssuerDids ?? []\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { noUndefinedVals } from '@atproto/common'\nimport { subLogger as log } from './logger'\n\ntype LiveNowConfig = {\n did: string\n domains: string[]\n}[]\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: string\n alternateAudienceDids: string[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: string\n adminPasswords: string[]\n labelsFromIssuerDids?: string[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n eventProxyTrackingEndpoint?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid)\n\n const eventProxyTrackingEndpoint =\n process.env.BSKY_EVENT_PROXY_TRACKING_ENDPOINT || undefined\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n eventProxyTrackingEndpoint,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return this.cfg.labelsFromIssuerDids ?? []\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get eventProxyTrackingEndpoint() {\n return this.cfg.eventProxyTrackingEndpoint\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
|
package/dist/context.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { BsyncClient } from './bsync';
|
|
|
10
10
|
import { ServerConfig } from './config';
|
|
11
11
|
import { CourierClient } from './courier';
|
|
12
12
|
import { DataPlaneClient, HostList } from './data-plane/client';
|
|
13
|
-
import {
|
|
13
|
+
import { FeatureGatesClient } from './feature-gates';
|
|
14
14
|
import { Hydrator } from './hydration/hydrator';
|
|
15
15
|
import { KwsClient } from './kws';
|
|
16
16
|
import { RolodexClient } from './rolodex';
|
|
@@ -36,7 +36,7 @@ export declare class AppContext {
|
|
|
36
36
|
courierClient: CourierClient | undefined;
|
|
37
37
|
rolodexClient: RolodexClient | undefined;
|
|
38
38
|
authVerifier: AuthVerifier;
|
|
39
|
-
|
|
39
|
+
featureGatesClient: FeatureGatesClient;
|
|
40
40
|
blobDispatcher: Dispatcher;
|
|
41
41
|
kwsClient: KwsClient | undefined;
|
|
42
42
|
});
|
|
@@ -57,7 +57,7 @@ export declare class AppContext {
|
|
|
57
57
|
get courierClient(): CourierClient | undefined;
|
|
58
58
|
get rolodexClient(): RolodexClient | undefined;
|
|
59
59
|
get authVerifier(): AuthVerifier;
|
|
60
|
-
get
|
|
60
|
+
get featureGatesClient(): FeatureGatesClient;
|
|
61
61
|
get blobDispatcher(): Dispatcher;
|
|
62
62
|
get kwsClient(): KwsClient | undefined;
|
|
63
63
|
reqLabelers(req: express.Request): ParsedLabelers;
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/context.js
CHANGED
|
@@ -97,8 +97,8 @@ class AppContext {
|
|
|
97
97
|
get authVerifier() {
|
|
98
98
|
return this.opts.authVerifier;
|
|
99
99
|
}
|
|
100
|
-
get
|
|
101
|
-
return this.opts.
|
|
100
|
+
get featureGatesClient() {
|
|
101
|
+
return this.opts.featureGatesClient;
|
|
102
102
|
}
|
|
103
103
|
get blobDispatcher() {
|
|
104
104
|
return this.opts.blobDispatcher;
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAmC;AAenC,qCAA4C;AAG5C,iCAIe;AAGf,MAAa,UAAU;IACrB,YACU,IAoBP;QApBD;;;;mBAAQ,IAAI;WAoBX;IACA,CAAC;IAEJ,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;IACtB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAA;IAC5B,CAAC;IAED,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAA;IACpC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAA;IACnC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC3B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;IACxB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;IAC7B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;IAC7B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;IAChC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;IAChC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAA;IAC/B,CAAC;IAED,IAAI,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAmC;AAenC,qCAA4C;AAG5C,iCAIe;AAGf,MAAa,UAAU;IACrB,YACU,IAoBP;QApBD;;;;mBAAQ,IAAI;WAoBX;IACA,CAAC;IAEJ,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;IACtB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAA;IAC5B,CAAC;IAED,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAA;IACpC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAA;IACnC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC3B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;IACxB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;IAC7B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;IAC7B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;IAC9B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;IAChC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;IAChC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAA;IAC/B,CAAC;IAED,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAA;IACrC,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAA;IACjC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAA;IAC5B,CAAC;IAED,WAAW,CAAC,GAAoB;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAA;QACjD,IAAI,MAA6B,CAAA;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,IAAA,yBAAkB,EAAC,GAAG,CAAC,CAAA;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,IAAI,CAAA;YACb,mBAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,gCAAgC,CAAC,CAAA;QAC1D,CAAC;QACD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAA,2BAAoB,EAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QACvE,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AArHD,gCAqHC","sourcesContent":["import * as plc from '@did-plc/lib'\nimport { Etcd3 } from 'etcd3'\nimport express from 'express'\nimport { Dispatcher } from 'undici'\nimport { AtpAgent } from '@atproto/api'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { AuthVerifier } from './auth-verifier'\nimport { BsyncClient } from './bsync'\nimport { ServerConfig } from './config'\nimport { CourierClient } from './courier'\nimport { DataPlaneClient, HostList } from './data-plane/client'\nimport { FeatureGatesClient } from './feature-gates'\nimport { Hydrator } from './hydration/hydrator'\nimport { KwsClient } from './kws'\nimport { httpLogger as log } from './logger'\nimport { RolodexClient } from './rolodex'\nimport { StashClient } from './stash'\nimport {\n ParsedLabelers,\n defaultLabelerHeader,\n parseLabelerHeader,\n} from './util'\nimport { Views } from './views'\n\nexport class AppContext {\n constructor(\n private opts: {\n cfg: ServerConfig\n etcd: Etcd3 | undefined\n dataplane: DataPlaneClient\n dataplaneHostList: HostList\n searchAgent: AtpAgent | undefined\n suggestionsAgent: AtpAgent | undefined\n topicsAgent: AtpAgent | undefined\n hydrator: Hydrator\n views: Views\n signingKey: Keypair\n idResolver: IdResolver\n bsyncClient: BsyncClient\n stashClient: StashClient\n courierClient: CourierClient | undefined\n rolodexClient: RolodexClient | undefined\n authVerifier: AuthVerifier\n featureGatesClient: FeatureGatesClient\n blobDispatcher: Dispatcher\n kwsClient: KwsClient | undefined\n },\n ) {}\n\n get cfg(): ServerConfig {\n return this.opts.cfg\n }\n\n get etcd() {\n return this.opts.etcd\n }\n\n get dataplane(): DataPlaneClient {\n return this.opts.dataplane\n }\n\n get dataplaneHostList(): HostList {\n return this.opts.dataplaneHostList\n }\n\n get searchAgent(): AtpAgent | undefined {\n return this.opts.searchAgent\n }\n\n get suggestionsAgent(): AtpAgent | undefined {\n return this.opts.suggestionsAgent\n }\n\n get topicsAgent(): AtpAgent | undefined {\n return this.opts.topicsAgent\n }\n\n get hydrator(): Hydrator {\n return this.opts.hydrator\n }\n\n get views(): Views {\n return this.opts.views\n }\n\n get signingKey(): Keypair {\n return this.opts.signingKey\n }\n\n get plcClient(): plc.Client {\n return new plc.Client(this.cfg.didPlcUrl)\n }\n\n get idResolver(): IdResolver {\n return this.opts.idResolver\n }\n\n get bsyncClient(): BsyncClient {\n return this.opts.bsyncClient\n }\n\n get stashClient(): StashClient {\n return this.opts.stashClient\n }\n\n get courierClient(): CourierClient | undefined {\n return this.opts.courierClient\n }\n\n get rolodexClient(): RolodexClient | undefined {\n return this.opts.rolodexClient\n }\n\n get authVerifier(): AuthVerifier {\n return this.opts.authVerifier\n }\n\n get featureGatesClient(): FeatureGatesClient {\n return this.opts.featureGatesClient\n }\n\n get blobDispatcher(): Dispatcher {\n return this.opts.blobDispatcher\n }\n\n get kwsClient(): KwsClient | undefined {\n return this.opts.kwsClient\n }\n\n reqLabelers(req: express.Request): ParsedLabelers {\n const val = req.header('atproto-accept-labelers')\n let parsed: ParsedLabelers | null\n try {\n parsed = parseLabelerHeader(val)\n } catch (err) {\n parsed = null\n log.info({ err, val }, 'failed to parse labeler header')\n }\n if (!parsed) return defaultLabelerHeader(this.cfg.labelsFromIssuerDids)\n return parsed\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADD ALL FEATURE GATES HERE.
|
|
3
|
+
*/
|
|
4
|
+
export type FeatureGate = 'suggested_users:discover_agent:enable' | 'suggested_onboarding_users:discover_agent:enable' | 'threads:reply_ranking_exploration:enable' | 'search:filtering_exploration:enable';
|
|
5
|
+
//# sourceMappingURL=gates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,WAAW,GACnB,uCAAuC,GACvC,kDAAkD,GAClD,0CAA0C,GAC1C,qCAAqC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":";AAAA;;GAEG","sourcesContent":["/**\n * ADD ALL FEATURE GATES HERE.\n */\n\nexport type FeatureGate =\n | 'suggested_users:discover_agent:enable'\n | 'suggested_onboarding_users:discover_agent:enable'\n | 'threads:reply_ranking_exploration:enable'\n | 'search:filtering_exploration:enable'\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GrowthBookClient } from '@growthbook/growthbook';
|
|
2
|
+
import { FeatureGate } from './gates';
|
|
3
|
+
import { MetricsClient } from './metrics';
|
|
4
|
+
import { CheckedFeatureGatesMap, RawUserContext } from './types';
|
|
5
|
+
export declare class FeatureGatesClient {
|
|
6
|
+
private config;
|
|
7
|
+
ready: boolean;
|
|
8
|
+
client: GrowthBookClient | undefined;
|
|
9
|
+
refreshInterval: NodeJS.Timeout | undefined;
|
|
10
|
+
metrics: MetricsClient;
|
|
11
|
+
constructor(config: {
|
|
12
|
+
growthBookApiHost?: string;
|
|
13
|
+
growthBookClientKey?: string;
|
|
14
|
+
eventProxyTrackingEndpoint?: string;
|
|
15
|
+
});
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Evaluate multiple feature gates for a given user, returning a map of gate
|
|
20
|
+
* ID to boolean result.
|
|
21
|
+
*/
|
|
22
|
+
checkGates(gates: FeatureGate[], rawUserContext: RawUserContext): CheckedFeatureGatesMap;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAmBhE,qBAAa,kBAAkB;IAO3B,OAAO,CAAC,MAAM;IANhB,KAAK,UAAQ;IACb,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAY;IAChD,eAAe,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAY;IACvD,OAAO,EAAE,aAAa,CAAA;gBAGZ,MAAM,EAAE;QACd,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAA;KACpC;IAOG,KAAK;IAiFX,OAAO;IAUP;;;OAGG;IACH,UAAU,CACR,KAAK,EAAE,WAAW,EAAE,EACpB,cAAc,EAAE,cAAc,GAC7B,sBAAsB;CAM1B"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FeatureGatesClient = void 0;
|
|
4
|
+
const growthbook_1 = require("@growthbook/growthbook");
|
|
5
|
+
const logger_1 = require("../logger");
|
|
6
|
+
const metrics_1 = require("./metrics");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
/**
|
|
9
|
+
* We want this to be sufficiently high that we don't time out under
|
|
10
|
+
* normal conditions, but not so high that it takes too long to boot
|
|
11
|
+
* the server.
|
|
12
|
+
*/
|
|
13
|
+
const FETCH_TIMEOUT = 3e3; // 3 seconds
|
|
14
|
+
/**
|
|
15
|
+
* StatSig used to default to every 10s, but I think 1m is fine
|
|
16
|
+
*/
|
|
17
|
+
const REFETCH_INTERVAL = 60e3; // 1 minute
|
|
18
|
+
class FeatureGatesClient {
|
|
19
|
+
constructor(config) {
|
|
20
|
+
Object.defineProperty(this, "config", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: config
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "ready", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: false
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "client", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: undefined
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "refreshInterval", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: undefined
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(this, "metrics", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true,
|
|
48
|
+
value: void 0
|
|
49
|
+
});
|
|
50
|
+
this.metrics = new metrics_1.MetricsClient({
|
|
51
|
+
trackingEndpoint: config.eventProxyTrackingEndpoint,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async start() {
|
|
55
|
+
if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {
|
|
56
|
+
logger_1.featureGatesLogger.info({}, 'feature gates not configured, skipping initialization');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
this.client = new growthbook_1.GrowthBookClient({
|
|
61
|
+
apiHost: this.config.growthBookApiHost,
|
|
62
|
+
clientKey: this.config.growthBookClientKey,
|
|
63
|
+
onFeatureUsage: (feature, result, userContext) => {
|
|
64
|
+
this.metrics.track('feature:viewed', {
|
|
65
|
+
featureId: feature,
|
|
66
|
+
featureResultValue: result.value,
|
|
67
|
+
experimentId: result.experiment?.key,
|
|
68
|
+
variationId: result.experimentResult?.key,
|
|
69
|
+
}, (0, utils_1.parsedUserContextToTrackingMetadata)((0, utils_1.extractParsedUserContextFromGrowthBookUserContext)(userContext)));
|
|
70
|
+
},
|
|
71
|
+
trackingCallback: (experiment, result, userContext) => {
|
|
72
|
+
this.metrics.track('experiment:viewed', {
|
|
73
|
+
experimentId: experiment.key,
|
|
74
|
+
variationId: result.key,
|
|
75
|
+
}, (0, utils_1.parsedUserContextToTrackingMetadata)((0, utils_1.extractParsedUserContextFromGrowthBookUserContext)(userContext)));
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
const { source, error } = await this.client.init({
|
|
79
|
+
timeout: FETCH_TIMEOUT,
|
|
80
|
+
});
|
|
81
|
+
/**
|
|
82
|
+
* This does not necessarily mean that the client completely failed,
|
|
83
|
+
* since it could just be that the request timed out. It may succeed
|
|
84
|
+
* after the timeout, or later during refreshes.
|
|
85
|
+
*
|
|
86
|
+
* @see https://docs.growthbook.io/lib/node#error-handling
|
|
87
|
+
*/
|
|
88
|
+
if (error) {
|
|
89
|
+
logger_1.featureGatesLogger.error({ err: error, source }, 'Client failed to initialize normally');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Set up periodic refresh of feature definitions
|
|
93
|
+
*
|
|
94
|
+
* @see https://docs.growthbook.io/lib/node#refreshing-features
|
|
95
|
+
*/
|
|
96
|
+
this.refreshInterval = setInterval(async () => {
|
|
97
|
+
try {
|
|
98
|
+
await this.client?.refreshFeatures({
|
|
99
|
+
timeout: FETCH_TIMEOUT,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
logger_1.featureGatesLogger.error({ err }, 'Failed to refresh features');
|
|
104
|
+
}
|
|
105
|
+
}, REFETCH_INTERVAL);
|
|
106
|
+
/* Ready or not, here we come */
|
|
107
|
+
this.ready = true;
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
logger_1.featureGatesLogger.error({ err }, 'Client initialization failed');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
destroy() {
|
|
114
|
+
if (this.ready) {
|
|
115
|
+
this.ready = false;
|
|
116
|
+
if (this.refreshInterval) {
|
|
117
|
+
clearInterval(this.refreshInterval);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.metrics.stop();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Evaluate multiple feature gates for a given user, returning a map of gate
|
|
124
|
+
* ID to boolean result.
|
|
125
|
+
*/
|
|
126
|
+
checkGates(gates, rawUserContext) {
|
|
127
|
+
const gb = this.client;
|
|
128
|
+
const attributes = (0, utils_1.parseRawUserContext)(rawUserContext);
|
|
129
|
+
if (!gb || !this.ready)
|
|
130
|
+
return new Map(gates.map((g) => [g, false]));
|
|
131
|
+
return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.FeatureGatesClient = FeatureGatesClient;
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GrowthBookClient } from '@growthbook/growthbook'\nimport { featureGatesLogger } from '../logger'\nimport { FeatureGate } from './gates'\nimport { MetricsClient } from './metrics'\nimport { CheckedFeatureGatesMap, RawUserContext } from './types'\nimport {\n extractParsedUserContextFromGrowthBookUserContext,\n parseRawUserContext,\n parsedUserContextToTrackingMetadata,\n} from './utils'\n\n/**\n * We want this to be sufficiently high that we don't time out under\n * normal conditions, but not so high that it takes too long to boot\n * the server.\n */\nconst FETCH_TIMEOUT = 3e3 // 3 seconds\n\n/**\n * StatSig used to default to every 10s, but I think 1m is fine\n */\nconst REFETCH_INTERVAL = 60e3 // 1 minute\n\nexport class FeatureGatesClient {\n ready = false\n client: GrowthBookClient | undefined = undefined\n refreshInterval: NodeJS.Timeout | undefined = undefined\n metrics: MetricsClient\n\n constructor(\n private config: {\n growthBookApiHost?: string\n growthBookClientKey?: string\n eventProxyTrackingEndpoint?: string\n },\n ) {\n this.metrics = new MetricsClient({\n trackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n }\n\n async start() {\n if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {\n featureGatesLogger.info(\n {},\n 'feature gates not configured, skipping initialization',\n )\n return\n }\n\n try {\n this.client = new GrowthBookClient({\n apiHost: this.config.growthBookApiHost,\n clientKey: this.config.growthBookClientKey,\n onFeatureUsage: (feature, result, userContext) => {\n this.metrics.track(\n 'feature:viewed',\n {\n featureId: feature,\n featureResultValue: result.value,\n experimentId: result.experiment?.key,\n variationId: result.experimentResult?.key,\n },\n parsedUserContextToTrackingMetadata(\n extractParsedUserContextFromGrowthBookUserContext(userContext),\n ),\n )\n },\n trackingCallback: (experiment, result, userContext) => {\n this.metrics.track(\n 'experiment:viewed',\n {\n experimentId: experiment.key,\n variationId: result.key,\n },\n parsedUserContextToTrackingMetadata(\n extractParsedUserContextFromGrowthBookUserContext(userContext),\n ),\n )\n },\n })\n\n const { source, error } = await this.client.init({\n timeout: FETCH_TIMEOUT,\n })\n\n /**\n * This does not necessarily mean that the client completely failed,\n * since it could just be that the request timed out. It may succeed\n * after the timeout, or later during refreshes.\n *\n * @see https://docs.growthbook.io/lib/node#error-handling\n */\n if (error) {\n featureGatesLogger.error(\n { err: error, source },\n 'Client failed to initialize normally',\n )\n }\n\n /**\n * Set up periodic refresh of feature definitions\n *\n * @see https://docs.growthbook.io/lib/node#refreshing-features\n */\n this.refreshInterval = setInterval(async () => {\n try {\n await this.client?.refreshFeatures({\n timeout: FETCH_TIMEOUT,\n })\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to refresh features')\n }\n }, REFETCH_INTERVAL)\n\n /* Ready or not, here we come */\n this.ready = true\n } catch (err) {\n featureGatesLogger.error({ err }, 'Client initialization failed')\n }\n }\n\n destroy() {\n if (this.ready) {\n this.ready = false\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval)\n }\n }\n this.metrics.stop()\n }\n\n /**\n * Evaluate multiple feature gates for a given user, returning a map of gate\n * ID to boolean result.\n */\n checkGates(\n gates: FeatureGate[],\n rawUserContext: RawUserContext,\n ): CheckedFeatureGatesMap {\n const gb = this.client\n const attributes = parseRawUserContext(rawUserContext)\n if (!gb || !this.ready) return new Map(gates.map((g) => [g, false]))\n return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]))\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
type Events = {
|
|
2
|
+
'experiment:viewed': {
|
|
3
|
+
experimentId: string;
|
|
4
|
+
variationId: string;
|
|
5
|
+
};
|
|
6
|
+
'feature:viewed': {
|
|
7
|
+
featureId: string;
|
|
8
|
+
featureResultValue: unknown;
|
|
9
|
+
/** Only available if feature has experiment rules applied */
|
|
10
|
+
experimentId?: string;
|
|
11
|
+
/** Only available if feature has experiment rules applied */
|
|
12
|
+
variationId?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export type Config = {
|
|
16
|
+
trackingEndpoint?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare class MetricsClient<M extends Record<string, any> = Events> {
|
|
19
|
+
private config;
|
|
20
|
+
maxBatchSize: number;
|
|
21
|
+
private started;
|
|
22
|
+
private queue;
|
|
23
|
+
private flushInterval;
|
|
24
|
+
constructor(config: Config);
|
|
25
|
+
start(): void;
|
|
26
|
+
stop(): void;
|
|
27
|
+
track<E extends keyof M>(event: E, payload: M[E], metadata?: Record<string, any>): void;
|
|
28
|
+
flush(): void;
|
|
29
|
+
private sendBatch;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":"AAEA,KAAK,MAAM,GAAG;IACZ,mBAAmB,EAAE;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,gBAAgB,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,kBAAkB,EAAE,OAAO,CAAA;QAC3B,6DAA6D;QAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,6DAA6D;QAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF,CAAA;AASD,MAAM,MAAM,MAAM,GAAG;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,qBAAa,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAMnD,OAAO,CAAC,MAAM;IAL1B,YAAY,SAAM;IAElB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,aAAa,CAA8B;gBAC/B,MAAM,EAAE,MAAM;IAElC,KAAK;IAQL,IAAI;IAQJ,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EACrB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EACb,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAkBpC,KAAK;YAMS,SAAS;CA2BxB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetricsClient = void 0;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
class MetricsClient {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
Object.defineProperty(this, "config", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: config
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "maxBatchSize", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: 100
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "started", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: false
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "queue", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: []
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "flushInterval", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: null
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
start() {
|
|
39
|
+
if (this.started)
|
|
40
|
+
return;
|
|
41
|
+
this.started = true;
|
|
42
|
+
this.flushInterval = setInterval(() => {
|
|
43
|
+
this.flush();
|
|
44
|
+
}, 10000);
|
|
45
|
+
}
|
|
46
|
+
stop() {
|
|
47
|
+
if (this.flushInterval) {
|
|
48
|
+
clearInterval(this.flushInterval);
|
|
49
|
+
this.flushInterval = null;
|
|
50
|
+
}
|
|
51
|
+
this.flush();
|
|
52
|
+
}
|
|
53
|
+
track(event, payload, metadata = {}) {
|
|
54
|
+
this.start();
|
|
55
|
+
const e = {
|
|
56
|
+
source: 'appview',
|
|
57
|
+
time: Date.now(),
|
|
58
|
+
event,
|
|
59
|
+
payload,
|
|
60
|
+
metadata,
|
|
61
|
+
};
|
|
62
|
+
this.queue.push(e);
|
|
63
|
+
if (this.queue.length > this.maxBatchSize) {
|
|
64
|
+
this.flush();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
flush() {
|
|
68
|
+
if (!this.queue.length)
|
|
69
|
+
return;
|
|
70
|
+
const events = this.queue.splice(0, this.queue.length);
|
|
71
|
+
this.sendBatch(events);
|
|
72
|
+
}
|
|
73
|
+
async sendBatch(events) {
|
|
74
|
+
if (!this.config.trackingEndpoint)
|
|
75
|
+
return;
|
|
76
|
+
try {
|
|
77
|
+
const res = await fetch(this.config.trackingEndpoint, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify({ events }),
|
|
83
|
+
keepalive: true,
|
|
84
|
+
});
|
|
85
|
+
if (!res.ok) {
|
|
86
|
+
const errorText = await res.text().catch(() => 'Unknown error');
|
|
87
|
+
logger_1.featureGatesLogger.error({ err: new Error(`${res.status} Failed to fetch - ${errorText}`) }, 'Failed to send metrics');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Drain response body to allow connection reuse.
|
|
91
|
+
await res.text().catch(() => { });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
logger_1.featureGatesLogger.error({ err }, 'Failed to send metrics');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.MetricsClient = MetricsClient;
|
|
100
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":";;;AAAA,sCAA8C;AA4B9C,MAAa,aAAa;IAMxB,YAAoB,MAAc;QAAtB;;;;mBAAQ,MAAM;WAAQ;QALlC;;;;mBAAe,GAAG;WAAA;QAEV;;;;mBAAmB,KAAK;WAAA;QACxB;;;;mBAAoB,EAAE;WAAA;QACtB;;;;mBAAuC,IAAI;WAAA;IACd,CAAC;IAEtC,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC,EAAE,KAAM,CAAC,CAAA;IACZ,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC3B,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CACH,KAAQ,EACR,OAAa,EACb,WAAgC,EAAE;QAElC,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,MAAM,CAAC,GAAG;YACR,MAAM,EAAE,SAAS;YACjB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,KAAK;YACL,OAAO;YACP,QAAQ;SACT,CAAA;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAElB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACtD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,MAAkB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAM;QAEzC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE;gBACpD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;gBAChC,SAAS,EAAE,IAAI;aAChB,CAAC,CAAA;YAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAA;gBAC/D,2BAAkB,CAAC,KAAK,CACtB,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,sBAAsB,SAAS,EAAE,CAAC,EAAE,EAClE,wBAAwB,CACzB,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YAClC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,2BAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,wBAAwB,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;CACF;AA9ED,sCA8EC","sourcesContent":["import { featureGatesLogger } from '../logger'\n\ntype Events = {\n 'experiment:viewed': {\n experimentId: string\n variationId: string\n }\n 'feature:viewed': {\n featureId: string\n featureResultValue: unknown\n /** Only available if feature has experiment rules applied */\n experimentId?: string\n /** Only available if feature has experiment rules applied */\n variationId?: string\n }\n}\n\ntype Event<M extends Record<string, any>> = {\n time: number\n event: keyof M\n payload: M[keyof M]\n metadata: Record<string, any>\n}\n\nexport type Config = {\n trackingEndpoint?: string\n}\n\nexport class MetricsClient<M extends Record<string, any> = Events> {\n maxBatchSize = 100\n\n private started: boolean = false\n private queue: Event<M>[] = []\n private flushInterval: NodeJS.Timeout | null = null\n constructor(private config: Config) {}\n\n start() {\n if (this.started) return\n this.started = true\n this.flushInterval = setInterval(() => {\n this.flush()\n }, 10_000)\n }\n\n stop() {\n if (this.flushInterval) {\n clearInterval(this.flushInterval)\n this.flushInterval = null\n }\n this.flush()\n }\n\n track<E extends keyof M>(\n event: E,\n payload: M[E],\n metadata: Record<string, any> = {},\n ) {\n this.start()\n\n const e = {\n source: 'appview',\n time: Date.now(),\n event,\n payload,\n metadata,\n }\n this.queue.push(e)\n\n if (this.queue.length > this.maxBatchSize) {\n this.flush()\n }\n }\n\n flush() {\n if (!this.queue.length) return\n const events = this.queue.splice(0, this.queue.length)\n this.sendBatch(events)\n }\n\n private async sendBatch(events: Event<M>[]) {\n if (!this.config.trackingEndpoint) return\n\n try {\n const res = await fetch(this.config.trackingEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ events }),\n keepalive: true,\n })\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => 'Unknown error')\n featureGatesLogger.error(\n { err: new Error(`${res.status} Failed to fetch - ${errorText}`) },\n 'Failed to send metrics',\n )\n } else {\n // Drain response body to allow connection reuse.\n await res.text().catch(() => {})\n }\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to send metrics')\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.test.d.ts","sourceRoot":"","sources":["../../src/feature-gates/metrics.test.ts"],"names":[],"mappings":""}
|