Skip to content

Commit 1c1e8ec

Browse files
committed
feat(web): add tree shaking for lucide-icons
1 parent 48deca9 commit 1c1e8ec

61 files changed

Lines changed: 227 additions & 386 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/api/src/db/queries.ts

Lines changed: 0 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ import {
2929
executions,
3030
type ExecutionStatusType,
3131
type MembershipInsert,
32-
type MembershipRow,
3332
memberships,
3433
type OrganizationInsert,
3534
OrganizationRole,
36-
type OrganizationRoleType,
3735
organizations,
3836
Plan,
3937
type PlanType,
@@ -1703,204 +1701,3 @@ export async function deleteOrganization(
17031701

17041702
return !!deletedOrganization;
17051703
}
1706-
1707-
/**
1708-
* Add or update a user's membership in an organization (only admins and owners can do this)
1709-
*
1710-
* @param db Database instance
1711-
* @param organizationIdOrHandle Organization ID or handle
1712-
* @param targetUserId User ID to add/update membership for
1713-
* @param role Role to assign (member, admin, owner)
1714-
* @param adminUserId User ID of the admin/owner making the change
1715-
* @returns The created or updated membership record, or null if permission denied
1716-
*/
1717-
export async function addOrUpdateMembership(
1718-
db: ReturnType<typeof createDatabase>,
1719-
organizationIdOrHandle: string,
1720-
targetUserId: string,
1721-
role: OrganizationRoleType,
1722-
adminUserId: string
1723-
): Promise<MembershipRow | null> {
1724-
// First, verify the admin user has permission (admin or owner)
1725-
const [adminMembership] = await db
1726-
.select()
1727-
.from(memberships)
1728-
.innerJoin(organizations, eq(memberships.organizationId, organizations.id))
1729-
.where(
1730-
and(
1731-
eq(memberships.userId, adminUserId),
1732-
getOrganizationCondition(organizationIdOrHandle),
1733-
inArray(memberships.role, [
1734-
OrganizationRole.ADMIN,
1735-
OrganizationRole.OWNER,
1736-
])
1737-
)
1738-
)
1739-
.limit(1);
1740-
1741-
if (!adminMembership) {
1742-
return null; // Admin user doesn't have permission
1743-
}
1744-
1745-
// Additional check: only owners can assign the owner role
1746-
if (
1747-
role === OrganizationRole.OWNER &&
1748-
adminMembership.memberships.role !== OrganizationRole.OWNER
1749-
) {
1750-
return null; // Only owners can assign owner role
1751-
}
1752-
1753-
const organizationId = adminMembership.organizations.id;
1754-
const now = new Date();
1755-
1756-
// Check if the target user is already a member
1757-
const [existingMembership] = await db
1758-
.select()
1759-
.from(memberships)
1760-
.where(
1761-
and(
1762-
eq(memberships.userId, targetUserId),
1763-
eq(memberships.organizationId, organizationId)
1764-
)
1765-
)
1766-
.limit(1);
1767-
1768-
if (existingMembership) {
1769-
// Update existing membership
1770-
const [updatedMembership] = await db
1771-
.update(memberships)
1772-
.set({
1773-
role,
1774-
updatedAt: now,
1775-
})
1776-
.where(
1777-
and(
1778-
eq(memberships.userId, targetUserId),
1779-
eq(memberships.organizationId, organizationId)
1780-
)
1781-
)
1782-
.returning();
1783-
1784-
return updatedMembership;
1785-
} else {
1786-
// Create new membership
1787-
const newMembership: MembershipInsert = {
1788-
userId: targetUserId,
1789-
organizationId,
1790-
role,
1791-
createdAt: now,
1792-
updatedAt: now,
1793-
};
1794-
1795-
const [createdMembership] = await db
1796-
.insert(memberships)
1797-
.values(newMembership)
1798-
.returning();
1799-
1800-
return createdMembership;
1801-
}
1802-
}
1803-
1804-
/**
1805-
* Delete a user's membership from an organization (only admins and owners can do this)
1806-
*
1807-
* @param db Database instance
1808-
* @param organizationIdOrHandle Organization ID or handle
1809-
* @param targetUserId User ID to remove from the organization
1810-
* @param adminUserId User ID of the admin/owner making the change
1811-
* @returns True if membership was deleted, false if permission denied or not found
1812-
*/
1813-
export async function deleteMembership(
1814-
db: ReturnType<typeof createDatabase>,
1815-
organizationIdOrHandle: string,
1816-
targetUserId: string,
1817-
adminUserId: string
1818-
): Promise<boolean> {
1819-
// First, verify the admin user has permission (admin or owner)
1820-
const [adminMembership] = await db
1821-
.select()
1822-
.from(memberships)
1823-
.innerJoin(organizations, eq(memberships.organizationId, organizations.id))
1824-
.where(
1825-
and(
1826-
eq(memberships.userId, adminUserId),
1827-
getOrganizationCondition(organizationIdOrHandle),
1828-
inArray(memberships.role, [
1829-
OrganizationRole.ADMIN,
1830-
OrganizationRole.OWNER,
1831-
])
1832-
)
1833-
)
1834-
.limit(1);
1835-
1836-
if (!adminMembership) {
1837-
return false; // Admin user doesn't have permission
1838-
}
1839-
1840-
// Get the target user's membership to check their role
1841-
const [targetMembership] = await db
1842-
.select()
1843-
.from(memberships)
1844-
.where(
1845-
and(
1846-
eq(memberships.userId, targetUserId),
1847-
eq(memberships.organizationId, adminMembership.organizations.id)
1848-
)
1849-
)
1850-
.limit(1);
1851-
1852-
if (!targetMembership) {
1853-
return false; // Target user is not a member
1854-
}
1855-
1856-
// Additional check: only owners can delete other owners
1857-
if (
1858-
targetMembership.role === OrganizationRole.OWNER &&
1859-
adminMembership.memberships.role !== OrganizationRole.OWNER
1860-
) {
1861-
return false; // Only owners can delete other owners
1862-
}
1863-
1864-
// Prevent users from deleting themselves
1865-
if (targetUserId === adminUserId) {
1866-
return false; // Users cannot delete their own membership
1867-
}
1868-
1869-
// Delete the membership
1870-
const [deletedMembership] = await db
1871-
.delete(memberships)
1872-
.where(
1873-
and(
1874-
eq(memberships.userId, targetUserId),
1875-
eq(memberships.organizationId, adminMembership.organizations.id)
1876-
)
1877-
)
1878-
.returning({ id: memberships.userId });
1879-
1880-
return !!deletedMembership;
1881-
}
1882-
1883-
/**
1884-
* List all memberships for an organization
1885-
*
1886-
* @param db Database instance
1887-
* @param organizationIdOrHandle Organization ID or handle
1888-
* @returns Array of membership records
1889-
*/
1890-
export async function getOrganizationMemberships(
1891-
db: ReturnType<typeof createDatabase>,
1892-
organizationIdOrHandle: string
1893-
) {
1894-
return await db
1895-
.select({
1896-
userId: memberships.userId,
1897-
organizationId: memberships.organizationId,
1898-
role: memberships.role,
1899-
createdAt: memberships.createdAt,
1900-
updatedAt: memberships.updatedAt,
1901-
})
1902-
.from(memberships)
1903-
.innerJoin(organizations, eq(memberships.organizationId, organizations.id))
1904-
.where(getOrganizationCondition(organizationIdOrHandle))
1905-
.orderBy(memberships.createdAt);
1906-
}

apps/web/server.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ const vite = await createServer({
5151
});
5252
app.use(vite.middlewares);
5353

54-
let template = await fs.readFile("./index.html", "utf-8");
54+
const originalTemplate = await fs.readFile("./index.html", "utf-8");
5555
const render = (await vite.ssrLoadModule("/src/entry-server.tsx")).render;
5656

5757
// Serve HTML
5858
app.use("*all", async (req, res) => {
5959
try {
6060
const pathname = req.originalUrl;
61-
template = await vite.transformIndexHtml(pathname, template);
61+
let html = await vite.transformIndexHtml(pathname, originalTemplate);
6262

6363
// Construct a Fetch API Request object from the Express request
6464
const url = new URL(
@@ -72,7 +72,7 @@ app.use("*all", async (req, res) => {
7272

7373
const rendered = await render(fetchRequest);
7474

75-
let html = template
75+
html = html
7676
.replace(`<!--app-head-->`, rendered.headHtml ?? "")
7777
.replace(`<!--app-html-->`, "");
7878

apps/web/src/components/app-header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Bot } from "lucide-react";
1+
import Bot from "lucide-react/icons/bot";
22
import { Link } from "react-router";
33

44
import { OrganizationSwitcher } from "@/components/organization-switcher";

apps/web/src/components/deployments/deployment-info-card.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { format } from "date-fns";
2-
import {
3-
ArrowUpToLine,
4-
Clock,
5-
GitCommitHorizontal,
6-
IdCard,
7-
} from "lucide-react";
2+
import ArrowUpToLine from "lucide-react/icons/arrow-up-to-line";
3+
import Clock from "lucide-react/icons/clock";
4+
import GitCommitHorizontal from "lucide-react/icons/git-commit-horizontal";
5+
import IdCard from "lucide-react/icons/id-card";
86
import { Link } from "react-router";
97

108
import { Badge } from "@/components/ui/badge";

apps/web/src/components/deployments/workflow-info-card.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { IdCard, Workflow } from "lucide-react";
1+
import IdCard from "lucide-react/icons/id-card";
2+
import Workflow from "lucide-react/icons/workflow";
23
import { Link } from "react-router";
34

45
import {

apps/web/src/components/docs/code-block.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Check, Copy } from "lucide-react";
1+
import Check from "lucide-react/icons/check";
2+
import Copy from "lucide-react/icons/copy";
23
import { useEffect, useState } from "react";
34

45
import { Button } from "@/components/ui/button";

apps/web/src/components/docs/nodes-browser.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { Grid, List, Loader2 } from "lucide-react";
1+
import Grid from "lucide-react/icons/grid";
2+
import List from "lucide-react/icons/list";
3+
import Loader2 from "lucide-react/icons/loader-2";
24
import { useMemo, useState } from "react";
35

46
import { Button } from "@/components/ui/button";

apps/web/src/components/docs/ready-to-build.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { CreateWorkflowRequest, WorkflowType } from "@dafthunk/types";
2-
import {
3-
Activity,
4-
CloudUpload,
5-
LayoutDashboard,
6-
PlusCircle,
7-
Workflow,
8-
Zap,
9-
} from "lucide-react";
2+
import Activity from "lucide-react/icons/activity";
3+
import CloudUpload from "lucide-react/icons/cloud-upload";
4+
import LayoutDashboard from "lucide-react/icons/layout-dashboard";
5+
import PlusCircle from "lucide-react/icons/plus-circle";
6+
import Workflow from "lucide-react/icons/workflow";
7+
import Zap from "lucide-react/icons/zap";
108
import { useState } from "react";
119
import { Link, useNavigate } from "react-router";
1210

apps/web/src/components/executions/execution-info-card.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { WorkflowExecutionStatus } from "@dafthunk/types";
22
import { format } from "date-fns";
3-
import {
4-
AlertCircle,
5-
Clock,
6-
Eye,
7-
EyeOff,
8-
IdCard,
9-
Workflow,
10-
} from "lucide-react";
3+
import AlertCircle from "lucide-react/icons/alert-circle";
4+
import Clock from "lucide-react/icons/clock";
5+
import Eye from "lucide-react/icons/eye";
6+
import EyeOff from "lucide-react/icons/eye-off";
7+
import IdCard from "lucide-react/icons/id-card";
8+
import Workflow from "lucide-react/icons/workflow";
119
import { Link } from "react-router";
1210

1311
import {

apps/web/src/components/executions/execution-status-badge.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import type { WorkflowExecution } from "@dafthunk/types";
22
import type { VariantProps } from "class-variance-authority";
3-
import {
4-
AlertCircle,
5-
CheckCircle2,
6-
CircleDashed,
7-
CircleSlash,
8-
Zap,
9-
} from "lucide-react";
3+
import AlertCircle from "lucide-react/icons/alert-circle";
4+
import CheckCircle2 from "lucide-react/icons/check-circle-2";
5+
import CircleDashed from "lucide-react/icons/circle-dashed";
6+
import CircleSlash from "lucide-react/icons/circle-slash";
7+
import Zap from "lucide-react/icons/zap";
108

119
import { Badge, badgeVariants } from "@/components/ui/badge";
1210
import { cn } from "@/utils/utils";

0 commit comments

Comments
 (0)