Skip to content

Commit

Permalink
refactor: to use combine adapters with one
Browse files Browse the repository at this point in the history
  • Loading branch information
tdeekens committed Jan 14, 2021
1 parent de98b10 commit 56d45d4
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 65 deletions.
8 changes: 8 additions & 0 deletions @types-extensions/graphql-mc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ declare module '*/project-switcher.mc.graphql' {
export default defaultDocument;
}

declare module '*/fetch-all-features.mc.graphql' {
import { DocumentNode } from 'graphql';
const defaultDocument: DocumentNode;
export const AllFeatures: DocumentNode;

export default defaultDocument;
}

declare module '*/select-user-id.mc.graphql' {
import { DocumentNode } from 'graphql';
const defaultDocument: DocumentNode;
Expand Down
15 changes: 15 additions & 0 deletions packages/application-shell-connectors/src/types/generated/mc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export type Scalars = {
Float: number;
};





export type TAdditionalUserInfo = {
firstName: Scalars['String'];
lastName: Scalars['String'];
Expand Down Expand Up @@ -810,6 +814,17 @@ export type TFetchUserProjectsQuery = (
)> }
);

export type TAllFeaturesQueryVariables = Exact<{ [key: string]: never; }>;


export type TAllFeaturesQuery = (
{ __typename?: 'Query' }
& { allFeatures: Array<(
{ __typename?: 'Feature' }
& Pick<TFeature, 'name' | 'value'>
)> }
);

export type TFetchUserIdQueryVariables = Exact<{ [key: string]: never; }>;


Expand Down
10 changes: 6 additions & 4 deletions packages/application-shell/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@
"@commercetools/http-user-agent": "2.1.2",
"@emotion/react": "11.1.4",
"@emotion/styled": "11.0.0",
"@flopflip/launchdarkly-adapter": "5.0.1",
"@flopflip/memory-adapter": "3.0.5",
"@flopflip/react-broadcast": "12.1.3",
"@flopflip/types": "4.1.3",
"@flopflip/combine-adapters": "0.0.11",
"@flopflip/http-adapter": "0.0.2",
"@flopflip/launchdarkly-adapter": "5.0.5",
"@flopflip/memory-adapter": "3.0.9",
"@flopflip/react-broadcast": "12.1.7",
"@flopflip/types": "4.1.7",
"@types/classnames": "2.2.9",
"@types/common-tags": "^1.8.0",
"@types/history": "4.7.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
query AllFeatures { allFeatures { name value } }
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import type { TFlags } from '@flopflip/types';
import type { TFetchLoggedInUserQuery } from '../../types/generated/mc';
import type {
TAllFeaturesQuery,
TFetchLoggedInUserQuery,
} from '../../types/generated/mc';

import React from 'react';
import ldAdapter from '@flopflip/launchdarkly-adapter';
import omitEmpty from 'omit-empty-es';
import httpAdapter from '@flopflip/http-adapter';
import combineAdapters from '@flopflip/combine-adapters';
import { ConfigureFlopFlip } from '@flopflip/react-broadcast';
import { useApolloClient } from '@apollo/client/react';
import { GRAPHQL_TARGETS } from '@commercetools-frontend/constants';
import useAllMenuFeatureToggles from '../../hooks/use-all-menu-feature-toggles';
import { FLAGS } from '../../feature-toggles';
import AllFeaturesQuery from './fetch-all-features.mc.graphql';

type Props = {
projectKey?: string;
Expand All @@ -18,21 +25,58 @@ type Props = {
shouldDeferAdapterConfiguration?: boolean;
};

type CustomLDUser = {
project: string;
id: string;
team: string[];
group: string;
subgroup: string;
tenant: string;
type TLaunchDarklyUserCustomFields = {
project?: string;
id?: string;
team?: string[];
group?: string;
subgroup?: string;
tenant?: string;
};

type TFetchedGraphQLAdapterFlag = {
name: string;
value: boolean;
reason?: string;
};

// This value is hard-coded here because we want to make sure that the
// app uses our account of LD. The value is meant to be public, so there
// is no need to be concerned about security.
const ldClientSideIdProduction = '5979d95f6040390cd07b5e01';

combineAdapters.combine([ldAdapter, httpAdapter]);

function getUserCustomFieldsForLaunchDarklyAdapter(
user?: Props['user'],
projectKey?: string
): TLaunchDarklyUserCustomFields {
return {
project: projectKey ?? '',
id: user?.launchdarklyTrackingId ?? '',
team: user?.launchdarklyTrackingTeam ?? [],
group: user?.launchdarklyTrackingGroup ?? '',
subgroup: user?.launchdarklyTrackingSubgroup ?? '',
tenant: user?.launchdarklyTrackingTenant ?? '',
};
}

type TFetchedFlags = {
allFeatures: TFetchedGraphQLAdapterFlag[];
};
const parseFlags = (fetchedFlags: TFetchedFlags) =>
Object.fromEntries(
fetchedFlags.allFeatures.map((fetchedFlag) => [
fetchedFlag.name,
{
value: fetchedFlag.value,
reason: fetchedFlag.reason,
},
])
);

export const SetupFlopFlipProvider = (props: Props) => {
const apolloClient = useApolloClient();
const allMenuFeatureToggles = useAllMenuFeatureToggles();
const flags = React.useMemo(
() => ({
Expand All @@ -54,34 +98,54 @@ export const SetupFlopFlipProvider = (props: Props) => {

const adapterArgs = React.useMemo(
() => ({
sdk: {
// Allow to overwrite the client ID, passed via the `additionalEnv` properties
// of the application config.
// This is mostly useful for internal usage on our staging environments.
clientSideId: props.ldClientSideId ?? ldClientSideIdProduction,
},
flags,
user: {
key: props.user?.id,
custom: omitEmpty<CustomLDUser, Partial<CustomLDUser>>({
id: props.user?.launchdarklyTrackingId,
project: props.projectKey,
team: props.user?.launchdarklyTrackingTeam,
group: props.user?.launchdarklyTrackingGroup,
subgroup: props.user?.launchdarklyTrackingSubgroup,
tenant: props.user?.launchdarklyTrackingTenant,
}),
},
memory: {
user: {
key: props.user?.id,
},
},
launchdarkly: {
sdk: {
// Allow to overwrite the client ID, passed via the `additionalEnv` properties
// of the application config.
// This is mostly useful for internal usage on our staging environments.
clientSideId: props.ldClientSideId ?? ldClientSideIdProduction,
},
flags,
user: {
key: props.user?.id,
custom: getUserCustomFieldsForLaunchDarklyAdapter(
props.user,
props.projectKey
),
},
},
http: {
execute: async () => {
const response = await apolloClient.query<TAllFeaturesQuery>({
query: AllFeaturesQuery,
errorPolicy: 'ignore',
context: {
target: GRAPHQL_TARGETS.COMMERCETOOLS_PLATFORM,
},
});

return parseFlags(response.data);
},
cacheIdentifier: 'local',
},
}),
[flags, props.ldClientSideId, props.projectKey, props.user]
[apolloClient, flags, props.ldClientSideId, props.projectKey, props.user]
);

if (process.env.NODE_ENV === 'test') {
const memoryAdapter = require('@flopflip/memory-adapter').default;
return (
<ConfigureFlopFlip<typeof memoryAdapter>
adapter={memoryAdapter}
adapterArgs={adapterArgs}
adapterArgs={adapterArgs.memory}
defaultFlags={defaultFlags}
shouldDeferAdapterConfiguration={
typeof props.shouldDeferAdapterConfiguration === 'boolean'
Expand All @@ -95,8 +159,8 @@ export const SetupFlopFlipProvider = (props: Props) => {
}

return (
<ConfigureFlopFlip<typeof ldAdapter>
adapter={ldAdapter}
<ConfigureFlopFlip<typeof combineAdapters>
adapter={combineAdapters}
adapterArgs={adapterArgs}
defaultFlags={defaultFlags}
shouldDeferAdapterConfiguration={
Expand Down
15 changes: 15 additions & 0 deletions packages/application-shell/src/types/generated/mc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export type Scalars = {
Float: number;
};





export type TAdditionalUserInfo = {
firstName: Scalars['String'];
lastName: Scalars['String'];
Expand Down Expand Up @@ -810,6 +814,17 @@ export type TFetchUserProjectsQuery = (
)> }
);

export type TAllFeaturesQueryVariables = Exact<{ [key: string]: never; }>;


export type TAllFeaturesQuery = (
{ __typename?: 'Query' }
& { allFeatures: Array<(
{ __typename?: 'Feature' }
& Pick<TFeature, 'name' | 'value'>
)> }
);

export type TFetchUserIdQueryVariables = Exact<{ [key: string]: never; }>;


Expand Down
112 changes: 111 additions & 1 deletion schemas/mc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4994,7 +4994,7 @@
{
"kind": "OBJECT",
"name": "OrganizationTeamsCreated",
"description": "Note:\n This is not a `Organization` type as in the future MC schema will not support\ne.g. expanding on team members on its internal schema.",
"description": "Note:\n This is not a `Organization` type as in the future MC schema will not support e.g. expanding on team members on its internal schema.",
"fields": [
{
"name": "id",
Expand Down Expand Up @@ -6353,6 +6353,116 @@
}
],
"directives": [
{
"name": "isAuthenticated",
"description": null,
"locations": ["FIELD_DEFINITION"],
"args": []
},
{
"name": "rateLimit",
"description": null,
"locations": ["FIELD_DEFINITION"],
"args": [
{
"name": "max",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "window",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "message",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "identityArgs",
"description": null,
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "arrayLengthField",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
]
},
{
"name": "collectMetrics",
"description": null,
"locations": ["FIELD_DEFINITION"],
"args": []
},
{
"name": "deprecate",
"description": null,
"locations": ["FIELD_DEFINITION"],
"args": [
{
"name": "reason",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "withCounter",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": "true"
},
{
"name": "withLog",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": "true"
}
]
},
{
"name": "skip",
"description": "Directs the executor to skip this field or fragment when the `if` argument is true.",
Expand Down
Loading

0 comments on commit 56d45d4

Please sign in to comment.