Skip to content
Merged
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
9 changes: 8 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
}
},
"files": {
"includes": ["commerce/**", "shopify/**", "vtex/**", "resend/**", "vitest.config.ts"]
"includes": [
"commerce/**",
"shopify/**",
"vtex/**",
"resend/**",
"website/**",
"vitest.config.ts"
]
}
}
4 changes: 2 additions & 2 deletions package-lock.json

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

14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,18 @@
"./resend/mod": "./resend/mod.ts",
"./resend/client": "./resend/client.ts",
"./resend/types": "./resend/types.ts",
"./resend/actions/send": "./resend/actions/send.ts"
"./resend/actions/send": "./resend/actions/send.ts",
"./website": "./website/index.ts",
"./website/mod": "./website/mod.ts",
"./website/client": "./website/client.ts",
"./website/types": "./website/types.ts",
"./website/components/*": "./website/components/*.tsx",
"./website/loaders/*": "./website/loaders/*.ts",
"./website/loaders/fonts/*": "./website/loaders/fonts/*.ts",
"./website/matchers/*": "./website/matchers/*.ts",
"./website/flags/*": "./website/flags/*.ts",
"./website/flags/multivariate/*": "./website/flags/multivariate/*.ts",
"./website/utils/*": "./website/utils/*.ts"
},
"scripts": {
"generate:manifests": "tsx scripts/generate-manifests.ts",
Expand Down Expand Up @@ -80,6 +91,7 @@
"shopify/",
"vtex/",
"resend/",
"website/",
"!**/__tests__/",
"!scripts/"
],
Expand Down
1 change: 1 addition & 0 deletions scripts/generate-manifests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const APPS: AppConfig[] = [
{ name: "vtex", dir: "vtex" },
{ name: "shopify", dir: "shopify" },
{ name: "resend", dir: "resend" },
{ name: "website", dir: "website" },
];

const CATEGORIES = ["loaders", "actions", "sections"] as const;
Expand Down
2 changes: 1 addition & 1 deletion vtex/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export async function vtexCachedFetch<T>(
export async function vtexFetchWithCookies<T>(path: string, init?: RequestInit): Promise<T> {
// Auto-inject request cookies from RequestContext
const existingHeaders = init?.headers as Record<string, string> | undefined;
if (!existingHeaders?.["cookie"]) {
if (!existingHeaders?.cookie) {
const ctx = RequestContext.current;
const cookies = ctx?.request.headers.get("cookie");
if (cookies) {
Expand Down
2 changes: 1 addition & 1 deletion vtex/commerceLoaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function createVtexCommerceLoaders(
static: options?.cacheProfiles?.static ?? "static",
};

const cachedProductList = createCachedLoader(
const _cachedProductList = createCachedLoader(
"vtex/productList",
vtexProductList,
profiles.listing,
Expand Down
2 changes: 2 additions & 0 deletions vtex/manifest.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as actions_session from "./actions/session";
import * as actions_trigger from "./actions/trigger";
import * as actions_wishlist from "./actions/wishlist";
import * as loaders_address from "./loaders/address";
import * as loaders_autocomplete from "./loaders/autocomplete";
import * as loaders_brands from "./loaders/brands";
import * as loaders_cart from "./loaders/cart";
import * as loaders_catalog from "./loaders/catalog";
Expand All @@ -36,6 +37,7 @@ const manifest = {
name: "vtex",
loaders: {
"vtex/loaders/address": loaders_address,
"vtex/loaders/autocomplete": loaders_autocomplete,
"vtex/loaders/brands": loaders_brands,
"vtex/loaders/cart": loaders_cart,
"vtex/loaders/catalog": loaders_catalog,
Expand Down
116 changes: 116 additions & 0 deletions website/__tests__/flags.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { describe, expect, it } from "vitest";
import Audience from "../flags/audience";
import Everyone from "../flags/everyone";
import Flag from "../flags/flag";
import type { Matcher } from "../types";
import multivariate from "../utils/multivariate";

// ---------------------------------------------------------------------------
// flag.ts
// ---------------------------------------------------------------------------

describe("Flag", () => {
it("returns a FlagObj with the same values", () => {
const matcher: Matcher = () => true;
const result = Flag({
matcher,
true: "variant-a",
false: "variant-b",
name: "test-flag",
});

expect(result.matcher).toBe(matcher);
expect(result.true).toBe("variant-a");
expect(result.false).toBe("variant-b");
expect(result.name).toBe("test-flag");
});

it("preserves complex true/false values", () => {
const routes = [{ pathTemplate: "/*", handler: { value: {} } }];
const result = Flag<typeof routes>({
matcher: () => false,
true: routes,
false: [],
name: "routes-flag",
});

expect(result.true).toBe(routes);
expect(result.false).toEqual([]);
});
});

// ---------------------------------------------------------------------------
// audience.ts
// ---------------------------------------------------------------------------

describe("Audience", () => {
it("returns FlagObj with routes as true branch and empty as false", () => {
const matcher: Matcher = () => true;
const routes = [{ pathTemplate: "/products/*", handler: { value: {} } }];

const result = Audience({ matcher, name: "vip-users", routes });

expect(result.name).toBe("vip-users");
expect(result.true).toEqual(routes);
expect(result.false).toEqual([]);
});

it("defaults routes to empty array when not provided", () => {
const result = Audience({ matcher: () => false, name: "empty" });

expect(result.true).toEqual([]);
expect(result.false).toEqual([]);
});
});

// ---------------------------------------------------------------------------
// everyone.ts
// ---------------------------------------------------------------------------

describe("Everyone", () => {
it("creates a flag named Everyone that always matches", () => {
const routes = [{ pathTemplate: "/*", handler: { value: {} } }];
const result = Everyone({ routes });

expect(result.name).toBe("Everyone");
expect(result.true).toEqual(routes);
expect(result.false).toEqual([]);
// The matcher should be MatchAlways which returns true
expect(result.matcher({} as any)).toBe(true);
});

it("works with no routes", () => {
const result = Everyone({});

expect(result.name).toBe("Everyone");
expect(result.true).toEqual([]);
});
});

// ---------------------------------------------------------------------------
// multivariate
// ---------------------------------------------------------------------------

describe("multivariate", () => {
it("returns the variants as-is", () => {
const variants = [
{ value: "A", weight: 0.5 },
{ value: "B", weight: 0.5 },
];

const result = multivariate({ variants });

expect(result.variants).toBe(variants);
expect(result.variants).toHaveLength(2);
});

it("supports variants with matchers", () => {
const matcher: Matcher = () => true;
const variants = [{ value: "control", matcher }, { value: "default" }];

const result = multivariate({ variants });

expect(result.variants[0].matcher).toBe(matcher);
expect(result.variants[1].matcher).toBeUndefined();
});
});
Loading
Loading