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

Feat(VTEX): Implement Addresses related APIs #1014

Open
wants to merge 4 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
104 changes: 104 additions & 0 deletions vtex/actions/address/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { PostalAddress } from "../../../commerce/types.ts";
import type { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface Props {
/**
* Address name.
*/
addressName: string | null;
/**
* Type of address. For example, Residential or Pickup, among others.
*/
addressType: string | null;
/**
* Name of the person who is going to receive the order.
*/
receiverName: string | null;
/**
* City of the shipping address.
*/
city: string | null;
/**
* State of the shipping address.
*/
state: string | null;
/**
* Three letter ISO code of the country of the shipping address.
*/
country: string | null;
/**
* Postal Code.
*/
postalCode: string | null;
/**
* Street of the address.
*/
street: string | null;
/**
* Number of the building, house or apartment in the shipping address.
*/
number: string | null;
/**
* Neighborhood of the address.
*/
neighborhood: string | null;
/**
* Complement to the shipping address in case it applies.
*/
complement: string | null;
/**
* Complement that might help locate the shipping address more precisely in case of delivery.
*/
reference: string | null;
}

async function action(
props: Props,
req: Request,
ctx: AppContext,
): Promise<PostalAddress | null> {
const { vcs } = ctx;
const { cookie, payload } = parseCookie(req.headers, ctx.account);

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

try {
const { Id } = await vcs["POST /api/dataentities/:acronym/documents"]({
acronym: "AD",
}, {
body: { ...props, userId: payload.userId } as unknown as Record<
string,
unknown
>,
headers: {
accept: "application/json",
"content-type": "application/json",
cookie,
},
}).then((res) => res.json());

return {
"@type": "PostalAddress",
"@id": Id,
name: props.addressName ?? undefined,
additionalType: props.addressType ?? undefined,
alternateName: props.receiverName ?? undefined,
addressLocality: props.city ?? undefined,
addressRegion: props.state ?? undefined,
addressCountry: props.country ?? undefined,
postalCode: props.postalCode ?? undefined,
streetAddress: props.street ?? undefined,
description: props.complement ?? undefined,
disambiguatingDescription: props.reference ?? undefined,
};
} catch (error) {
console.error("Error saving address:", error);
return null;
}
}

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

interface Props {
addressId: string;
}

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

try {
return await vcs["DELETE /api/dataentities/:acronym/documents/:id"]({
acronym: "AD",
id: addressId,
}, { headers: { cookie, accept: "application/json" } });
} catch (error) {
console.error("Error deleting address:", error);
return null;
}
}

export const defaultVisibility = "private";
export default action;
109 changes: 109 additions & 0 deletions vtex/actions/address/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type { PostalAddress } from "../../../commerce/types.ts";
import type { AppContext } from "../../mod.ts";
import { parseCookie } from "../../utils/vtexId.ts";

interface Props {
/**
* Address ID.
*/
addressId: string;
/**
* Address name.
*/
addressName: string | null;
/**
* Type of address. For example, Residential or Pickup, among others.
*/
addressType: string | null;
/**
* Name of the person who is going to receive the order.
*/
receiverName: string | null;
/**
* City of the shipping address.
*/
city: string | null;
/**
* State of the shipping address.
*/
state: string | null;
/**
* Three letter ISO code of the country of the shipping address.
*/
country: string | null;
/**
* Postal Code.
*/
postalCode: string | null;
/**
* Street of the address.
*/
street: string | null;
/**
* Number of the building, house or apartment in the shipping address.
*/
number: string | null;
/**
* Neighborhood of the address.
*/
neighborhood: string | null;
/**
* Complement to the shipping address in case it applies.
*/
complement: string | null;
/**
* Complement that might help locate the shipping address more precisely in case of delivery.
*/
reference: string | null;
}

async function action(
{ addressId, ...props }: Props,
req: Request,
ctx: AppContext,
): Promise<PostalAddress | null> {
const { vcs } = ctx;
const { cookie, payload } = parseCookie(req.headers, ctx.account);

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

try {
await vcs["PATCH /api/dataentities/:acronym/documents/:id"]({
acronym: "AD",
id: addressId,
}, {
body: { ...props, userId: payload.userId } as unknown as Record<
string,
unknown
>,
headers: {
accept: "application/json",
"content-type": "application/json",
cookie,
},
}).then((res) => res.json());

return {
"@type": "PostalAddress",
"@id": addressId,
name: props.addressName ?? undefined,
additionalType: props.addressType ?? undefined,
alternateName: props.receiverName ?? undefined,
addressLocality: props.city ?? undefined,
addressRegion: props.state ?? undefined,
addressCountry: props.country ?? undefined,
postalCode: props.postalCode ?? undefined,
streetAddress: props.street ?? undefined,
description: props.complement ?? undefined,
disambiguatingDescription: props.reference ?? undefined,
};
} catch (error) {
console.error("Error updating address:", error);
return null;
}
}

export const defaultVisibility = "private";
export default action;
47 changes: 47 additions & 0 deletions vtex/loaders/address/getAddressByPostalCode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { PostalAddress } from "../../../commerce/types.ts";
import { AppContext } from "../../mod.ts";

interface Props {
/**
* @description User country code. Ex: USA
*/
countryCode: string;
/**
* @description User postal code.
*/
postalCode: string;
}

export default async function loader(
props: Props,
_req: Request,
ctx: AppContext,
): Promise<PostalAddress | null> {
const { countryCode, postalCode } = props;
const { vcs } = ctx;

try {
const addressByPostalCode = await vcs
["GET /api/checkout/pub/postal-code/:countryCode/:postalCode"]({
countryCode,
postalCode,
})
.then((r) => r.json());

return {
"@type": "PostalAddress",
postalCode: addressByPostalCode.postalCode,
addressLocality: addressByPostalCode.city,
addressRegion: addressByPostalCode.state,
addressCountry: addressByPostalCode.country,
streetAddress: addressByPostalCode.street || undefined,
identifier: addressByPostalCode.number || undefined,
areaServed: addressByPostalCode.neighborhood || undefined,
description: addressByPostalCode.complement || undefined,
disambiguatingDescription: addressByPostalCode.reference || undefined,
};
} catch (error) {
console.error(error);
return null;
}
}
41 changes: 41 additions & 0 deletions vtex/loaders/address/getUserAddresses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { PostalAddress } from "../../../commerce/types.ts";
import type { AppContext } from "../../mod.ts";
import { toPostalAddress } from "../../utils/transform.ts";
import type { Address } from "../../utils/types.ts";
import { parseCookie } from "../../utils/vtexId.ts";

async function loader(
_props: unknown,
req: Request,
ctx: AppContext,
): Promise<PostalAddress[] | null> {
const { vcs } = ctx;
const { cookie, payload } = parseCookie(req.headers, ctx.account);

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

try {
const addresses = await vcs["GET /api/dataentities/:acronym/search"]({
acronym: "AD",
_where: `userId=${payload.userId}`,
_fields:
"addressName,addressType,city,complement,country,geoCoordinate,neighborhood,number,postalCode,receiverName,reference,state,street,userId",
}, { headers: { cookie } }).then((r) => r.json()) as Omit<
Address,
"isDisposable"
>[];

if (!addresses?.length) {
return null;
}

return addresses.map(toPostalAddress);
} catch (_) {
return null;
}
}

export const defaultVisibility = "private";
export default loader;
Loading
Loading