>;
+
+export function withSupabase(handler: SupabaseHandler
) {
+ return async (context: GetServerSidePropsContext) => {
+ const supabase = createServerClientSSR(context);
+
+ const {
+ data: { user },
+ error,
+ } = await supabase.auth.getUser();
+
+ if (!user || error) {
+ const next = encodeURIComponent(context.resolvedUrl || "/");
+ return {
+ redirect: {
+ destination: `/login?redirectedFrom=${next}`,
+ permanent: false,
+ },
+ } as GetServerSidePropsResult
;
+ }
+
+ return handler(context, { supabase, user });
+ };
+}
diff --git a/apps/web/utils/useDatabase.ts b/apps/web/utils/useDatabase.ts
index b1646da..130141f 100644
--- a/apps/web/utils/useDatabase.ts
+++ b/apps/web/utils/useDatabase.ts
@@ -206,9 +206,7 @@ export const updateSubscriptionUsage = async (
}
};
-export const createOrRetrievePageSettings = async (
- page_id: string
-) => {
+export const createOrRetrievePageSettings = async (page_id: string) => {
const { data: pageSettings } = await supabaseAdmin
.from("page_settings")
.select("*")
@@ -218,10 +216,7 @@ export const createOrRetrievePageSettings = async (
if (pageSettings) return pageSettings;
const { data: newPageSettings, error: createPageSettingsError } =
- await supabaseAdmin
- .from("page_settings")
- .insert([{ page_id }])
- .select();
+ await supabaseAdmin.from("page_settings").insert([{ page_id }]).select();
if (createPageSettingsError) throw createPageSettingsError;
@@ -311,6 +306,7 @@ export const reportEmailUsage = async (
`Update email usage count for user: ${user_id} to ${count}`,
idempotencyKey
);
+
try {
await stripe.subscriptionItems.createUsageRecord(
emailSubscriptionItem.id,
@@ -335,7 +331,7 @@ export const reportEmailUsage = async (
export async function getPageAnalytics(
page_id: string,
metric: string,
- range: string
+ range: number
) {
let functionName:
| "page_view_browsers"
@@ -357,10 +353,7 @@ export async function getPageAnalytics(
break;
}
- // date {range} days ago
- const date = new Date(
- Date.now() - (Number(range) || 7) * 24 * 60 * 60 * 1000
- );
+ const date = new Date(Date.now() - (range || 7) * 24 * 60 * 60 * 1000);
console.log(
`Fetching ${metric} for page ${page_id} for last ${range} days: ${date.toISOString()}`
);
@@ -374,4 +367,3 @@ export async function getPageAnalytics(
return data as unknown as IAnalyticsData[];
}
-
diff --git a/apps/web/utils/useSSR.ts b/apps/web/utils/useSSR.ts
index 34d723e..fd15fa4 100644
--- a/apps/web/utils/useSSR.ts
+++ b/apps/web/utils/useSSR.ts
@@ -1,6 +1,7 @@
-import { SupabaseClient } from "@supabase/auth-helpers-nextjs";
+import { SupabaseClient } from "@supabase/supabase-js";
+import { Database } from "@changes-page/supabase/types";
-export async function getPage(supabase: SupabaseClient, id: string) {
+export async function getPage(supabase: SupabaseClient, id: string) {
const { data: page } = await supabase
.from("pages")
.select("id,title,type,description,url_slug,user_id")
diff --git a/apps/web/utils/useUser.tsx b/apps/web/utils/useUser.tsx
index 7d3762d..90b7d65 100644
--- a/apps/web/utils/useUser.tsx
+++ b/apps/web/utils/useUser.tsx
@@ -1,10 +1,10 @@
import { Database } from "@changes-page/supabase/types";
-import { Session, SupabaseClient, User } from "@supabase/auth-helpers-nextjs";
import {
- useSession,
- useSupabaseClient,
- useUser,
-} from "@supabase/auth-helpers-react";
+ AuthError,
+ Session,
+ SupabaseClient,
+ User,
+} from "@supabase/supabase-js";
import { useRouter } from "next/router";
import posthog from "posthog-js";
import {
@@ -16,17 +16,17 @@ import {
} from "react";
import { notifyError, notifyInfo } from "../components/core/toast.component";
import { ROUTES } from "../data/routes.data";
-import { IBillingInfo, IUser } from "../data/user.interface";
+import { IBillingInfo } from "../data/user.interface";
import { httpGet } from "../utils/http";
+import { createClient } from "./supabase/client";
const UserContext = createContext<{
loading: boolean;
session: Session | null;
user: User | null;
- billingDetails: IBillingInfo;
- fetchBilling: () => void;
- fetchUser: () => Promise;
- signOut: () => Promise<{ error: Error | null }>;
+ billingDetails: IBillingInfo | null;
+ fetchBilling: () => Promise;
+ signOut: () => Promise<{ error: AuthError | null }>;
supabase: SupabaseClient;
}>({
loading: true,
@@ -34,25 +34,31 @@ const UserContext = createContext<{
user: null,
billingDetails: null,
fetchBilling: () => null,
- fetchUser: () => null,
signOut: () => null,
supabase: null,
});
-export const UserContextProvider = (props: any) => {
- const supabase = useSupabaseClient();
- const session = useSession();
- const user = useUser();
+export const UserContextProvider = ({
+ children,
+ initialSession = null,
+}: {
+ children: React.ReactNode;
+ initialSession?: Session | null;
+}) => {
+ const [supabase] = useState(() => createClient());
+ const [session, setSession] = useState(initialSession);
+ const [user, setUser] = useState(initialSession?.user ?? null);
+ const [loading, setLoading] = useState(!initialSession);
+ const [billingDetails, setBillingDetails] = useState(
+ null
+ );
const router = useRouter();
- const [loading, setLoading] = useState(true);
- const [billingDetails, setBillingDetails] = useState(null);
const fetchBilling = useCallback(async () => {
return httpGet({ url: `/api/billing` })
.then((billingDetails) => {
setBillingDetails(billingDetails);
-
return billingDetails;
})
.catch((error) => {
@@ -61,6 +67,43 @@ export const UserContextProvider = (props: any) => {
});
}, []);
+ const signOut = useCallback(async () => {
+ const { error } = await supabase.auth.signOut();
+
+ posthog.reset();
+ setBillingDetails(null);
+ await router.replace(ROUTES.HOME);
+
+ notifyInfo("Logout completed");
+
+ return { error };
+ }, [supabase, router]);
+
+ useEffect(() => {
+ // Get initial session
+ const getInitialSession = async () => {
+ const {
+ data: { session },
+ } = await supabase.auth.getSession();
+ setSession(session);
+ setUser(session?.user ?? null);
+ setLoading(false);
+ };
+
+ getInitialSession();
+
+ // Listen for auth changes
+ const {
+ data: { subscription },
+ } = supabase.auth.onAuthStateChange(async (_, session) => {
+ setSession(session);
+ setUser(session?.user ?? null);
+ setLoading(false);
+ });
+
+ return () => subscription.unsubscribe();
+ }, [supabase]);
+
useEffect(() => {
if (user) {
fetchBilling().then(() => {
@@ -79,29 +122,20 @@ export const UserContextProvider = (props: any) => {
loading,
session,
user,
-
billingDetails,
fetchBilling,
-
- signOut: async () => {
- await router.replace(ROUTES.HOME);
- await supabase.auth.signOut();
-
- setBillingDetails(null);
-
- notifyInfo("Logout completed");
- },
-
+ signOut,
supabase,
};
- return ;
+ // @ts-ignore
+ return {children};
};
export const useUserData = () => {
const context = useContext(UserContext);
if (context === undefined) {
- throw new Error(`useUser must be used within a UserContextProvider.`);
+ throw new Error(`useUserData must be used within a UserContextProvider.`);
}
return context;
};
diff --git a/apps/web/utils/withAuth.ts b/apps/web/utils/withAuth.ts
new file mode 100644
index 0000000..f3d86d1
--- /dev/null
+++ b/apps/web/utils/withAuth.ts
@@ -0,0 +1,40 @@
+import { Database } from "@changes-page/supabase/types";
+import { IErrorResponse } from "@changes-page/supabase/types/api";
+import { SupabaseClient, User } from "@supabase/supabase-js";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { createServerClientForAPI } from "./supabase/server";
+
+type AuthenticatedHandler = (
+ req: NextApiRequest,
+ res: NextApiResponse,
+ { supabase, user }: { supabase: SupabaseClient; user: User }
+) => Promise | void;
+
+export function withAuth(handler: AuthenticatedHandler) {
+ return async (
+ req: NextApiRequest,
+ res: NextApiResponse
+ ) => {
+ try {
+ const supabase = createServerClientForAPI({ req, res });
+
+ const {
+ data: { user },
+ error,
+ } = await supabase.auth.getUser();
+
+ if (!user || error) {
+ return res.status(401).json({
+ error: { statusCode: 401, message: "Unauthorized" },
+ });
+ }
+
+ return handler(req, res, { supabase, user });
+ } catch (error) {
+ console.error("Auth wrapper error:", error);
+ return res.status(500).json({
+ error: { statusCode: 500, message: "Internal server error" },
+ });
+ }
+ };
+}
diff --git a/package.json b/package.json
index f45c711..1062b37 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"dev:page": "pnpm --filter './apps/page' -r dev",
"dev:web": "pnpm --filter './apps/web' -r dev",
"dev:docs": "pnpm --filter './apps/docs' -r dev",
+ "dev:apps": "pnpm --filter './apps/{page,web}' -r dev",
"dev": "pnpm -r dev",
"test": "echo \"Error: no test specified\" && exit 1"
},
diff --git a/packages/supabase/migrations/18_roadmap.sql b/packages/supabase/migrations/18_roadmap.sql
new file mode 100644
index 0000000..7c13fc8
--- /dev/null
+++ b/packages/supabase/migrations/18_roadmap.sql
@@ -0,0 +1,137 @@
+-- ROADMAP BOARDS table
+create table roadmap_boards (
+ id uuid default uuid_generate_v4() primary key,
+ page_id uuid references pages(id) on delete cascade not null,
+ title text not null,
+ description text,
+ slug text not null,
+ is_public boolean not null default false,
+ created_at timestamp with time zone default timezone('utc'::text, now()) not null,
+ updated_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+
+alter table roadmap_boards add constraint unique_page_slug unique (page_id, slug);
+alter table roadmap_boards add constraint slug_length check (length(slug) >= 1);
+
+alter table roadmap_boards enable row level security;
+create policy "Can view public roadmap boards." on roadmap_boards for select using (is_public = true);
+create policy "Can view own page roadmap boards." on roadmap_boards for select using (page_id in (select id from pages));
+create policy "Can insert own page roadmap boards." on roadmap_boards for insert with check (page_id in (select id from pages));
+create policy "Can update own page roadmap boards." on roadmap_boards for update using (page_id in (select id from pages));
+create policy "Can delete own page roadmap boards." on roadmap_boards for delete using (page_id in (select id from pages));
+
+CREATE TRIGGER set_timestamp
+BEFORE UPDATE ON roadmap_boards
+FOR EACH ROW
+EXECUTE PROCEDURE trigger_set_timestamp();
+
+-- ROADMAP COLUMNS table
+create table roadmap_columns (
+ id uuid default uuid_generate_v4() primary key,
+ board_id uuid references roadmap_boards(id) on delete cascade not null,
+ name text not null,
+ position integer not null,
+ created_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+
+alter table roadmap_columns add constraint unique_board_position unique (board_id, position);
+alter table roadmap_columns add constraint unique_board_name unique (board_id, name);
+
+alter table roadmap_columns enable row level security;
+create policy "Can view public roadmap columns." on roadmap_columns for select using (board_id in (select id from roadmap_boards where is_public = true));
+create policy "Can view own roadmap columns." on roadmap_columns for select using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can insert own roadmap columns." on roadmap_columns for insert with check (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can update own roadmap columns." on roadmap_columns for update using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can delete own roadmap columns." on roadmap_columns for delete using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+
+-- ROADMAP CATEGORIES table
+create table roadmap_categories (
+ id uuid default uuid_generate_v4() primary key,
+ board_id uuid references roadmap_boards(id) on delete cascade not null,
+ name text not null,
+ color text default 'blue' check (color in (
+ 'blue', 'indigo', 'purple', 'pink', 'red',
+ 'orange', 'yellow', 'green', 'emerald', 'cyan'
+ )),
+ created_at timestamp with time zone default timezone('utc'::text, now()) not null,
+ updated_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+
+alter table roadmap_categories add constraint unique_board_category_name unique (board_id, name);
+alter table roadmap_categories add constraint category_name_length check (length(name) >= 1);
+
+alter table roadmap_categories enable row level security;
+create policy "Can view public roadmap categories." on roadmap_categories for select using (board_id in (select id from roadmap_boards where is_public = true));
+create policy "Can view own roadmap categories." on roadmap_categories for select using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can insert own roadmap categories." on roadmap_categories for insert with check (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can update own roadmap categories." on roadmap_categories for update using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can delete own roadmap categories." on roadmap_categories for delete using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+
+CREATE TRIGGER set_timestamp
+BEFORE UPDATE ON roadmap_categories
+FOR EACH ROW
+EXECUTE PROCEDURE trigger_set_timestamp();
+
+-- ROADMAP ITEMS table
+create table roadmap_items (
+ id uuid default uuid_generate_v4() primary key,
+ board_id uuid references roadmap_boards(id) on delete cascade not null,
+ column_id uuid references roadmap_columns(id) on delete cascade not null,
+ category_id uuid references roadmap_categories(id) on delete set null,
+ title text not null,
+ description text,
+ position integer not null,
+ created_at timestamp with time zone default timezone('utc'::text, now()) not null,
+ updated_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+
+alter table roadmap_items add constraint unique_column_position unique (column_id, position);
+
+alter table roadmap_items enable row level security;
+create policy "Can view public roadmap items." on roadmap_items for select using (board_id in (select id from roadmap_boards where is_public = true));
+create policy "Can view own roadmap items." on roadmap_items for select using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can insert own roadmap items." on roadmap_items for insert with check (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can update own roadmap items." on roadmap_items for update using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+create policy "Can delete own roadmap items." on roadmap_items for delete using (board_id in (select id from roadmap_boards where page_id in (select id from pages)));
+
+CREATE TRIGGER set_timestamp
+BEFORE UPDATE ON roadmap_items
+FOR EACH ROW
+EXECUTE PROCEDURE trigger_set_timestamp();
+
+-- ROADMAP VOTES table (similar to post_reactions)
+create table roadmap_votes (
+ id uuid default uuid_generate_v4() primary key,
+ item_id uuid references roadmap_items(id) on delete cascade not null,
+ visitor_id uuid not null,
+ created_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+
+alter table roadmap_votes add constraint unique_item_visitor unique (item_id, visitor_id);
+
+alter table roadmap_votes enable row level security;
+
+-- Function to initialize default columns for a roadmap board
+CREATE OR REPLACE FUNCTION initialize_roadmap_columns(board_id uuid)
+RETURNS void
+AS $$
+BEGIN
+ INSERT INTO roadmap_columns (board_id, name, position) VALUES
+ (board_id, 'Backlog', 1),
+ (board_id, 'Planned', 2),
+ (board_id, 'In Progress', 3),
+ (board_id, 'Done', 4);
+END;
+$$ LANGUAGE 'plpgsql';
+
+-- Function to initialize default categories for a roadmap board
+CREATE OR REPLACE FUNCTION initialize_roadmap_categories(board_id uuid)
+RETURNS void
+AS $$
+BEGIN
+ INSERT INTO roadmap_categories (board_id, name) VALUES
+ (board_id, 'Feature'),
+ (board_id, 'Bug Fix'),
+ (board_id, 'Improvement');
+END;
+$$ LANGUAGE 'plpgsql';
diff --git a/packages/supabase/types/index.ts b/packages/supabase/types/index.ts
index 4034a99..1072451 100644
--- a/packages/supabase/types/index.ts
+++ b/packages/supabase/types/index.ts
@@ -7,7 +7,7 @@ export type Json =
| Json[]
export type Database = {
- // Allows to automatically instanciate createClient with right options
+ // Allows to automatically instantiate createClient with right options
// instead of createClient(URL, KEY)
__InternalSupabase: {
PostgrestVersion: "10.2.0 (e07807d)"
@@ -392,6 +392,201 @@ export type Database = {
},
]
}
+ roadmap_boards: {
+ Row: {
+ created_at: string
+ description: string | null
+ id: string
+ is_public: boolean
+ page_id: string
+ slug: string
+ title: string
+ updated_at: string
+ }
+ Insert: {
+ created_at?: string
+ description?: string | null
+ id?: string
+ is_public?: boolean
+ page_id: string
+ slug: string
+ title: string
+ updated_at?: string
+ }
+ Update: {
+ created_at?: string
+ description?: string | null
+ id?: string
+ is_public?: boolean
+ page_id?: string
+ slug?: string
+ title?: string
+ updated_at?: string
+ }
+ Relationships: [
+ {
+ foreignKeyName: "roadmap_boards_page_id_fkey"
+ columns: ["page_id"]
+ isOneToOne: false
+ referencedRelation: "pages"
+ referencedColumns: ["id"]
+ },
+ ]
+ }
+ roadmap_categories: {
+ Row: {
+ board_id: string
+ color: string | null
+ created_at: string
+ id: string
+ name: string
+ updated_at: string
+ }
+ Insert: {
+ board_id: string
+ color?: string | null
+ created_at?: string
+ id?: string
+ name: string
+ updated_at?: string
+ }
+ Update: {
+ board_id?: string
+ color?: string | null
+ created_at?: string
+ id?: string
+ name?: string
+ updated_at?: string
+ }
+ Relationships: [
+ {
+ foreignKeyName: "roadmap_categories_board_id_fkey"
+ columns: ["board_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_boards"
+ referencedColumns: ["id"]
+ },
+ ]
+ }
+ roadmap_columns: {
+ Row: {
+ board_id: string
+ created_at: string
+ id: string
+ name: string
+ position: number
+ }
+ Insert: {
+ board_id: string
+ created_at?: string
+ id?: string
+ name: string
+ position: number
+ }
+ Update: {
+ board_id?: string
+ created_at?: string
+ id?: string
+ name?: string
+ position?: number
+ }
+ Relationships: [
+ {
+ foreignKeyName: "roadmap_columns_board_id_fkey"
+ columns: ["board_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_boards"
+ referencedColumns: ["id"]
+ },
+ ]
+ }
+ roadmap_items: {
+ Row: {
+ board_id: string
+ category_id: string | null
+ column_id: string
+ created_at: string
+ description: string | null
+ id: string
+ position: number
+ title: string
+ updated_at: string
+ }
+ Insert: {
+ board_id: string
+ category_id?: string | null
+ column_id: string
+ created_at?: string
+ description?: string | null
+ id?: string
+ position: number
+ title: string
+ updated_at?: string
+ }
+ Update: {
+ board_id?: string
+ category_id?: string | null
+ column_id?: string
+ created_at?: string
+ description?: string | null
+ id?: string
+ position?: number
+ title?: string
+ updated_at?: string
+ }
+ Relationships: [
+ {
+ foreignKeyName: "roadmap_items_board_id_fkey"
+ columns: ["board_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_boards"
+ referencedColumns: ["id"]
+ },
+ {
+ foreignKeyName: "roadmap_items_category_id_fkey"
+ columns: ["category_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_categories"
+ referencedColumns: ["id"]
+ },
+ {
+ foreignKeyName: "roadmap_items_column_id_fkey"
+ columns: ["column_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_columns"
+ referencedColumns: ["id"]
+ },
+ ]
+ }
+ roadmap_votes: {
+ Row: {
+ created_at: string
+ id: string
+ item_id: string
+ visitor_id: string
+ }
+ Insert: {
+ created_at?: string
+ id?: string
+ item_id: string
+ visitor_id: string
+ }
+ Update: {
+ created_at?: string
+ id?: string
+ item_id?: string
+ visitor_id?: string
+ }
+ Relationships: [
+ {
+ foreignKeyName: "roadmap_votes_item_id_fkey"
+ columns: ["item_id"]
+ isOneToOne: false
+ referencedRelation: "roadmap_items"
+ referencedColumns: ["id"]
+ },
+ ]
+ }
team_invitations: {
Row: {
created_at: string
@@ -561,13 +756,21 @@ export type Database = {
get_pages_with_inactive_subscriptions: {
Args: Record
Returns: {
+ page_created_at: string
page_id: string
page_title: string
- page_created_at: string
url: string
user_id: string
}[]
}
+ initialize_roadmap_categories: {
+ Args: { board_id: string }
+ Returns: undefined
+ }
+ initialize_roadmap_columns: {
+ Args: { board_id: string }
+ Returns: undefined
+ }
is_subscription_active: {
Args: { user_id: string }
Returns: boolean
@@ -577,40 +780,48 @@ export type Database = {
Returns: boolean
}
page_view_browsers: {
- Args: { pageid: string; date: string }
+ Args: { date: string; pageid: string }
Returns: {
- data_name: string
data_count: number
+ data_name: string
}[]
}
page_view_os: {
- Args: { pageid: string; date: string }
+ Args: { date: string; pageid: string }
Returns: {
- data_name: string
data_count: number
+ data_name: string
}[]
}
page_view_referrers: {
- Args: { pageid: string; date: string }
+ Args: { date: string; pageid: string }
Returns: {
- data_name: string
data_count: number
+ data_name: string
}[]
}
page_view_stats: {
- Args: { pageid: string; date: string }
+ Args: { date: string; pageid: string }
Returns: Record
}
post_reactions_aggregate: {
Args: { postid: string }
Returns: {
- thumbs_up_count: number
- thumbs_down_count: number
+ heart_count: number
rocket_count: number
sad_count: number
- heart_count: number
+ thumbs_down_count: number
+ thumbs_up_count: number
}[]
}
+ roadmap_item_has_voted: {
+ Args: { itemid: string; visitorid: string }
+ Returns: boolean
+ }
+ roadmap_item_votes_count: {
+ Args: { itemid: string }
+ Returns: number
+ }
}
Enums: {
page_color_scheme: "auto" | "dark" | "light"
diff --git a/packages/supabase/types/page.ts b/packages/supabase/types/page.ts
index 6b68040..5294193 100644
--- a/packages/supabase/types/page.ts
+++ b/packages/supabase/types/page.ts
@@ -1,16 +1,18 @@
-import type { Database } from "./index";
+import type { Database, Tables } from "./index";
-export type IPage = Database["public"]["Tables"]["pages"]["Row"];
-export type IPageSettings =
- Database["public"]["Tables"]["page_settings"]["Row"];
-export type IPost = Database["public"]["Tables"]["posts"]["Row"];
-export type IPageEmailSubscriber =
- Database["public"]["Tables"]["page_email_subscribers"]["Row"];
-export type IPageView = Database["public"]["Tables"]["page_views"]["Row"];
-export type ITeam = Database["public"]["Tables"]["teams"]["Row"];
-export type ITeamMember = Database["public"]["Tables"]["team_members"]["Row"];
-export type ITeamInvitation =
- Database["public"]["Tables"]["team_invitations"]["Row"];
+export type IPage = Tables<"pages">;
+export type IPageSettings = Tables<"page_settings">;
+export type IPost = Tables<"posts">;
+export type IPageEmailSubscriber = Tables<"page_email_subscribers">;
+export type IPageView = Tables<"page_views">;
+export type ITeam = Tables<"teams">;
+export type ITeamMember = Tables<"team_members">;
+export type ITeamInvitation = Tables<"team_invitations">;
+export type IRoadmapBoard = Tables<"roadmap_boards">;
+export type IRoadmapColumn = Tables<"roadmap_columns">;
+export type IRoadmapCategory = Tables<"roadmap_categories">;
+export type IRoadmapItem = Tables<"roadmap_items">;
+export type IRoadmapVote = Tables<"roadmap_votes">;
export enum PageType {
changelogs = "changelogs",
diff --git a/packages/utils/index.ts b/packages/utils/index.ts
index bba468a..269e1ca 100644
--- a/packages/utils/index.ts
+++ b/packages/utils/index.ts
@@ -1,2 +1,3 @@
export * from "./datetime";
export * from "./markdown";
+export * from "./roadmap";
diff --git a/packages/utils/roadmap/index.ts b/packages/utils/roadmap/index.ts
new file mode 100644
index 0000000..82bc1ce
--- /dev/null
+++ b/packages/utils/roadmap/index.ts
@@ -0,0 +1,78 @@
+export const ROADMAP_COLORS = {
+ blue: {
+ name: 'Blue',
+ light: 'bg-blue-100 text-blue-800 border-blue-200',
+ dark: 'dark:bg-blue-900 dark:text-blue-200 dark:border-blue-800',
+ preview: 'bg-blue-500',
+ },
+ indigo: {
+ name: 'Indigo',
+ light: 'bg-indigo-100 text-indigo-800 border-indigo-200',
+ dark: 'dark:bg-indigo-900 dark:text-indigo-200 dark:border-indigo-800',
+ preview: 'bg-indigo-500',
+ },
+ purple: {
+ name: 'Purple',
+ light: 'bg-purple-100 text-purple-800 border-purple-200',
+ dark: 'dark:bg-purple-900 dark:text-purple-200 dark:border-purple-800',
+ preview: 'bg-purple-500',
+ },
+ pink: {
+ name: 'Pink',
+ light: 'bg-pink-100 text-pink-800 border-pink-200',
+ dark: 'dark:bg-pink-900 dark:text-pink-200 dark:border-pink-800',
+ preview: 'bg-pink-500',
+ },
+ red: {
+ name: 'Red',
+ light: 'bg-red-100 text-red-800 border-red-200',
+ dark: 'dark:bg-red-900 dark:text-red-200 dark:border-red-800',
+ preview: 'bg-red-500',
+ },
+ orange: {
+ name: 'Orange',
+ light: 'bg-orange-100 text-orange-800 border-orange-200',
+ dark: 'dark:bg-orange-900 dark:text-orange-200 dark:border-orange-800',
+ preview: 'bg-orange-500',
+ },
+ yellow: {
+ name: 'Yellow',
+ light: 'bg-yellow-100 text-yellow-800 border-yellow-200',
+ dark: 'dark:bg-yellow-900 dark:text-yellow-200 dark:border-yellow-800',
+ preview: 'bg-yellow-500',
+ },
+ green: {
+ name: 'Green',
+ light: 'bg-green-100 text-green-800 border-green-200',
+ dark: 'dark:bg-green-900 dark:text-green-200 dark:border-green-800',
+ preview: 'bg-green-500',
+ },
+ emerald: {
+ name: 'Emerald',
+ light: 'bg-emerald-100 text-emerald-800 border-emerald-200',
+ dark: 'dark:bg-emerald-900 dark:text-emerald-200 dark:border-emerald-800',
+ preview: 'bg-emerald-500',
+ },
+ cyan: {
+ name: 'Cyan',
+ light: 'bg-cyan-100 text-cyan-800 border-cyan-200',
+ dark: 'dark:bg-cyan-900 dark:text-cyan-200 dark:border-cyan-800',
+ preview: 'bg-cyan-500',
+ },
+} as const;
+
+export type RoadmapColor = keyof typeof ROADMAP_COLORS;
+
+export function getCategoryColorClasses(color: string = 'blue') {
+ const colorKey = color as RoadmapColor;
+ const colorConfig = ROADMAP_COLORS[colorKey] || ROADMAP_COLORS.blue;
+ return `${colorConfig.light} ${colorConfig.dark}`;
+}
+
+export function getCategoryColorOptions() {
+ return Object.entries(ROADMAP_COLORS).map(([key, value]) => ({
+ value: key,
+ label: value.name,
+ preview: value.preview,
+ }));
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 31107d3..d5e4a99 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -110,6 +110,9 @@ importers:
next-themes:
specifier: ^0.2.1
version: 0.2.1(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ nprogress:
+ specifier: ^0.2.0
+ version: 0.2.0
postcss:
specifier: ^8.4.33
version: 8.5.3
@@ -171,6 +174,9 @@ importers:
'@types/node':
specifier: ^17.0.41
version: 17.0.45
+ '@types/nprogress':
+ specifier: ^0.2.3
+ version: 0.2.3
'@types/react':
specifier: ^18.2.0
version: 18.3.21
@@ -237,18 +243,15 @@ importers:
'@sentry/nextjs':
specifier: ^7.77.0
version: 7.120.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
- '@supabase/auth-helpers-nextjs':
- specifier: ^0.8.7
- version: 0.8.7(@supabase/supabase-js@2.49.4)
- '@supabase/auth-helpers-react':
- specifier: ^0.4.2
- version: 0.4.2(@supabase/supabase-js@2.49.4)
'@supabase/auth-ui-react':
specifier: ^0.4.7
version: 0.4.7(@supabase/supabase-js@2.49.4)
'@supabase/auth-ui-shared':
specifier: ^0.1.8
version: 0.1.8(@supabase/supabase-js@2.49.4)
+ '@supabase/ssr':
+ specifier: ^0.7.0
+ version: 0.7.0(@supabase/supabase-js@2.49.4)
'@supabase/supabase-js':
specifier: ^2.39.3
version: 2.49.4
@@ -258,6 +261,9 @@ importers:
'@types/canvas-confetti':
specifier: ^1.6.4
version: 1.9.0
+ '@types/validator':
+ specifier: ^13.15.3
+ version: 13.15.3
'@vercel/og':
specifier: ^0.0.20
version: 0.0.20
@@ -275,7 +281,7 @@ importers:
version: 2.20.0
eslint-config-next:
specifier: ^14.0.4
- version: 14.2.28(eslint@7.32.0)(typescript@4.9.5)
+ version: 14.2.28(eslint@7.32.0)(typescript@5.8.3)
eventsource-parser:
specifier: ^0.0.5
version: 0.0.5
@@ -290,7 +296,7 @@ importers:
version: 3.88.2
inngest:
specifier: ^1.5.4
- version: 1.10.1(typescript@4.9.5)
+ version: 1.10.1(typescript@5.8.3)
mime-types:
specifier: ^2.1.34
version: 2.1.35
@@ -375,6 +381,9 @@ importers:
uuid:
specifier: ^8.3.2
version: 8.3.2
+ validator:
+ specifier: ^13.15.15
+ version: 13.15.15
yup:
specifier: ^1.3.3
version: 1.6.1
@@ -407,8 +416,8 @@ importers:
specifier: ^3.0.15
version: 3.4.17
typescript:
- specifier: ^4
- version: 4.9.5
+ specifier: ^5
+ version: 5.8.3
packages/supabase:
dependencies:
@@ -1685,24 +1694,6 @@ packages:
'@streamparser/json@0.0.12':
resolution: {integrity: sha512-+kmRpd+EeTFd3qNt1AoKphJqbAN26ZDsbiwqjBFeoAmdCyiUO19xMXPtYi9vovAj9a7OAJnvWtiHkwwjU2Fx4Q==}
- '@supabase/auth-helpers-nextjs@0.8.7':
- resolution: {integrity: sha512-iYdOjFo0GkRvha340l8JdCiBiyXQuG9v8jnq7qMJ/2fakrskRgHTCOt7ryWbip1T6BExcWKC8SoJrhCzPOxhhg==}
- deprecated: This package is now deprecated - please use the @supabase/ssr package instead.
- peerDependencies:
- '@supabase/supabase-js': ^2.19.0
-
- '@supabase/auth-helpers-react@0.4.2':
- resolution: {integrity: sha512-zRj1leYMKJVYQeHFvZiUzlmHM+ATWFR/V7Q9F0yXSWEnMcNHL0CKnIBqhkjtSQ2trE+YaoCvFEHjxISppxIZXQ==}
- deprecated: This package is now deprecated - please use the @supabase/ssr package instead.
- peerDependencies:
- '@supabase/supabase-js': ^2.19.0
-
- '@supabase/auth-helpers-shared@0.6.3':
- resolution: {integrity: sha512-xYQRLFeFkL4ZfwC7p9VKcarshj3FB2QJMgJPydvOY7J5czJe6xSG5/wM1z63RmAzGbCkKg+dzpq61oeSyWiGBQ==}
- deprecated: This package is now deprecated - please use the @supabase/ssr package instead.
- peerDependencies:
- '@supabase/supabase-js': ^2.19.0
-
'@supabase/auth-js@2.69.1':
resolution: {integrity: sha512-FILtt5WjCNzmReeRLq5wRs3iShwmnWgBvxHfqapC/VoljJl+W8hDAyFmf1NVw3zH+ZjZ05AKxiKxVeb0HNWRMQ==}
@@ -1729,6 +1720,11 @@ packages:
'@supabase/realtime-js@2.11.2':
resolution: {integrity: sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==}
+ '@supabase/ssr@0.7.0':
+ resolution: {integrity: sha512-G65t5EhLSJ5c8hTCcXifSL9Q/ZRXvqgXeNo+d3P56f4U1IxwTqjB64UfmfixvmMcjuxnq2yGqEWVJqUcO+AzAg==}
+ peerDependencies:
+ '@supabase/supabase-js': ^2.43.4
+
'@supabase/storage-js@2.7.1':
resolution: {integrity: sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==}
@@ -1920,6 +1916,9 @@ packages:
'@types/node@22.15.12':
resolution: {integrity: sha512-K0fpC/ZVeb8G9rm7bH7vI0KAec4XHEhBam616nVJCV51bKzJ6oA3luG4WdKoaztxe70QaNjS/xBmcDLmr4PiGw==}
+ '@types/nprogress@0.2.3':
+ resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
+
'@types/parse5@6.0.3':
resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==}
@@ -1965,6 +1964,9 @@ packages:
'@types/uuid@9.0.8':
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
+ '@types/validator@13.15.3':
+ resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==}
+
'@types/ws@8.18.1':
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
@@ -2465,6 +2467,10 @@ packages:
cookie-es@1.2.2:
resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
+ cookie@1.0.2:
+ resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
+ engines: {node: '>=18'}
+
core-js@3.42.0:
resolution: {integrity: sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==}
@@ -3469,9 +3475,6 @@ packages:
jju@1.4.0:
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
- jose@4.15.9:
- resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
-
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -4627,9 +4630,6 @@ packages:
resolution: {integrity: sha512-6a6dNqipzbCPlTFgztfNP2oG+IGcflMe/01zSzGrQcxGMKbIjOemBBD85pH92klWaJavAUWxAh9Z0aU28zxW6A==}
deprecated: Rolling release, please update to 0.2.0
- set-cookie-parser@2.7.1:
- resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
-
set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'}
@@ -5140,6 +5140,10 @@ packages:
v8-compile-cache@2.4.0:
resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==}
+ validator@13.15.15:
+ resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==}
+ engines: {node: '>= 0.10'}
+
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
@@ -6414,21 +6418,6 @@ snapshots:
'@streamparser/json@0.0.12': {}
- '@supabase/auth-helpers-nextjs@0.8.7(@supabase/supabase-js@2.49.4)':
- dependencies:
- '@supabase/auth-helpers-shared': 0.6.3(@supabase/supabase-js@2.49.4)
- '@supabase/supabase-js': 2.49.4
- set-cookie-parser: 2.7.1
-
- '@supabase/auth-helpers-react@0.4.2(@supabase/supabase-js@2.49.4)':
- dependencies:
- '@supabase/supabase-js': 2.49.4
-
- '@supabase/auth-helpers-shared@0.6.3(@supabase/supabase-js@2.49.4)':
- dependencies:
- '@supabase/supabase-js': 2.49.4
- jose: 4.15.9
-
'@supabase/auth-js@2.69.1':
dependencies:
'@supabase/node-fetch': 2.6.15
@@ -6468,6 +6457,11 @@ snapshots:
- bufferutil
- utf-8-validate
+ '@supabase/ssr@0.7.0(@supabase/supabase-js@2.49.4)':
+ dependencies:
+ '@supabase/supabase-js': 2.49.4
+ cookie: 1.0.2
+
'@supabase/storage-js@2.7.1':
dependencies:
'@supabase/node-fetch': 2.6.15
@@ -6662,6 +6656,8 @@ snapshots:
dependencies:
undici-types: 6.21.0
+ '@types/nprogress@0.2.3': {}
+
'@types/parse5@6.0.3': {}
'@types/phoenix@1.6.6': {}
@@ -6710,29 +6706,14 @@ snapshots:
'@types/uuid@9.0.8': {}
+ '@types/validator@13.15.3': {}
+
'@types/ws@8.18.1':
dependencies:
'@types/node': 18.19.100
'@types/yoga-layout@1.9.2': {}
- '@typescript-eslint/eslint-plugin@8.32.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)':
- dependencies:
- '@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- '@typescript-eslint/scope-manager': 8.32.0
- '@typescript-eslint/type-utils': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- '@typescript-eslint/utils': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- '@typescript-eslint/visitor-keys': 8.32.0
- eslint: 7.32.0
- graphemer: 1.4.0
- ignore: 5.3.2
- natural-compare: 1.4.0
- ts-api-utils: 2.1.0(typescript@4.9.5)
- typescript: 4.9.5
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/eslint-plugin@8.32.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -6750,18 +6731,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5)':
- dependencies:
- '@typescript-eslint/scope-manager': 8.32.0
- '@typescript-eslint/types': 8.32.0
- '@typescript-eslint/typescript-estree': 8.32.0(typescript@4.9.5)
- '@typescript-eslint/visitor-keys': 8.32.0
- debug: 4.4.0
- eslint: 7.32.0
- typescript: 4.9.5
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.32.0
@@ -6779,17 +6748,6 @@ snapshots:
'@typescript-eslint/types': 8.32.0
'@typescript-eslint/visitor-keys': 8.32.0
- '@typescript-eslint/type-utils@8.32.0(eslint@7.32.0)(typescript@4.9.5)':
- dependencies:
- '@typescript-eslint/typescript-estree': 8.32.0(typescript@4.9.5)
- '@typescript-eslint/utils': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- debug: 4.4.0
- eslint: 7.32.0
- ts-api-utils: 2.1.0(typescript@4.9.5)
- typescript: 4.9.5
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/type-utils@8.32.0(eslint@7.32.0)(typescript@5.8.3)':
dependencies:
'@typescript-eslint/typescript-estree': 8.32.0(typescript@5.8.3)
@@ -6803,20 +6761,6 @@ snapshots:
'@typescript-eslint/types@8.32.0': {}
- '@typescript-eslint/typescript-estree@8.32.0(typescript@4.9.5)':
- dependencies:
- '@typescript-eslint/types': 8.32.0
- '@typescript-eslint/visitor-keys': 8.32.0
- debug: 4.4.0
- fast-glob: 3.3.3
- is-glob: 4.0.3
- minimatch: 9.0.5
- semver: 7.7.1
- ts-api-utils: 2.1.0(typescript@4.9.5)
- typescript: 4.9.5
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/typescript-estree@8.32.0(typescript@5.8.3)':
dependencies:
'@typescript-eslint/types': 8.32.0
@@ -6831,17 +6775,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.32.0(eslint@7.32.0)(typescript@4.9.5)':
- dependencies:
- '@eslint-community/eslint-utils': 4.7.0(eslint@7.32.0)
- '@typescript-eslint/scope-manager': 8.32.0
- '@typescript-eslint/types': 8.32.0
- '@typescript-eslint/typescript-estree': 8.32.0(typescript@4.9.5)
- eslint: 7.32.0
- typescript: 4.9.5
- transitivePeerDependencies:
- - supports-color
-
'@typescript-eslint/utils@8.32.0(eslint@7.32.0)(typescript@5.8.3)':
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@7.32.0)
@@ -7300,6 +7233,8 @@ snapshots:
cookie-es@1.2.2: {}
+ cookie@1.0.2: {}
+
core-js@3.42.0: {}
cors@2.8.5:
@@ -7618,26 +7553,6 @@ snapshots:
escape-string-regexp@5.0.0: {}
- eslint-config-next@14.2.28(eslint@7.32.0)(typescript@4.9.5):
- dependencies:
- '@next/eslint-plugin-next': 14.2.28
- '@rushstack/eslint-patch': 1.11.0
- '@typescript-eslint/eslint-plugin': 8.32.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)
- '@typescript-eslint/parser': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- eslint: 7.32.0
- eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@7.32.0)
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0)
- eslint-plugin-jsx-a11y: 6.10.2(eslint@7.32.0)
- eslint-plugin-react: 7.37.5(eslint@7.32.0)
- eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@7.32.0)
- optionalDependencies:
- typescript: 4.9.5
- transitivePeerDependencies:
- - eslint-import-resolver-webpack
- - eslint-plugin-import-x
- - supports-color
-
eslint-config-next@14.2.28(eslint@7.32.0)(typescript@5.8.3):
dependencies:
'@next/eslint-plugin-next': 14.2.28
@@ -7647,7 +7562,7 @@ snapshots:
eslint: 7.32.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@7.32.0)
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0)
eslint-plugin-jsx-a11y: 6.10.2(eslint@7.32.0)
eslint-plugin-react: 7.37.5(eslint@7.32.0)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@7.32.0)
@@ -7677,18 +7592,7 @@ snapshots:
tinyglobby: 0.2.13
unrs-resolver: 1.7.2
optionalDependencies:
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)
- transitivePeerDependencies:
- - supports-color
-
- eslint-module-utils@2.12.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0):
- dependencies:
- debug: 3.2.7
- optionalDependencies:
- '@typescript-eslint/parser': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- eslint: 7.32.0
- eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@7.32.0)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0)
transitivePeerDependencies:
- supports-color
@@ -7703,36 +7607,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0):
- dependencies:
- '@rtsao/scc': 1.1.0
- array-includes: 3.1.8
- array.prototype.findlastindex: 1.2.6
- array.prototype.flat: 1.3.3
- array.prototype.flatmap: 1.3.3
- debug: 3.2.7
- doctrine: 2.1.0
- eslint: 7.32.0
- eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0)
- hasown: 2.0.2
- is-core-module: 2.16.1
- is-glob: 4.0.3
- minimatch: 3.1.2
- object.fromentries: 2.0.8
- object.groupby: 1.0.3
- object.values: 1.2.1
- semver: 6.3.1
- string.prototype.trimend: 1.0.9
- tsconfig-paths: 3.15.0
- optionalDependencies:
- '@typescript-eslint/parser': 8.32.0(eslint@7.32.0)(typescript@4.9.5)
- transitivePeerDependencies:
- - eslint-import-resolver-typescript
- - eslint-import-resolver-webpack
- - supports-color
-
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0):
+ eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.0(eslint@7.32.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@7.32.0):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -8538,7 +8413,7 @@ snapshots:
transitivePeerDependencies:
- encoding
- inngest@1.10.1(typescript@4.9.5):
+ inngest@1.10.1(typescript@5.8.3):
dependencies:
buffer: 6.0.3
canonicalize: 1.0.8
@@ -8551,7 +8426,7 @@ snapshots:
queue-microtask: 1.2.3
serialize-error-cjs: 0.1.4
type-fest: 3.13.1
- typescript: 4.9.5
+ typescript: 5.8.3
zod: 3.24.4
transitivePeerDependencies:
- encoding
@@ -8735,8 +8610,6 @@ snapshots:
jju@1.4.0: {}
- jose@4.15.9: {}
-
js-tokens@4.0.0: {}
js-yaml@3.14.1:
@@ -10336,8 +10209,6 @@ snapshots:
serialize-error-cjs@0.1.4: {}
- set-cookie-parser@2.7.1: {}
-
set-function-length@1.2.2:
dependencies:
define-data-property: 1.1.4
@@ -10756,10 +10627,6 @@ snapshots:
try-to-catch@3.0.1: {}
- ts-api-utils@2.1.0(typescript@4.9.5):
- dependencies:
- typescript: 4.9.5
-
ts-api-utils@2.1.0(typescript@5.8.3):
dependencies:
typescript: 5.8.3
@@ -10996,6 +10863,8 @@ snapshots:
v8-compile-cache@2.4.0: {}
+ validator@13.15.15: {}
+
vary@1.1.2: {}
vfile-location@4.1.0: