diff --git a/.github/workflows/bun-test.yml b/.github/workflows/bun-test.yml
index f562cc5..33b9338 100644
--- a/.github/workflows/bun-test.yml
+++ b/.github/workflows/bun-test.yml
@@ -19,7 +19,7 @@ jobs:
bun-version: latest
- name: Install dependencies
- run: bun install
+ run: bun install && cd cf-proxy && bun install && cd ..
- name: Cache setup artifacts
id: cache-setup
diff --git a/routes/api/search.tsx b/routes/api/search.tsx
index 4bf0cad..3f354f6 100644
--- a/routes/api/search.tsx
+++ b/routes/api/search.tsx
@@ -42,6 +42,7 @@ export default withWinterSpec({
limit: z.string().optional(),
is_basic: z.boolean().optional(),
is_preferred: z.boolean().optional(),
+ is_extended_promotional: z.boolean().optional(),
}),
jsonResponse: z.any(),
} as const)(async (req, ctx) => {
@@ -64,6 +65,9 @@ export default withWinterSpec({
if (req.query.is_preferred) {
query = query.where("preferred", "=", 1)
}
+ if (req.query.is_extended_promotional) {
+ query = query.where("preferred", "=", 1).where("basic", "=", 0)
+ }
const baseQuery = query
let fallbackLikeTokens: string[] = []
@@ -189,6 +193,7 @@ export default withWinterSpec({
package: c.package,
is_basic: Boolean(c.basic),
is_preferred: Boolean(c.preferred),
+ is_extended_promotional: Boolean(c.preferred) && !c.basic,
description: c.description,
stock: c.stock,
price: extractSmallQuantityPrice(c.price),
diff --git a/routes/components/list.tsx b/routes/components/list.tsx
index 8d26b56..863cb9e 100644
--- a/routes/components/list.tsx
+++ b/routes/components/list.tsx
@@ -1,6 +1,4 @@
-import { sql } from "kysely"
import { Table } from "lib/ui/Table"
-import { ExpressionBuilder } from "kysely"
import { withWinterSpec } from "lib/with-winter-spec"
import { z } from "zod"
@@ -23,6 +21,7 @@ export default withWinterSpec({
search: z.string().optional(),
is_basic: z.boolean().optional(),
is_preferred: z.boolean().optional(),
+ is_extended_promotional: z.boolean().optional(),
}),
jsonResponse: z.any(),
} as const)(async (req, ctx) => {
@@ -39,6 +38,7 @@ export default withWinterSpec({
"price",
"extra",
"basic",
+ "preferred",
])
.limit(limit)
.orderBy("stock", "desc")
@@ -58,6 +58,9 @@ export default withWinterSpec({
if (req.query.is_preferred) {
query = query.where("preferred", "=", 1)
}
+ if (req.query.is_extended_promotional) {
+ query = query.where("preferred", "=", 1).where("basic", "=", 0)
+ }
if (req.query.search) {
const search = req.query.search // TypeScript now knows this is defined within this block
@@ -82,6 +85,7 @@ export default withWinterSpec({
package: c.package,
is_basic: Boolean(c.basic),
is_preferred: Boolean(c.preferred),
+ is_extended_promotional: Boolean(c.preferred) && !c.basic,
description: c.description,
stock: c.stock,
price: extractSmallQuantityPrice(c.price),
@@ -126,6 +130,17 @@ export default withWinterSpec({
/>
+
+
+
diff --git a/tests/routes/api/search.test.ts b/tests/routes/api/search.test.ts
index 90f3794..6ad1440 100644
--- a/tests/routes/api/search.test.ts
+++ b/tests/routes/api/search.test.ts
@@ -107,3 +107,32 @@ test("GET /api/search supports '0402 LED'", async () => {
expect(res.data.components.every((c: any) => c.package === "0402")).toBe(true)
expect(res.data.components.some((c: any) => c.lcsc === 965793)).toBe(true)
})
+
+test("GET /api/search returns is_extended_promotional field", async () => {
+ const { axios } = await getTestServer()
+ const res = await axios.get("/api/search?q=resistor&limit=10")
+
+ expect(res.data).toHaveProperty("components")
+ expect(Array.isArray(res.data.components)).toBe(true)
+ expect(res.data.components.length).toBeGreaterThan(0)
+
+ const component = res.data.components[0]
+ expect(component).toHaveProperty("is_extended_promotional")
+ expect(typeof component.is_extended_promotional).toBe("boolean")
+})
+
+test("GET /api/search with is_extended_promotional=true returns only extended promotional components", async () => {
+ const { axios } = await getTestServer()
+ const res = await axios.get(
+ "/api/search?is_extended_promotional=true&limit=50",
+ )
+
+ expect(res.data).toHaveProperty("components")
+ expect(Array.isArray(res.data.components)).toBe(true)
+
+ for (const component of res.data.components) {
+ expect(component.is_preferred).toBe(true)
+ expect(component.is_basic).toBe(false)
+ expect(component.is_extended_promotional).toBe(true)
+ }
+})
diff --git a/tests/routes/components/list.test.ts b/tests/routes/components/list.test.ts
index 061f1c3..feea0e1 100644
--- a/tests/routes/components/list.test.ts
+++ b/tests/routes/components/list.test.ts
@@ -1,4 +1,4 @@
-import { test, expect } from "bun:test"
+import { expect, test } from "bun:test"
import { getTestServer } from "tests/fixtures/get-test-server"
test("GET /components/list with json param returns component data", async () => {
@@ -7,3 +7,32 @@ test("GET /components/list with json param returns component data", async () =>
expect(res.data).toHaveProperty("components")
expect(Array.isArray(res.data.components)).toBe(true)
})
+
+test("GET /components/list returns is_extended_promotional field", async () => {
+ const { axios } = await getTestServer()
+ const res = await axios.get("/components/list?json=true")
+
+ expect(res.data).toHaveProperty("components")
+ expect(Array.isArray(res.data.components)).toBe(true)
+ expect(res.data.components.length).toBeGreaterThan(0)
+
+ const component = res.data.components[0]
+ expect(component).toHaveProperty("is_extended_promotional")
+ expect(typeof component.is_extended_promotional).toBe("boolean")
+})
+
+test("GET /components/list with is_extended_promotional=true returns only extended promotional components", async () => {
+ const { axios } = await getTestServer()
+ const res = await axios.get(
+ "/components/list?json=true&is_extended_promotional=true",
+ )
+
+ expect(res.data).toHaveProperty("components")
+ expect(Array.isArray(res.data.components)).toBe(true)
+
+ for (const component of res.data.components) {
+ expect(component.is_preferred).toBe(true)
+ expect(component.is_basic).toBe(false)
+ expect(component.is_extended_promotional).toBe(true)
+ }
+})