Skip to content

Commit

Permalink
feat: algolia starter
Browse files Browse the repository at this point in the history
  • Loading branch information
ddaoxuan committed Sep 5, 2024
1 parent 712b5bd commit 842719b
Show file tree
Hide file tree
Showing 44 changed files with 28,754 additions and 13,721 deletions.
10 changes: 7 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"tailwindCSS.experimental.classRegex": [["cva(?:<[^>]*>)?(([^)]*))", "[\"'`]([^\"'`]*).*?[\"'`]", "(?:twMerge|twJoin)\\(([^\\);]*)[\\);]"]],
"prettier.configPath": "prettier.config.js"
"tailwindCSS.experimental.classRegex": [
[
"cva(?:<[^>]*>)?(([^)]*))",
"[\"'`]([^\"'`]*).*?[\"'`]",
"(?:twMerge|twJoin)\\(([^\\);]*)[\\);]"
]
]
}
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ $ yarn create commerce
- TailwindCSS
- Analytics (GTM, Vercel)
- Highly Scalable SEO Redirects ([Bloom Filters](https://nextjs.org/docs/app/building-your-application/routing/redirecting#managing-redirects-at-scale-advanced))
- Complete and fast CI/CD pipelines
- Platform agnostic (integrated with Shopify by default)
- Easy migration - migrate your existing solution in minutes
- Conventional commits git hook
- Playwright - write end-to-end tests like a pro
- Storybook - create, test, and showcase your components
- T3 Env - manage your environment variables with ease
Expand Down
36 changes: 1 addition & 35 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,6 @@
"name": "enterprise-commerce",
"version": "link",
"private": true,
"workspaces": [
"starters/**"
],
"scripts": {
"lint": "turbo run lint",
"test": "turbo run test",
"e2e": "turbo run e2e",
"commitlint": "commitlint --edit"
},
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^12.0.0",
Expand All @@ -20,33 +11,8 @@
"@semantic-release/release-notes-generator": "^12.1.0",
"@commitlint/cli": "19.2.1",
"@commitlint/config-conventional": "19.1.0",
"@jest/globals": "^29.7.0",
"@t3-oss/env-core": "^0.9.2",
"@total-typescript/ts-reset": "^0.5.1",
"@types/jest": "^29.5.12",
"@types/react": "^18.2.69",
"@types/react-dom": "^18.2.22",
"@types/node": "^20.11.30",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"husky": "^9.0.11",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"patch-package": "^8.0.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "3.2.5",
"prettier-plugin-tailwindcss": "^0.5.12",
"semantic-release": "^23.0.5",
"server-only": "^0.0.1",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"tsup": "^8.0.2",
"turbo": "1.13.0",
"typescript": "5.4.3",
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.4.1",
"webpack": "5.91.0",
"zod": "^3.22.4"
"semantic-release": "^23.0.5"
},
"engines": {
"node": ">=20.11.1"
Expand Down
13 changes: 6 additions & 7 deletions starters/shopify-algolia/app/actions/collection.actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"use server"

import { unstable_cache } from "next/cache"
import { meilisearch } from "clients/search"
import { ComparisonOperators, FilterBuilder } from "utils/filterBuilder"
import { algolia } from "clients/search"
import { getDemoSingleCategory, isDemoMode } from "utils/demoUtils"
import type { PlatformCollection } from "lib/shopify/types"
import { env } from "env.mjs"
Expand All @@ -11,11 +10,11 @@ export const getCollection = unstable_cache(
async (slug: string) => {
if (isDemoMode()) return getDemoSingleCategory(slug)

const results = await meilisearch.searchDocuments<PlatformCollection>({
indexName: env.MEILISEARCH_CATEGORIES_INDEX,
options: {
filter: new FilterBuilder().where("handle", ComparisonOperators.Equal, slug).build(),
limit: 1,
const results = await algolia.search<PlatformCollection>({
indexName: env.CATEGORIES_INDEX,
searchParams: {
filters: algolia.filterBuilder().where("handle", slug).build(),
hitsPerPage: 1,
attributesToRetrieve: ["handle", "title", "seo"],
},
})
Expand Down
45 changes: 19 additions & 26 deletions starters/shopify-algolia/app/actions/product.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import { unstable_cache } from "next/cache"
import { env } from "env.mjs"

import { meilisearch } from "clients/search"
import { algolia } from "clients/search"
import type { Review } from "lib/reviews/types"

import { ComparisonOperators, FilterBuilder } from "utils/filterBuilder"
import { getDemoProductReviews, getDemoSingleProduct, isDemoMode } from "utils/demoUtils"
import type { CommerceProduct } from "types"
import { notifyOptIn } from "utils/opt-in"
Expand All @@ -19,11 +18,11 @@ export const searchProducts = unstable_cache(
hasMore: false,
}

const { hits, estimatedTotalHits } = await meilisearch.searchDocuments<CommerceProduct>({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
query,
options: {
limit,
const { hits, estimatedTotalHits } = await algolia.search<CommerceProduct>({
indexName: env.PRODUCTS_INDEX,
searchParams: {
query,
hitsPerPage: limit,
attributesToRetrieve: ["id", "handle", "title", "featuredImage", "images", "variants"],
},
})
Expand All @@ -38,11 +37,11 @@ export const getProduct = unstable_cache(
async (handle: string) => {
if (isDemoMode()) return getDemoSingleProduct(handle)

const { results } = await meilisearch.getDocuments<CommerceProduct>({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
options: {
filter: new FilterBuilder().where("handle", ComparisonOperators.Equal, handle).build(),
limit: 1,
const { results } = await algolia.search<CommerceProduct>({
indexName: env.PRODUCTS_INDEX,
searchParams: {
filters: algolia.filterBuilder().where("handle", handle).build(),
hitsPerPage: 1,
},
})

Expand All @@ -56,24 +55,18 @@ export const getProductReviews = unstable_cache(
async (handle: string, { page = 1, limit = 10 } = { page: 1, limit: 10 }) => {
if (isDemoMode()) return getDemoProductReviews()

if (!env.MEILISEARCH_REVIEWS_INDEX) {
if (!env.REVIEWS_INDEX) {
notifyOptIn({ feature: "reviews", source: "product.actions.ts" })
return { reviews: [], total: 0 }
}

const { results, total } = await meilisearch.getDocuments<Review>({
indexName: env.MEILISEARCH_REVIEWS_INDEX,
options: {
filter: new FilterBuilder()
.where("product_handle", ComparisonOperators.Equal, handle)
.and()
.where("published", ComparisonOperators.Equal, "true")
.and()
.where("hidden", ComparisonOperators.Equal, "false")
.build(),
limit,
offset: (page - 1) * limit,
fields: ["body", "rating", "verified", "reviewer", "published", "created_at", "hidden", "featured"],
const { results, total } = await algolia.search<Review>({
indexName: env.REVIEWS_INDEX,
searchParams: {
filters: algolia.filterBuilder().where("product_handle", handle).and().where("published", "true").and().where("hidden", "false").build(),
hitsPerPage: limit,
page,
attributesToRetrieve: ["body", "rating", "verified", "reviewer", "published", "created_at", "hidden", "featured"],
},
})

Expand Down
32 changes: 13 additions & 19 deletions starters/shopify-algolia/app/api/feed/sync/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PlatformProduct } from "lib/shopify/types"
import { meilisearch } from "clients/search"
import { algolia } from "clients/search"
import { storefrontClient } from "clients/storefrontClient"
import { env } from "env.mjs"
import { compareHmac } from "utils/compare-hmac"
Expand Down Expand Up @@ -54,20 +54,17 @@ async function handleCollectionTopics(topic: SupportedTopic, { id }: Record<stri
console.error(`Collection ${id} not found`)
return new Response(JSON.stringify({ message: "Collection not found" }), { status: 404, headers: { "Content-Type": "application/json" } })
}
await meilisearch.updateDocuments({
indexName: env.MEILISEARCH_CATEGORIES_INDEX,
documents: [{ ...collection, id: `${id}` }],
options: {
primaryKey: "id",
},
await algolia.update({
indexName: env.CATEGORIES_INDEX,
objects: [{ ...collection, id: `${id}` }],
})

break

case "collections/delete":
await meilisearch.deleteDocuments({
indexName: env.MEILISEARCH_CATEGORIES_INDEX,
params: [id],
await algolia.delete({
indexName: env.CATEGORIES_INDEX,
objectIDs: [id],
})
break

Expand All @@ -91,19 +88,16 @@ async function handleProductTopics(topic: SupportedTopic, { id }: Record<string,
}

const enrichedProduct = await enrichProduct(product, items)
await meilisearch.updateDocuments({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
documents: [normalizeProduct(enrichedProduct, id)],
options: {
primaryKey: "id",
},
await algolia.update({
indexName: env.PRODUCTS_INDEX,
objects: [normalizeProduct(enrichedProduct, id)],
})

break
case "products/delete":
await meilisearch.deleteDocuments({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
params: [id],
await algolia.delete({
indexName: env.PRODUCTS_INDEX,
objectIDs: [id],
})
break

Expand Down
28 changes: 14 additions & 14 deletions starters/shopify-algolia/app/api/reviews/ai-summary/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import z from "zod"
import { openai } from "@ai-sdk/openai"
import type { Review } from "lib/reviews/types"
import type { CommerceProduct } from "types"
import { meilisearch } from "clients/search"
import { algolia } from "clients/search"
import { env } from "env.mjs"
import { authenticate } from "utils/authenticate-api-route"
import { isOptIn, notifyOptIn } from "utils/opt-in"
Expand Down Expand Up @@ -38,7 +38,7 @@ export async function GET(req: Request) {
return new Response(JSON.stringify(res), { status: 200 })
}

if (isDemoMode() || !env.MEILISEARCH_REVIEWS_INDEX) {
if (isDemoMode() || !env.REVIEWS_INDEX) {
console.error({
message: "Lacking environment variables",
source: "api/reviews/ai-summary",
Expand All @@ -47,19 +47,19 @@ export async function GET(req: Request) {
}

const [allReviews, allProducts] = await Promise.all([
meilisearch.getDocuments<Review>({
indexName: env.MEILISEARCH_REVIEWS_INDEX,
options: {
limit: 10000,
fields: ["body", "title", "product_handle", "rating"],
filter: "published=true AND hidden=false",
algolia.search<Review>({
indexName: env.REVIEWS_INDEX,
searchParams: {
hitsPerPage: 10000,
attributesToRetrieve: ["body", "title", "product_handle", "rating"],
filters: "published:true AND hidden:false",
},
}),
meilisearch.getDocuments<CommerceProduct>({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
options: {
limit: 10000,
fields: ["handle", "title", "id", "totalReviews"],
algolia.search<CommerceProduct>({
indexName: env.PRODUCTS_INDEX,
searchParams: {
hitsPerPage: 10000,
attributesToRetrieve: ["handle", "title", "id", "totalReviews"],
},
}),
])
Expand Down Expand Up @@ -123,7 +123,7 @@ export async function GET(req: Request) {
})
.filter(Boolean)

await meilisearch.updateDocuments<CommerceProduct>({ indexName: env.MEILISEARCH_PRODUCTS_INDEX, documents: updatedProducts, options: { primaryKey: "id" } })
await algolia.update({ indexName: env.PRODUCTS_INDEX, objects: updatedProducts })

return new Response(JSON.stringify({ message: "Reviews synced" }), { status: 200 })
}
Expand Down
42 changes: 18 additions & 24 deletions starters/shopify-algolia/app/api/reviews/sync/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_noStore } from "next/cache"
import { meilisearch } from "clients/search"
import { algolia } from "clients/search"
import { reviewsClient } from "clients/reviews"
import { env } from "env.mjs"
import { authenticate } from "utils/authenticate-api-route"
Expand All @@ -23,7 +23,7 @@ export async function GET(req: Request) {
return new Response(JSON.stringify(res), { status: 200 })
}

if (isDemoMode() || !env.MEILISEARCH_REVIEWS_INDEX) {
if (isDemoMode() || !env.REVIEWS_INDEX) {
console.error({
message: "Lacking environment variables",
source: "api/reviews/sync",
Expand All @@ -33,18 +33,18 @@ export async function GET(req: Request) {

const [allReviews, allProducts, allIndexReviews] = await Promise.all([
reviewsClient.getAllProductReviews(),
meilisearch.getDocuments<CommerceProduct>({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
options: {
limit: 10000,
fields: ["handle", "totalReviews", "avgRating", "id"],
algolia.search<CommerceProduct>({
indexName: env.PRODUCTS_INDEX,
searchParams: {
hitsPerPage: 10000,
attributesToRetrieve: ["handle", "totalReviews", "avgRating", "id"],
},
}),
meilisearch.getDocuments<Review>({
indexName: env.MEILISEARCH_REVIEWS_INDEX,
options: {
limit: 10000,
fields: ["updated_at", "id"],
algolia.search<Review>({
indexName: env.REVIEWS_INDEX,
searchParams: {
hitsPerPage: 10000,
attributesToRetrieve: ["updated_at", "id"],
},
}),
])
Expand Down Expand Up @@ -72,23 +72,17 @@ export async function GET(req: Request) {

!!reviewsDelta.length &&
(async () => {
meilisearch.updateDocuments({
indexName: env.MEILISEARCH_REVIEWS_INDEX!,
documents: reviewsDelta,
options: {
primaryKey: "id",
},
algolia.update({
indexName: env.REVIEWS_INDEX!,
objects: reviewsDelta,
})
console.log("API/sync: Reviews synced", reviewsDelta.length)
})()
!!productTotalReviewsDelta.length &&
(async () => {
meilisearch.updateDocuments({
indexName: env.MEILISEARCH_PRODUCTS_INDEX,
documents: productTotalReviewsDelta,
options: {
primaryKey: "id",
},
algolia.update({
indexName: env.PRODUCTS_INDEX,
objects: productTotalReviewsDelta,
})
console.log("API/sync:Products synced", productTotalReviewsDelta.length)
})()
Expand Down
10 changes: 5 additions & 5 deletions starters/shopify-algolia/app/category/clp/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PlatformCollection } from "lib/shopify/types"
import { meilisearch } from "clients/search"
import { algolia } from "clients/search"
import { env } from "env.mjs"
import type { Metadata } from "next"
import { isDemoMode } from "utils/demoUtils"
Expand All @@ -22,10 +22,10 @@ export async function generateMetadata({ params }: CategoryPageProps): Promise<M
export async function generateStaticParams() {
if (isDemoMode()) return []

const { hits } = await meilisearch.searchDocuments<PlatformCollection>({
indexName: env.MEILISEARCH_CATEGORIES_INDEX,
options: {
limit: 50,
const { hits } = await algolia.search<PlatformCollection>({
indexName: env.CATEGORIES_INDEX,
searchParams: {
hitsPerPage: 50,
attributesToRetrieve: ["handle"],
},
})
Expand Down
Loading

0 comments on commit 842719b

Please sign in to comment.