Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] : My account headless #881

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions commerce/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,29 @@ export interface Person extends Omit<Thing, "@type"> {
image?: ImageObject[] | null;
/** The Tax / Fiscal ID of the organization or person, e.g. the TIN in the US or the CIF/NIF in Spain. */
taxID?: string;
/** The telephone number. */
telephone?: string;
/** The birth date of the person. */
birthDate?: string;
/** User's corporate name */
corporateName?: string;
/** User's corporate document */
corporateDocument?: string;
/** User's corporate trade name */
tradeName?: string;
/** User's business phone */
businessPhone?: string;
/** Whether the user is a corporation or not */
isCorporate?: boolean;
/** Custom fields */
customFields?: CustomFields[];
}

interface CustomFields {
key: string;
value: string;
}

// NON SCHEMA.ORG Compliant. Should be removed ASAP
export interface Author extends Omit<Thing, "@type"> {
"@type": "Author";
Expand Down Expand Up @@ -593,6 +615,25 @@ export interface PostalAddress extends Omit<ContactPoint, "@type"> {
/** The street address. For example, 1600 Amphitheatre Pkwy. */
streetAddress?: string;
}

export interface PostalAddressVTEX extends Omit<ContactPoint, "@type"> {
"@type": "PostalAddress";
/** The country. For example, USA. You can also provide the two-letter ISO 3166-1 alpha-2 country code. */
addressCountry?: string;
/** The locality in which the street address is, and which is in the region. For example, Mountain View. */
addressLocality?: string;
/** The region in which the locality is, and which is in the country. For example, California. */
addressRegion?: string;
/** The postal code. For example, 94043. */
postalCode?: string;
/** The street address. For example, 1600 Amphitheatre Pkwy. */
streetAddress?: string;
receiverName: string | null;
addressName?: string;
complement: string | null;
addressId: string;
}

export interface LocationFeatureSpecification
extends Omit<PropertyValue, "@type"> {
"@type": "LocationFeatureSpecification";
Expand Down
26 changes: 18 additions & 8 deletions power-reviews/loaders/productListingPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,27 @@ export default function productListingPage(
})
);

const fullReviewsResponse = await Promise.all(fullReviewsPromises);
const fullReviewsResponse = await Promise.allSettled(fullReviewsPromises);

const fullReviewsResults = await Promise.all(
fullReviewsResponse.map((review) => review.json()),
const fullReviewsResults = await Promise.allSettled(
fullReviewsResponse.map((response) => {
if (response.status === "fulfilled") {
return response.value.json();
} else {
return null;
}
}),
);

const productsExtendeds = fullReviewsResults.map((review, idx) => {
return {
...products[idx],
aggregateRating: toAggregateRating(review.results[0].rollup),
};
const productsExtendeds = fullReviewsResults.map((result, idx) => {
if (result.status === "fulfilled" && result.value) {
return {
...products[idx],
aggregateRating: toAggregateRating(result.value.results[0].rollup),
};
} else {
return products[idx];
}
});

return {
Expand Down
11 changes: 11 additions & 0 deletions shopify/utils/storefront/storefront.graphql.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7789,6 +7789,17 @@ export type AddItemToCartMutationVariables = Exact<{

export type AddItemToCartMutation = { payload?: { cart?: { id: string, checkoutUrl: any, totalQuantity: number, lines: { nodes: Array<{ id: string, quantity: number, merchandise: { id: string, title: string, image?: { url: any, altText?: string | null } | null, product: { title: string, onlineStoreUrl?: any | null, handle: string }, price: { amount: any, currencyCode: CurrencyCode } }, discountAllocations: Array<{ code: string, discountedAmount: { amount: any, currencyCode: CurrencyCode } } | {}>, cost: { totalAmount: { amount: any, currencyCode: CurrencyCode }, subtotalAmount: { amount: any, currencyCode: CurrencyCode }, amountPerQuantity: { amount: any, currencyCode: CurrencyCode }, compareAtAmountPerQuantity?: { amount: any, currencyCode: CurrencyCode } | null } } | { id: string, quantity: number, merchandise: { id: string, title: string, image?: { url: any, altText?: string | null } | null, product: { title: string, onlineStoreUrl?: any | null, handle: string }, price: { amount: any, currencyCode: CurrencyCode } }, discountAllocations: Array<{ code: string, discountedAmount: { amount: any, currencyCode: CurrencyCode } } | {}>, cost: { totalAmount: { amount: any, currencyCode: CurrencyCode }, subtotalAmount: { amount: any, currencyCode: CurrencyCode }, amountPerQuantity: { amount: any, currencyCode: CurrencyCode }, compareAtAmountPerQuantity?: { amount: any, currencyCode: CurrencyCode } | null } }> }, cost: { totalTaxAmount?: { amount: any, currencyCode: CurrencyCode } | null, subtotalAmount: { amount: any, currencyCode: CurrencyCode }, totalAmount: { amount: any, currencyCode: CurrencyCode }, checkoutChargeAmount: { amount: any, currencyCode: CurrencyCode } }, discountCodes: Array<{ code: string, applicable: boolean }>, discountAllocations: Array<{ discountedAmount: { amount: any, currencyCode: CurrencyCode } } | { discountedAmount: { amount: any, currencyCode: CurrencyCode } } | { discountedAmount: { amount: any, currencyCode: CurrencyCode } }> } | null } | null };

export type RegisterAccountMutationVariables = Exact<{
email: Scalars['String']['input'];
password: Scalars['String']['input'];
firstName?: InputMaybe<Scalars['String']['input']>;
lastName?: InputMaybe<Scalars['String']['input']>;
acceptsMarketing?: InputMaybe<Scalars['Boolean']['input']>;
}>;


export type RegisterAccountMutation = { customerCreate?: { customer?: { id: string } | null, customerUserErrors: Array<{ code?: CustomerErrorCode | null, message: string }> } | null };

export type AddCouponMutationVariables = Exact<{
cartId: Scalars['ID']['input'];
discountCodes: Array<Scalars['String']['input']> | Scalars['String']['input'];
Expand Down
67 changes: 67 additions & 0 deletions vtex/actions/address/createAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface AddressInput {
name?: string;
addressName: string;
addressType?: string;
city?: string;
complement?: string;
country?: string;
geoCoordinates?: number[];
neighborhood?: string;
number?: string;
postalCode?: string;
receiverName?: string;
reference?: string;
state?: string;
street?: string;
}

interface SavedAddress {
id: string;
cacheId: string;
}

async function action(
props: AddressInput,
req: Request,
ctx: AppContext,
): Promise<
| SavedAddress
| null
> {
const { io } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);

const mutation = `
mutation SaveAddress($address: AddressInput!) {
saveAddress(address: $address) @context(provider: "vtex.store-graphql") {
id
cacheId
}
}`;

try {
const { saveAddress: savedAddress } = await io.query<
{ saveAddress: SavedAddress },
{ address: AddressInput }
>(
{
query: mutation,
operationName: "SaveAddress",
variables: {
address: props,
},
},
{ headers: { cookie } },
);

return savedAddress;
} catch (error) {
console.error("Error saving address:", error);
return null;
}
}

export default action;
58 changes: 58 additions & 0 deletions vtex/actions/address/deleteAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface DeleteAddress {
addressId: string;
}

interface AddressInput {
addressId: string;
}

async function action(
{ addressId }: AddressInput,
req: Request,
ctx: AppContext,
) {
const { io } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);

const mutation = `
mutation DeleteAddress($addressId: String) {
deleteAddress(id: $addressId) {
cacheId
addresses: address {
addressId: id
addressType
addressName
city
complement
country
neighborhood
number
postalCode
geoCoordinates
receiverName
reference
state
street
}
}
}`;

try {
return await io.query<DeleteAddress, { addressId: string }>(
{
query: mutation,
operationName: "DeleteAddress",
variables: { addressId },
},
{ headers: { cookie } },
);
} catch (error) {
console.error("Error deleting address:", error);
return null;
}
}

export default action;
92 changes: 92 additions & 0 deletions vtex/actions/address/updateAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { PostalAddressVTEX } from "../../../commerce/types.ts";
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface Address {
name?: string;
addressName?: string;
addressType?: string;
city?: string;
complement: string | null;
country?: string;
geoCoordinates?: number[];
neighborhood?: string;
number?: string;
postalCode?: string;
receiverName: string | null;
reference?: string;
state?: string;
street?: string;
addressId: string;
}

async function action(
props: Address,
req: Request,
ctx: AppContext,
): Promise<
| PostalAddressVTEX
| null
> {
const { io } = ctx;
const { cookie } = parseCookie(req.headers, ctx.account);
const { addressId, ...addressFields } = props;

const mutation = `
mutation UpdateAddress($addressId: String!, $addressFields: AddressInput) {
updateAddress(id: $addressId, fields: $addressFields)
@context(provider: "vtex.store-graphql") {
cacheId
addresses: address {
addressId: id
addressType
addressName
city
complement
country
neighborhood
number
postalCode
geoCoordinates
receiverName
reference
state
street
}
}
}
`;

try {
const { updateAddress: updatedAddress } = await io.query<
{ updateAddress: Address },
{ addressId: string; addressFields: Omit<Address, "addressId"> }
>(
{
query: mutation,
operationName: "UpdateAddress",
variables: {
addressId,
addressFields,
},
},
{ headers: { cookie } },
);

return {
"@type": "PostalAddress",
addressCountry: updatedAddress?.country,
addressLocality: updatedAddress?.city,
addressRegion: updatedAddress?.state,
postalCode: updatedAddress?.postalCode,
streetAddress: updatedAddress?.street,
receiverName: updatedAddress?.receiverName,
complement: updatedAddress?.complement,
addressId: updatedAddress?.addressId,
};
} catch (error) {
console.error("Error updating address:", error);
return null;
}
}
export default action;
39 changes: 39 additions & 0 deletions vtex/actions/payments/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

export interface DeleteCard {
deletePaymentToken: boolean;
}

interface Props {
id: string;
}

async function loader(
{ id }: Props,
req: Request,
ctx: AppContext,
): Promise<DeleteCard | null> {
const { io } = ctx;
const { cookie, payload } = parseCookie(req.headers, ctx.account);

if (!payload?.sub || !payload?.userId) {
return null;
}

const mutation = `mutation DeleteCreditCardToken($tokenId: ID!) {
deletePaymentToken(tokenId: $tokenId) @context(provider: "[email protected]")
}`;

try {
return await io.query<DeleteCard, { tokenId: string }>({
query: mutation,
variables: { tokenId: id },
}, { headers: { cookie } });
} catch (e) {
console.error(e);
return null;
}
}

export default loader;
Loading
Loading