зеркало из https://github.com/mozilla/fxa.git
feat(contentful): add planIdsToClientCapabilities to capability manager
Because: * We want to fetch the list of capabilities for the given plan ids. This commit: * Adds planIdsToClientCapabilities method to the capability manager. Closes FXA-8240
This commit is contained in:
Родитель
d9ec27c859
Коммит
c8a059e468
|
@ -27,4 +27,41 @@ export class CapabilityManager {
|
|||
),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the list of capabilities for the given price ids.
|
||||
*
|
||||
* Returns Record<string, string[]>
|
||||
* Keys are clientIds
|
||||
* Values are capabilitySlugs[]
|
||||
*/
|
||||
async planIdsToClientCapabilities(
|
||||
subscribedPrices: string[]
|
||||
): Promise<Record<string, string[]>> {
|
||||
const purchaseDetails =
|
||||
await this.contentfulManager.getPurchaseDetailsForCapabilityServiceByPlanIds(
|
||||
[...subscribedPrices]
|
||||
);
|
||||
|
||||
const result: Record<string, string[]> = {};
|
||||
|
||||
for (const subscribedPrice of subscribedPrices) {
|
||||
const capabilityOffering =
|
||||
purchaseDetails.capabilityOfferingForPlanId(subscribedPrice);
|
||||
|
||||
if (!capabilityOffering) continue;
|
||||
|
||||
for (const capabilityCollection of capabilityOffering
|
||||
.capabilitiesCollection.items) {
|
||||
for (const capability of capabilityCollection.servicesCollection
|
||||
.items) {
|
||||
result[capability.oauthClientId] ||= [];
|
||||
|
||||
result[capability.oauthClientId].push(capabilityCollection.slug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import {
|
||||
ResultOf,
|
||||
DocumentTypeDecoration,
|
||||
TypedDocumentNode,
|
||||
} from '@graphql-typed-document-node/core';
|
||||
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
|
||||
import { FragmentDefinitionNode } from 'graphql';
|
||||
import { Incremental } from './graphql';
|
||||
|
||||
export type FragmentType<
|
||||
TDocumentType extends DocumentTypeDecoration<any, any>
|
||||
> = TDocumentType extends DocumentTypeDecoration<infer TType, any>
|
||||
|
||||
export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
|
||||
infer TType,
|
||||
any
|
||||
>
|
||||
? [TType] extends [{ ' $fragmentName'?: infer TKey }]
|
||||
? TKey extends string
|
||||
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
|
||||
|
@ -24,10 +22,7 @@ export function useFragment<TType>(
|
|||
// return nullable if `fragmentType` is nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| FragmentType<DocumentTypeDecoration<TType, any>>
|
||||
| null
|
||||
| undefined
|
||||
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
|
||||
): TType | null | undefined;
|
||||
// return array of non-nullable if `fragmentType` is array of non-nullable
|
||||
export function useFragment<TType>(
|
||||
|
@ -37,22 +32,16 @@ export function useFragment<TType>(
|
|||
// return array of nullable if `fragmentType` is array of nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| null
|
||||
| undefined
|
||||
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
|
||||
): ReadonlyArray<TType> | null | undefined;
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| FragmentType<DocumentTypeDecoration<TType, any>>
|
||||
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| null
|
||||
| undefined
|
||||
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
|
||||
): TType | ReadonlyArray<TType> | null | undefined {
|
||||
return fragmentType as any;
|
||||
}
|
||||
|
||||
|
||||
export function makeFragmentData<
|
||||
F extends DocumentTypeDecoration<any, any>,
|
||||
FT extends ResultOf<F>
|
||||
|
@ -62,24 +51,16 @@ export function makeFragmentData<
|
|||
export function isFragmentReady<TQuery, TFrag>(
|
||||
queryNode: DocumentTypeDecoration<TQuery, any>,
|
||||
fragmentNode: TypedDocumentNode<TFrag>,
|
||||
data:
|
||||
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
|
||||
| null
|
||||
| undefined
|
||||
data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
|
||||
): data is FragmentType<typeof fragmentNode> {
|
||||
const deferredFields = (
|
||||
queryNode as {
|
||||
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> };
|
||||
}
|
||||
).__meta__?.deferredFields;
|
||||
const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
|
||||
?.deferredFields;
|
||||
|
||||
if (!deferredFields) return true;
|
||||
|
||||
const fragDef = fragmentNode.definitions[0] as
|
||||
| FragmentDefinitionNode
|
||||
| undefined;
|
||||
const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
|
||||
const fragName = fragDef?.name?.value;
|
||||
|
||||
const fields = (fragName && deferredFields[fragName]) || [];
|
||||
return fields.length > 0 && fields.every((field) => data && field in data);
|
||||
return fields.length > 0 && fields.every(field => data && field in data);
|
||||
}
|
||||
|
|
|
@ -13,18 +13,12 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
|
|||
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
||||
*/
|
||||
const documents = {
|
||||
'\n query CapabilityServiceByPriceIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n':
|
||||
types.CapabilityServiceByPriceIdsDocument,
|
||||
'\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n':
|
||||
types.EligibilityContentByPlanIdsDocument,
|
||||
'\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n':
|
||||
types.OfferingDocument,
|
||||
'\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n':
|
||||
types.PurchaseWithDetailsOfferingContentDocument,
|
||||
'\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n':
|
||||
types.PurchaseWithDetailsDocument,
|
||||
'\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n':
|
||||
types.ServicesWithCapabilitiesDocument,
|
||||
"\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n": types.CapabilityServiceByPlanIdsDocument,
|
||||
"\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n": types.EligibilityContentByPlanIdsDocument,
|
||||
"\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n": types.OfferingDocument,
|
||||
"\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n": types.PurchaseWithDetailsOfferingContentDocument,
|
||||
"\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n": types.PurchaseWithDetailsDocument,
|
||||
"\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n": types.ServicesWithCapabilitiesDocument,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -44,43 +38,30 @@ export function graphql(source: string): unknown;
|
|||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query CapabilityServiceByPriceIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query CapabilityServiceByPriceIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n servicesCollection(skip: $skip, limit: $limit) {\n items {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: { stripePlanChoices_contains_some: $stripePlanIds }\n ) {\n items {\n stripePlanChoices\n offering {\n stripeProductId\n countries\n linkedFrom {\n subGroupCollection(skip: $skip, limit: $limit) {\n items {\n groupName\n offeringCollection(skip: $skip, limit: $limit) {\n items {\n stripeProductId\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n"): (typeof documents)["\n query Offering($id: String!, $locale: String!) {\n offering(id: $id, locale: $locale) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchaseCollection(\n skip: $skip\n limit: $limit\n locale: $locale\n where: {\n OR: [\n { stripePlanChoices_contains_some: $stripePlanIds }\n { offering: { stripeLegacyPlans_contains_some: $stripePlanIds } }\n ]\n }\n ) {\n items {\n stripePlanChoices\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n }\n offering {\n stripeProductId\n stripeLegacyPlans\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n"): (typeof documents)["\n query PurchaseWithDetails($id: String!, $locale: String!) {\n purchase(id: $id, locale: $locale) {\n internalName\n description\n purchaseDetails {\n productName\n details\n webIcon\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: '\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n'
|
||||
): (typeof documents)['\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n'];
|
||||
export function graphql(source: "\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ServicesWithCapabilities($skip: Int!, $limit: Int!, $locale: String!) {\n serviceCollection(skip: $skip, limit: $limit, locale: $locale) {\n items {\n oauthClientId\n capabilitiesCollection(skip: $skip, limit: $limit) {\n items {\n slug\n }\n }\n }\n }\n }\n"];
|
||||
|
||||
export function graphql(source: string) {
|
||||
return (documents as any)[source] ?? {};
|
||||
}
|
||||
|
||||
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
|
||||
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
||||
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,2 +1,2 @@
|
|||
export * from './fragment-masking';
|
||||
export * from './gql';
|
||||
export * from "./fragment-masking";
|
||||
export * from "./gql";
|
|
@ -7,5 +7,6 @@ export * from './lib/contentful.client.config';
|
|||
export * from './lib/contentful.error';
|
||||
export * from './lib/contentful.manager';
|
||||
export * from './lib/factories';
|
||||
export * from './lib/queries/capability-service-by-plan-ids';
|
||||
export * from './lib/queries/eligibility-content-by-plan-ids';
|
||||
export * from './lib/queries/services-with-capabilities';
|
||||
|
|
|
@ -8,8 +8,14 @@ import {
|
|||
EligibilityContentByPlanIdsQuery,
|
||||
PurchaseWithDetailsOfferingContentQuery,
|
||||
ServicesWithCapabilitiesQuery,
|
||||
CapabilityServiceByPlanIdsQuery,
|
||||
} from '../__generated__/graphql';
|
||||
import { ContentfulClient } from './contentful.client';
|
||||
|
||||
import {
|
||||
capabilityServiceByPlanIdsQuery,
|
||||
CapabilityServiceByPlanIdsResultUtil,
|
||||
} from './queries/capability-service-by-plan-ids';
|
||||
import {
|
||||
EligibilityContentByPlanIdsResultUtil,
|
||||
eligibilityContentByPlanIdsQuery,
|
||||
|
@ -28,6 +34,24 @@ import { DeepNonNullable } from './types';
|
|||
export class ContentfulManager {
|
||||
constructor(private client: ContentfulClient) {}
|
||||
|
||||
async getPurchaseDetailsForCapabilityServiceByPlanIds(
|
||||
stripePlanIds: string[]
|
||||
): Promise<CapabilityServiceByPlanIdsResultUtil> {
|
||||
const queryResult = await this.client.query(
|
||||
capabilityServiceByPlanIdsQuery,
|
||||
{
|
||||
skip: 0,
|
||||
limit: 100,
|
||||
locale: 'en',
|
||||
stripePlanIds,
|
||||
}
|
||||
);
|
||||
|
||||
return new CapabilityServiceByPlanIdsResultUtil(
|
||||
queryResult.data as DeepNonNullable<CapabilityServiceByPlanIdsQuery>
|
||||
);
|
||||
}
|
||||
|
||||
async getPurchaseDetailsForEligibility(
|
||||
stripePlanIds: string[]
|
||||
): Promise<EligibilityContentByPlanIdsResultUtil> {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
import { CapabilityServiceByPlanIdsQuery } from '../../../__generated__/graphql';
|
||||
import {
|
||||
CapabilityPurchaseResult,
|
||||
CapabilityOfferingResult,
|
||||
CapabilityCapabilitiesResult,
|
||||
CapabilityServicesResult,
|
||||
} from '.';
|
||||
|
||||
export const CapabilityServiceByPlanIdsQueryFactory = (
|
||||
override?: Partial<CapabilityServiceByPlanIdsQuery>
|
||||
): CapabilityServiceByPlanIdsQuery => {
|
||||
return {
|
||||
purchaseCollection: {
|
||||
items: [CapabilityPurchaseResultFactory()],
|
||||
},
|
||||
...override,
|
||||
};
|
||||
};
|
||||
|
||||
export const CapabilityPurchaseResultFactory = (
|
||||
override?: Partial<CapabilityPurchaseResult>
|
||||
): CapabilityPurchaseResult => ({
|
||||
stripePlanChoices: [faker.string.sample()],
|
||||
offering: CapabilityOfferingResultFactory(),
|
||||
...override,
|
||||
});
|
||||
|
||||
export const CapabilityOfferingResultFactory = (
|
||||
override?: Partial<CapabilityOfferingResult>
|
||||
): CapabilityOfferingResult => ({
|
||||
capabilitiesCollection: {
|
||||
items: [CapabilityCapabilitiesResultFactory()],
|
||||
},
|
||||
...override,
|
||||
});
|
||||
|
||||
export const CapabilityCapabilitiesResultFactory = (
|
||||
override?: Partial<CapabilityCapabilitiesResult>
|
||||
): CapabilityCapabilitiesResult => ({
|
||||
slug: faker.string.sample(),
|
||||
servicesCollection: {
|
||||
items: [CapabilityServicesResultFactory()],
|
||||
},
|
||||
...override,
|
||||
});
|
||||
|
||||
export const CapabilityServicesResultFactory = (
|
||||
override?: Partial<CapabilityServicesResult>
|
||||
): CapabilityServicesResult => ({
|
||||
oauthClientId: faker.string.sample(),
|
||||
...override,
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export * from './factories';
|
||||
export * from './query';
|
||||
export * from './types';
|
||||
export * from './util';
|
|
@ -2,10 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { graphql } from '../../__generated__/gql';
|
||||
import { graphql } from '../../../__generated__/gql';
|
||||
|
||||
export const capabilityServiceByPlanIdsQuery = graphql(`
|
||||
query CapabilityServiceByPriceIds(
|
||||
query CapabilityServiceByPlanIds(
|
||||
$skip: Int!
|
||||
$limit: Int!
|
||||
$locale: String!
|
|
@ -0,0 +1,31 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export interface CapabilityServicesResult {
|
||||
oauthClientId: string;
|
||||
}
|
||||
|
||||
export interface CapabilityCapabilitiesResult {
|
||||
slug: string;
|
||||
servicesCollection: {
|
||||
items: CapabilityServicesResult[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface CapabilityOfferingResult {
|
||||
capabilitiesCollection: {
|
||||
items: CapabilityCapabilitiesResult[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface CapabilityPurchaseResult {
|
||||
stripePlanChoices: string[];
|
||||
offering: CapabilityOfferingResult;
|
||||
}
|
||||
|
||||
export interface CapabilityServiceByPlanIdsResult {
|
||||
purchaseCollection: {
|
||||
items: CapabilityPurchaseResult[];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { CapabilityServiceByPlanIdsQueryFactory } from './factories';
|
||||
import { CapabilityServiceByPlanIdsResult } from './types';
|
||||
import { CapabilityServiceByPlanIdsResultUtil } from './util';
|
||||
|
||||
describe('CapabilityServiceByPlanIdsResultUtil', () => {
|
||||
it('should create a util from response', () => {
|
||||
const result = CapabilityServiceByPlanIdsQueryFactory();
|
||||
const planId = result.purchaseCollection?.items[0]?.stripePlanChoices?.[0];
|
||||
const util = new CapabilityServiceByPlanIdsResultUtil(
|
||||
result as CapabilityServiceByPlanIdsResult
|
||||
);
|
||||
expect(util).toBeDefined();
|
||||
expect(
|
||||
util.capabilityOfferingForPlanId(planId ?? '')?.capabilitiesCollection
|
||||
).toBeDefined();
|
||||
expect(util.purchaseCollection.items.length).toBe(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import {
|
||||
CapabilityServiceByPlanIdsResult,
|
||||
CapabilityOfferingResult,
|
||||
CapabilityPurchaseResult,
|
||||
} from './types';
|
||||
|
||||
export class CapabilityServiceByPlanIdsResultUtil {
|
||||
private purchaseByPlanId: Record<string, CapabilityPurchaseResult> = {};
|
||||
|
||||
constructor(private rawResult: CapabilityServiceByPlanIdsResult) {
|
||||
for (const purchase of rawResult.purchaseCollection.items) {
|
||||
for (const planId of purchase.stripePlanChoices) {
|
||||
this.purchaseByPlanId[planId] = purchase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
capabilityOfferingForPlanId(
|
||||
planId: string
|
||||
): CapabilityOfferingResult | undefined {
|
||||
return this.purchaseByPlanId[planId]?.offering;
|
||||
}
|
||||
|
||||
get purchaseCollection() {
|
||||
return this.rawResult.purchaseCollection;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче