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(api): Add session mutation #1176

Merged
merged 8 commits into from Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api/codegen.yml
@@ -1,5 +1,5 @@
overwrite: true
schema: "./src/typeDefs/*.graphql"
schema: "./src/**/*.graphql"
documents: null
generates:
src/__generated__/schema.ts:
Expand Down
19 changes: 19 additions & 0 deletions packages/api/src/__generated__/schema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/api/src/index.ts
Expand Up @@ -29,5 +29,5 @@ export const getContextFactory = (options: Options) =>
export const getSchema = async (options: Options) =>
makeExecutableSchema({
resolvers: getResolvers(options),
typeDefs: getTypeDefs(),
typeDefs,
})
12 changes: 12 additions & 0 deletions packages/api/src/platforms/vtex/clients/commerce/index.ts
Expand Up @@ -4,6 +4,7 @@ import type { Brand } from './types/Brand'
import type { CategoryTree } from './types/CategoryTree'
import type { OrderForm, OrderFormInputItem } from './types/OrderForm'
import type { PortalPagetype } from './types/Portal'
import type { Region, RegionInput } from './types/Region'
import type {
Simulation,
SimulationArgs,
Expand Down Expand Up @@ -102,6 +103,17 @@ export const VtexCommerce = (
}
)
},
region: async ({
postalCode,
country,
salesChannel,
}: RegionInput): Promise<Region> => {
return fetchAPI(
`${base}/api/checkout/pub/regions/?postalCode=${postalCode}&country=${country}&sc=${
salesChannel ?? ''
}`
)
},
},
session: (): Promise<Session> =>
fetchAPI(
Expand Down
@@ -0,0 +1,7 @@
export interface RegionInput {
postalCode: string
country: string
salesChannel?: string | null
}

export type Region = Array<{ id: string }>
2 changes: 2 additions & 0 deletions packages/api/src/platforms/vtex/resolvers/mutation.ts
@@ -1,5 +1,7 @@
import { validateCart } from './validateCart'
import session from './session'

export const Mutation = {
validateCart,
session,
}
19 changes: 19 additions & 0 deletions packages/api/src/platforms/vtex/resolvers/session.ts
@@ -0,0 +1,19 @@
import type { Context } from '..'
import type { MutationSessionArgs } from '../../../__generated__/schema'
import ChannelParser from '../utils/channel'

export default async function sessionResolvers(
igorbrasileiro marked this conversation as resolved.
Show resolved Hide resolved
_: any,
{ session }: MutationSessionArgs,
{ clients }: Context
) {
const channelParser = new ChannelParser(session?.channel ?? '')
const regionData = await clients.commerce.checkout.region({
postalCode: String(session.postalCode ?? '').replace(/\D/g, ''),
country: session.country ?? '',
})

channelParser.updateChannel({ regionId: regionData?.[0]?.id })

return { ...session, channel: channelParser.stringify() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why you chose to create this stringify function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the channel for all platforms is a string that should be handled only on the backend, for the front end is only a string.

}
46 changes: 46 additions & 0 deletions packages/api/src/platforms/vtex/utils/channel.ts
@@ -0,0 +1,46 @@
export interface Channel {
postalCode: string
regionId: string
salesChannel: string
}

export default class ChannelParser {
igorbrasileiro marked this conversation as resolved.
Show resolved Hide resolved
private _channel: string
private channel: Channel
constructor(channel: string) {
this._channel = channel
this.channel = this._parse()
}

private _parse(): Channel {
try {
const parsedChannel = JSON.parse(this._channel)

this.channel = {
...this.channel,
regionId: parsedChannel.regionId ?? '',
salesChannel: parsedChannel.salesChannel ?? '',
}

return this.channel
} catch (error) {
console.error(error)

throw new Error('Malformed channel string')
}
}

public parse(): Channel {
return this.channel
}

public stringify(): string {
return this._channel
}

public updateChannel(partialChannel: Partial<Channel>) {
this.channel = { ...this.channel, ...partialChannel }

this._channel = JSON.stringify(this.channel)
}
}
14 changes: 14 additions & 0 deletions packages/api/src/typeDefs/mutation.graphql
@@ -1,4 +1,18 @@
type StoreSession {
channel: String
country: String
postalCode: String
}

input IStoreSession {
channel: String
country: String
postalCode: String
}

type Mutation {
# Returns the order if anything changed with the order. Null if the order is valid
validateCart(cart: IStoreCart!): StoreCart

session(session: IStoreSession!): StoreSession!
igorbrasileiro marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions packages/api/src/typings/index.ts
@@ -0,0 +1 @@
export type Platform = 'vtex'