diff --git a/jest.config.ts b/jest.config.ts
index a1d73c021..02599aa7f 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -187,7 +187,7 @@ const config: Config = {
// transform: undefined,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
- // transformIgnorePatterns: ['/node_modules/copilot-node-sdk/(.*)'],
+ // transformIgnorePatterns: ['/node_modules/@assembly-js/node-sdk/(.*)'],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
diff --git a/package.json b/package.json
index 05e3c500b..c022a1e1c 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,8 @@
"bottleneck": "^2.19.5",
"clsx": "^2.1.1",
"copilot-design-system": "^2.3.4",
- "copilot-node-sdk": "^3.16.0",
+ "@assembly-js/app-bridge": "^1.1.0",
+ "@assembly-js/node-sdk": "^4.0.2",
"dayjs": "^1.11.10",
"deep-equal": "^2.2.3",
"fetch-retry": "^6.0.0",
diff --git a/src/app/client/page.tsx b/src/app/client/page.tsx
index 51ba540a7..efd9f0c87 100644
--- a/src/app/client/page.tsx
+++ b/src/app/client/page.tsx
@@ -104,7 +104,7 @@ export default async function ClientPage(props: { searchParams: Promise<{ token:
-
+
diff --git a/src/app/detail/[task_id]/[user_type]/page.tsx b/src/app/detail/[task_id]/[user_type]/page.tsx
index aff41864b..7fbd41e0b 100644
--- a/src/app/detail/[task_id]/[user_type]/page.tsx
+++ b/src/app/detail/[task_id]/[user_type]/page.tsx
@@ -160,12 +160,7 @@ export default async function TaskDetailPage(props: {
) : (
<>
-
+
>
)}
@@ -249,7 +244,6 @@ export default async function TaskDetailPage(props: {
task_id={task_id}
selectedAssigneeId={task?.assigneeId}
userType={user_type}
- portalUrl={workspace.portalUrl}
selectedWorkflowState={task?.workflowState}
updateWorkflowState={async (workflowState) => {
'use server'
diff --git a/src/app/detail/ui/ClientDetailAppBridge.tsx b/src/app/detail/ui/ClientDetailAppBridge.tsx
index a0e2152c4..7cbca2786 100644
--- a/src/app/detail/ui/ClientDetailAppBridge.tsx
+++ b/src/app/detail/ui/ClientDetailAppBridge.tsx
@@ -9,10 +9,9 @@ import { useCallback, useEffect, useState } from 'react'
interface DetailAppBridgeProps {
handleTaskComplete: () => void
isTaskCompleted: boolean
- portalUrl?: string
}
-export const ClientDetailAppBridge = ({ handleTaskComplete, isTaskCompleted, portalUrl }: DetailAppBridgeProps) => {
+export const ClientDetailAppBridge = ({ handleTaskComplete, isTaskCompleted }: DetailAppBridgeProps) => {
const awake = useAwake()
const handleMarkAsDone = useCallback(() => {
@@ -29,9 +28,8 @@ export const ClientDetailAppBridge = ({ handleTaskComplete, isTaskCompleted, por
icon: Icons.CHECK,
onClick: handleMarkAsDone,
},
- { portalUrl },
)
- useSecondaryCta(null, { portalUrl })
+ useSecondaryCta(null)
return <>>
}
diff --git a/src/app/detail/ui/DetailAppBridge.tsx b/src/app/detail/ui/DetailAppBridge.tsx
index 37e867f47..b705b52a1 100644
--- a/src/app/detail/ui/DetailAppBridge.tsx
+++ b/src/app/detail/ui/DetailAppBridge.tsx
@@ -10,13 +10,12 @@ import store from '@/redux/store'
interface DetailAppBridgeProps {
isArchived: boolean
handleToggleArchive: () => void
- portalUrl?: string
}
-export const DetailAppBridge = ({ isArchived, handleToggleArchive, portalUrl }: DetailAppBridgeProps) => {
+export const DetailAppBridge = ({ isArchived, handleToggleArchive }: DetailAppBridgeProps) => {
const handleDelete = () => store.dispatch(setShowConfirmDeleteModal())
- usePrimaryCta(null, { portalUrl })
+ usePrimaryCta(null)
useSecondaryCta(
isArchived
? {
@@ -25,7 +24,6 @@ export const DetailAppBridge = ({ isArchived, handleToggleArchive, portalUrl }:
onClick: handleToggleArchive,
}
: null,
- { portalUrl },
)
const items: Clickable[] = [
@@ -44,7 +42,7 @@ export const DetailAppBridge = ({ isArchived, handleToggleArchive, portalUrl }:
})
}
- useActionsMenu(items, { portalUrl })
+ useActionsMenu(items)
return <>>
}
diff --git a/src/app/detail/ui/Sidebar.tsx b/src/app/detail/ui/Sidebar.tsx
index ccdc621d7..c8efc86f7 100644
--- a/src/app/detail/ui/Sidebar.tsx
+++ b/src/app/detail/ui/Sidebar.tsx
@@ -67,7 +67,6 @@ export const Sidebar = ({
disabled,
workflowDisabled = false,
userType,
- portalUrl,
}: {
task_id: string
selectedWorkflowState: WorkflowStateResponse
@@ -78,7 +77,6 @@ export const Sidebar = ({
disabled: boolean
workflowDisabled?: boolean
userType: UserType
- portalUrl?: string
}) => {
const { activeTask, workflowStates, assignee, previewMode } = useSelector(selectTaskBoard)
const { showSidebar, showConfirmAssignModal, fromNotificationCenter } = useSelector(selectTaskDetails)
@@ -617,7 +615,6 @@ export const Sidebar = ({
completedWorkflowState && updateStatusValue(completedWorkflowState)
completedWorkflowState && updateWorkflowState(completedWorkflowState)
}}
- portalUrl={portalUrl}
/>
)}
diff --git a/src/app/manage-templates/[template_id]/page.tsx b/src/app/manage-templates/[template_id]/page.tsx
index e5426a3e7..d1314b85a 100644
--- a/src/app/manage-templates/[template_id]/page.tsx
+++ b/src/app/manage-templates/[template_id]/page.tsx
@@ -80,7 +80,7 @@ export default async function TaskDetailPage(props: {
)}
-
+
-
+
{
diff --git a/src/app/manage-templates/ui/ManageTemplatesAppBridge.tsx b/src/app/manage-templates/ui/ManageTemplatesAppBridge.tsx
index 24fd20ca5..e89432793 100644
--- a/src/app/manage-templates/ui/ManageTemplatesAppBridge.tsx
+++ b/src/app/manage-templates/ui/ManageTemplatesAppBridge.tsx
@@ -13,31 +13,24 @@ import { useRouter } from 'next/navigation'
interface TaskBoardAppBridgeProps {
token: string
role: UserRole
- portalUrl?: string
}
-export const ManageTemplatesAppBridge = ({ token, role, portalUrl }: TaskBoardAppBridgeProps) => {
+export const ManageTemplatesAppBridge = ({ token, role }: TaskBoardAppBridgeProps) => {
const handleTemplateCreate = () => {
store.dispatch(setShowTemplateModal({ targetMethod: TargetMethod.POST }))
}
- usePrimaryCta(
+ usePrimaryCta({
+ label: 'Create template',
+ icon: Icons.PLUS,
+ onClick: handleTemplateCreate,
+ })
+ useActionsMenu([])
+ useBreadcrumbs([
{
- label: 'Create template',
- icon: Icons.PLUS,
- onClick: handleTemplateCreate,
+ label: 'Manage templates',
},
- { portalUrl },
- )
- useActionsMenu([], { portalUrl })
- useBreadcrumbs(
- [
- {
- label: 'Manage templates',
- },
- ],
- { portalUrl },
- )
+ ])
return <>>
}
diff --git a/src/app/manage-templates/ui/ManageTemplatesDetailsAppBridge.tsx b/src/app/manage-templates/ui/ManageTemplatesDetailsAppBridge.tsx
index c31bf8785..b93faa444 100644
--- a/src/app/manage-templates/ui/ManageTemplatesDetailsAppBridge.tsx
+++ b/src/app/manage-templates/ui/ManageTemplatesDetailsAppBridge.tsx
@@ -12,11 +12,10 @@ import { ITemplate } from '@/types/interfaces'
import { useCallback, useEffect, useState } from 'react'
interface ManageTemplateDetailsAppBridgeProps {
- portalUrl?: string
template: ITemplate
}
-export const ManageTemplateDetailsAppBridge = ({ portalUrl, template }: ManageTemplateDetailsAppBridgeProps) => {
+export const ManageTemplateDetailsAppBridge = ({ template }: ManageTemplateDetailsAppBridgeProps) => {
const awake = useAwake()
const handleDeleteTemplate = useCallback(() => {
@@ -34,8 +33,8 @@ export const ManageTemplateDetailsAppBridge = ({ portalUrl, template }: ManageTe
onClick: handleDeleteTemplate,
},
]
- usePrimaryCta(null, { portalUrl })
- useActionsMenu(items, { portalUrl })
+ usePrimaryCta(null)
+ useActionsMenu(items)
return <>>
}
diff --git a/src/app/ui/TaskBoard.tsx b/src/app/ui/TaskBoard.tsx
index d8c90d9b3..4b3453586 100644
--- a/src/app/ui/TaskBoard.tsx
+++ b/src/app/ui/TaskBoard.tsx
@@ -134,7 +134,7 @@ export const TaskBoard = ({ mode, workspace, token }: TaskBoardProps) => {
<>
- {mode == UserRole.IU && }
+ {mode == UserRole.IU && }
{/* Filterbars */}
diff --git a/src/app/ui/TaskBoardAppBridge.tsx b/src/app/ui/TaskBoardAppBridge.tsx
index 70f53bb33..227f912f6 100644
--- a/src/app/ui/TaskBoardAppBridge.tsx
+++ b/src/app/ui/TaskBoardAppBridge.tsx
@@ -15,11 +15,10 @@ import { useCallback, useEffect, useState } from 'react'
interface TaskBoardAppBridgeProps {
token: string
role: UserRole
- portalUrl?: string
isTaskBoardEmpty?: boolean
}
-export const TaskBoardAppBridge = ({ token, role, portalUrl, isTaskBoardEmpty = false }: TaskBoardAppBridgeProps) => {
+export const TaskBoardAppBridge = ({ token, role, isTaskBoardEmpty = false }: TaskBoardAppBridgeProps) => {
const router = useRouter()
const awake = useAwake()
@@ -41,11 +40,10 @@ export const TaskBoardAppBridge = ({ token, role, portalUrl, isTaskBoardEmpty =
icon: Icons.PLUS,
onClick: handleTaskCreate,
},
- { portalUrl },
)
// Unset "Unarchive" button from tasks details if redirected to board from an archived task
- useSecondaryCta(null, { portalUrl })
+ useSecondaryCta(null)
useActionsMenu(
role == UserRole.Client
@@ -57,9 +55,8 @@ export const TaskBoardAppBridge = ({ token, role, portalUrl, isTaskBoardEmpty =
onClick: handleManageTemplatesClick,
},
],
- { portalUrl },
)
- useBreadcrumbs([], { portalUrl })
+ useBreadcrumbs([])
return <>>
}
diff --git a/src/cmd/serve-embedded/index.ts b/src/cmd/serve-embedded/index.ts
index 1a1ae41e6..ca4b5ea39 100644
--- a/src/cmd/serve-embedded/index.ts
+++ b/src/cmd/serve-embedded/index.ts
@@ -29,8 +29,8 @@ const createNgrokTunnel = async (port: number): Promise => {
return ngrokUrl
}
-const openDashboard = async (ngrokUrl: string) => {
- const url = `${DASHBOARD_DOMAIN}/dev-mode?url=${encodeURIComponent(ngrokUrl)}`
+const openDashboard = async (appUrl: string) => {
+ const url = `${DASHBOARD_DOMAIN[0]}/dev-mode?url=${encodeURIComponent(appUrl)}`
console.info(`> Opening browser at ${url}`)
const browserApp = Array.isArray(apps.browser) ? apps.browser[0] : apps.browser
@@ -51,6 +51,9 @@ const handleProcessEvents = () => {
async function startServer() {
await app.prepare()
+ const useNgrok = !!process.env.NGROK_AUTHTOKEN
+ const appUrl = useNgrok ? await createNgrokTunnel(port) : `http://localhost:${port}`
+
const server = createServer((req: IncomingMessage, res: ServerResponse) => {
if (!req.url) {
res.statusCode = 400
@@ -59,7 +62,7 @@ async function startServer() {
}
const parsedUrl = parse(req.url, true)
- res.setHeader('Set-Cookie', `ngrokUrl=${ngrokUrl}`)
+ res.setHeader('Set-Cookie', `appUrl=${appUrl}`)
res.setHeader('X-Frame-Options', '')
handle(req, res, parsedUrl)
})
@@ -68,8 +71,7 @@ async function startServer() {
console.info(`> Server listening at http://localhost:${port}`)
})
- const ngrokUrl = await createNgrokTunnel(port)
- await openDashboard(ngrokUrl)
+ await openDashboard(appUrl)
handleProcessEvents()
}
diff --git a/src/components/layouts/HeaderBreadcrumbs.tsx b/src/components/layouts/HeaderBreadcrumbs.tsx
index 00ab5364c..abf66f52a 100644
--- a/src/components/layouts/HeaderBreadcrumbs.tsx
+++ b/src/components/layouts/HeaderBreadcrumbs.tsx
@@ -17,12 +17,10 @@ export const HeaderBreadcrumbs = ({
token,
items,
userType,
- portalUrl,
}: {
token: string | undefined
items: { label: string; href?: string }[]
userType: UserType
- portalUrl?: string
}) => {
const { previewMode } = useSelector(selectTaskBoard)
const router = useRouter()
@@ -41,7 +39,6 @@ export const HeaderBreadcrumbs = ({
label,
onClick: index === items.length - 1 ? undefined : href ? () => router.push(href) : undefined,
})),
- { portalUrl },
)
if (!previewMode) {
diff --git a/src/config/index.ts b/src/config/index.ts
index d4b27e017..a99459792 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -1,5 +1,3 @@
-import z from 'zod'
-
export const copilotAPIKey = process.env.COPILOT_API_KEY || ''
export const tasksAppId = process.env.COPILOT_TASKS_APP_ID || ''
@@ -30,4 +28,4 @@ export const showQueries = (() => {
return true
})()
-export const assemblyApiDomain = z.string().url().parse(process.env.NEXT_PUBLIC_ASSEMBLY_API_DOMAIN)
+export const assemblyApiDomain = process.env.NEXT_PUBLIC_ASSEMBLY_API_DOMAIN ?? ''
diff --git a/src/hoc/ClientSideStateUpdate.tsx b/src/hoc/ClientSideStateUpdate.tsx
index d159c4a25..58ca04d45 100644
--- a/src/hoc/ClientSideStateUpdate.tsx
+++ b/src/hoc/ClientSideStateUpdate.tsx
@@ -1,5 +1,6 @@
'use client'
+import { AssemblyBridge } from '@assembly-js/app-bridge'
import { setTokenPayload, setWorkspace } from '@/redux/features/authDetailsSlice'
import {
selectTaskBoard,
@@ -87,6 +88,10 @@ export const ClientSideStateUpdate = ({
store.dispatch(setToken(token))
}
+ const unsubscribeTokenRefresh = AssemblyBridge.sessionToken.onTokenUpdate((data) => {
+ store.dispatch(setToken(data.token))
+ })
+
if (assignee) {
store.dispatch(setAssigneeList(assignee))
}
@@ -152,6 +157,9 @@ export const ClientSideStateUpdate = ({
if (workspace) {
store.dispatch(setWorkspace(workspace))
+ if (workspace.portalUrl) {
+ AssemblyBridge.configure({ additionalOrigins: [workspace.portalUrl] })
+ }
}
if (template) {
store.dispatch(setActiveTemplate(template))
@@ -159,6 +167,7 @@ export const ClientSideStateUpdate = ({
return () => {
store.dispatch(setActiveTask(undefined))
store.dispatch(setActiveTemplate(null))
+ unsubscribeTokenRefresh()
} //when component is unmounted, we need to clear the active task.
}, [
workflowStates,
diff --git a/src/hooks/app-bridge/types.ts b/src/hooks/app-bridge/types.ts
index 6890a6ef0..a425dae26 100644
--- a/src/hooks/app-bridge/types.ts
+++ b/src/hooks/app-bridge/types.ts
@@ -7,45 +7,9 @@ export enum Icons {
CHECK = 'Check',
}
-export interface BreadcrumbsPayload {
- items: {
- label: string
- onClick: string
- }[]
- type: 'header.breadcrumbs'
-}
-
-export interface PrimaryCtaPayload {
- icon?: Icons
- label: string
- onClick?: string
- type: 'header.primaryCta'
-}
-
-export interface SecondaryCtaPayload {
- icon?: Icons
- label: string
- onClick?: string
- type: 'header.secondaryCta'
-}
-
-export interface ActionsMenuPayload {
- items: {
- label: string
- onClick: string
- icon?: Icons
- color?: string
- }[]
- type: 'header.actionsMenu'
-}
-
export interface Clickable {
label: string
onClick?: () => void
icon?: Icons
color?: string
}
-
-export interface Configurable {
- portalUrl?: string
-}
diff --git a/src/hooks/app-bridge/useActionsMenu.tsx b/src/hooks/app-bridge/useActionsMenu.tsx
index d8f461b09..2c6028a64 100644
--- a/src/hooks/app-bridge/useActionsMenu.tsx
+++ b/src/hooks/app-bridge/useActionsMenu.tsx
@@ -1,58 +1,18 @@
-import { ActionsMenuPayload, Clickable, Configurable } from '@/hooks/app-bridge/types'
-import { ensureHttps } from '@/utils/https'
-import { useEffect, useMemo } from 'react'
-import { DASHBOARD_DOMAIN } from '@/constants/domains'
-import { postMessageParentDashboard } from './utils'
-const getActionMenuItemId = (idx: number) => `header.actionsMenu.${idx}`
-
-export function useActionsMenu(actions: Clickable[], config?: Configurable) {
- const callbackRefs = useMemo(() => {
- return actions.reduce void>>((acc, { onClick }, idx) => {
- if (onClick) acc[getActionMenuItemId(idx)] = onClick
- return acc
- }, {})
- }, [actions])
+import { AssemblyBridge } from '@assembly-js/app-bridge'
+import { Clickable } from '@/hooks/app-bridge/types'
+import { useEffect } from 'react'
+export function useActionsMenu(actions: Clickable[]) {
useEffect(() => {
- const payload: ActionsMenuPayload = {
- type: 'header.actionsMenu',
- items: actions.map(({ label, onClick, icon, color }, idx) => ({
- onClick: onClick ? getActionMenuItemId(idx) : '',
- label,
- icon,
- color,
- })),
- }
-
- postMessageParentDashboard(payload)
- if (config?.portalUrl) {
- window.parent.postMessage(payload, ensureHttps(config.portalUrl))
- }
-
- const handleMessage = (event: MessageEvent) => {
- if (
- event.data.type === 'header.actionsMenu.onClick' &&
- typeof event.data.id === 'string' &&
- callbackRefs[event.data.id]
- ) {
- callbackRefs[event.data.id]()
- }
- }
-
- addEventListener('message', handleMessage)
-
- return () => {
- removeEventListener('message', handleMessage)
- }
- }, [actions, callbackRefs, config?.portalUrl])
-
- useEffect(() => {
- const handleUnload = () => {
- postMessageParentDashboard({ type: 'header.actionsMenu', items: [] })
- }
- addEventListener('beforeunload', handleUnload)
- return () => {
- removeEventListener('beforeunload', handleUnload)
- }
- }, [])
+ AssemblyBridge.header.setActionsMenu(
+ actions
+ .filter((action) => action.onClick)
+ .map(({ label, onClick, icon, color }) => ({
+ label,
+ onClick: onClick!,
+ icon,
+ ...(color ? { color: color as 'red' } : {}),
+ })),
+ )
+ }, [actions])
}
diff --git a/src/hooks/app-bridge/useBreadcrumbs.tsx b/src/hooks/app-bridge/useBreadcrumbs.tsx
index 755701ccb..6eca0470e 100644
--- a/src/hooks/app-bridge/useBreadcrumbs.tsx
+++ b/src/hooks/app-bridge/useBreadcrumbs.tsx
@@ -1,47 +1,14 @@
-import { BreadcrumbsPayload, Clickable, Configurable } from '@/hooks/app-bridge/types'
-import { ensureHttps } from '@/utils/https'
-import { useEffect, useMemo } from 'react'
-import { DASHBOARD_DOMAIN } from '@/constants/domains'
-import { postMessageParentDashboard } from './utils'
-
-const getBreadcrumbId = (idx: number) => `header.breadcrumbs.${idx}`
-
-export const useBreadcrumbs = (breadcrumbs: Clickable[], config?: Configurable) => {
- const callbackRefs = useMemo(() => {
- return breadcrumbs.reduce void>>((acc, { onClick }, idx) => {
- if (onClick) acc[getBreadcrumbId(idx)] = onClick
- return acc
- }, {})
- }, [breadcrumbs])
+import { AssemblyBridge } from '@assembly-js/app-bridge'
+import { Clickable } from '@/hooks/app-bridge/types'
+import { useEffect } from 'react'
+export const useBreadcrumbs = (breadcrumbs: Clickable[]) => {
useEffect(() => {
- const payload: BreadcrumbsPayload = {
- type: 'header.breadcrumbs',
- items: breadcrumbs.map(({ label, onClick }, idx) => ({
- onClick: onClick ? getBreadcrumbId(idx) : '',
+ AssemblyBridge.header.setBreadcrumbs(
+ breadcrumbs.map(({ label, onClick }) => ({
label,
+ onClick,
})),
- }
-
- postMessageParentDashboard(payload)
- if (config?.portalUrl) {
- window.parent.postMessage(payload, ensureHttps(config.portalUrl))
- }
-
- const handleMessage = (event: MessageEvent) => {
- if (
- event.data.type === 'header.breadcrumbs.onClick' &&
- typeof event.data.id === 'string' &&
- callbackRefs[event.data.id]
- ) {
- callbackRefs[event.data.id]()
- }
- }
-
- addEventListener('message', handleMessage)
-
- return () => {
- removeEventListener('message', handleMessage)
- }
- }, [breadcrumbs, callbackRefs, config?.portalUrl])
+ )
+ }, [breadcrumbs])
}
diff --git a/src/hooks/app-bridge/usePrimaryCta.tsx b/src/hooks/app-bridge/usePrimaryCta.tsx
index 947f12df3..efd4aeb2a 100644
--- a/src/hooks/app-bridge/usePrimaryCta.tsx
+++ b/src/hooks/app-bridge/usePrimaryCta.tsx
@@ -1,48 +1,17 @@
-import { Clickable, Configurable, PrimaryCtaPayload } from '@/hooks/app-bridge/types'
-import { ensureHttps } from '@/utils/https'
+import { AssemblyBridge } from '@assembly-js/app-bridge'
+import { Clickable } from '@/hooks/app-bridge/types'
import { useEffect } from 'react'
-import { DASHBOARD_DOMAIN } from '@/constants/domains'
-import { postMessageParentDashboard } from './utils'
-export const usePrimaryCta = (primaryCta: Clickable | null, config?: Configurable) => {
+export const usePrimaryCta = (primaryCta: Clickable | null) => {
useEffect(() => {
- const payload: PrimaryCtaPayload | Pick = !primaryCta
- ? { type: 'header.primaryCta' }
- : {
- icon: primaryCta.icon,
- label: primaryCta.label,
- onClick: 'header.primaryCta.onClick',
- type: 'header.primaryCta',
- }
-
- postMessageParentDashboard(payload)
- if (config?.portalUrl) {
- window.parent.postMessage(payload, ensureHttps(config.portalUrl))
- }
-
- const handleMessage = (event: MessageEvent) => {
- if (event.data.type === 'header.primaryCta.onClick' && typeof event.data.id === 'string' && primaryCta?.onClick) {
- primaryCta.onClick()
- }
- }
-
- addEventListener('message', handleMessage)
-
- return () => {
- removeEventListener('message', handleMessage)
- }
- }, [primaryCta, config?.portalUrl])
-
- useEffect(() => {
- const handleUnload = () => {
- postMessageParentDashboard({ type: 'header.primaryCta' })
- if (config?.portalUrl) {
- window.parent.postMessage({ type: 'header.primaryCta' }, ensureHttps(config.portalUrl))
- }
- }
- addEventListener('beforeunload', handleUnload)
- return () => {
- removeEventListener('beforeunload', handleUnload)
+ if (primaryCta?.onClick) {
+ AssemblyBridge.header.setPrimaryCta({
+ label: primaryCta.label,
+ icon: primaryCta.icon,
+ onClick: primaryCta.onClick,
+ })
+ } else {
+ AssemblyBridge.header.setPrimaryCta(null)
}
- }, [config?.portalUrl])
+ }, [primaryCta])
}
diff --git a/src/hooks/app-bridge/useSecondaryCta.tsx b/src/hooks/app-bridge/useSecondaryCta.tsx
index 62f4ac491..821a36a10 100644
--- a/src/hooks/app-bridge/useSecondaryCta.tsx
+++ b/src/hooks/app-bridge/useSecondaryCta.tsx
@@ -1,48 +1,17 @@
-import { Clickable, Configurable, SecondaryCtaPayload } from '@/hooks/app-bridge/types'
-import { ensureHttps } from '@/utils/https'
+import { AssemblyBridge } from '@assembly-js/app-bridge'
+import { Clickable } from '@/hooks/app-bridge/types'
import { useEffect } from 'react'
-import { DASHBOARD_DOMAIN } from '@/constants/domains'
-import { postMessageParentDashboard } from './utils'
-export const useSecondaryCta = (secondaryCta: Clickable | null, config?: Configurable) => {
+export const useSecondaryCta = (secondaryCta: Clickable | null) => {
useEffect(() => {
- const payload: SecondaryCtaPayload | Pick = !secondaryCta
- ? { type: 'header.secondaryCta' }
- : {
- type: 'header.secondaryCta',
- label: secondaryCta.label,
- icon: secondaryCta.icon,
- onClick: 'header.secondaryCta.onClick',
- }
-
- postMessageParentDashboard(payload)
- if (config?.portalUrl) {
- window.parent.postMessage(payload, ensureHttps(config.portalUrl))
- }
-
- const handleMessage = (event: MessageEvent) => {
- if (event.data.type === 'header.secondaryCta.onClick' && typeof event.data.id === 'string' && secondaryCta?.onClick) {
- secondaryCta.onClick()
- }
- }
-
- addEventListener('message', handleMessage)
-
- return () => {
- removeEventListener('message', handleMessage)
- }
- }, [secondaryCta, config?.portalUrl])
-
- useEffect(() => {
- const handleUnload = () => {
- postMessageParentDashboard({ type: 'header.secondaryCta' })
- if (config?.portalUrl) {
- window.parent.postMessage({ type: 'header.secondaryCta' }, ensureHttps(config.portalUrl))
- }
- }
- addEventListener('beforeunload', handleUnload)
- return () => {
- removeEventListener('beforeunload', handleUnload)
+ if (secondaryCta?.onClick) {
+ AssemblyBridge.header.setSecondaryCta({
+ label: secondaryCta.label,
+ icon: secondaryCta.icon,
+ onClick: secondaryCta.onClick,
+ })
+ } else {
+ AssemblyBridge.header.setSecondaryCta(null)
}
- }, [config?.portalUrl])
+ }, [secondaryCta])
}
diff --git a/src/hooks/app-bridge/utils.ts b/src/hooks/app-bridge/utils.ts
deleted file mode 100644
index dd201e717..000000000
--- a/src/hooks/app-bridge/utils.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { DASHBOARD_DOMAIN } from '@/constants/domains'
-
-export const postMessageParentDashboard = (payload: object) => {
- for (const domain of DASHBOARD_DOMAIN) {
- window.parent.postMessage(payload, domain)
- }
-}
diff --git a/src/utils/CopilotAPI.ts b/src/utils/CopilotAPI.ts
index d734d02df..5b03adc5e 100644
--- a/src/utils/CopilotAPI.ts
+++ b/src/utils/CopilotAPI.ts
@@ -37,22 +37,33 @@ import {
} from '@/types/common'
import { DISPATCHABLE_EVENT } from '@/types/webhook'
import Bottleneck from 'bottleneck'
-import type { CopilotAPI as SDK } from 'copilot-node-sdk'
-import { copilotApi } from 'copilot-node-sdk'
+import type { AssemblyAPI as SDK } from '@assembly-js/node-sdk'
+import { assemblyApi } from '@assembly-js/node-sdk'
import { z } from 'zod'
export class CopilotAPI {
- copilot: SDK
+ private assemblyPromise: Promise
constructor(
private token: string,
customApiKey?: string,
) {
- this.copilot = copilotApi({ apiKey: customApiKey ?? apiKey, token })
+ this.assemblyPromise = assemblyApi({ apiKey: customApiKey ?? apiKey, token })
+ }
+
+ private async _getBaseUrl(): Promise {
+ const assembly = await this.assemblyPromise
+ const tokenPayload = assembly.getTokenPayload ? await assembly.getTokenPayload() : null
+ const baseUrl = tokenPayload?.baseUrl || assemblyApiDomain
+ if (!baseUrl) {
+ throw new Error('No API base URL available: set NEXT_PUBLIC_ASSEMBLY_API_DOMAIN or provide a token with baseUrl')
+ }
+ return baseUrl
}
private async _manualFetch(route: string, query?: Record, workspaceId?: string) {
- const url = new URL(`${assemblyApiDomain}/v1/${route}`)
+ const baseUrl = await this._getBaseUrl()
+ const url = new URL(`${baseUrl}/v1/${route}`)
if (query) {
for (const key of Object.keys(query)) {
url.searchParams.set(key, query[key])
@@ -78,7 +89,8 @@ export class CopilotAPI {
// Get Token Payload from copilot request token
async _getTokenPayload(): Promise {
- const getTokenPayload = this.copilot.getTokenPayload
+ const assembly = await this.assemblyPromise
+ const getTokenPayload = assembly.getTokenPayload
if (!getTokenPayload) {
console.error(`CopilotAPI#getTokenPayload | Could not parse token payload for token ${this.token}`)
return null
@@ -93,9 +105,8 @@ export class CopilotAPI {
const id = tokenPayload?.internalUserId || tokenPayload?.clientId
if (!tokenPayload || !id) return null
- const retrieveCurrentUserInfo = tokenPayload.internalUserId
- ? this.copilot.retrieveInternalUser
- : this.copilot.retrieveClient
+ const assembly = await this.assemblyPromise
+ const retrieveCurrentUserInfo = tokenPayload.internalUserId ? assembly.retrieveInternalUser : assembly.retrieveClient
const currentUserInfo = await retrieveCurrentUserInfo({ id })
return MeResponseSchema.parse(currentUserInfo)
@@ -103,7 +114,8 @@ export class CopilotAPI {
async _getWorkspace(): Promise {
console.info('CopilotAPI#_getWorkspace', this.token)
- return WorkspaceResponseSchema.parse(await this.copilot.retrieveWorkspace())
+ const assembly = await this.assemblyPromise
+ return WorkspaceResponseSchema.parse(await assembly.retrieveWorkspace())
}
async _getClientTokenPayload(): Promise {
@@ -124,30 +136,33 @@ export class CopilotAPI {
async _createClient(requestBody: ClientRequest, sendInvite: boolean = false): Promise {
console.info('CopilotAPI#_createClient', this.token)
- return ClientResponseSchema.parse(await this.copilot.createClient({ sendInvite, requestBody }))
+ const assembly = await this.assemblyPromise
+ return ClientResponseSchema.parse(await assembly.createClient({ sendInvite, requestBody }))
}
async _getClient(id: string): Promise {
console.info('CopilotAPI#_getClient', this.token)
- return ClientResponseSchema.parse(await this.copilot.retrieveClient({ id }))
+ const assembly = await this.assemblyPromise
+ return ClientResponseSchema.parse(await assembly.retrieveClient({ id }))
}
async _getClients(args: CopilotListArgs & { companyId?: string } = {}) {
console.info('CopilotAPI#_getClients', this.token)
+ const assembly = await this.assemblyPromise
const maxLimit = MAX_LIMIT_CLIENT_COUNT
const requestedLimit = args.limit || maxLimit
let clients: ClientResponse[] = []
let nextToken: string | undefined = undefined
if (requestedLimit <= maxLimit) {
- return ClientsResponseSchema.parse(await this.copilot.listClients(args))
+ return ClientsResponseSchema.parse(await assembly.listClients(args))
}
//fetching client data in batches of MAX_LIMIT_CLIENT_COUNT instead of fetching it as a whole.
do {
const remaining = requestedLimit - clients.length
const fetchLimit = Math.min(maxLimit, remaining)
- const response = await this.copilot.listClients({
+ const response = await assembly.listClients({
...args,
limit: fetchLimit,
nextToken,
@@ -162,28 +177,33 @@ export class CopilotAPI {
async _updateClient(id: string, requestBody: ClientRequest): Promise {
console.info('CopilotAPI#_updateClient', this.token)
+ const assembly = await this.assemblyPromise
// @ts-ignore
- return ClientResponseSchema.parse(await this.copilot.updateClient({ id, requestBody }))
+ return ClientResponseSchema.parse(await assembly.updateClient({ id, requestBody }))
}
async _deleteClient(id: string) {
console.info('CopilotAPI#_deleteClient', this.token)
- return await this.copilot.deleteClient({ id })
+ const assembly = await this.assemblyPromise
+ return await assembly.deleteClient({ id })
}
async _createCompany(requestBody: CompanyCreateRequest) {
console.info('CopilotAPI#_createCompany', this.token)
- return CompanyResponseSchema.parse(await this.copilot.createCompany({ requestBody }))
+ const assembly = await this.assemblyPromise
+ return CompanyResponseSchema.parse(await assembly.createCompany({ requestBody }))
}
async _getCompany(id: string): Promise {
console.info('CopilotAPI#_getCompany', this.token)
- return CompanyResponseSchema.parse(await this.copilot.retrieveCompany({ id }))
+ const assembly = await this.assemblyPromise
+ return CompanyResponseSchema.parse(await assembly.retrieveCompany({ id }))
}
async _getCompanies(args: CopilotListArgs & { isPlaceholder?: boolean } = {}): Promise {
console.info('CopilotAPI#_getCompanies', this.token)
- return CompaniesResponseSchema.parse(await this.copilot.listCompanies(args))
+ const assembly = await this.assemblyPromise
+ return CompaniesResponseSchema.parse(await assembly.listCompanies(args))
}
async _getCompanyClients(companyId: string): Promise {
@@ -193,28 +213,33 @@ export class CopilotAPI {
async _getCustomFields(): Promise {
console.info('CopilotAPI#_getCustomFields', this.token)
- return CustomFieldResponseSchema.parse(await this.copilot.listCustomFields())
+ const assembly = await this.assemblyPromise
+ return CustomFieldResponseSchema.parse(await assembly.listCustomFields({}))
}
async _getInternalUsers(args: CopilotListArgs = {}): Promise {
console.info('CopilotAPI#_getInternalUsers', this.token)
- return InternalUsersResponseSchema.parse(await this.copilot.listInternalUsers(args))
+ const assembly = await this.assemblyPromise
+ return InternalUsersResponseSchema.parse(await assembly.listInternalUsers(args))
}
async _getInternalUser(id: string): Promise {
console.info('CopilotAPI#_getInternalUser', this.token)
- return InternalUsersSchema.parse(await this.copilot.retrieveInternalUser({ id }))
+ const assembly = await this.assemblyPromise
+ return InternalUsersSchema.parse(await assembly.retrieveInternalUser({ id }))
}
async _createNotification(requestBody: NotificationRequestBody): Promise {
console.info('CopilotAPI#_createNotification', this.token)
- const notification = await this.copilot.createNotification({ requestBody })
+ const assembly = await this.assemblyPromise
+ const notification = await assembly.createNotification({ requestBody })
return NotificationCreatedResponseSchema.parse(notification)
}
async _markNotificationAsRead(id: string): Promise {
console.info('CopilotAPI#_markNotificationAsRead', this.token)
- await this.copilot.markNotificationRead({ id })
+ const assembly = await this.assemblyPromise
+ await assembly.markNotificationRead({ id })
}
async _bulkMarkNotificationsAsRead(notificationIds: string[], shouldThrowError: boolean = true): Promise {
@@ -247,7 +272,8 @@ export class CopilotAPI {
async _deleteNotification(id: string): Promise {
console.info('CopilotAPI#_deleteNotification', this.token)
- await this.copilot.deleteNotification({ id })
+ const assembly = await this.assemblyPromise
+ await assembly.deleteNotification({ id })
}
async _bulkDeleteNotifications(notificationIds: string[]): Promise {
@@ -313,18 +339,11 @@ export class CopilotAPI {
async dispatchWebhook(eventName: DISPATCHABLE_EVENT, { workspaceId, payload }: { workspaceId: string; payload?: object }) {
console.info('CopilotAPI#dispatchWebhook', this.token)
- const url = `${assemblyApiDomain}/v1/webhooks/${eventName}`
- console.info('CopilotAPI#dispatchWebhook | Dispatching webhook to ', url, 'with payload', payload ?? null)
+ console.info('CopilotAPI#dispatchWebhook | Dispatching webhook', eventName, 'with payload', payload ?? null)
try {
- await fetch(url, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'x-api-key': `${workspaceId}/${apiKey}`,
- },
- body: payload ? JSON.stringify(payload) : null,
- })
+ const assembly = await this.assemblyPromise
+ await assembly.sendWebhook(eventName, payload)
} catch (e) {
console.error(`Failed to dispatch webhook for event ${eventName}`, e)
}
diff --git a/yarn.lock b/yarn.lock
index 599e62c91..b1d9d206a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -18,6 +18,16 @@
"@csstools/css-tokenizer" "^3.0.3"
lru-cache "^10.4.3"
+"@assembly-js/app-bridge@^1.1.0":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@assembly-js/app-bridge/-/app-bridge-1.1.1.tgz#671b49991bd89538dd8bda2444b0e5ac8e81c1bd"
+ integrity sha512-NWD8FuRBmLb8+5bMHX8NtepSnIVShmmYoPPD6rHfcFrkN9SKm61/vdCASJnMViWVOjItuKku9QSpn6sOy4L6Og==
+
+"@assembly-js/node-sdk@^4.0.2":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@assembly-js/node-sdk/-/node-sdk-4.0.2.tgz#d745fedcb1247479757916f6170057909a99cf98"
+ integrity sha512-mZo+bFTKGYO9YR7m95OlGJpGkF4tYNtxsCABvmNbCTBVXnTfpPjkQMDCYIoE0N3ljN8Iht0+AKBdF+kjTep7fQ==
+
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be"
@@ -2081,11 +2091,6 @@
dependencies:
"@types/pg" "8.6.6"
-"@next/env@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.32.tgz#6d1107e2b7cc8649ff3730b8b46deb4e8a6d38fa"
- integrity sha512-n9mQdigI6iZ/DF6pCTwMKeWgF2e8lg7qgt5M7HXMLtyhZYMnf/u905M18sSpPmHL9MKp9JHo56C6jrD2EvWxng==
-
"@next/env@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.1.tgz#3d06a470efff135746ef609cc02a4996512bd9ab"
@@ -2098,86 +2103,41 @@
dependencies:
fast-glob "3.3.1"
-"@next/swc-darwin-arm64@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz#83482a7282df899b73d916e02b02a189771e706c"
- integrity sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==
-
"@next/swc-darwin-arm64@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.1.tgz#1e7e87fd21fcabce546dfb04fb946ecd9f866917"
integrity sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA==
-"@next/swc-darwin-x64@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz#1a9eb676a014e1fc999251f10288c25a0f81d6d1"
- integrity sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==
-
"@next/swc-darwin-x64@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.1.tgz#6617d03b96bdffad7bf4df50d4a699faea0d04c3"
integrity sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw==
-"@next/swc-linux-arm64-gnu@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz#7713a49abd555d6f698e766b1631b67d881b4ee4"
- integrity sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==
-
"@next/swc-linux-arm64-gnu@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.1.tgz#d8337e2f4881a80221a1f56ac3f979b665b7e574"
integrity sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ==
-"@next/swc-linux-arm64-musl@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz#327efdffe97e56f5389a7889cdedbd676fdbb519"
- integrity sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==
-
"@next/swc-linux-arm64-musl@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.1.tgz#6c24392824406a50f27fb9cf4e49362d4666db1c"
integrity sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg==
-"@next/swc-linux-x64-gnu@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.32.tgz#a3e7444613d0fe5c8ea4ead08d6a9c818246758c"
- integrity sha512-7S1GY4TdnlGVIdeXXKQdDkfDysoIVFMD0lJuVVMeb3eoVjrknQ0JNN7wFlhCvea0hEk0Sd4D1hedVChDKfV2jw==
-
"@next/swc-linux-x64-gnu@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.1.tgz#f1bd19fc7d119f27c4cf7f51915aef0f119c943f"
integrity sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ==
-"@next/swc-linux-x64-musl@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.32.tgz#a2ec5b0a06c740d6740c938b1d4a614f1a13f018"
- integrity sha512-OHHC81P4tirVa6Awk6eCQ6RBfWl8HpFsZtfEkMpJ5GjPsJ3nhPe6wKAJUZ/piC8sszUkAgv3fLflgzPStIwfWg==
-
"@next/swc-linux-x64-musl@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.1.tgz#20c1ea0c98988c337614ce6fda01b82300ff00fd"
integrity sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA==
-"@next/swc-win32-arm64-msvc@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz#b4d3e47c6b276fc4711deb978d04015d029d198d"
- integrity sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==
-
"@next/swc-win32-arm64-msvc@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.1.tgz#9d66be9dc4ebc458d445a7f6ee804f416d5c2daf"
integrity sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA==
-"@next/swc-win32-ia32-msvc@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz#d1f1f854a1fbbaeefa8f81271437448653f33494"
- integrity sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==
-
-"@next/swc-win32-x64-msvc@14.2.32":
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz#8212d681cf6858a9e3204728f8f2b161000683ed"
- integrity sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==
-
"@next/swc-win32-x64-msvc@16.1.1":
version "16.1.1"
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.1.tgz#96e9e335e2577481dab6fc7a2af48f3e4a28fbdb"
@@ -3495,11 +3455,6 @@
"@svgr/plugin-jsx" "8.1.0"
"@svgr/plugin-svgo" "8.1.0"
-"@swc/counter@^0.1.3":
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
- integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
-
"@swc/helpers@0.5.15":
version "0.5.15"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7"
@@ -3507,14 +3462,6 @@
dependencies:
tslib "^2.8.0"
-"@swc/helpers@0.5.5":
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.5.tgz#12689df71bfc9b21c4f4ca00ae55f2f16c8b77c0"
- integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==
- dependencies:
- "@swc/counter" "^0.1.3"
- tslib "^2.4.0"
-
"@tanstack/react-virtual@^3.13.12":
version "3.13.12"
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz#d372dc2783739cc04ec1a728ca8203937687a819"
@@ -4608,13 +4555,6 @@ bundle-name@^4.1.0:
dependencies:
run-applescript "^7.0.0"
-busboy@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
- integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
- dependencies:
- streamsearch "^1.1.0"
-
bytes@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
@@ -4893,14 +4833,6 @@ copilot-design-system@^2.3.4:
tailwind-merge "^2.3.0"
uuid "^9.0.1"
-copilot-node-sdk@^3.16.0:
- version "3.16.0"
- resolved "https://registry.yarnpkg.com/copilot-node-sdk/-/copilot-node-sdk-3.16.0.tgz#c1335c768bd3f9d091c154f930fce9a2633ade8d"
- integrity sha512-wqqeJuW+uge39nC1/+cqMWSSgCCNThtCR+JykPYFB2PTj0d0tfROCXofwtqZZccUUzk/xXXkJF53QfweVxmMLg==
- dependencies:
- isomorphic-fetch "^3.0.0"
- next "^14.0.2"
-
copy-anything@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.5.tgz#2d92dce8c498f790fa7ad16b01a1ae5a45b020a0"
@@ -6304,7 +6236,7 @@ gopd@^1.0.1, gopd@^1.2.0:
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
-graceful-fs@^4.2.11, graceful-fs@^4.2.9:
+graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -6827,14 +6759,6 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
-isomorphic-fetch@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4"
- integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==
- dependencies:
- node-fetch "^2.6.1"
- whatwg-fetch "^3.4.1"
-
istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756"
@@ -7771,29 +7695,6 @@ next@16.1.1:
"@next/swc-win32-x64-msvc" "16.1.1"
sharp "^0.34.4"
-next@^14.0.2:
- version "14.2.32"
- resolved "https://registry.yarnpkg.com/next/-/next-14.2.32.tgz#279b544f0c8ed023c33454ce4d563d3e05c2f3fb"
- integrity sha512-fg5g0GZ7/nFc09X8wLe6pNSU8cLWbLRG3TZzPJ1BJvi2s9m7eF991se67wliM9kR5yLHRkyGKU49MMx58s3LJg==
- dependencies:
- "@next/env" "14.2.32"
- "@swc/helpers" "0.5.5"
- busboy "1.6.0"
- caniuse-lite "^1.0.30001579"
- graceful-fs "^4.2.11"
- postcss "8.4.31"
- styled-jsx "5.1.1"
- optionalDependencies:
- "@next/swc-darwin-arm64" "14.2.32"
- "@next/swc-darwin-x64" "14.2.32"
- "@next/swc-linux-arm64-gnu" "14.2.32"
- "@next/swc-linux-arm64-musl" "14.2.32"
- "@next/swc-linux-x64-gnu" "14.2.32"
- "@next/swc-linux-x64-musl" "14.2.32"
- "@next/swc-win32-arm64-msvc" "14.2.32"
- "@next/swc-win32-ia32-msvc" "14.2.32"
- "@next/swc-win32-x64-msvc" "14.2.32"
-
nextjs-progressloader@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/nextjs-progressloader/-/nextjs-progressloader-1.3.0.tgz#5290df9585d63f09443a17939c232d70cd9bc79f"
@@ -7831,7 +7732,7 @@ node-fetch-native@^1.6.6:
resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.7.tgz#9d09ca63066cc48423211ed4caf5d70075d76a71"
integrity sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==
-node-fetch@^2.6.1, node-fetch@^2.6.7:
+node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
@@ -9223,11 +9124,6 @@ stop-iteration-iterator@^1.0.0, stop-iteration-iterator@^1.1.0:
es-errors "^1.3.0"
internal-slot "^1.1.0"
-streamsearch@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
- integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
-
string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
@@ -9404,13 +9300,6 @@ styled-components@^6.1.11:
stylis "4.3.2"
tslib "2.6.2"
-styled-jsx@5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f"
- integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==
- dependencies:
- client-only "0.0.1"
-
styled-jsx@5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499"
@@ -10067,11 +9956,6 @@ whatwg-encoding@^3.1.1:
dependencies:
iconv-lite "0.6.3"
-whatwg-fetch@^3.4.1:
- version "3.6.20"
- resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70"
- integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==
-
whatwg-mimetype@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a"