Skip to content

Commit

Permalink
fix: Move ConfigSource abstract class to types package (#935)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajwootto authored Aug 14, 2024
1 parent 9930a90 commit 443a320
Show file tree
Hide file tree
Showing 17 changed files with 55 additions and 58 deletions.
16 changes: 9 additions & 7 deletions lib/shared/config-manager/src/CDNConfigSource.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ConfigBody, DVCLogger } from '@devcycle/types'
import { ConfigSource } from './ConfigSource'
import { ConfigBody, DVCLogger, ConfigSource, UserError } from '@devcycle/types'
import { getEnvironmentConfig } from './request'
import { ResponseError, UserError } from '@devcycle/server-request'
import { ResponseError } from '@devcycle/server-request'

export class CDNConfigSource extends ConfigSource {
constructor(
Expand All @@ -12,13 +11,14 @@ export class CDNConfigSource extends ConfigSource {
super()
}

async getConfig(
// type generic to make typescript happy. It's always false in this implementation
async getConfig<T extends boolean = false>(
sdkKey: string,
kind: 'server' | 'bootstrap',
obfuscated: boolean,
lastModifiedThreshold?: string,
): Promise<{
config: ConfigBody | null
config: T extends true ? ConfigBody : ConfigBody | null
metaData: Record<string, unknown>
lastModified: string | null
}> {
Expand Down Expand Up @@ -66,7 +66,9 @@ export class CDNConfigSource extends ConfigSource {
'Skipping saving config, existing last modified date is newer.',
)
return {
config: null,
config: null as T extends true
? ConfigBody
: ConfigBody | null,
metaData: metadata,
lastModified: lastModifiedHeader,
}
Expand All @@ -80,7 +82,7 @@ export class CDNConfigSource extends ConfigSource {
}
}
return {
config: null,
config: null as T extends true ? ConfigBody : ConfigBody | null,
metaData: metadata,
lastModified: null,
}
Expand Down
7 changes: 2 additions & 5 deletions lib/shared/config-manager/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { ConfigBody, DVCLogger } from '@devcycle/types'
import { ResponseError, UserError } from '@devcycle/server-request'
import { ConfigBody, DVCLogger, ConfigSource, UserError } from '@devcycle/types'
import { ResponseError } from '@devcycle/server-request'
import { SSEConnection } from '@devcycle/sse-connection'
import { CDNConfigSource } from './CDNConfigSource'
import { isValidDate } from './request'
import { ConfigSource } from './ConfigSource'

export * from './ConfigSource'

type ConfigPollingOptions = {
configPollingIntervalMS?: number
Expand Down
1 change: 0 additions & 1 deletion lib/shared/server-request/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './request'
export * from './userError'
2 changes: 2 additions & 0 deletions lib/shared/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from './types/validators/dvcCustomDataJSON'
export * from './types/apis/events/eventsAPI'
export * from './types/config/models'
export * from './utils'
export * from './types/ConfigSource'
export * from './types/UserError'
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ConfigBody } from '@devcycle/types'
import { isValidDate } from './request'
import { ConfigBody } from './config/configBody'

export const isValidDate = (date: Date | null): date is Date =>
date instanceof Date && !isNaN(date.getTime())

/**
* Interface representing a source to pull config data from. Used by the Node and Next SDKs
*/
export abstract class ConfigSource {
configEtag?: string
configLastModified?: string
Expand All @@ -12,16 +17,18 @@ export abstract class ConfigSource {
* @param kind
* @param obfuscated
* @param lastModifiedThreshold
* @param skipLastModified
*/
abstract getConfig(
abstract getConfig<T extends boolean = false>(
sdkKey: string,
kind: 'server' | 'bootstrap',
obfuscated: boolean,
lastModifiedThreshold?: string,
skipLastModified?: T,
): Promise<{
config: ConfigBody | null
metaData: Record<string, unknown>
config: T extends true ? ConfigBody : ConfigBody | null
lastModified: string | null
metaData: Record<string, unknown>
}>

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export class UserError extends Error {
constructor(error: Error | string) {
super(error instanceof Error ? error.message : error)
this.name = 'UserError'
this.stack = error instanceof Error ? error.stack : undefined
if (error instanceof Error) {
this.stack = error.stack
}
}
}
1 change: 0 additions & 1 deletion lib/shared/vercel-edge-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "@devcycle/vercel-edge-config",
"version": "0.1.5",
"peerDependencies": {
"@devcycle/nodejs-server-sdk": "*",
"@devcycle/types": "*",
"@vercel/edge-config": "^1.2.0"
},
Expand Down
3 changes: 1 addition & 2 deletions lib/shared/vercel-edge-config/src/edge-config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ConfigSource, UserError } from '@devcycle/nodejs-server-sdk'
import { EdgeConfigClient, EdgeConfigValue } from '@vercel/edge-config'
import { ConfigBody } from '@devcycle/types'
import { ConfigBody, ConfigSource, UserError } from '@devcycle/types'

export class EdgeConfigSource extends ConfigSource {
constructor(private edgeConfigClient: EdgeConfigClient) {
Expand Down
23 changes: 0 additions & 23 deletions sdk/nextjs/src/common/ConfigSource.ts

This file was deleted.

3 changes: 1 addition & 2 deletions sdk/nextjs/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { DevCycleOptions, DevCycleUser } from '@devcycle/js-client-sdk'
import { BucketedUserConfig } from '@devcycle/types'
import { ConfigSource } from './ConfigSource'
import { BucketedUserConfig, ConfigSource } from '@devcycle/types'

export type DevCycleNextOptions = Pick<
DevCycleOptions,
Expand Down
2 changes: 1 addition & 1 deletion sdk/nextjs/src/pages/appWithDevCycle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SSRProps } from './types'
import { DevCycleProvider } from '@devcycle/react-client-sdk'
import React from 'react'
import { DevCycleOptions } from '@devcycle/js-client-sdk'
import { ConfigSource } from '../common/ConfigSource.js'
import { ConfigSource } from '@devcycle/types'

type DevCycleNextOptions = Pick<
DevCycleOptions,
Expand Down
14 changes: 12 additions & 2 deletions sdk/nextjs/src/pages/bucketing.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { DevCycleUser, DVCPopulatedUser } from '@devcycle/js-client-sdk'
import { generateBucketedConfig } from '@devcycle/bucketing'
import { BucketedUserConfig, ConfigBody } from '@devcycle/types'
import { ConfigSource } from '../common/ConfigSource.js'
import { BucketedUserConfig, ConfigBody, ConfigSource } from '@devcycle/types'

const getFetchUrl = (sdkKey: string, obfuscated: boolean) =>
`https://config-cdn.devcycle.com/config/v1/server/bootstrap/${
Expand All @@ -23,6 +22,7 @@ class CDNConfigSource extends ConfigSource {
): Promise<{
config: ConfigBody
lastModified: string | null
metaData: Record<string, unknown>
}> {
const configResponse = await fetchCDNConfig(sdkKey, obfuscated)
if (!configResponse.ok) {
Expand All @@ -31,8 +31,18 @@ class CDNConfigSource extends ConfigSource {
return {
config: await configResponse.json(),
lastModified: configResponse.headers.get('last-modified'),
metaData: {},
}
}

// implement a dummy version of this to satisfy shared type definition. Next does not use this method
getConfigURL(
sdkKey: string,
kind: 'server' | 'bootstrap',
obfuscated: boolean,
): string {
return ''
}
}

const cdnConfigSource = new CDNConfigSource()
Expand Down
3 changes: 1 addition & 2 deletions sdk/nextjs/src/pages/getServerSideDevCycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { SSRProps } from './types'
import { DevCycleOptions, DevCycleUser } from '@devcycle/js-client-sdk'
import { getBucketedConfig } from './bucketing.js'
import { GetServerSidePropsContext } from 'next'
import { BucketedUserConfig } from '@devcycle/types'
import { ConfigSource } from '../common/ConfigSource.js'
import { BucketedUserConfig, ConfigSource } from '@devcycle/types'

type IdentifiedUser = Omit<DevCycleUser, 'user_id' | 'isAnonymous'> & {
user_id: string
Expand Down
9 changes: 7 additions & 2 deletions sdk/nextjs/src/server/bucketing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
BucketedConfigWithAdditionalFields,
DevCycleNextOptions,
} from '../common/types'
import { ConfigSource } from '../common/ConfigSource'
import { ConfigBody } from '@devcycle/types'
import { ConfigBody, ConfigSource } from '@devcycle/types'

// wrap this function in react cache to avoid redoing work for the same user and config
const generateBucketedConfigCached = cache(
Expand Down Expand Up @@ -59,8 +58,14 @@ class CDNConfigSource extends ConfigSource {
return {
config: (await cdnConfig.json()) as ConfigBody,
lastModified: cdnConfig.headers.get('last-modified'),
metaData: {},
}
}

// dummy implementation to make types happy, this method isn't used in Next
getConfigURL(): string {
return ''
}
}

/**
Expand Down
3 changes: 2 additions & 1 deletion sdk/nodejs/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EnvironmentConfigManager } from '@devcycle/config-manager'
import { ResponseError, UserError } from '@devcycle/server-request'
import { ResponseError } from '@devcycle/server-request'
import {
bucketUserForConfig,
getSDKKeyFromConfig,
Expand All @@ -16,6 +16,7 @@ import {
getVariableTypeFromValue,
VariableTypeAlias,
type VariableValue,
UserError,
} from '@devcycle/types'
import os from 'os'
import {
Expand Down
4 changes: 2 additions & 2 deletions sdk/nodejs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ export type DVCEvent = DevCycleEvent
*/
export type DVCOptions = DevCycleServerSDKOptions

import { ConfigSource } from '@devcycle/config-manager'
import { ConfigSource } from '@devcycle/types'

export { ConfigSource }

export { UserError } from '@devcycle/server-request'
export { UserError } from '@devcycle/types'

type DevCycleOptionsCloudEnabled = DevCycleServerSDKOptions & {
enableCloudBucketing: true
Expand Down
1 change: 0 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4845,7 +4845,6 @@ __metadata:
version: 0.0.0-use.local
resolution: "@devcycle/vercel-edge-config@workspace:lib/shared/vercel-edge-config"
peerDependencies:
"@devcycle/nodejs-server-sdk": "*"
"@devcycle/types": "*"
"@vercel/edge-config": ^1.2.0
languageName: unknown
Expand Down

0 comments on commit 443a320

Please sign in to comment.