diff --git a/src/create-context.ts b/src/create-context.ts index caa673d..9dc8ae1 100644 --- a/src/create-context.ts +++ b/src/create-context.ts @@ -1,6 +1,18 @@ /* eslint-disable prefer-object-spread */ import { Context } from 'unleash-client'; +function tryParseDate(dateString: string | undefined): Date | undefined { + if (!dateString) { + return undefined; + } + const parsedDate = new Date(dateString); + if (!isNaN(parsedDate.getTime())) { + return parsedDate; + } else { + return undefined; + } +} + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function createContext(value: any): Context { const { @@ -10,6 +22,7 @@ export function createContext(value: any): Context { sessionId, remoteAddress, properties, + currentTime, ...rest } = value; @@ -20,6 +33,7 @@ export function createContext(value: any): Context { userId, sessionId, remoteAddress, + currentTime: tryParseDate(currentTime), properties: Object.assign({}, rest, properties), }; diff --git a/src/test/__snapshots__/openapi.test.ts.snap b/src/test/__snapshots__/openapi.test.ts.snap index 0503c3c..980172b 100644 --- a/src/test/__snapshots__/openapi.test.ts.snap +++ b/src/test/__snapshots__/openapi.test.ts.snap @@ -644,6 +644,14 @@ Object { "type": "string", }, }, + Object { + "description": "The current time in ISO 8601 format, representing the time at which the feature toggle is being resolved", + "in": "query", + "name": "currentTime", + "schema": Object { + "type": "string", + }, + }, Object { "description": "Additional (custom) context fields", "example": Object { @@ -868,6 +876,14 @@ However, using this endpoint will increase the payload size transmitted to your "type": "string", }, }, + Object { + "description": "The current time in ISO 8601 format, representing the time at which the feature toggle is being resolved", + "in": "query", + "name": "currentTime", + "schema": Object { + "type": "string", + }, + }, Object { "description": "Additional (custom) context fields", "example": Object { diff --git a/src/test/create-context.test.ts b/src/test/create-context.test.ts index 37caa2b..8c9272c 100644 --- a/src/test/create-context.test.ts +++ b/src/test/create-context.test.ts @@ -60,6 +60,31 @@ test('will not blow up if properties is an array', () => { expect(context).not.toHaveProperty('region'); }); +test('accepts current time as a context value', () => { + const targetDate = new Date('2024-01-01T00:00:00.000Z'); + const context = createContext({ + currentTime: targetDate.toISOString(), + }); + + expect(context.currentTime).toStrictEqual(targetDate); +}); + +test('invalid time strings fall back to undefined currentTime', () => { + const context = createContext({ + currentTime: 'its cute that you think this will parse', + }); + + expect(context).not.toHaveProperty('currentTime'); +}); + +test('missing time current time falls back to undefined currentTime', () => { + const context = createContext({ + userId: '123', + }); + + expect(context).not.toHaveProperty('currentTime'); +}); + test.skip('will not blow up if userId is an array', () => { const context = createContext({ userId: ['123'], diff --git a/src/unleash-proxy.ts b/src/unleash-proxy.ts index 235f378..36c6969 100644 --- a/src/unleash-proxy.ts +++ b/src/unleash-proxy.ts @@ -81,6 +81,8 @@ export default class UnleashProxy { userId: "The current user's ID", sessionId: "The current session's ID", remoteAddress: "Your application's IP address", + currentTime: + 'The current time in ISO 8601 format, representing the time at which the feature toggle is being resolved', }), ...createDeepObjectRequestParameters({ properties: { @@ -117,6 +119,8 @@ export default class UnleashProxy { userId: "The current user's ID", sessionId: "The current session's ID", remoteAddress: "Your application's IP address", + currentTime: + 'The current time in ISO 8601 format, representing the time at which the feature toggle is being resolved', }), ...createDeepObjectRequestParameters({ properties: {