sanity-plugin-dashboard-widget-vercel 3.1.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -659,7 +659,7 @@ const TableCell = (props) => {
659
659
  description && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginY: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { htmlFor: name, muted: !0, size: 1, children: description }) })
660
660
  ] });
661
661
  }, FormFieldInputText = react.forwardRef((props, ref) => {
662
- const { description, disabled, error, label, name, placeholder, value } = props;
662
+ const { description, disabled, error, label, name, placeholder, value, onChange, onBlur } = props;
663
663
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { children: [
664
664
  /* @__PURE__ */ jsxRuntime.jsx(FormFieldInputLabel, { description, error, label, name }),
665
665
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -672,6 +672,8 @@ const TableCell = (props) => {
672
672
  id: name,
673
673
  name,
674
674
  placeholder,
675
+ onChange,
676
+ onBlur,
675
677
  ref
676
678
  }
677
679
  )
@@ -729,18 +731,18 @@ const formSchema = yup__namespace.object().shape({
729
731
  }
730
732
  }
731
733
  }), formUpdating = formState.matches("creating") || formState.matches("deleting") || formState.matches("updating"), {
732
- // Read the formState before render to subscribe the form state through Proxy
733
734
  formState: { errors, isDirty, isValid },
734
735
  handleSubmit,
735
736
  register
736
737
  } = reactHookForm.useForm({
738
+ // @ts-expect-error - fix typings later
737
739
  defaultValues: {
738
740
  deployHook: deploymentTarget?.deployHook || "",
739
741
  deployLimit: deploymentTarget?.deployLimit || 5,
740
- name: deploymentTarget?.name,
741
- projectId: deploymentTarget?.projectId,
742
+ name: deploymentTarget?.name || "",
743
+ projectId: deploymentTarget?.projectId || "",
742
744
  teamId: deploymentTarget?.teamId || "",
743
- token: deploymentTarget?.token
745
+ token: deploymentTarget?.token || ""
744
746
  },
745
747
  mode: "onChange",
746
748
  resolver: yup$1.yupResolver(formSchema)
@@ -793,8 +795,7 @@ const formSchema = yup__namespace.object().shape({
793
795
  description: "Name displayed in this plugin (e.g. production, staging)",
794
796
  error: errors?.name,
795
797
  label: "Name",
796
- name: "name",
797
- ref: register
798
+ ...register("name")
798
799
  }
799
800
  ),
800
801
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -803,8 +804,7 @@ const formSchema = yup__namespace.object().shape({
803
804
  disabled: formUpdating,
804
805
  error: errors?.token,
805
806
  label: "Vercel Account Token",
806
- name: "token",
807
- ref: register
807
+ ...register("token")
808
808
  }
809
809
  ),
810
810
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -813,8 +813,7 @@ const formSchema = yup__namespace.object().shape({
813
813
  disabled: formUpdating,
814
814
  error: errors?.projectId,
815
815
  label: "Vercel Project ID",
816
- name: "projectId",
817
- ref: register
816
+ ...register("projectId")
818
817
  }
819
818
  ),
820
819
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -824,8 +823,7 @@ const formSchema = yup__namespace.object().shape({
824
823
  disabled: formUpdating,
825
824
  error: errors?.teamId,
826
825
  label: "Vercel Team ID (optional)",
827
- name: "teamId",
828
- ref: register
826
+ ...register("teamId")
829
827
  }
830
828
  ),
831
829
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -835,8 +833,7 @@ const formSchema = yup__namespace.object().shape({
835
833
  disabled: formUpdating,
836
834
  error: errors?.deployHook,
837
835
  label: "Vercel Deploy Hook (optional)",
838
- name: "deployHook",
839
- ref: register
836
+ ...register("deployHook")
840
837
  }
841
838
  ),
842
839
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -845,8 +842,7 @@ const formSchema = yup__namespace.object().shape({
845
842
  disabled: formUpdating,
846
843
  error: errors?.deployLimit,
847
844
  label: "Number of deploys to display",
848
- name: "deployLimit",
849
- ref: register({ valueAsNumber: !0 })
845
+ ...register("deployLimit", { valueAsNumber: !0 })
850
846
  }
851
847
  )
852
848
  ] })
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/constants.ts","../src/components/StateDebug/index.tsx","../src/machines/deploymentTargetList.ts","../src/utils/fetcher.ts","../src/hooks/useDeployments.ts","../src/machines/refresh.ts","../src/utils/useCardColor.ts","../src/components/TableCell/index.tsx","../src/components/StatusDot/index.tsx","../src/components/Deployment/index.tsx","../src/machines/deploy.ts","../src/components/DeployButton/index.tsx","../src/components/PlaceholderAvatar/index.tsx","../src/components/PlaceholderText/index.tsx","../src/components/DeploymentPlaceholder/index.tsx","../src/components/Deployments/index.tsx","../src/components/DeploymentTarget/index.tsx","../src/components/DeploymentTargets/index.tsx","../src/machines/form.ts","../src/utils/sanitizeFormData.ts","../src/components/FormFieldInputLabel/index.tsx","../src/components/FormFieldInputText/index.tsx","../src/client.ts","../src/components/DialogForm/index.tsx","../src/machines/dialog.ts","../src/app.tsx","../src/index.ts"],"sourcesContent":["// https://vercel.com/docs/platform/limits\nexport const API_ENDPOINT_DEPLOYMENTS = 'https://api.vercel.com/v5/now/deployments'\nexport const API_ENDPOINT_ALIASES = 'https://api.vercel.com/v3/now/aliases'\n\n// Sanity API version\nexport const API_VERSION = '1'\n\nexport const DEBUG_MODE = false\n\nexport const DEPLOYMENT_TARGET_DOCUMENT_TYPE = 'vercel.deploymentTarget'\n\nexport const VERCEL_STATUS_COLORS = {\n BUILDING: '#f5a623',\n CANCELED: '#ff0000',\n ERROR: '#ff0000',\n READY: '#50e3c2',\n QUEUED: '#333',\n}\n\n// Name displayed in toasts\nexport const WIDGET_NAME = 'Vercel (dashboard)'\n\n// NOTE: Manually set plugin z-index values to be higher than Sanity's header search field\n// (which is currently 500202). Also ensure toasts always sit above dialogs.\nexport const Z_INDEX_DIALOG = 600001\nexport const Z_INDEX_TOAST_PROVIDER = 600002\n","import {Box, Card, Stack, Text} from '@sanity/ui'\nimport React from 'react'\n\nimport {DEBUG_MODE} from '../../constants'\n\ntype Props = {\n name: string\n state: any // TODO: type correctly\n}\n\nconst StateDebug = (props: Props) => {\n const {name, state} = props\n\n if (!DEBUG_MODE) {\n return null\n }\n\n return (\n <Card\n scheme=\"dark\"\n style={{\n backgroundColor: 'rgba(0, 0, 255, 0.9)',\n borderRadius: '3px',\n fontSize: 1,\n fontWeight: 500,\n lineHeight: 'body',\n right: 0,\n opacity: 0.75,\n pointerEvents: 'none',\n position: 'absolute',\n textAlign: 'left',\n top: 0,\n zIndex: 9000,\n }}\n >\n <Box padding={2}>\n <Stack space={2}>\n <Text size={0}>Name: {name}</Text>\n <Text size={0}>state.value: {JSON.stringify(state.value)}</Text>\n </Stack>\n </Box>\n </Card>\n )\n}\n\nexport default StateDebug\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n message: string\n results: Sanity.DeploymentTarget[] // TODO: type correctly\n}\n\ntype Event =\n | {type: 'CLOSE'}\n | {type: 'CREATE'; deploymentTarget: Sanity.DeploymentTarget}\n | {type: 'DELETE'; id: string}\n | {type: 'FETCH'}\n | {type: 'REJECT'; message: string}\n | {type: 'RESOLVE'; results: any[]}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n failed: {}\n pending: {}\n ready: {\n states: {\n unknown: {}\n withData: {}\n withoutData: {}\n }\n }\n }\n}\n\nconst sortByTargetName = (items: Sanity.DeploymentTarget[]) => {\n return items.sort((a, b) => {\n if (a.name > b.name) {\n return 1\n }\n\n if (a.name < b.name) {\n return -1\n }\n\n return 0\n })\n}\n\nconst deploymentTargetListMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n message: '',\n results: [],\n },\n initial: 'pending',\n states: {\n pending: {\n invoke: {\n src: 'fetchDataService',\n onDone: {actions: ['setResults'], target: 'ready'},\n onError: {actions: ['setMessage'], target: 'failed'},\n },\n },\n ready: {\n initial: 'unknown',\n on: {\n CREATE: {actions: ['targetCreate']},\n DELETE: {actions: ['targetDelete']},\n UPDATE: {actions: ['targetUpdate']},\n },\n states: {\n unknown: {\n always: [\n {cond: 'hasData', target: 'withData'},\n {cond: 'hasNoData', target: 'withoutData'},\n ],\n },\n withData: {\n always: [{cond: 'hasNoData', target: 'withoutData'}],\n },\n withoutData: {\n always: [{cond: 'hasData', target: 'withData'}],\n },\n },\n },\n failed: {\n type: 'final',\n },\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n setResults: assign((_context, event: any) => ({\n results: event.data,\n })),\n targetCreate: assign((context, event: any) => ({\n results: sortByTargetName([...context.results, event.deploymentTarget]),\n })),\n targetDelete: assign((context, event: any) => ({\n results: context.results.filter((target) => target._id !== event.id),\n })),\n targetUpdate: assign((context, event: any) => {\n const {deploymentTarget} = event\n const index = context.results.findIndex((target) => target._id === deploymentTarget._id)\n const updatedResults = Object.assign([], context.results, {\n [index]: event.deploymentTarget,\n })\n\n return {\n results: sortByTargetName(updatedResults),\n }\n }),\n },\n guards: {\n hasData: (context) => {\n return context?.results?.length > 0\n },\n hasNoData: (context) => {\n return context?.results?.length === 0\n },\n },\n }\n )\n\nexport default deploymentTargetListMachine\n","import fetch from 'unfetch'\nimport {Sanity} from '../types'\n\nconst fetcher =\n (deploymentTarget: Sanity.DeploymentTarget) =>\n async (url: string, extraParams?: URLSearchParams) => {\n const params = new URLSearchParams()\n params.set('projectId', deploymentTarget.projectId)\n if (deploymentTarget.teamId) {\n params.set('teamId', deploymentTarget.teamId)\n }\n\n if (extraParams) {\n for (const [k, v] of extraParams.entries()) {\n params.append(k, v)\n }\n }\n\n const response = await fetch(`${url}?${params.toString()}`, {\n headers: {\n Authorization: `Bearer ${deploymentTarget.token}`,\n },\n })\n\n // Manually throw on non-OK responses for react-query\n // https://react-query.tanstack.com/guides/query-functions#usage-with-fetch-and-others-clients-that-do-not-throw-by-default\n if (!response.ok) {\n throw new Error('Response not OK')\n }\n\n try {\n return response.json()\n } catch (err) {\n throw new Error(err as string)\n }\n }\n\nexport default fetcher\n","import hash from 'object-hash'\nimport {useQuery} from '@tanstack/react-query'\n\nimport fetcher from '../utils/fetcher'\nimport {API_ENDPOINT_ALIASES, API_ENDPOINT_DEPLOYMENTS} from '../constants'\nimport {Sanity, Vercel} from '../types'\n\ntype Options = {\n enabled?: boolean\n}\n\nconst useDeployments = (deploymentTarget: Sanity.DeploymentTarget, options?: Options) => {\n const fetchUrl = fetcher(deploymentTarget)\n\n // Fetch deployments\n const deployParams = new URLSearchParams()\n deployParams.set('limit', String(deploymentTarget?.deployLimit))\n\n const {\n data: deploymentsData,\n isFetching: deploymentsIsFetching,\n isSuccess: deploymentsIsSuccess,\n error: deploymentsError,\n refetch,\n } = useQuery<{deployments: Vercel.Deployment[]}, Error>({\n queryKey: [hash(deploymentTarget)],\n queryFn: () => fetchUrl(API_ENDPOINT_DEPLOYMENTS, deployParams),\n enabled: options?.enabled ?? true,\n refetchInterval: 20000, // ms\n refetchIntervalInBackground: false,\n refetchOnMount: true,\n refetchOnReconnect: 'always',\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n // Fetch aliases (only if deployments have been retrieved)\n const aliasParams = new URLSearchParams()\n aliasParams.set('limit', '20')\n\n const {\n data: aliasesData,\n isFetching: aliasesIsFetching,\n isSuccess: aliasesIsSuccess,\n error: aliasesError,\n } = useQuery<\n {\n aliases: Vercel.Alias[]\n pagination: {\n count: number\n next?: number\n prev?: number\n }\n },\n Error\n >({\n queryKey: [hash(deploymentTarget), 'aliases'],\n queryFn: () => fetchUrl(API_ENDPOINT_ALIASES, aliasParams),\n enabled: !!deploymentsData,\n refetchOnMount: false,\n refetchOnReconnect: false,\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n const aliases = aliasesData?.aliases as Vercel.Alias[]\n\n let deploymentsWithAlias: Vercel.DeploymentWithAlias[] | undefined\n\n if (aliases) {\n deploymentsWithAlias = deploymentsData?.deployments?.map((val: Vercel.DeploymentWithAlias) => {\n const alias = aliases.find((a) => a.deploymentId === val.uid)\n return {\n ...val,\n alias: alias?.alias,\n }\n })\n }\n\n return {\n deployments: deploymentsWithAlias,\n error: aliasesError || deploymentsError,\n isFetching: aliasesIsFetching || deploymentsIsFetching,\n isSuccess: aliasesIsSuccess && deploymentsIsSuccess,\n refetch,\n }\n}\n\nexport default useDeployments\n","import {Machine} from 'xstate'\n\ntype Context = {}\n\ntype Event = {type: 'ERROR'} | {type: 'REFRESH'} | {type: 'REFRESHED'} | {type: 'RETRY'}\n\ntype Schema = {\n states: {\n idle: {}\n refreshing: {}\n refreshed: {}\n error: {}\n }\n}\n\nconst refreshMachine = Machine<Context, Schema, Event>({\n initial: 'idle',\n states: {\n idle: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n refreshing: {\n on: {\n ERROR: 'error',\n REFRESHED: 'refreshed',\n },\n },\n refreshed: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n error: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n },\n})\n\nexport default refreshMachine\n","import {useTheme} from '@sanity/ui'\n\nexport function useCardColor() {\n return useTheme().sanity.color.card.enabled\n}\n","import {Box, Label} from '@sanity/ui'\nimport React, {ReactNode} from 'react'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n children: ReactNode\n colSpan?: number\n header?: boolean\n variant?: 'age' | 'branch' | 'creator' | 'state'\n}\n\nconst TableCell = (props: Props) => {\n const {children, colSpan, header, variant} = props\n\n let display: Sanity.BoxDisplay | Sanity.BoxDisplay[] = 'table-cell'\n let cellWidth: string = 'auto'\n\n switch (variant) {\n case 'age':\n cellWidth = '50px'\n break\n case 'branch':\n cellWidth = '300px'\n display = ['none', 'none', 'none', 'table-cell']\n break\n case 'creator':\n cellWidth = '80px'\n break\n case 'state':\n cellWidth = '110px'\n display = ['none', 'none', 'none', 'none', 'table-cell']\n break\n default:\n break\n }\n\n const {border} = useCardColor()\n\n if (header) {\n return (\n <Box\n as=\"th\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={2}\n style={{\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n <Label size={0}>{children}</Label>\n </Box>\n )\n }\n return (\n <Box\n as=\"td\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={[2, 2, 3]}\n style={{\n borderTop: `1px solid ${border}`,\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n {children}\n </Box>\n )\n}\n\nexport default TableCell\n","import {Box} from '@sanity/ui'\nimport React from 'react'\n\nimport {VERCEL_STATUS_COLORS} from '../../constants'\nimport {Vercel} from '../../types'\n\ntype Props = {\n state: Vercel.DeploymentState\n}\n\nconst StatusDot = ({state}: Props) => (\n <Box\n style={{\n backgroundColor: `${VERCEL_STATUS_COLORS[state]}`,\n borderRadius: '20px',\n height: '9px',\n width: '9px',\n }}\n />\n)\n\nexport default StatusDot\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport ReactTimeAgo from 'react-time-ago'\n\nimport TableCell from '../TableCell'\nimport StatusDot from '../StatusDot'\nimport {LinkIcon} from '@sanity/icons'\nimport {Vercel} from '../../types'\n\ntype Props = {\n deployment: Vercel.DeploymentWithAlias\n}\n\nconst Deployment = (props: Props) => {\n const {deployment} = props\n\n const date = useRef(new Date(deployment.created))\n\n const commitMessage = deployment?.meta?.githubCommitMessage\n const commitRef = deployment?.meta?.githubCommitRef\n\n const targetUrl = deployment.alias ?? deployment.url\n\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <Flex align=\"center\">\n <Box\n display={['block', 'block', 'block', 'block', 'none']}\n marginRight={3}\n style={{flexShrink: 0}}\n >\n <StatusDot state={deployment.state} />\n </Box>\n\n {targetUrl ? (\n <>\n {/* Alias icon */}\n {deployment.alias && <LinkIcon />}\n\n <Box marginLeft={deployment.alias ? 1 : 0}>\n <Text\n muted={!(deployment.state === 'READY')}\n size={1}\n style={{\n textDecoration:\n deployment.state === 'CANCELED' || deployment.state === 'ERROR'\n ? 'line-through'\n : 'normal',\n }}\n textOverflow=\"ellipsis\"\n >\n {deployment.state === 'READY' ? (\n <a href={`https://${targetUrl}`} rel=\"noopener noreferrer\" target=\"_blank\">\n {targetUrl}\n </a>\n ) : (\n targetUrl\n )}\n </Text>\n </Box>\n </>\n ) : (\n <Text size={1}>Uploading...</Text>\n )}\n </Flex>\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <Flex align=\"center\">\n <StatusDot state={deployment.state} />\n <Box marginLeft={2}>\n <Text size={1}>\n {deployment.state\n .trim()\n .toLowerCase()\n .replace(/^[a-z]/i, (t) => t.toUpperCase())}\n </Text>\n </Box>\n </Flex>\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <Stack space={2}>\n <Text size={1} textOverflow=\"ellipsis\">\n {commitRef}\n </Text>\n {commitMessage && (\n <Text muted size={1} textOverflow=\"ellipsis\">\n {commitMessage}\n </Text>\n )}\n </Stack>\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <Flex align=\"center\">\n <Text size={1}>\n <ReactTimeAgo date={date.current} locale=\"en-US\" timeStyle=\"mini\" />\n </Text>\n </Flex>\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex align=\"center\" justify=\"center\">\n <img\n draggable={false}\n src={`https://vercel.com/api/www/avatar/${deployment?.creator?.uid}?&s=48`}\n style={{\n borderRadius: '20px',\n height: '20px',\n width: '20px',\n }}\n />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default Deployment\n","import fetch from 'unfetch'\nimport {assign, Machine} from 'xstate'\nimport {Vercel} from '../types'\n\ntype Context = {\n disabled: boolean\n feedback?: string\n label?: string\n error?: string\n}\n\ntype Event = {type: 'DEPLOY'}\n\ntype Schema = {\n states: {\n idle: {}\n deploying: {}\n success: {}\n error: {}\n }\n}\n\nconst deployMachine = (deployHook: string) =>\n Machine<Context, Schema, Event>(\n // Machine\n {\n id: 'deploy',\n initial: 'idle',\n context: {\n disabled: false,\n feedback: undefined,\n label: undefined,\n error: undefined,\n },\n states: {\n idle: {\n entry: assign({\n feedback: () => undefined,\n label: () => 'Deploy',\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n deploying: {\n entry: assign({\n disabled: () => true,\n label: () => 'Deploying',\n }),\n exit: assign({\n disabled: () => false,\n label: () => 'Deploy',\n }),\n invoke: {\n onDone: {\n target: 'success',\n },\n onError: {\n target: 'error',\n actions: assign({\n error: (_context, event) => {\n return event.data\n },\n }),\n },\n src: 'deploy',\n },\n },\n success: {\n entry: [assign({feedback: () => 'Succesfully started!'})],\n exit: assign({\n feedback: () => undefined,\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n error: {\n on: {\n DEPLOY: 'deploying',\n },\n },\n },\n },\n // Config\n {\n services: {\n deploy: (): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n try {\n if (!deployHook) {\n return reject(new Error('No deployHook URL defined'))\n }\n\n const res = await fetch(deployHook, {method: 'POST'})\n const data = await res.json()\n\n if (!res.ok) {\n const errorMessage = (data?.error as Vercel.Error).message || res.statusText\n return reject(errorMessage)\n }\n\n return resolve()\n } catch (err) {\n console.error('Unable to deploy with error:', err)\n return reject(new Error('Please check the developer console for more information'))\n }\n })\n },\n },\n }\n )\n\nexport default deployMachine\n","import {UploadIcon} from '@sanity/icons'\nimport {Box, Button, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useMemo} from 'react'\n\nimport {WIDGET_NAME} from '../../constants'\nimport deployMachine from '../../machines/deploy'\nimport StateDebug from '../StateDebug'\n\ntype Props = {\n deployHook: string\n onDeploySuccess?: () => void\n targetName: string\n}\n\nconst DeployButton = (props: Props) => {\n const {deployHook, onDeploySuccess, targetName} = props\n\n const machine = useMemo(() => deployMachine(deployHook), [deployHook])\n\n const [deployState, deployStateTransition, deployStateInterpreter] = useMachine(machine)\n\n const toast = useToast()\n\n const isError = deployState.matches('error')\n const isSuccess = deployState.matches('success')\n\n // Callbacks\n const handleDeploy = () => {\n deployStateTransition({type: 'DEPLOY'})\n }\n\n // Effects\n useEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to queue deploy for ${targetName}: ${deployState.context.error}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n\n if (isSuccess) {\n toast.push({\n closable: true,\n description: `Deploy queued for ${targetName}`,\n duration: 8000,\n status: 'success',\n title: WIDGET_NAME,\n })\n }\n }, [isError, isSuccess, toast, targetName, deployState.context.error])\n\n useEffect(() => {\n deployStateInterpreter.onTransition((state) => {\n if (state.value === 'success') {\n if (onDeploySuccess) {\n onDeploySuccess()\n }\n }\n })\n }, [deployStateInterpreter, onDeploySuccess])\n\n return (\n <Box padding={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Deploy\" state={deployState} />\n\n <Button\n disabled={deployState.context.disabled}\n fontSize={1}\n icon={UploadIcon}\n mode=\"ghost\"\n onClick={handleDeploy}\n padding={3}\n text={`${deployState.context.label} ${targetName}`}\n tone=\"default\"\n />\n </Box>\n )\n}\n\nexport default DeployButton\n","import {Box} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\nconst PlaceholderAvatar = () => {\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '20px',\n height: '20px',\n userSelect: 'none',\n width: '20px',\n }}\n />\n )\n}\n\nexport default PlaceholderAvatar\n","import {Box, Stack, Text} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n rows: number\n}\n\nconst PlaceholderText = (props: Props) => {\n const {rows} = props\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '3px',\n userSelect: 'none',\n width: '100%',\n }}\n >\n <Stack space={2}>\n {new Array(rows).fill(undefined).map((_, index) => (\n <Text key={index} size={1}>\n &nbsp;\n </Text>\n ))}\n </Stack>\n </Box>\n )\n}\n\nexport default PlaceholderText\n","import {Flex} from '@sanity/ui'\nimport React from 'react'\n\nimport PlaceholderAvatar from '../PlaceholderAvatar'\nimport PlaceholderText from '../PlaceholderText'\nimport TableCell from '../TableCell'\n\nconst DeploymentPlaceholder = () => {\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <PlaceholderText rows={2} />\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex justify=\"center\">\n <PlaceholderAvatar />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default DeploymentPlaceholder\n","import {Box, Text, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useRef} from 'react'\nimport useDeepCompareEffect from 'use-deep-compare-effect'\n\nimport {WIDGET_NAME} from '../../constants'\nimport useDeployments from '../../hooks/useDeployments'\nimport refreshMachine from '../../machines/refresh'\nimport Deployment from '../Deployment'\nimport DeployButton from '../DeployButton'\nimport DeploymentPlaceholder from '../DeploymentPlaceholder'\nimport StateDebug from '../StateDebug'\nimport TableCell from '../TableCell'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n deploymentTarget: Sanity.DeploymentTarget\n}\n\nconst Deployments = (props: Props) => {\n const {deploymentTarget} = props\n\n // Refs\n const refTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // XState\n const [refreshState, refreshStateTransition] = useMachine(refreshMachine)\n\n // Fetch deployments - disable hook / auto-refetching on error state\n const {deployments, error, isFetching, isSuccess, refetch} = useDeployments(deploymentTarget, {\n enabled: !refreshState.matches('error'),\n })\n\n const toast = useToast()\n const isError = refreshState.matches('error')\n\n const handleDeploySuccess = () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n refTimeout.current = setTimeout(() => {\n refetch({\n cancelRefetch: true,\n throwOnError: true,\n })\n }, 4000)\n }\n\n useEffect(() => {\n return () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (error) {\n refreshStateTransition({type: 'ERROR'})\n }\n\n if (isFetching) {\n refreshStateTransition({type: 'REFRESH'})\n }\n\n if (!isFetching && isSuccess) {\n refreshStateTransition({type: 'REFRESHED'})\n }\n }, [error, isFetching, isSuccess, refreshStateTransition])\n\n useDeepCompareEffect(() => {\n if (!refreshState.matches('refreshing')) {\n refreshStateTransition({type: 'REFRESH'})\n }\n }, [deploymentTarget])\n\n useDeepCompareEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to fetch deployments for ${deploymentTarget.name}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n }, [deploymentTarget, isError])\n\n const hasFetched = typeof deployments !== 'undefined'\n const hasDeployments = deployments && deployments.length > 0\n\n const {border} = useCardColor()\n return (\n <Box marginTop={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Refresh\" state={refreshState} />\n\n {!refreshState.matches('error') && (\n <>\n <Box\n as=\"table\"\n style={{\n borderBottom: `1px solid ${border}`,\n borderCollapse: 'collapse',\n display: 'table',\n tableLayout: 'fixed',\n width: '100%',\n }}\n >\n <Box as=\"thead\" style={{display: 'table-header-group'}}>\n <tr>\n {/* Deployment */}\n <TableCell header>Deployment</TableCell>\n\n {/* State */}\n <TableCell header variant=\"state\">\n State\n </TableCell>\n\n {/* Branch */}\n <TableCell header variant=\"branch\">\n Branch\n </TableCell>\n\n {/* Age */}\n <TableCell header variant=\"age\">\n Age\n </TableCell>\n\n {/* Creator */}\n <TableCell header variant=\"age\">\n Creator\n </TableCell>\n </tr>\n </Box>\n\n <Box as=\"tbody\" style={{display: 'table-header-group'}}>\n {/* Placeholders */}\n {!deployments &&\n new Array(deploymentTarget?.deployLimit)\n .fill(undefined)\n .map((_, index) => <DeploymentPlaceholder key={index} />)}\n {/* Deployments */}\n {hasDeployments &&\n deployments?.map((deployment) => (\n <Deployment deployment={deployment} key={deployment.uid} />\n ))}\n </Box>\n </Box>\n\n {/* No results */}\n {hasFetched && !hasDeployments && (\n <Box padding={3} style={{width: '100%'}}>\n <Text muted size={1}>\n No deployments found. Don't forget to specify a valid team ID if your project\n belongs to a team.\n </Text>\n </Box>\n )}\n </>\n )}\n\n {/* Error message */}\n {refreshState.matches('error') && (\n <Box padding={3}>\n <Text muted size={1}>\n Unable to fetch recent deployments. Please check your network and deployment settings.\n </Text>\n </Box>\n )}\n\n {/* Deploy button */}\n {!refreshState.matches('error') && deploymentTarget.deployHook && (\n <Box>\n <DeployButton\n deployHook={deploymentTarget.deployHook}\n onDeploySuccess={handleDeploySuccess}\n targetName={deploymentTarget.name}\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport default Deployments\n","import {EditIcon} from '@sanity/icons'\nimport {Box, Button, Flex, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n\nimport Deployments from '../Deployments'\nimport {Sanity} from '../../types'\n\ntype Props = {\n item: Sanity.DeploymentTarget\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTarget: FC<Props> = (props: Props) => {\n const {item, onDialogEdit} = props\n\n const deploymentTarget = {\n deployHook: item.deployHook,\n deployLimit: item.deployLimit,\n name: item.name,\n projectId: item.projectId,\n teamId: item.teamId,\n token: item.token,\n } as Sanity.DeploymentTarget\n\n return (\n <Box style={{position: 'relative'}}>\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" marginTop={2} paddingX={3}>\n <Text size={2}>{item.name}</Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Edit deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={EditIcon} mode=\"bleed\" onClick={() => onDialogEdit(item)} />\n </Tooltip>\n </Flex>\n\n {/* Content */}\n <Deployments deploymentTarget={deploymentTarget} />\n </Box>\n )\n}\n\nexport default DeploymentTarget\n","import React from 'react'\nimport {Stack} from '@sanity/ui'\n\nimport DeploymentTarget from '../DeploymentTarget'\nimport {Sanity} from '../../types'\n\ntype Props = {\n items: Sanity.DeploymentTarget[]\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTargets = (props: Props) => {\n const {items, onDialogEdit} = props\n\n return (\n <Stack space={5}>\n {items?.map((item) => (\n <DeploymentTarget item={item} key={item._id} onDialogEdit={onDialogEdit} />\n ))}\n </Stack>\n )\n}\n\nexport default DeploymentTargets\n","import {assign, Machine} from 'xstate'\n\ntype Context = {\n formData?: Record<string, any>\n message: string\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'DELETE'}\n | {type: 'REJECT'}\n | {type: 'RESOLVE'}\n | {type: 'SUBMIT'}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n idle: {}\n creating: {}\n updating: {}\n deleting: {}\n success: {}\n error: {}\n }\n}\n\nconst formMachine = Machine<Context, Schema, Event>(\n {\n context: {\n formData: {},\n message: '',\n },\n initial: 'idle',\n states: {\n idle: {\n on: {\n CREATE: {\n actions: ['createDocument'],\n target: 'creating',\n },\n DELETE: {\n actions: ['deleteDocument'],\n target: 'deleting',\n },\n UPDATE: {\n actions: ['updateDocument'],\n target: 'updating',\n },\n },\n },\n creating: {\n invoke: {\n src: 'createDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n updating: {\n invoke: {\n src: 'updateDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n deleting: {\n invoke: {\n src: 'deleteDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n success: {\n invoke: {\n src: 'formSubmittedService',\n },\n },\n error: {},\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n createDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n deleteDocument: assign(() => ({\n // id: event.id,\n })),\n updateDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n },\n }\n)\n\nexport default formMachine\n","// Recursively sanitize form data:\n// - convert empty strings, undefined values and empty arrays to null (to correctly unset / delete fields)\n// - trim whitespace on string fleids\n\ntype FormData = Record<string, any>\n\nconst sanitizeFormData = (formData: FormData): FormData => {\n return Object.keys(formData).reduce((acc: FormData, key) => {\n const val = formData[key]\n\n // TODO: refactor\n if (typeof val === 'object' && val !== null && val.constructor !== Array) {\n acc[key] = sanitizeFormData(val)\n } else if (val === '' || typeof val === 'undefined' || val?.length === 0) {\n acc[key] = null\n } else if (typeof val === 'string' && val) {\n acc[key] = formData[key].trim()\n } else {\n acc[key] = formData[key]\n }\n\n return acc\n }, {})\n}\n\nexport default sanitizeFormData\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Inline, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n// @ts-expect-error - fix typings later\nimport {FieldError} from 'react-hook-form'\nimport {styled} from 'styled-components'\n\ntype Props = {\n description?: string\n error?: FieldError\n label: string\n name: string\n}\n\nconst StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({theme}) => {\n return {\n color: theme.sanity.color.spot.red,\n }\n})\n\nconst FormFieldInputLabel: FC<Props> = (props: Props) => {\n const {description, error, label, name} = props\n\n return (\n <Box marginBottom={3}>\n {/* Label */}\n <Inline space={2}>\n <Text as=\"label\" htmlFor={name} size={1} weight=\"semibold\">\n {label}\n </Text>\n\n {/* Error icon + tooltip */}\n {error && (\n <Text size={1}>\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n <StyledErrorOutlineIcon style={{marginRight: '0.1em'}} />\n {error.message}\n </Text>\n </Box>\n }\n fallbackPlacements={['top', 'left']}\n placement=\"right\"\n portal\n >\n <StyledErrorOutlineIcon />\n </Tooltip>\n </Text>\n )}\n </Inline>\n\n {/* Description */}\n {description && (\n <Box marginY={3}>\n <Text htmlFor={name} muted size={1}>\n {description}\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n\nexport default FormFieldInputLabel\n","import {Box, TextInput} from '@sanity/ui'\nimport React, {forwardRef} from 'react'\n// @ts-expect-error - fix typings later\nimport {FieldError} from 'react-hook-form'\n\nimport FormFieldInputLabel from '../FormFieldInputLabel'\n\ntype Props = {\n description?: string\n disabled?: boolean\n error?: FieldError\n label: string\n name: string\n placeholder?: string\n value?: string\n}\n\ntype Ref = HTMLInputElement\n\nconst FormFieldInputText = forwardRef<Ref, Props>((props: Props, ref) => {\n const {description, disabled, error, label, name, placeholder, value} = props\n\n return (\n <Box>\n {/* Label */}\n <FormFieldInputLabel description={description} error={error} label={label} name={name} />\n {/* Input */}\n <TextInput\n autoComplete=\"off\"\n autoFocus\n defaultValue={value}\n disabled={disabled}\n id={name}\n name={name}\n placeholder={placeholder}\n ref={ref}\n />\n </Box>\n )\n})\n\nexport default FormFieldInputText\n","import type {SanityClient} from '@sanity/client'\nimport {API_VERSION} from './constants'\nimport {useClient} from 'sanity'\n\nexport function useSanityClient(): SanityClient {\n return useClient({apiVersion: API_VERSION})\n}\n","// @ts-expect-error - fix typings later\nimport {yupResolver} from '@hookform/resolvers/yup'\nimport {Box, Button, Dialog, Flex, Stack} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport {useMachine} from '@xstate/react'\nimport React, {FC} from 'react'\n// @ts-expect-error - fix typings later\nimport {useForm} from 'react-hook-form'\nimport * as yup from 'yup'\n\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_DIALOG} from '../../constants'\nimport formMachine from '../../machines/form'\nimport sanitizeFormData from '../../utils/sanitizeFormData'\nimport FormFieldInputText from '../FormFieldInputText'\nimport {Sanity} from '../../types'\nimport {useSanityClient} from '../../client'\n\ntype Props = {\n deploymentTarget?: Sanity.DeploymentTarget\n onClose: () => void\n onCreate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n onDelete?: (id: string) => void\n onUpdate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\ntype FormData = yup.InferType<typeof formSchema>\n\nconst formSchema = yup.object().shape({\n deployHook: yup.string().url('Deploy hook must be a valid URL'),\n deployLimit: yup\n .number()\n .positive()\n .integer()\n .min(1, 'Deploy limit must no less than 1')\n .max(15, 'Deploy limit must no higher than 15')\n .typeError('Deploy limit must be a number')\n .required('Deploy limit must be a positive integer between 1 and 15'),\n name: yup.string().required('Name cannot be empty'),\n projectId: yup.string().required('Vercel Project ID cannot be empty'),\n teamId: yup.string(),\n token: yup.string().required('Vercel Account Token cannot be empty'),\n})\n\nconst DialogForm: FC<Props> = (props: Props) => {\n const {deploymentTarget, onClose, onCreate, onDelete, onUpdate} = props\n const client = useSanityClient()\n\n // xstate\n const [formState, formStateTransition] = useMachine(formMachine, {\n services: {\n formSubmittedService: async () => {\n onClose()\n },\n // TODO: refactor\n createDocumentService: async (_context, event: any) => {\n let document\n try {\n document = await client.create({\n _id: `vercel.${uuid()}`,\n _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,\n ...event.formData,\n })\n if (onCreate) {\n onCreate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n },\n // TODO: refactor\n deleteDocumentService: async () => {\n if (deploymentTarget) {\n try {\n await client.delete(deploymentTarget._id)\n if (onDelete) {\n onDelete(deploymentTarget._id)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n // TODO: refactor\n updateDocumentService: async (_context, event: any) => {\n let document\n if (deploymentTarget) {\n try {\n document = await client.patch(deploymentTarget._id).set(event.formData).commit()\n if (onUpdate) {\n onUpdate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n },\n })\n\n const formUpdating =\n formState.matches('creating') || formState.matches('deleting') || formState.matches('updating')\n\n // react-hook-form\n const {\n // Read the formState before render to subscribe the form state through Proxy\n formState: {errors, isDirty, isValid},\n handleSubmit,\n register,\n } = useForm({\n defaultValues: {\n deployHook: deploymentTarget?.deployHook || '',\n deployLimit: deploymentTarget?.deployLimit || 5,\n name: deploymentTarget?.name,\n projectId: deploymentTarget?.projectId,\n teamId: deploymentTarget?.teamId || '',\n token: deploymentTarget?.token,\n },\n mode: 'onChange',\n resolver: yupResolver(formSchema),\n })\n\n // Callbacks\n // - submit react-hook-form\n const onSubmit = async (formData: FormData) => {\n const sanitizedFormData = sanitizeFormData(formData)\n await formStateTransition(deploymentTarget ? 'UPDATE' : 'CREATE', {\n formData: sanitizedFormData,\n })\n }\n\n const handleDelete = () => {\n formStateTransition('DELETE', {id: deploymentTarget?._id})\n }\n\n const Footer = () => (\n <Box padding={3}>\n <Flex justify={deploymentTarget ? 'space-between' : 'flex-end'}>\n {/* Delete button */}\n {deploymentTarget && (\n <Button\n disabled={formUpdating}\n fontSize={1}\n mode=\"bleed\"\n onClick={handleDelete}\n text=\"Delete\"\n tone=\"critical\"\n />\n )}\n\n {/* Submit button */}\n <Button\n disabled={formUpdating || !isDirty || !isValid}\n fontSize={1}\n onClick={handleSubmit(onSubmit)}\n text={deploymentTarget ? 'Update and close' : 'Create'}\n tone=\"primary\"\n />\n </Flex>\n </Box>\n )\n\n return (\n <Dialog\n footer={<Footer />}\n header={`${deploymentTarget ? 'Edit' : 'Create'} deployment target`}\n id=\"create\"\n onClose={onClose}\n width={1}\n zOffset={Z_INDEX_DIALOG}\n >\n {/* We reverse direction to ensure that inline links dont autofocus before other form elements */}\n <Box as=\"form\" padding={4} onSubmit={handleSubmit(onSubmit)}>\n {/* Hidden button to enable enter key submissions */}\n <button style={{display: 'none'}} tabIndex={-1} type=\"submit\" />\n\n {/* Form fields */}\n <Stack space={5}>\n {/* Title */}\n <FormFieldInputText\n disabled={formUpdating}\n description=\"Name displayed in this plugin (e.g. production, staging)\"\n error={errors?.name}\n label=\"Name\"\n name=\"name\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.token}\n label=\"Vercel Account Token\"\n name=\"token\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.projectId}\n label=\"Vercel Project ID\"\n name=\"projectId\"\n ref={register}\n />\n\n <FormFieldInputText\n description=\"Required only if your project is owned by a team account\"\n disabled={formUpdating}\n error={errors?.teamId}\n label=\"Vercel Team ID (optional)\"\n name=\"teamId\"\n ref={register}\n />\n\n <FormFieldInputText\n description=\"Enter a valid deploy hook URL to enable manual deploys\"\n disabled={formUpdating}\n error={errors?.deployHook}\n label=\"Vercel Deploy Hook (optional)\"\n name=\"deployHook\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.deployLimit}\n label=\"Number of deploys to display\"\n name=\"deployLimit\"\n ref={register({valueAsNumber: true})}\n />\n </Stack>\n </Box>\n </Dialog>\n )\n}\n\nexport default DialogForm\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n editDeploymentTarget?: Sanity.DeploymentTarget\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'CLOSE'}\n | {type: 'EDIT'; deploymentTarget: Sanity.DeploymentTarget}\n\ntype Schema = {\n states: {\n idle: {}\n edit: {}\n create: {}\n }\n}\n\nconst dialogMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n editDeploymentTarget: undefined,\n },\n initial: 'idle',\n states: {\n idle: {\n entry: assign({\n editDeploymentTarget: () => undefined,\n }),\n on: {\n CREATE: 'create',\n EDIT: {\n actions: ['setEditDeploymentTarget'],\n target: 'edit',\n },\n },\n },\n edit: {\n on: {\n CLOSE: 'idle',\n },\n },\n create: {\n on: {\n CLOSE: 'idle',\n },\n },\n },\n },\n {\n actions: {\n setEditDeploymentTarget: assign((_context, event: any) => ({\n editDeploymentTarget: event.deploymentTarget,\n })),\n },\n }\n )\n\nexport default dialogMachine\n","import {AddIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, ToastProvider, Tooltip} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React from 'react'\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query'\n\nimport StateDebug from './components/StateDebug'\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_TOAST_PROVIDER} from './constants'\nimport deploymentTargetListMachine from './machines/deploymentTargetList'\nimport DeploymentTargets from './components/DeploymentTargets'\nimport DialogForm from './components/DialogForm'\nimport dialogMachine from './machines/dialog'\nimport {Sanity} from './types'\nimport {useSanityClient} from './client'\n\nconst Widget = () => {\n const client = useSanityClient()\n // xstate\n const [deploymentTargetListState, deploymentTargetListStateTransition] = useMachine(\n deploymentTargetListMachine,\n {\n services: {\n fetchDataService: () => {\n return client\n .fetch(`*[_type == \"${DEPLOYMENT_TARGET_DOCUMENT_TYPE}\"] | order(name asc)`)\n .then((result: any) => result)\n },\n },\n }\n )\n const [dialogState, dialogStateTransition] = useMachine(dialogMachine)\n\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n gcTime: 0,\n staleTime: 0,\n },\n },\n })\n\n // Callbacks\n const handleDialogClose = () => {\n dialogStateTransition('CLOSE')\n }\n const handleDialogShowCreate = () => {\n dialogStateTransition('CREATE')\n }\n const handleDialogShowEdit = (deploymentTarget: Sanity.DeploymentTarget) => {\n dialogStateTransition('EDIT', {deploymentTarget})\n }\n const handleTargetCreate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('CREATE', {deploymentTarget})\n }\n const handleTargetDelete = (id: string) => {\n deploymentTargetListStateTransition('DELETE', {id})\n }\n const handleTargetUpdate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('UPDATE', {deploymentTarget})\n }\n\n return (\n <ToastProvider zOffset={Z_INDEX_TOAST_PROVIDER}>\n <QueryClientProvider client={queryClient}>\n <Card radius={2} style={{overflow: 'hidden '}}>\n {/* xstate debug */}\n <StateDebug name=\"List\" state={deploymentTargetListState} />\n\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" paddingX={3} paddingY={2}>\n <Text size={5} weight=\"semibold\">\n Vercel deployments\n </Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Create new deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={AddIcon} onClick={handleDialogShowCreate} mode=\"bleed\" />\n </Tooltip>\n </Flex>\n\n <Box>\n {deploymentTargetListState.matches('pending') && (\n <Box paddingX={3} paddingY={4}>\n <Text>Loading...</Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withoutData') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n No deployment targets found.{' '}\n <a onClick={handleDialogShowCreate} style={{cursor: 'pointer'}}>\n Create a new target?\n </a>\n </Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withData') && (\n <DeploymentTargets\n items={deploymentTargetListState.context.results}\n onDialogEdit={handleDialogShowEdit}\n />\n )}\n\n {deploymentTargetListState.matches('failed') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n Failed to retrieve deployment targets. Please check the developer console log for\n more information.\n </Text>\n </Box>\n )}\n </Box>\n </Card>\n\n {/* Dialogs */}\n {dialogState.matches('create') && (\n <DialogForm onClose={handleDialogClose} onCreate={handleTargetCreate} />\n )}\n\n {dialogState.matches('edit') && (\n <DialogForm\n deploymentTarget={dialogState.context.editDeploymentTarget}\n onClose={handleDialogClose}\n onDelete={handleTargetDelete}\n onUpdate={handleTargetUpdate}\n />\n )}\n </QueryClientProvider>\n </ToastProvider>\n )\n}\n\nexport default Widget\n","import Widget from './app'\n\n// Initialize `javascript-time-ago` locale (required for react-time-ago)\nimport TimeAgo from 'javascript-time-ago'\nimport en from 'javascript-time-ago/locale/en'\nimport {DashboardWidget, type LayoutConfig} from '@sanity/dashboard'\n\nTimeAgo.addDefaultLocale(en)\n\nexport function vercelWidget(config: {layout?: LayoutConfig} = {}): DashboardWidget {\n return {\n name: 'vercel',\n component: Widget,\n layout: config.layout ?? {width: 'full'},\n }\n}\n"],"names":["Machine","assign","fetch","useQuery","hash","useTheme","jsx","Box","Label","useRef","jsxs","Flex","Fragment","LinkIcon","Text","Stack","ReactTimeAgo","useMemo","useMachine","useToast","useEffect","Button","UploadIcon","useDeepCompareEffect","Tooltip","EditIcon","styled","ErrorOutlineIcon","Inline","forwardRef","TextInput","useClient","yup","uuid","useForm","yupResolver","Dialog","QueryClient","ToastProvider","QueryClientProvider","Card","AddIcon","TimeAgo","en"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/constants.ts","../src/components/StateDebug/index.tsx","../src/machines/deploymentTargetList.ts","../src/utils/fetcher.ts","../src/hooks/useDeployments.ts","../src/machines/refresh.ts","../src/utils/useCardColor.ts","../src/components/TableCell/index.tsx","../src/components/StatusDot/index.tsx","../src/components/Deployment/index.tsx","../src/machines/deploy.ts","../src/components/DeployButton/index.tsx","../src/components/PlaceholderAvatar/index.tsx","../src/components/PlaceholderText/index.tsx","../src/components/DeploymentPlaceholder/index.tsx","../src/components/Deployments/index.tsx","../src/components/DeploymentTarget/index.tsx","../src/components/DeploymentTargets/index.tsx","../src/machines/form.ts","../src/utils/sanitizeFormData.ts","../src/components/FormFieldInputLabel/index.tsx","../src/components/FormFieldInputText/index.tsx","../src/client.ts","../src/components/DialogForm/index.tsx","../src/machines/dialog.ts","../src/app.tsx","../src/index.ts"],"sourcesContent":["// https://vercel.com/docs/platform/limits\nexport const API_ENDPOINT_DEPLOYMENTS = 'https://api.vercel.com/v5/now/deployments'\nexport const API_ENDPOINT_ALIASES = 'https://api.vercel.com/v3/now/aliases'\n\n// Sanity API version\nexport const API_VERSION = '1'\n\nexport const DEBUG_MODE = false\n\nexport const DEPLOYMENT_TARGET_DOCUMENT_TYPE = 'vercel.deploymentTarget'\n\nexport const VERCEL_STATUS_COLORS = {\n BUILDING: '#f5a623',\n CANCELED: '#ff0000',\n ERROR: '#ff0000',\n READY: '#50e3c2',\n QUEUED: '#333',\n}\n\n// Name displayed in toasts\nexport const WIDGET_NAME = 'Vercel (dashboard)'\n\n// NOTE: Manually set plugin z-index values to be higher than Sanity's header search field\n// (which is currently 500202). Also ensure toasts always sit above dialogs.\nexport const Z_INDEX_DIALOG = 600001\nexport const Z_INDEX_TOAST_PROVIDER = 600002\n","import {Box, Card, Stack, Text} from '@sanity/ui'\nimport React from 'react'\n\nimport {DEBUG_MODE} from '../../constants'\n\ntype Props = {\n name: string\n state: any // TODO: type correctly\n}\n\nconst StateDebug = (props: Props) => {\n const {name, state} = props\n\n if (!DEBUG_MODE) {\n return null\n }\n\n return (\n <Card\n scheme=\"dark\"\n style={{\n backgroundColor: 'rgba(0, 0, 255, 0.9)',\n borderRadius: '3px',\n fontSize: 1,\n fontWeight: 500,\n lineHeight: 'body',\n right: 0,\n opacity: 0.75,\n pointerEvents: 'none',\n position: 'absolute',\n textAlign: 'left',\n top: 0,\n zIndex: 9000,\n }}\n >\n <Box padding={2}>\n <Stack space={2}>\n <Text size={0}>Name: {name}</Text>\n <Text size={0}>state.value: {JSON.stringify(state.value)}</Text>\n </Stack>\n </Box>\n </Card>\n )\n}\n\nexport default StateDebug\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n message: string\n results: Sanity.DeploymentTarget[] // TODO: type correctly\n}\n\ntype Event =\n | {type: 'CLOSE'}\n | {type: 'CREATE'; deploymentTarget: Sanity.DeploymentTarget}\n | {type: 'DELETE'; id: string}\n | {type: 'FETCH'}\n | {type: 'REJECT'; message: string}\n | {type: 'RESOLVE'; results: any[]}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n failed: {}\n pending: {}\n ready: {\n states: {\n unknown: {}\n withData: {}\n withoutData: {}\n }\n }\n }\n}\n\nconst sortByTargetName = (items: Sanity.DeploymentTarget[]) => {\n return items.sort((a, b) => {\n if (a.name > b.name) {\n return 1\n }\n\n if (a.name < b.name) {\n return -1\n }\n\n return 0\n })\n}\n\nconst deploymentTargetListMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n message: '',\n results: [],\n },\n initial: 'pending',\n states: {\n pending: {\n invoke: {\n src: 'fetchDataService',\n onDone: {actions: ['setResults'], target: 'ready'},\n onError: {actions: ['setMessage'], target: 'failed'},\n },\n },\n ready: {\n initial: 'unknown',\n on: {\n CREATE: {actions: ['targetCreate']},\n DELETE: {actions: ['targetDelete']},\n UPDATE: {actions: ['targetUpdate']},\n },\n states: {\n unknown: {\n always: [\n {cond: 'hasData', target: 'withData'},\n {cond: 'hasNoData', target: 'withoutData'},\n ],\n },\n withData: {\n always: [{cond: 'hasNoData', target: 'withoutData'}],\n },\n withoutData: {\n always: [{cond: 'hasData', target: 'withData'}],\n },\n },\n },\n failed: {\n type: 'final',\n },\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n setResults: assign((_context, event: any) => ({\n results: event.data,\n })),\n targetCreate: assign((context, event: any) => ({\n results: sortByTargetName([...context.results, event.deploymentTarget]),\n })),\n targetDelete: assign((context, event: any) => ({\n results: context.results.filter((target) => target._id !== event.id),\n })),\n targetUpdate: assign((context, event: any) => {\n const {deploymentTarget} = event\n const index = context.results.findIndex((target) => target._id === deploymentTarget._id)\n const updatedResults = Object.assign([], context.results, {\n [index]: event.deploymentTarget,\n })\n\n return {\n results: sortByTargetName(updatedResults),\n }\n }),\n },\n guards: {\n hasData: (context) => {\n return context?.results?.length > 0\n },\n hasNoData: (context) => {\n return context?.results?.length === 0\n },\n },\n }\n )\n\nexport default deploymentTargetListMachine\n","import fetch from 'unfetch'\nimport {Sanity} from '../types'\n\nconst fetcher =\n (deploymentTarget: Sanity.DeploymentTarget) =>\n async (url: string, extraParams?: URLSearchParams) => {\n const params = new URLSearchParams()\n params.set('projectId', deploymentTarget.projectId)\n if (deploymentTarget.teamId) {\n params.set('teamId', deploymentTarget.teamId)\n }\n\n if (extraParams) {\n for (const [k, v] of extraParams.entries()) {\n params.append(k, v)\n }\n }\n\n const response = await fetch(`${url}?${params.toString()}`, {\n headers: {\n Authorization: `Bearer ${deploymentTarget.token}`,\n },\n })\n\n // Manually throw on non-OK responses for react-query\n // https://react-query.tanstack.com/guides/query-functions#usage-with-fetch-and-others-clients-that-do-not-throw-by-default\n if (!response.ok) {\n throw new Error('Response not OK')\n }\n\n try {\n return response.json()\n } catch (err) {\n throw new Error(err as string)\n }\n }\n\nexport default fetcher\n","import hash from 'object-hash'\nimport {useQuery} from '@tanstack/react-query'\n\nimport fetcher from '../utils/fetcher'\nimport {API_ENDPOINT_ALIASES, API_ENDPOINT_DEPLOYMENTS} from '../constants'\nimport {Sanity, Vercel} from '../types'\n\ntype Options = {\n enabled?: boolean\n}\n\nconst useDeployments = (deploymentTarget: Sanity.DeploymentTarget, options?: Options) => {\n const fetchUrl = fetcher(deploymentTarget)\n\n // Fetch deployments\n const deployParams = new URLSearchParams()\n deployParams.set('limit', String(deploymentTarget?.deployLimit))\n\n const {\n data: deploymentsData,\n isFetching: deploymentsIsFetching,\n isSuccess: deploymentsIsSuccess,\n error: deploymentsError,\n refetch,\n } = useQuery<{deployments: Vercel.Deployment[]}, Error>({\n queryKey: [hash(deploymentTarget)],\n queryFn: () => fetchUrl(API_ENDPOINT_DEPLOYMENTS, deployParams),\n enabled: options?.enabled ?? true,\n refetchInterval: 20000, // ms\n refetchIntervalInBackground: false,\n refetchOnMount: true,\n refetchOnReconnect: 'always',\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n // Fetch aliases (only if deployments have been retrieved)\n const aliasParams = new URLSearchParams()\n aliasParams.set('limit', '20')\n\n const {\n data: aliasesData,\n isFetching: aliasesIsFetching,\n isSuccess: aliasesIsSuccess,\n error: aliasesError,\n } = useQuery<\n {\n aliases: Vercel.Alias[]\n pagination: {\n count: number\n next?: number\n prev?: number\n }\n },\n Error\n >({\n queryKey: [hash(deploymentTarget), 'aliases'],\n queryFn: () => fetchUrl(API_ENDPOINT_ALIASES, aliasParams),\n enabled: !!deploymentsData,\n refetchOnMount: false,\n refetchOnReconnect: false,\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n const aliases = aliasesData?.aliases as Vercel.Alias[]\n\n let deploymentsWithAlias: Vercel.DeploymentWithAlias[] | undefined\n\n if (aliases) {\n deploymentsWithAlias = deploymentsData?.deployments?.map((val: Vercel.DeploymentWithAlias) => {\n const alias = aliases.find((a) => a.deploymentId === val.uid)\n return {\n ...val,\n alias: alias?.alias,\n }\n })\n }\n\n return {\n deployments: deploymentsWithAlias,\n error: aliasesError || deploymentsError,\n isFetching: aliasesIsFetching || deploymentsIsFetching,\n isSuccess: aliasesIsSuccess && deploymentsIsSuccess,\n refetch,\n }\n}\n\nexport default useDeployments\n","import {Machine} from 'xstate'\n\ntype Context = {}\n\ntype Event = {type: 'ERROR'} | {type: 'REFRESH'} | {type: 'REFRESHED'} | {type: 'RETRY'}\n\ntype Schema = {\n states: {\n idle: {}\n refreshing: {}\n refreshed: {}\n error: {}\n }\n}\n\nconst refreshMachine = Machine<Context, Schema, Event>({\n initial: 'idle',\n states: {\n idle: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n refreshing: {\n on: {\n ERROR: 'error',\n REFRESHED: 'refreshed',\n },\n },\n refreshed: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n error: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n },\n})\n\nexport default refreshMachine\n","import {useTheme} from '@sanity/ui'\n\nexport function useCardColor() {\n return useTheme().sanity.color.card.enabled\n}\n","import {Box, Label} from '@sanity/ui'\nimport React, {ReactNode} from 'react'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n children: ReactNode\n colSpan?: number\n header?: boolean\n variant?: 'age' | 'branch' | 'creator' | 'state'\n}\n\nconst TableCell = (props: Props) => {\n const {children, colSpan, header, variant} = props\n\n let display: Sanity.BoxDisplay | Sanity.BoxDisplay[] = 'table-cell'\n let cellWidth: string = 'auto'\n\n switch (variant) {\n case 'age':\n cellWidth = '50px'\n break\n case 'branch':\n cellWidth = '300px'\n display = ['none', 'none', 'none', 'table-cell']\n break\n case 'creator':\n cellWidth = '80px'\n break\n case 'state':\n cellWidth = '110px'\n display = ['none', 'none', 'none', 'none', 'table-cell']\n break\n default:\n break\n }\n\n const {border} = useCardColor()\n\n if (header) {\n return (\n <Box\n as=\"th\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={2}\n style={{\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n <Label size={0}>{children}</Label>\n </Box>\n )\n }\n return (\n <Box\n as=\"td\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={[2, 2, 3]}\n style={{\n borderTop: `1px solid ${border}`,\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n {children}\n </Box>\n )\n}\n\nexport default TableCell\n","import {Box} from '@sanity/ui'\nimport React from 'react'\n\nimport {VERCEL_STATUS_COLORS} from '../../constants'\nimport {Vercel} from '../../types'\n\ntype Props = {\n state: Vercel.DeploymentState\n}\n\nconst StatusDot = ({state}: Props) => (\n <Box\n style={{\n backgroundColor: `${VERCEL_STATUS_COLORS[state]}`,\n borderRadius: '20px',\n height: '9px',\n width: '9px',\n }}\n />\n)\n\nexport default StatusDot\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport ReactTimeAgo from 'react-time-ago'\n\nimport TableCell from '../TableCell'\nimport StatusDot from '../StatusDot'\nimport {LinkIcon} from '@sanity/icons'\nimport {Vercel} from '../../types'\n\ntype Props = {\n deployment: Vercel.DeploymentWithAlias\n}\n\nconst Deployment = (props: Props) => {\n const {deployment} = props\n\n const date = useRef(new Date(deployment.created))\n\n const commitMessage = deployment?.meta?.githubCommitMessage\n const commitRef = deployment?.meta?.githubCommitRef\n\n const targetUrl = deployment.alias ?? deployment.url\n\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <Flex align=\"center\">\n <Box\n display={['block', 'block', 'block', 'block', 'none']}\n marginRight={3}\n style={{flexShrink: 0}}\n >\n <StatusDot state={deployment.state} />\n </Box>\n\n {targetUrl ? (\n <>\n {/* Alias icon */}\n {deployment.alias && <LinkIcon />}\n\n <Box marginLeft={deployment.alias ? 1 : 0}>\n <Text\n muted={!(deployment.state === 'READY')}\n size={1}\n style={{\n textDecoration:\n deployment.state === 'CANCELED' || deployment.state === 'ERROR'\n ? 'line-through'\n : 'normal',\n }}\n textOverflow=\"ellipsis\"\n >\n {deployment.state === 'READY' ? (\n <a href={`https://${targetUrl}`} rel=\"noopener noreferrer\" target=\"_blank\">\n {targetUrl}\n </a>\n ) : (\n targetUrl\n )}\n </Text>\n </Box>\n </>\n ) : (\n <Text size={1}>Uploading...</Text>\n )}\n </Flex>\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <Flex align=\"center\">\n <StatusDot state={deployment.state} />\n <Box marginLeft={2}>\n <Text size={1}>\n {deployment.state\n .trim()\n .toLowerCase()\n .replace(/^[a-z]/i, (t) => t.toUpperCase())}\n </Text>\n </Box>\n </Flex>\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <Stack space={2}>\n <Text size={1} textOverflow=\"ellipsis\">\n {commitRef}\n </Text>\n {commitMessage && (\n <Text muted size={1} textOverflow=\"ellipsis\">\n {commitMessage}\n </Text>\n )}\n </Stack>\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <Flex align=\"center\">\n <Text size={1}>\n <ReactTimeAgo date={date.current} locale=\"en-US\" timeStyle=\"mini\" />\n </Text>\n </Flex>\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex align=\"center\" justify=\"center\">\n <img\n draggable={false}\n src={`https://vercel.com/api/www/avatar/${deployment?.creator?.uid}?&s=48`}\n style={{\n borderRadius: '20px',\n height: '20px',\n width: '20px',\n }}\n />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default Deployment\n","import fetch from 'unfetch'\nimport {assign, Machine} from 'xstate'\nimport {Vercel} from '../types'\n\ntype Context = {\n disabled: boolean\n feedback?: string\n label?: string\n error?: string\n}\n\ntype Event = {type: 'DEPLOY'}\n\ntype Schema = {\n states: {\n idle: {}\n deploying: {}\n success: {}\n error: {}\n }\n}\n\nconst deployMachine = (deployHook: string) =>\n Machine<Context, Schema, Event>(\n // Machine\n {\n id: 'deploy',\n initial: 'idle',\n context: {\n disabled: false,\n feedback: undefined,\n label: undefined,\n error: undefined,\n },\n states: {\n idle: {\n entry: assign({\n feedback: () => undefined,\n label: () => 'Deploy',\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n deploying: {\n entry: assign({\n disabled: () => true,\n label: () => 'Deploying',\n }),\n exit: assign({\n disabled: () => false,\n label: () => 'Deploy',\n }),\n invoke: {\n onDone: {\n target: 'success',\n },\n onError: {\n target: 'error',\n actions: assign({\n error: (_context, event) => {\n return event.data\n },\n }),\n },\n src: 'deploy',\n },\n },\n success: {\n entry: [assign({feedback: () => 'Succesfully started!'})],\n exit: assign({\n feedback: () => undefined,\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n error: {\n on: {\n DEPLOY: 'deploying',\n },\n },\n },\n },\n // Config\n {\n services: {\n deploy: (): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n try {\n if (!deployHook) {\n return reject(new Error('No deployHook URL defined'))\n }\n\n const res = await fetch(deployHook, {method: 'POST'})\n const data = await res.json()\n\n if (!res.ok) {\n const errorMessage = (data?.error as Vercel.Error).message || res.statusText\n return reject(errorMessage)\n }\n\n return resolve()\n } catch (err) {\n console.error('Unable to deploy with error:', err)\n return reject(new Error('Please check the developer console for more information'))\n }\n })\n },\n },\n }\n )\n\nexport default deployMachine\n","import {UploadIcon} from '@sanity/icons'\nimport {Box, Button, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useMemo} from 'react'\n\nimport {WIDGET_NAME} from '../../constants'\nimport deployMachine from '../../machines/deploy'\nimport StateDebug from '../StateDebug'\n\ntype Props = {\n deployHook: string\n onDeploySuccess?: () => void\n targetName: string\n}\n\nconst DeployButton = (props: Props) => {\n const {deployHook, onDeploySuccess, targetName} = props\n\n const machine = useMemo(() => deployMachine(deployHook), [deployHook])\n\n const [deployState, deployStateTransition, deployStateInterpreter] = useMachine(machine)\n\n const toast = useToast()\n\n const isError = deployState.matches('error')\n const isSuccess = deployState.matches('success')\n\n // Callbacks\n const handleDeploy = () => {\n deployStateTransition({type: 'DEPLOY'})\n }\n\n // Effects\n useEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to queue deploy for ${targetName}: ${deployState.context.error}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n\n if (isSuccess) {\n toast.push({\n closable: true,\n description: `Deploy queued for ${targetName}`,\n duration: 8000,\n status: 'success',\n title: WIDGET_NAME,\n })\n }\n }, [isError, isSuccess, toast, targetName, deployState.context.error])\n\n useEffect(() => {\n deployStateInterpreter.onTransition((state) => {\n if (state.value === 'success') {\n if (onDeploySuccess) {\n onDeploySuccess()\n }\n }\n })\n }, [deployStateInterpreter, onDeploySuccess])\n\n return (\n <Box padding={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Deploy\" state={deployState} />\n\n <Button\n disabled={deployState.context.disabled}\n fontSize={1}\n icon={UploadIcon}\n mode=\"ghost\"\n onClick={handleDeploy}\n padding={3}\n text={`${deployState.context.label} ${targetName}`}\n tone=\"default\"\n />\n </Box>\n )\n}\n\nexport default DeployButton\n","import {Box} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\nconst PlaceholderAvatar = () => {\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '20px',\n height: '20px',\n userSelect: 'none',\n width: '20px',\n }}\n />\n )\n}\n\nexport default PlaceholderAvatar\n","import {Box, Stack, Text} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n rows: number\n}\n\nconst PlaceholderText = (props: Props) => {\n const {rows} = props\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '3px',\n userSelect: 'none',\n width: '100%',\n }}\n >\n <Stack space={2}>\n {new Array(rows).fill(undefined).map((_, index) => (\n <Text key={index} size={1}>\n &nbsp;\n </Text>\n ))}\n </Stack>\n </Box>\n )\n}\n\nexport default PlaceholderText\n","import {Flex} from '@sanity/ui'\nimport React from 'react'\n\nimport PlaceholderAvatar from '../PlaceholderAvatar'\nimport PlaceholderText from '../PlaceholderText'\nimport TableCell from '../TableCell'\n\nconst DeploymentPlaceholder = () => {\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <PlaceholderText rows={2} />\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex justify=\"center\">\n <PlaceholderAvatar />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default DeploymentPlaceholder\n","import {Box, Text, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useRef} from 'react'\nimport useDeepCompareEffect from 'use-deep-compare-effect'\n\nimport {WIDGET_NAME} from '../../constants'\nimport useDeployments from '../../hooks/useDeployments'\nimport refreshMachine from '../../machines/refresh'\nimport Deployment from '../Deployment'\nimport DeployButton from '../DeployButton'\nimport DeploymentPlaceholder from '../DeploymentPlaceholder'\nimport StateDebug from '../StateDebug'\nimport TableCell from '../TableCell'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n deploymentTarget: Sanity.DeploymentTarget\n}\n\nconst Deployments = (props: Props) => {\n const {deploymentTarget} = props\n\n // Refs\n const refTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // XState\n const [refreshState, refreshStateTransition] = useMachine(refreshMachine)\n\n // Fetch deployments - disable hook / auto-refetching on error state\n const {deployments, error, isFetching, isSuccess, refetch} = useDeployments(deploymentTarget, {\n enabled: !refreshState.matches('error'),\n })\n\n const toast = useToast()\n const isError = refreshState.matches('error')\n\n const handleDeploySuccess = () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n refTimeout.current = setTimeout(() => {\n refetch({\n cancelRefetch: true,\n throwOnError: true,\n })\n }, 4000)\n }\n\n useEffect(() => {\n return () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (error) {\n refreshStateTransition({type: 'ERROR'})\n }\n\n if (isFetching) {\n refreshStateTransition({type: 'REFRESH'})\n }\n\n if (!isFetching && isSuccess) {\n refreshStateTransition({type: 'REFRESHED'})\n }\n }, [error, isFetching, isSuccess, refreshStateTransition])\n\n useDeepCompareEffect(() => {\n if (!refreshState.matches('refreshing')) {\n refreshStateTransition({type: 'REFRESH'})\n }\n }, [deploymentTarget])\n\n useDeepCompareEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to fetch deployments for ${deploymentTarget.name}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n }, [deploymentTarget, isError])\n\n const hasFetched = typeof deployments !== 'undefined'\n const hasDeployments = deployments && deployments.length > 0\n\n const {border} = useCardColor()\n return (\n <Box marginTop={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Refresh\" state={refreshState} />\n\n {!refreshState.matches('error') && (\n <>\n <Box\n as=\"table\"\n style={{\n borderBottom: `1px solid ${border}`,\n borderCollapse: 'collapse',\n display: 'table',\n tableLayout: 'fixed',\n width: '100%',\n }}\n >\n <Box as=\"thead\" style={{display: 'table-header-group'}}>\n <tr>\n {/* Deployment */}\n <TableCell header>Deployment</TableCell>\n\n {/* State */}\n <TableCell header variant=\"state\">\n State\n </TableCell>\n\n {/* Branch */}\n <TableCell header variant=\"branch\">\n Branch\n </TableCell>\n\n {/* Age */}\n <TableCell header variant=\"age\">\n Age\n </TableCell>\n\n {/* Creator */}\n <TableCell header variant=\"age\">\n Creator\n </TableCell>\n </tr>\n </Box>\n\n <Box as=\"tbody\" style={{display: 'table-header-group'}}>\n {/* Placeholders */}\n {!deployments &&\n new Array(deploymentTarget?.deployLimit)\n .fill(undefined)\n .map((_, index) => <DeploymentPlaceholder key={index} />)}\n {/* Deployments */}\n {hasDeployments &&\n deployments?.map((deployment) => (\n <Deployment deployment={deployment} key={deployment.uid} />\n ))}\n </Box>\n </Box>\n\n {/* No results */}\n {hasFetched && !hasDeployments && (\n <Box padding={3} style={{width: '100%'}}>\n <Text muted size={1}>\n No deployments found. Don't forget to specify a valid team ID if your project\n belongs to a team.\n </Text>\n </Box>\n )}\n </>\n )}\n\n {/* Error message */}\n {refreshState.matches('error') && (\n <Box padding={3}>\n <Text muted size={1}>\n Unable to fetch recent deployments. Please check your network and deployment settings.\n </Text>\n </Box>\n )}\n\n {/* Deploy button */}\n {!refreshState.matches('error') && deploymentTarget.deployHook && (\n <Box>\n <DeployButton\n deployHook={deploymentTarget.deployHook}\n onDeploySuccess={handleDeploySuccess}\n targetName={deploymentTarget.name}\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport default Deployments\n","import {EditIcon} from '@sanity/icons'\nimport {Box, Button, Flex, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n\nimport Deployments from '../Deployments'\nimport {Sanity} from '../../types'\n\ntype Props = {\n item: Sanity.DeploymentTarget\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTarget: FC<Props> = (props: Props) => {\n const {item, onDialogEdit} = props\n\n const deploymentTarget = {\n deployHook: item.deployHook,\n deployLimit: item.deployLimit,\n name: item.name,\n projectId: item.projectId,\n teamId: item.teamId,\n token: item.token,\n } as Sanity.DeploymentTarget\n\n return (\n <Box style={{position: 'relative'}}>\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" marginTop={2} paddingX={3}>\n <Text size={2}>{item.name}</Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Edit deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={EditIcon} mode=\"bleed\" onClick={() => onDialogEdit(item)} />\n </Tooltip>\n </Flex>\n\n {/* Content */}\n <Deployments deploymentTarget={deploymentTarget} />\n </Box>\n )\n}\n\nexport default DeploymentTarget\n","import React from 'react'\nimport {Stack} from '@sanity/ui'\n\nimport DeploymentTarget from '../DeploymentTarget'\nimport {Sanity} from '../../types'\n\ntype Props = {\n items: Sanity.DeploymentTarget[]\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTargets = (props: Props) => {\n const {items, onDialogEdit} = props\n\n return (\n <Stack space={5}>\n {items?.map((item) => (\n <DeploymentTarget item={item} key={item._id} onDialogEdit={onDialogEdit} />\n ))}\n </Stack>\n )\n}\n\nexport default DeploymentTargets\n","import {assign, Machine} from 'xstate'\n\ntype Context = {\n formData?: Record<string, any>\n message: string\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'DELETE'}\n | {type: 'REJECT'}\n | {type: 'RESOLVE'}\n | {type: 'SUBMIT'}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n idle: {}\n creating: {}\n updating: {}\n deleting: {}\n success: {}\n error: {}\n }\n}\n\nconst formMachine = Machine<Context, Schema, Event>(\n {\n context: {\n formData: {},\n message: '',\n },\n initial: 'idle',\n states: {\n idle: {\n on: {\n CREATE: {\n actions: ['createDocument'],\n target: 'creating',\n },\n DELETE: {\n actions: ['deleteDocument'],\n target: 'deleting',\n },\n UPDATE: {\n actions: ['updateDocument'],\n target: 'updating',\n },\n },\n },\n creating: {\n invoke: {\n src: 'createDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n updating: {\n invoke: {\n src: 'updateDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n deleting: {\n invoke: {\n src: 'deleteDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n success: {\n invoke: {\n src: 'formSubmittedService',\n },\n },\n error: {},\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n createDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n deleteDocument: assign(() => ({\n // id: event.id,\n })),\n updateDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n },\n }\n)\n\nexport default formMachine\n","// Recursively sanitize form data:\n// - convert empty strings, undefined values and empty arrays to null (to correctly unset / delete fields)\n// - trim whitespace on string fleids\n\ntype FormData = Record<string, any>\n\nconst sanitizeFormData = (formData: FormData): FormData => {\n return Object.keys(formData).reduce((acc: FormData, key) => {\n const val = formData[key]\n\n // TODO: refactor\n if (typeof val === 'object' && val !== null && val.constructor !== Array) {\n acc[key] = sanitizeFormData(val)\n } else if (val === '' || typeof val === 'undefined' || val?.length === 0) {\n acc[key] = null\n } else if (typeof val === 'string' && val) {\n acc[key] = formData[key].trim()\n } else {\n acc[key] = formData[key]\n }\n\n return acc\n }, {})\n}\n\nexport default sanitizeFormData\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Inline, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\nimport {FieldError} from 'react-hook-form'\nimport {styled} from 'styled-components'\n\ntype Props = {\n description?: string\n error?: FieldError\n label: string\n name: string\n}\n\nconst StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({theme}) => {\n return {\n color: theme.sanity.color.spot.red,\n }\n})\n\nconst FormFieldInputLabel: FC<Props> = (props: Props) => {\n const {description, error, label, name} = props\n\n return (\n <Box marginBottom={3}>\n {/* Label */}\n <Inline space={2}>\n <Text as=\"label\" htmlFor={name} size={1} weight=\"semibold\">\n {label}\n </Text>\n\n {/* Error icon + tooltip */}\n {error && (\n <Text size={1}>\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n <StyledErrorOutlineIcon style={{marginRight: '0.1em'}} />\n {error.message}\n </Text>\n </Box>\n }\n fallbackPlacements={['top', 'left']}\n placement=\"right\"\n portal\n >\n <StyledErrorOutlineIcon />\n </Tooltip>\n </Text>\n )}\n </Inline>\n\n {/* Description */}\n {description && (\n <Box marginY={3}>\n <Text htmlFor={name} muted size={1}>\n {description}\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n\nexport default FormFieldInputLabel\n","import {Box, TextInput} from '@sanity/ui'\nimport React, {forwardRef} from 'react'\nimport {FieldError} from 'react-hook-form'\n\nimport FormFieldInputLabel from '../FormFieldInputLabel'\n\ntype Props = {\n description?: string\n disabled?: boolean\n error?: FieldError\n label: string\n name: string\n placeholder?: string\n value?: string\n onChange?: React.ChangeEventHandler<HTMLInputElement>\n onBlur?: React.FocusEventHandler<HTMLInputElement>\n}\n\nconst FormFieldInputText = forwardRef<HTMLInputElement, Props>((props: Props, ref) => {\n const {description, disabled, error, label, name, placeholder, value, onChange, onBlur} = props\n\n return (\n <Box>\n {/* Label */}\n <FormFieldInputLabel description={description} error={error} label={label} name={name} />\n {/* Input */}\n <TextInput\n autoComplete=\"off\"\n autoFocus\n defaultValue={value}\n disabled={disabled}\n id={name}\n name={name}\n placeholder={placeholder}\n onChange={onChange}\n onBlur={onBlur}\n ref={ref}\n />\n </Box>\n )\n})\n\nexport default FormFieldInputText\n","import type {SanityClient} from '@sanity/client'\nimport {API_VERSION} from './constants'\nimport {useClient} from 'sanity'\n\nexport function useSanityClient(): SanityClient {\n return useClient({apiVersion: API_VERSION})\n}\n","import {yupResolver} from '@hookform/resolvers/yup'\nimport {Box, Button, Dialog, Flex, Stack} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport {useMachine} from '@xstate/react'\nimport React, {FC} from 'react'\nimport {useForm} from 'react-hook-form'\nimport * as yup from 'yup'\n\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_DIALOG} from '../../constants'\nimport formMachine from '../../machines/form'\nimport sanitizeFormData from '../../utils/sanitizeFormData'\nimport FormFieldInputText from '../FormFieldInputText'\nimport {Sanity} from '../../types'\nimport {useSanityClient} from '../../client'\n\ntype Props = {\n deploymentTarget?: Sanity.DeploymentTarget\n onClose: () => void\n onCreate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n onDelete?: (id: string) => void\n onUpdate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\ntype FormData = yup.InferType<typeof formSchema>\n\nconst formSchema = yup.object().shape({\n deployHook: yup.string().url('Deploy hook must be a valid URL'),\n deployLimit: yup\n .number()\n .positive()\n .integer()\n .min(1, 'Deploy limit must no less than 1')\n .max(15, 'Deploy limit must no higher than 15')\n .typeError('Deploy limit must be a number')\n .required('Deploy limit must be a positive integer between 1 and 15'),\n name: yup.string().required('Name cannot be empty'),\n projectId: yup.string().required('Vercel Project ID cannot be empty'),\n teamId: yup.string(),\n token: yup.string().required('Vercel Account Token cannot be empty'),\n})\n\nconst DialogForm: FC<Props> = (props: Props) => {\n const {deploymentTarget, onClose, onCreate, onDelete, onUpdate} = props\n const client = useSanityClient()\n\n // xstate\n const [formState, formStateTransition] = useMachine(formMachine, {\n services: {\n formSubmittedService: async () => {\n onClose()\n },\n // TODO: refactor\n createDocumentService: async (_context, event: any) => {\n let document\n try {\n document = await client.create({\n _id: `vercel.${uuid()}`,\n _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,\n ...event.formData,\n })\n if (onCreate) {\n onCreate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n },\n // TODO: refactor\n deleteDocumentService: async () => {\n if (deploymentTarget) {\n try {\n await client.delete(deploymentTarget._id)\n if (onDelete) {\n onDelete(deploymentTarget._id)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n // TODO: refactor\n updateDocumentService: async (_context, event: any) => {\n let document\n if (deploymentTarget) {\n try {\n document = await client.patch(deploymentTarget._id).set(event.formData).commit()\n if (onUpdate) {\n onUpdate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n },\n })\n\n const formUpdating =\n formState.matches('creating') || formState.matches('deleting') || formState.matches('updating')\n\n // react-hook-form v7\n const {\n formState: {errors, isDirty, isValid},\n handleSubmit,\n register,\n } = useForm<FormData>({\n // @ts-expect-error - fix typings later\n defaultValues: {\n deployHook: deploymentTarget?.deployHook || '',\n deployLimit: deploymentTarget?.deployLimit || 5,\n name: deploymentTarget?.name || '',\n projectId: deploymentTarget?.projectId || '',\n teamId: deploymentTarget?.teamId || '',\n token: deploymentTarget?.token || '',\n },\n mode: 'onChange',\n resolver: yupResolver(formSchema),\n })\n\n // Callbacks\n // - submit react-hook-form\n const onSubmit = async (formData: FormData) => {\n const sanitizedFormData = sanitizeFormData(formData)\n await formStateTransition(deploymentTarget ? 'UPDATE' : 'CREATE', {\n formData: sanitizedFormData,\n })\n }\n\n const handleDelete = () => {\n formStateTransition('DELETE', {id: deploymentTarget?._id})\n }\n\n const Footer = () => (\n <Box padding={3}>\n <Flex justify={deploymentTarget ? 'space-between' : 'flex-end'}>\n {/* Delete button */}\n {deploymentTarget && (\n <Button\n disabled={formUpdating}\n fontSize={1}\n mode=\"bleed\"\n onClick={handleDelete}\n text=\"Delete\"\n tone=\"critical\"\n />\n )}\n\n {/* Submit button */}\n <Button\n disabled={formUpdating || !isDirty || !isValid}\n fontSize={1}\n onClick={handleSubmit(onSubmit)}\n text={deploymentTarget ? 'Update and close' : 'Create'}\n tone=\"primary\"\n />\n </Flex>\n </Box>\n )\n\n return (\n <Dialog\n footer={<Footer />}\n header={`${deploymentTarget ? 'Edit' : 'Create'} deployment target`}\n id=\"create\"\n onClose={onClose}\n width={1}\n zOffset={Z_INDEX_DIALOG}\n >\n {/* We reverse direction to ensure that inline links dont autofocus before other form elements */}\n <Box as=\"form\" padding={4} onSubmit={handleSubmit(onSubmit)}>\n {/* Hidden button to enable enter key submissions */}\n <button style={{display: 'none'}} tabIndex={-1} type=\"submit\" />\n\n {/* Form fields */}\n <Stack space={5}>\n {/* Title */}\n <FormFieldInputText\n disabled={formUpdating}\n description=\"Name displayed in this plugin (e.g. production, staging)\"\n error={errors?.name}\n label=\"Name\"\n // @ts-expect-error - fix typings later\n {...register('name')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.token}\n label=\"Vercel Account Token\"\n // @ts-expect-error - fix typings later\n {...register('token')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.projectId}\n label=\"Vercel Project ID\"\n // @ts-expect-error - fix typings later\n {...register('projectId')}\n />\n\n <FormFieldInputText\n description=\"Required only if your project is owned by a team account\"\n disabled={formUpdating}\n error={errors?.teamId}\n label=\"Vercel Team ID (optional)\"\n // @ts-expect-error - fix typings later\n {...register('teamId')}\n />\n\n <FormFieldInputText\n description=\"Enter a valid deploy hook URL to enable manual deploys\"\n disabled={formUpdating}\n error={errors?.deployHook}\n label=\"Vercel Deploy Hook (optional)\"\n // @ts-expect-error - fix typings later\n {...register('deployHook')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.deployLimit}\n label=\"Number of deploys to display\"\n // @ts-expect-error - fix typings later\n {...register('deployLimit', {valueAsNumber: true})}\n />\n </Stack>\n </Box>\n </Dialog>\n )\n}\n\nexport default DialogForm\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n editDeploymentTarget?: Sanity.DeploymentTarget\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'CLOSE'}\n | {type: 'EDIT'; deploymentTarget: Sanity.DeploymentTarget}\n\ntype Schema = {\n states: {\n idle: {}\n edit: {}\n create: {}\n }\n}\n\nconst dialogMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n editDeploymentTarget: undefined,\n },\n initial: 'idle',\n states: {\n idle: {\n entry: assign({\n editDeploymentTarget: () => undefined,\n }),\n on: {\n CREATE: 'create',\n EDIT: {\n actions: ['setEditDeploymentTarget'],\n target: 'edit',\n },\n },\n },\n edit: {\n on: {\n CLOSE: 'idle',\n },\n },\n create: {\n on: {\n CLOSE: 'idle',\n },\n },\n },\n },\n {\n actions: {\n setEditDeploymentTarget: assign((_context, event: any) => ({\n editDeploymentTarget: event.deploymentTarget,\n })),\n },\n }\n )\n\nexport default dialogMachine\n","import {AddIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, ToastProvider, Tooltip} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React from 'react'\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query'\n\nimport StateDebug from './components/StateDebug'\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_TOAST_PROVIDER} from './constants'\nimport deploymentTargetListMachine from './machines/deploymentTargetList'\nimport DeploymentTargets from './components/DeploymentTargets'\nimport DialogForm from './components/DialogForm'\nimport dialogMachine from './machines/dialog'\nimport {Sanity} from './types'\nimport {useSanityClient} from './client'\n\nconst Widget = () => {\n const client = useSanityClient()\n // xstate\n const [deploymentTargetListState, deploymentTargetListStateTransition] = useMachine(\n deploymentTargetListMachine,\n {\n services: {\n fetchDataService: () => {\n return client\n .fetch(`*[_type == \"${DEPLOYMENT_TARGET_DOCUMENT_TYPE}\"] | order(name asc)`)\n .then((result: any) => result)\n },\n },\n }\n )\n const [dialogState, dialogStateTransition] = useMachine(dialogMachine)\n\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n gcTime: 0,\n staleTime: 0,\n },\n },\n })\n\n // Callbacks\n const handleDialogClose = () => {\n dialogStateTransition('CLOSE')\n }\n const handleDialogShowCreate = () => {\n dialogStateTransition('CREATE')\n }\n const handleDialogShowEdit = (deploymentTarget: Sanity.DeploymentTarget) => {\n dialogStateTransition('EDIT', {deploymentTarget})\n }\n const handleTargetCreate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('CREATE', {deploymentTarget})\n }\n const handleTargetDelete = (id: string) => {\n deploymentTargetListStateTransition('DELETE', {id})\n }\n const handleTargetUpdate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('UPDATE', {deploymentTarget})\n }\n\n return (\n <ToastProvider zOffset={Z_INDEX_TOAST_PROVIDER}>\n <QueryClientProvider client={queryClient}>\n <Card radius={2} style={{overflow: 'hidden '}}>\n {/* xstate debug */}\n <StateDebug name=\"List\" state={deploymentTargetListState} />\n\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" paddingX={3} paddingY={2}>\n <Text size={5} weight=\"semibold\">\n Vercel deployments\n </Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Create new deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={AddIcon} onClick={handleDialogShowCreate} mode=\"bleed\" />\n </Tooltip>\n </Flex>\n\n <Box>\n {deploymentTargetListState.matches('pending') && (\n <Box paddingX={3} paddingY={4}>\n <Text>Loading...</Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withoutData') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n No deployment targets found.{' '}\n <a onClick={handleDialogShowCreate} style={{cursor: 'pointer'}}>\n Create a new target?\n </a>\n </Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withData') && (\n <DeploymentTargets\n items={deploymentTargetListState.context.results}\n onDialogEdit={handleDialogShowEdit}\n />\n )}\n\n {deploymentTargetListState.matches('failed') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n Failed to retrieve deployment targets. Please check the developer console log for\n more information.\n </Text>\n </Box>\n )}\n </Box>\n </Card>\n\n {/* Dialogs */}\n {dialogState.matches('create') && (\n <DialogForm onClose={handleDialogClose} onCreate={handleTargetCreate} />\n )}\n\n {dialogState.matches('edit') && (\n <DialogForm\n deploymentTarget={dialogState.context.editDeploymentTarget}\n onClose={handleDialogClose}\n onDelete={handleTargetDelete}\n onUpdate={handleTargetUpdate}\n />\n )}\n </QueryClientProvider>\n </ToastProvider>\n )\n}\n\nexport default Widget\n","import Widget from './app'\n\n// Initialize `javascript-time-ago` locale (required for react-time-ago)\nimport TimeAgo from 'javascript-time-ago'\nimport en from 'javascript-time-ago/locale/en'\nimport {DashboardWidget, type LayoutConfig} from '@sanity/dashboard'\n\nTimeAgo.addDefaultLocale(en)\n\nexport function vercelWidget(config: {layout?: LayoutConfig} = {}): DashboardWidget {\n return {\n name: 'vercel',\n component: Widget,\n layout: config.layout ?? {width: 'full'},\n }\n}\n"],"names":["Machine","assign","fetch","useQuery","hash","useTheme","jsx","Box","Label","useRef","jsxs","Flex","Fragment","LinkIcon","Text","Stack","ReactTimeAgo","useMemo","useMachine","useToast","useEffect","Button","UploadIcon","useDeepCompareEffect","Tooltip","EditIcon","styled","ErrorOutlineIcon","Inline","forwardRef","TextInput","useClient","yup","uuid","useForm","yupResolver","Dialog","QueryClient","ToastProvider","QueryClientProvider","Card","AddIcon","TimeAgo","en"],"mappings":"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"}
package/lib/index.mjs CHANGED
@@ -656,7 +656,7 @@ const TableCell = (props) => {
656
656
  description && /* @__PURE__ */ jsx(Box, { marginY: 3, children: /* @__PURE__ */ jsx(Text, { htmlFor: name, muted: !0, size: 1, children: description }) })
657
657
  ] });
658
658
  }, FormFieldInputText = forwardRef((props, ref) => {
659
- const { description, disabled, error, label, name, placeholder, value } = props;
659
+ const { description, disabled, error, label, name, placeholder, value, onChange, onBlur } = props;
660
660
  return /* @__PURE__ */ jsxs(Box, { children: [
661
661
  /* @__PURE__ */ jsx(FormFieldInputLabel, { description, error, label, name }),
662
662
  /* @__PURE__ */ jsx(
@@ -669,6 +669,8 @@ const TableCell = (props) => {
669
669
  id: name,
670
670
  name,
671
671
  placeholder,
672
+ onChange,
673
+ onBlur,
672
674
  ref
673
675
  }
674
676
  )
@@ -726,18 +728,18 @@ const formSchema = yup.object().shape({
726
728
  }
727
729
  }
728
730
  }), formUpdating = formState.matches("creating") || formState.matches("deleting") || formState.matches("updating"), {
729
- // Read the formState before render to subscribe the form state through Proxy
730
731
  formState: { errors, isDirty, isValid },
731
732
  handleSubmit,
732
733
  register
733
734
  } = useForm({
735
+ // @ts-expect-error - fix typings later
734
736
  defaultValues: {
735
737
  deployHook: deploymentTarget?.deployHook || "",
736
738
  deployLimit: deploymentTarget?.deployLimit || 5,
737
- name: deploymentTarget?.name,
738
- projectId: deploymentTarget?.projectId,
739
+ name: deploymentTarget?.name || "",
740
+ projectId: deploymentTarget?.projectId || "",
739
741
  teamId: deploymentTarget?.teamId || "",
740
- token: deploymentTarget?.token
742
+ token: deploymentTarget?.token || ""
741
743
  },
742
744
  mode: "onChange",
743
745
  resolver: yupResolver(formSchema)
@@ -790,8 +792,7 @@ const formSchema = yup.object().shape({
790
792
  description: "Name displayed in this plugin (e.g. production, staging)",
791
793
  error: errors?.name,
792
794
  label: "Name",
793
- name: "name",
794
- ref: register
795
+ ...register("name")
795
796
  }
796
797
  ),
797
798
  /* @__PURE__ */ jsx(
@@ -800,8 +801,7 @@ const formSchema = yup.object().shape({
800
801
  disabled: formUpdating,
801
802
  error: errors?.token,
802
803
  label: "Vercel Account Token",
803
- name: "token",
804
- ref: register
804
+ ...register("token")
805
805
  }
806
806
  ),
807
807
  /* @__PURE__ */ jsx(
@@ -810,8 +810,7 @@ const formSchema = yup.object().shape({
810
810
  disabled: formUpdating,
811
811
  error: errors?.projectId,
812
812
  label: "Vercel Project ID",
813
- name: "projectId",
814
- ref: register
813
+ ...register("projectId")
815
814
  }
816
815
  ),
817
816
  /* @__PURE__ */ jsx(
@@ -821,8 +820,7 @@ const formSchema = yup.object().shape({
821
820
  disabled: formUpdating,
822
821
  error: errors?.teamId,
823
822
  label: "Vercel Team ID (optional)",
824
- name: "teamId",
825
- ref: register
823
+ ...register("teamId")
826
824
  }
827
825
  ),
828
826
  /* @__PURE__ */ jsx(
@@ -832,8 +830,7 @@ const formSchema = yup.object().shape({
832
830
  disabled: formUpdating,
833
831
  error: errors?.deployHook,
834
832
  label: "Vercel Deploy Hook (optional)",
835
- name: "deployHook",
836
- ref: register
833
+ ...register("deployHook")
837
834
  }
838
835
  ),
839
836
  /* @__PURE__ */ jsx(
@@ -842,8 +839,7 @@ const formSchema = yup.object().shape({
842
839
  disabled: formUpdating,
843
840
  error: errors?.deployLimit,
844
841
  label: "Number of deploys to display",
845
- name: "deployLimit",
846
- ref: register({ valueAsNumber: !0 })
842
+ ...register("deployLimit", { valueAsNumber: !0 })
847
843
  }
848
844
  )
849
845
  ] })
package/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/constants.ts","../src/components/StateDebug/index.tsx","../src/machines/deploymentTargetList.ts","../src/utils/fetcher.ts","../src/hooks/useDeployments.ts","../src/machines/refresh.ts","../src/utils/useCardColor.ts","../src/components/TableCell/index.tsx","../src/components/StatusDot/index.tsx","../src/components/Deployment/index.tsx","../src/machines/deploy.ts","../src/components/DeployButton/index.tsx","../src/components/PlaceholderAvatar/index.tsx","../src/components/PlaceholderText/index.tsx","../src/components/DeploymentPlaceholder/index.tsx","../src/components/Deployments/index.tsx","../src/components/DeploymentTarget/index.tsx","../src/components/DeploymentTargets/index.tsx","../src/machines/form.ts","../src/utils/sanitizeFormData.ts","../src/components/FormFieldInputLabel/index.tsx","../src/components/FormFieldInputText/index.tsx","../src/client.ts","../src/components/DialogForm/index.tsx","../src/machines/dialog.ts","../src/app.tsx","../src/index.ts"],"sourcesContent":["// https://vercel.com/docs/platform/limits\nexport const API_ENDPOINT_DEPLOYMENTS = 'https://api.vercel.com/v5/now/deployments'\nexport const API_ENDPOINT_ALIASES = 'https://api.vercel.com/v3/now/aliases'\n\n// Sanity API version\nexport const API_VERSION = '1'\n\nexport const DEBUG_MODE = false\n\nexport const DEPLOYMENT_TARGET_DOCUMENT_TYPE = 'vercel.deploymentTarget'\n\nexport const VERCEL_STATUS_COLORS = {\n BUILDING: '#f5a623',\n CANCELED: '#ff0000',\n ERROR: '#ff0000',\n READY: '#50e3c2',\n QUEUED: '#333',\n}\n\n// Name displayed in toasts\nexport const WIDGET_NAME = 'Vercel (dashboard)'\n\n// NOTE: Manually set plugin z-index values to be higher than Sanity's header search field\n// (which is currently 500202). Also ensure toasts always sit above dialogs.\nexport const Z_INDEX_DIALOG = 600001\nexport const Z_INDEX_TOAST_PROVIDER = 600002\n","import {Box, Card, Stack, Text} from '@sanity/ui'\nimport React from 'react'\n\nimport {DEBUG_MODE} from '../../constants'\n\ntype Props = {\n name: string\n state: any // TODO: type correctly\n}\n\nconst StateDebug = (props: Props) => {\n const {name, state} = props\n\n if (!DEBUG_MODE) {\n return null\n }\n\n return (\n <Card\n scheme=\"dark\"\n style={{\n backgroundColor: 'rgba(0, 0, 255, 0.9)',\n borderRadius: '3px',\n fontSize: 1,\n fontWeight: 500,\n lineHeight: 'body',\n right: 0,\n opacity: 0.75,\n pointerEvents: 'none',\n position: 'absolute',\n textAlign: 'left',\n top: 0,\n zIndex: 9000,\n }}\n >\n <Box padding={2}>\n <Stack space={2}>\n <Text size={0}>Name: {name}</Text>\n <Text size={0}>state.value: {JSON.stringify(state.value)}</Text>\n </Stack>\n </Box>\n </Card>\n )\n}\n\nexport default StateDebug\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n message: string\n results: Sanity.DeploymentTarget[] // TODO: type correctly\n}\n\ntype Event =\n | {type: 'CLOSE'}\n | {type: 'CREATE'; deploymentTarget: Sanity.DeploymentTarget}\n | {type: 'DELETE'; id: string}\n | {type: 'FETCH'}\n | {type: 'REJECT'; message: string}\n | {type: 'RESOLVE'; results: any[]}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n failed: {}\n pending: {}\n ready: {\n states: {\n unknown: {}\n withData: {}\n withoutData: {}\n }\n }\n }\n}\n\nconst sortByTargetName = (items: Sanity.DeploymentTarget[]) => {\n return items.sort((a, b) => {\n if (a.name > b.name) {\n return 1\n }\n\n if (a.name < b.name) {\n return -1\n }\n\n return 0\n })\n}\n\nconst deploymentTargetListMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n message: '',\n results: [],\n },\n initial: 'pending',\n states: {\n pending: {\n invoke: {\n src: 'fetchDataService',\n onDone: {actions: ['setResults'], target: 'ready'},\n onError: {actions: ['setMessage'], target: 'failed'},\n },\n },\n ready: {\n initial: 'unknown',\n on: {\n CREATE: {actions: ['targetCreate']},\n DELETE: {actions: ['targetDelete']},\n UPDATE: {actions: ['targetUpdate']},\n },\n states: {\n unknown: {\n always: [\n {cond: 'hasData', target: 'withData'},\n {cond: 'hasNoData', target: 'withoutData'},\n ],\n },\n withData: {\n always: [{cond: 'hasNoData', target: 'withoutData'}],\n },\n withoutData: {\n always: [{cond: 'hasData', target: 'withData'}],\n },\n },\n },\n failed: {\n type: 'final',\n },\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n setResults: assign((_context, event: any) => ({\n results: event.data,\n })),\n targetCreate: assign((context, event: any) => ({\n results: sortByTargetName([...context.results, event.deploymentTarget]),\n })),\n targetDelete: assign((context, event: any) => ({\n results: context.results.filter((target) => target._id !== event.id),\n })),\n targetUpdate: assign((context, event: any) => {\n const {deploymentTarget} = event\n const index = context.results.findIndex((target) => target._id === deploymentTarget._id)\n const updatedResults = Object.assign([], context.results, {\n [index]: event.deploymentTarget,\n })\n\n return {\n results: sortByTargetName(updatedResults),\n }\n }),\n },\n guards: {\n hasData: (context) => {\n return context?.results?.length > 0\n },\n hasNoData: (context) => {\n return context?.results?.length === 0\n },\n },\n }\n )\n\nexport default deploymentTargetListMachine\n","import fetch from 'unfetch'\nimport {Sanity} from '../types'\n\nconst fetcher =\n (deploymentTarget: Sanity.DeploymentTarget) =>\n async (url: string, extraParams?: URLSearchParams) => {\n const params = new URLSearchParams()\n params.set('projectId', deploymentTarget.projectId)\n if (deploymentTarget.teamId) {\n params.set('teamId', deploymentTarget.teamId)\n }\n\n if (extraParams) {\n for (const [k, v] of extraParams.entries()) {\n params.append(k, v)\n }\n }\n\n const response = await fetch(`${url}?${params.toString()}`, {\n headers: {\n Authorization: `Bearer ${deploymentTarget.token}`,\n },\n })\n\n // Manually throw on non-OK responses for react-query\n // https://react-query.tanstack.com/guides/query-functions#usage-with-fetch-and-others-clients-that-do-not-throw-by-default\n if (!response.ok) {\n throw new Error('Response not OK')\n }\n\n try {\n return response.json()\n } catch (err) {\n throw new Error(err as string)\n }\n }\n\nexport default fetcher\n","import hash from 'object-hash'\nimport {useQuery} from '@tanstack/react-query'\n\nimport fetcher from '../utils/fetcher'\nimport {API_ENDPOINT_ALIASES, API_ENDPOINT_DEPLOYMENTS} from '../constants'\nimport {Sanity, Vercel} from '../types'\n\ntype Options = {\n enabled?: boolean\n}\n\nconst useDeployments = (deploymentTarget: Sanity.DeploymentTarget, options?: Options) => {\n const fetchUrl = fetcher(deploymentTarget)\n\n // Fetch deployments\n const deployParams = new URLSearchParams()\n deployParams.set('limit', String(deploymentTarget?.deployLimit))\n\n const {\n data: deploymentsData,\n isFetching: deploymentsIsFetching,\n isSuccess: deploymentsIsSuccess,\n error: deploymentsError,\n refetch,\n } = useQuery<{deployments: Vercel.Deployment[]}, Error>({\n queryKey: [hash(deploymentTarget)],\n queryFn: () => fetchUrl(API_ENDPOINT_DEPLOYMENTS, deployParams),\n enabled: options?.enabled ?? true,\n refetchInterval: 20000, // ms\n refetchIntervalInBackground: false,\n refetchOnMount: true,\n refetchOnReconnect: 'always',\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n // Fetch aliases (only if deployments have been retrieved)\n const aliasParams = new URLSearchParams()\n aliasParams.set('limit', '20')\n\n const {\n data: aliasesData,\n isFetching: aliasesIsFetching,\n isSuccess: aliasesIsSuccess,\n error: aliasesError,\n } = useQuery<\n {\n aliases: Vercel.Alias[]\n pagination: {\n count: number\n next?: number\n prev?: number\n }\n },\n Error\n >({\n queryKey: [hash(deploymentTarget), 'aliases'],\n queryFn: () => fetchUrl(API_ENDPOINT_ALIASES, aliasParams),\n enabled: !!deploymentsData,\n refetchOnMount: false,\n refetchOnReconnect: false,\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n const aliases = aliasesData?.aliases as Vercel.Alias[]\n\n let deploymentsWithAlias: Vercel.DeploymentWithAlias[] | undefined\n\n if (aliases) {\n deploymentsWithAlias = deploymentsData?.deployments?.map((val: Vercel.DeploymentWithAlias) => {\n const alias = aliases.find((a) => a.deploymentId === val.uid)\n return {\n ...val,\n alias: alias?.alias,\n }\n })\n }\n\n return {\n deployments: deploymentsWithAlias,\n error: aliasesError || deploymentsError,\n isFetching: aliasesIsFetching || deploymentsIsFetching,\n isSuccess: aliasesIsSuccess && deploymentsIsSuccess,\n refetch,\n }\n}\n\nexport default useDeployments\n","import {Machine} from 'xstate'\n\ntype Context = {}\n\ntype Event = {type: 'ERROR'} | {type: 'REFRESH'} | {type: 'REFRESHED'} | {type: 'RETRY'}\n\ntype Schema = {\n states: {\n idle: {}\n refreshing: {}\n refreshed: {}\n error: {}\n }\n}\n\nconst refreshMachine = Machine<Context, Schema, Event>({\n initial: 'idle',\n states: {\n idle: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n refreshing: {\n on: {\n ERROR: 'error',\n REFRESHED: 'refreshed',\n },\n },\n refreshed: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n error: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n },\n})\n\nexport default refreshMachine\n","import {useTheme} from '@sanity/ui'\n\nexport function useCardColor() {\n return useTheme().sanity.color.card.enabled\n}\n","import {Box, Label} from '@sanity/ui'\nimport React, {ReactNode} from 'react'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n children: ReactNode\n colSpan?: number\n header?: boolean\n variant?: 'age' | 'branch' | 'creator' | 'state'\n}\n\nconst TableCell = (props: Props) => {\n const {children, colSpan, header, variant} = props\n\n let display: Sanity.BoxDisplay | Sanity.BoxDisplay[] = 'table-cell'\n let cellWidth: string = 'auto'\n\n switch (variant) {\n case 'age':\n cellWidth = '50px'\n break\n case 'branch':\n cellWidth = '300px'\n display = ['none', 'none', 'none', 'table-cell']\n break\n case 'creator':\n cellWidth = '80px'\n break\n case 'state':\n cellWidth = '110px'\n display = ['none', 'none', 'none', 'none', 'table-cell']\n break\n default:\n break\n }\n\n const {border} = useCardColor()\n\n if (header) {\n return (\n <Box\n as=\"th\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={2}\n style={{\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n <Label size={0}>{children}</Label>\n </Box>\n )\n }\n return (\n <Box\n as=\"td\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={[2, 2, 3]}\n style={{\n borderTop: `1px solid ${border}`,\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n {children}\n </Box>\n )\n}\n\nexport default TableCell\n","import {Box} from '@sanity/ui'\nimport React from 'react'\n\nimport {VERCEL_STATUS_COLORS} from '../../constants'\nimport {Vercel} from '../../types'\n\ntype Props = {\n state: Vercel.DeploymentState\n}\n\nconst StatusDot = ({state}: Props) => (\n <Box\n style={{\n backgroundColor: `${VERCEL_STATUS_COLORS[state]}`,\n borderRadius: '20px',\n height: '9px',\n width: '9px',\n }}\n />\n)\n\nexport default StatusDot\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport ReactTimeAgo from 'react-time-ago'\n\nimport TableCell from '../TableCell'\nimport StatusDot from '../StatusDot'\nimport {LinkIcon} from '@sanity/icons'\nimport {Vercel} from '../../types'\n\ntype Props = {\n deployment: Vercel.DeploymentWithAlias\n}\n\nconst Deployment = (props: Props) => {\n const {deployment} = props\n\n const date = useRef(new Date(deployment.created))\n\n const commitMessage = deployment?.meta?.githubCommitMessage\n const commitRef = deployment?.meta?.githubCommitRef\n\n const targetUrl = deployment.alias ?? deployment.url\n\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <Flex align=\"center\">\n <Box\n display={['block', 'block', 'block', 'block', 'none']}\n marginRight={3}\n style={{flexShrink: 0}}\n >\n <StatusDot state={deployment.state} />\n </Box>\n\n {targetUrl ? (\n <>\n {/* Alias icon */}\n {deployment.alias && <LinkIcon />}\n\n <Box marginLeft={deployment.alias ? 1 : 0}>\n <Text\n muted={!(deployment.state === 'READY')}\n size={1}\n style={{\n textDecoration:\n deployment.state === 'CANCELED' || deployment.state === 'ERROR'\n ? 'line-through'\n : 'normal',\n }}\n textOverflow=\"ellipsis\"\n >\n {deployment.state === 'READY' ? (\n <a href={`https://${targetUrl}`} rel=\"noopener noreferrer\" target=\"_blank\">\n {targetUrl}\n </a>\n ) : (\n targetUrl\n )}\n </Text>\n </Box>\n </>\n ) : (\n <Text size={1}>Uploading...</Text>\n )}\n </Flex>\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <Flex align=\"center\">\n <StatusDot state={deployment.state} />\n <Box marginLeft={2}>\n <Text size={1}>\n {deployment.state\n .trim()\n .toLowerCase()\n .replace(/^[a-z]/i, (t) => t.toUpperCase())}\n </Text>\n </Box>\n </Flex>\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <Stack space={2}>\n <Text size={1} textOverflow=\"ellipsis\">\n {commitRef}\n </Text>\n {commitMessage && (\n <Text muted size={1} textOverflow=\"ellipsis\">\n {commitMessage}\n </Text>\n )}\n </Stack>\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <Flex align=\"center\">\n <Text size={1}>\n <ReactTimeAgo date={date.current} locale=\"en-US\" timeStyle=\"mini\" />\n </Text>\n </Flex>\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex align=\"center\" justify=\"center\">\n <img\n draggable={false}\n src={`https://vercel.com/api/www/avatar/${deployment?.creator?.uid}?&s=48`}\n style={{\n borderRadius: '20px',\n height: '20px',\n width: '20px',\n }}\n />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default Deployment\n","import fetch from 'unfetch'\nimport {assign, Machine} from 'xstate'\nimport {Vercel} from '../types'\n\ntype Context = {\n disabled: boolean\n feedback?: string\n label?: string\n error?: string\n}\n\ntype Event = {type: 'DEPLOY'}\n\ntype Schema = {\n states: {\n idle: {}\n deploying: {}\n success: {}\n error: {}\n }\n}\n\nconst deployMachine = (deployHook: string) =>\n Machine<Context, Schema, Event>(\n // Machine\n {\n id: 'deploy',\n initial: 'idle',\n context: {\n disabled: false,\n feedback: undefined,\n label: undefined,\n error: undefined,\n },\n states: {\n idle: {\n entry: assign({\n feedback: () => undefined,\n label: () => 'Deploy',\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n deploying: {\n entry: assign({\n disabled: () => true,\n label: () => 'Deploying',\n }),\n exit: assign({\n disabled: () => false,\n label: () => 'Deploy',\n }),\n invoke: {\n onDone: {\n target: 'success',\n },\n onError: {\n target: 'error',\n actions: assign({\n error: (_context, event) => {\n return event.data\n },\n }),\n },\n src: 'deploy',\n },\n },\n success: {\n entry: [assign({feedback: () => 'Succesfully started!'})],\n exit: assign({\n feedback: () => undefined,\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n error: {\n on: {\n DEPLOY: 'deploying',\n },\n },\n },\n },\n // Config\n {\n services: {\n deploy: (): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n try {\n if (!deployHook) {\n return reject(new Error('No deployHook URL defined'))\n }\n\n const res = await fetch(deployHook, {method: 'POST'})\n const data = await res.json()\n\n if (!res.ok) {\n const errorMessage = (data?.error as Vercel.Error).message || res.statusText\n return reject(errorMessage)\n }\n\n return resolve()\n } catch (err) {\n console.error('Unable to deploy with error:', err)\n return reject(new Error('Please check the developer console for more information'))\n }\n })\n },\n },\n }\n )\n\nexport default deployMachine\n","import {UploadIcon} from '@sanity/icons'\nimport {Box, Button, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useMemo} from 'react'\n\nimport {WIDGET_NAME} from '../../constants'\nimport deployMachine from '../../machines/deploy'\nimport StateDebug from '../StateDebug'\n\ntype Props = {\n deployHook: string\n onDeploySuccess?: () => void\n targetName: string\n}\n\nconst DeployButton = (props: Props) => {\n const {deployHook, onDeploySuccess, targetName} = props\n\n const machine = useMemo(() => deployMachine(deployHook), [deployHook])\n\n const [deployState, deployStateTransition, deployStateInterpreter] = useMachine(machine)\n\n const toast = useToast()\n\n const isError = deployState.matches('error')\n const isSuccess = deployState.matches('success')\n\n // Callbacks\n const handleDeploy = () => {\n deployStateTransition({type: 'DEPLOY'})\n }\n\n // Effects\n useEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to queue deploy for ${targetName}: ${deployState.context.error}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n\n if (isSuccess) {\n toast.push({\n closable: true,\n description: `Deploy queued for ${targetName}`,\n duration: 8000,\n status: 'success',\n title: WIDGET_NAME,\n })\n }\n }, [isError, isSuccess, toast, targetName, deployState.context.error])\n\n useEffect(() => {\n deployStateInterpreter.onTransition((state) => {\n if (state.value === 'success') {\n if (onDeploySuccess) {\n onDeploySuccess()\n }\n }\n })\n }, [deployStateInterpreter, onDeploySuccess])\n\n return (\n <Box padding={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Deploy\" state={deployState} />\n\n <Button\n disabled={deployState.context.disabled}\n fontSize={1}\n icon={UploadIcon}\n mode=\"ghost\"\n onClick={handleDeploy}\n padding={3}\n text={`${deployState.context.label} ${targetName}`}\n tone=\"default\"\n />\n </Box>\n )\n}\n\nexport default DeployButton\n","import {Box} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\nconst PlaceholderAvatar = () => {\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '20px',\n height: '20px',\n userSelect: 'none',\n width: '20px',\n }}\n />\n )\n}\n\nexport default PlaceholderAvatar\n","import {Box, Stack, Text} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n rows: number\n}\n\nconst PlaceholderText = (props: Props) => {\n const {rows} = props\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '3px',\n userSelect: 'none',\n width: '100%',\n }}\n >\n <Stack space={2}>\n {new Array(rows).fill(undefined).map((_, index) => (\n <Text key={index} size={1}>\n &nbsp;\n </Text>\n ))}\n </Stack>\n </Box>\n )\n}\n\nexport default PlaceholderText\n","import {Flex} from '@sanity/ui'\nimport React from 'react'\n\nimport PlaceholderAvatar from '../PlaceholderAvatar'\nimport PlaceholderText from '../PlaceholderText'\nimport TableCell from '../TableCell'\n\nconst DeploymentPlaceholder = () => {\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <PlaceholderText rows={2} />\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex justify=\"center\">\n <PlaceholderAvatar />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default DeploymentPlaceholder\n","import {Box, Text, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useRef} from 'react'\nimport useDeepCompareEffect from 'use-deep-compare-effect'\n\nimport {WIDGET_NAME} from '../../constants'\nimport useDeployments from '../../hooks/useDeployments'\nimport refreshMachine from '../../machines/refresh'\nimport Deployment from '../Deployment'\nimport DeployButton from '../DeployButton'\nimport DeploymentPlaceholder from '../DeploymentPlaceholder'\nimport StateDebug from '../StateDebug'\nimport TableCell from '../TableCell'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n deploymentTarget: Sanity.DeploymentTarget\n}\n\nconst Deployments = (props: Props) => {\n const {deploymentTarget} = props\n\n // Refs\n const refTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // XState\n const [refreshState, refreshStateTransition] = useMachine(refreshMachine)\n\n // Fetch deployments - disable hook / auto-refetching on error state\n const {deployments, error, isFetching, isSuccess, refetch} = useDeployments(deploymentTarget, {\n enabled: !refreshState.matches('error'),\n })\n\n const toast = useToast()\n const isError = refreshState.matches('error')\n\n const handleDeploySuccess = () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n refTimeout.current = setTimeout(() => {\n refetch({\n cancelRefetch: true,\n throwOnError: true,\n })\n }, 4000)\n }\n\n useEffect(() => {\n return () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (error) {\n refreshStateTransition({type: 'ERROR'})\n }\n\n if (isFetching) {\n refreshStateTransition({type: 'REFRESH'})\n }\n\n if (!isFetching && isSuccess) {\n refreshStateTransition({type: 'REFRESHED'})\n }\n }, [error, isFetching, isSuccess, refreshStateTransition])\n\n useDeepCompareEffect(() => {\n if (!refreshState.matches('refreshing')) {\n refreshStateTransition({type: 'REFRESH'})\n }\n }, [deploymentTarget])\n\n useDeepCompareEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to fetch deployments for ${deploymentTarget.name}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n }, [deploymentTarget, isError])\n\n const hasFetched = typeof deployments !== 'undefined'\n const hasDeployments = deployments && deployments.length > 0\n\n const {border} = useCardColor()\n return (\n <Box marginTop={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Refresh\" state={refreshState} />\n\n {!refreshState.matches('error') && (\n <>\n <Box\n as=\"table\"\n style={{\n borderBottom: `1px solid ${border}`,\n borderCollapse: 'collapse',\n display: 'table',\n tableLayout: 'fixed',\n width: '100%',\n }}\n >\n <Box as=\"thead\" style={{display: 'table-header-group'}}>\n <tr>\n {/* Deployment */}\n <TableCell header>Deployment</TableCell>\n\n {/* State */}\n <TableCell header variant=\"state\">\n State\n </TableCell>\n\n {/* Branch */}\n <TableCell header variant=\"branch\">\n Branch\n </TableCell>\n\n {/* Age */}\n <TableCell header variant=\"age\">\n Age\n </TableCell>\n\n {/* Creator */}\n <TableCell header variant=\"age\">\n Creator\n </TableCell>\n </tr>\n </Box>\n\n <Box as=\"tbody\" style={{display: 'table-header-group'}}>\n {/* Placeholders */}\n {!deployments &&\n new Array(deploymentTarget?.deployLimit)\n .fill(undefined)\n .map((_, index) => <DeploymentPlaceholder key={index} />)}\n {/* Deployments */}\n {hasDeployments &&\n deployments?.map((deployment) => (\n <Deployment deployment={deployment} key={deployment.uid} />\n ))}\n </Box>\n </Box>\n\n {/* No results */}\n {hasFetched && !hasDeployments && (\n <Box padding={3} style={{width: '100%'}}>\n <Text muted size={1}>\n No deployments found. Don't forget to specify a valid team ID if your project\n belongs to a team.\n </Text>\n </Box>\n )}\n </>\n )}\n\n {/* Error message */}\n {refreshState.matches('error') && (\n <Box padding={3}>\n <Text muted size={1}>\n Unable to fetch recent deployments. Please check your network and deployment settings.\n </Text>\n </Box>\n )}\n\n {/* Deploy button */}\n {!refreshState.matches('error') && deploymentTarget.deployHook && (\n <Box>\n <DeployButton\n deployHook={deploymentTarget.deployHook}\n onDeploySuccess={handleDeploySuccess}\n targetName={deploymentTarget.name}\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport default Deployments\n","import {EditIcon} from '@sanity/icons'\nimport {Box, Button, Flex, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n\nimport Deployments from '../Deployments'\nimport {Sanity} from '../../types'\n\ntype Props = {\n item: Sanity.DeploymentTarget\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTarget: FC<Props> = (props: Props) => {\n const {item, onDialogEdit} = props\n\n const deploymentTarget = {\n deployHook: item.deployHook,\n deployLimit: item.deployLimit,\n name: item.name,\n projectId: item.projectId,\n teamId: item.teamId,\n token: item.token,\n } as Sanity.DeploymentTarget\n\n return (\n <Box style={{position: 'relative'}}>\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" marginTop={2} paddingX={3}>\n <Text size={2}>{item.name}</Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Edit deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={EditIcon} mode=\"bleed\" onClick={() => onDialogEdit(item)} />\n </Tooltip>\n </Flex>\n\n {/* Content */}\n <Deployments deploymentTarget={deploymentTarget} />\n </Box>\n )\n}\n\nexport default DeploymentTarget\n","import React from 'react'\nimport {Stack} from '@sanity/ui'\n\nimport DeploymentTarget from '../DeploymentTarget'\nimport {Sanity} from '../../types'\n\ntype Props = {\n items: Sanity.DeploymentTarget[]\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTargets = (props: Props) => {\n const {items, onDialogEdit} = props\n\n return (\n <Stack space={5}>\n {items?.map((item) => (\n <DeploymentTarget item={item} key={item._id} onDialogEdit={onDialogEdit} />\n ))}\n </Stack>\n )\n}\n\nexport default DeploymentTargets\n","import {assign, Machine} from 'xstate'\n\ntype Context = {\n formData?: Record<string, any>\n message: string\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'DELETE'}\n | {type: 'REJECT'}\n | {type: 'RESOLVE'}\n | {type: 'SUBMIT'}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n idle: {}\n creating: {}\n updating: {}\n deleting: {}\n success: {}\n error: {}\n }\n}\n\nconst formMachine = Machine<Context, Schema, Event>(\n {\n context: {\n formData: {},\n message: '',\n },\n initial: 'idle',\n states: {\n idle: {\n on: {\n CREATE: {\n actions: ['createDocument'],\n target: 'creating',\n },\n DELETE: {\n actions: ['deleteDocument'],\n target: 'deleting',\n },\n UPDATE: {\n actions: ['updateDocument'],\n target: 'updating',\n },\n },\n },\n creating: {\n invoke: {\n src: 'createDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n updating: {\n invoke: {\n src: 'updateDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n deleting: {\n invoke: {\n src: 'deleteDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n success: {\n invoke: {\n src: 'formSubmittedService',\n },\n },\n error: {},\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n createDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n deleteDocument: assign(() => ({\n // id: event.id,\n })),\n updateDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n },\n }\n)\n\nexport default formMachine\n","// Recursively sanitize form data:\n// - convert empty strings, undefined values and empty arrays to null (to correctly unset / delete fields)\n// - trim whitespace on string fleids\n\ntype FormData = Record<string, any>\n\nconst sanitizeFormData = (formData: FormData): FormData => {\n return Object.keys(formData).reduce((acc: FormData, key) => {\n const val = formData[key]\n\n // TODO: refactor\n if (typeof val === 'object' && val !== null && val.constructor !== Array) {\n acc[key] = sanitizeFormData(val)\n } else if (val === '' || typeof val === 'undefined' || val?.length === 0) {\n acc[key] = null\n } else if (typeof val === 'string' && val) {\n acc[key] = formData[key].trim()\n } else {\n acc[key] = formData[key]\n }\n\n return acc\n }, {})\n}\n\nexport default sanitizeFormData\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Inline, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n// @ts-expect-error - fix typings later\nimport {FieldError} from 'react-hook-form'\nimport {styled} from 'styled-components'\n\ntype Props = {\n description?: string\n error?: FieldError\n label: string\n name: string\n}\n\nconst StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({theme}) => {\n return {\n color: theme.sanity.color.spot.red,\n }\n})\n\nconst FormFieldInputLabel: FC<Props> = (props: Props) => {\n const {description, error, label, name} = props\n\n return (\n <Box marginBottom={3}>\n {/* Label */}\n <Inline space={2}>\n <Text as=\"label\" htmlFor={name} size={1} weight=\"semibold\">\n {label}\n </Text>\n\n {/* Error icon + tooltip */}\n {error && (\n <Text size={1}>\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n <StyledErrorOutlineIcon style={{marginRight: '0.1em'}} />\n {error.message}\n </Text>\n </Box>\n }\n fallbackPlacements={['top', 'left']}\n placement=\"right\"\n portal\n >\n <StyledErrorOutlineIcon />\n </Tooltip>\n </Text>\n )}\n </Inline>\n\n {/* Description */}\n {description && (\n <Box marginY={3}>\n <Text htmlFor={name} muted size={1}>\n {description}\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n\nexport default FormFieldInputLabel\n","import {Box, TextInput} from '@sanity/ui'\nimport React, {forwardRef} from 'react'\n// @ts-expect-error - fix typings later\nimport {FieldError} from 'react-hook-form'\n\nimport FormFieldInputLabel from '../FormFieldInputLabel'\n\ntype Props = {\n description?: string\n disabled?: boolean\n error?: FieldError\n label: string\n name: string\n placeholder?: string\n value?: string\n}\n\ntype Ref = HTMLInputElement\n\nconst FormFieldInputText = forwardRef<Ref, Props>((props: Props, ref) => {\n const {description, disabled, error, label, name, placeholder, value} = props\n\n return (\n <Box>\n {/* Label */}\n <FormFieldInputLabel description={description} error={error} label={label} name={name} />\n {/* Input */}\n <TextInput\n autoComplete=\"off\"\n autoFocus\n defaultValue={value}\n disabled={disabled}\n id={name}\n name={name}\n placeholder={placeholder}\n ref={ref}\n />\n </Box>\n )\n})\n\nexport default FormFieldInputText\n","import type {SanityClient} from '@sanity/client'\nimport {API_VERSION} from './constants'\nimport {useClient} from 'sanity'\n\nexport function useSanityClient(): SanityClient {\n return useClient({apiVersion: API_VERSION})\n}\n","// @ts-expect-error - fix typings later\nimport {yupResolver} from '@hookform/resolvers/yup'\nimport {Box, Button, Dialog, Flex, Stack} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport {useMachine} from '@xstate/react'\nimport React, {FC} from 'react'\n// @ts-expect-error - fix typings later\nimport {useForm} from 'react-hook-form'\nimport * as yup from 'yup'\n\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_DIALOG} from '../../constants'\nimport formMachine from '../../machines/form'\nimport sanitizeFormData from '../../utils/sanitizeFormData'\nimport FormFieldInputText from '../FormFieldInputText'\nimport {Sanity} from '../../types'\nimport {useSanityClient} from '../../client'\n\ntype Props = {\n deploymentTarget?: Sanity.DeploymentTarget\n onClose: () => void\n onCreate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n onDelete?: (id: string) => void\n onUpdate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\ntype FormData = yup.InferType<typeof formSchema>\n\nconst formSchema = yup.object().shape({\n deployHook: yup.string().url('Deploy hook must be a valid URL'),\n deployLimit: yup\n .number()\n .positive()\n .integer()\n .min(1, 'Deploy limit must no less than 1')\n .max(15, 'Deploy limit must no higher than 15')\n .typeError('Deploy limit must be a number')\n .required('Deploy limit must be a positive integer between 1 and 15'),\n name: yup.string().required('Name cannot be empty'),\n projectId: yup.string().required('Vercel Project ID cannot be empty'),\n teamId: yup.string(),\n token: yup.string().required('Vercel Account Token cannot be empty'),\n})\n\nconst DialogForm: FC<Props> = (props: Props) => {\n const {deploymentTarget, onClose, onCreate, onDelete, onUpdate} = props\n const client = useSanityClient()\n\n // xstate\n const [formState, formStateTransition] = useMachine(formMachine, {\n services: {\n formSubmittedService: async () => {\n onClose()\n },\n // TODO: refactor\n createDocumentService: async (_context, event: any) => {\n let document\n try {\n document = await client.create({\n _id: `vercel.${uuid()}`,\n _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,\n ...event.formData,\n })\n if (onCreate) {\n onCreate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n },\n // TODO: refactor\n deleteDocumentService: async () => {\n if (deploymentTarget) {\n try {\n await client.delete(deploymentTarget._id)\n if (onDelete) {\n onDelete(deploymentTarget._id)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n // TODO: refactor\n updateDocumentService: async (_context, event: any) => {\n let document\n if (deploymentTarget) {\n try {\n document = await client.patch(deploymentTarget._id).set(event.formData).commit()\n if (onUpdate) {\n onUpdate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n },\n })\n\n const formUpdating =\n formState.matches('creating') || formState.matches('deleting') || formState.matches('updating')\n\n // react-hook-form\n const {\n // Read the formState before render to subscribe the form state through Proxy\n formState: {errors, isDirty, isValid},\n handleSubmit,\n register,\n } = useForm({\n defaultValues: {\n deployHook: deploymentTarget?.deployHook || '',\n deployLimit: deploymentTarget?.deployLimit || 5,\n name: deploymentTarget?.name,\n projectId: deploymentTarget?.projectId,\n teamId: deploymentTarget?.teamId || '',\n token: deploymentTarget?.token,\n },\n mode: 'onChange',\n resolver: yupResolver(formSchema),\n })\n\n // Callbacks\n // - submit react-hook-form\n const onSubmit = async (formData: FormData) => {\n const sanitizedFormData = sanitizeFormData(formData)\n await formStateTransition(deploymentTarget ? 'UPDATE' : 'CREATE', {\n formData: sanitizedFormData,\n })\n }\n\n const handleDelete = () => {\n formStateTransition('DELETE', {id: deploymentTarget?._id})\n }\n\n const Footer = () => (\n <Box padding={3}>\n <Flex justify={deploymentTarget ? 'space-between' : 'flex-end'}>\n {/* Delete button */}\n {deploymentTarget && (\n <Button\n disabled={formUpdating}\n fontSize={1}\n mode=\"bleed\"\n onClick={handleDelete}\n text=\"Delete\"\n tone=\"critical\"\n />\n )}\n\n {/* Submit button */}\n <Button\n disabled={formUpdating || !isDirty || !isValid}\n fontSize={1}\n onClick={handleSubmit(onSubmit)}\n text={deploymentTarget ? 'Update and close' : 'Create'}\n tone=\"primary\"\n />\n </Flex>\n </Box>\n )\n\n return (\n <Dialog\n footer={<Footer />}\n header={`${deploymentTarget ? 'Edit' : 'Create'} deployment target`}\n id=\"create\"\n onClose={onClose}\n width={1}\n zOffset={Z_INDEX_DIALOG}\n >\n {/* We reverse direction to ensure that inline links dont autofocus before other form elements */}\n <Box as=\"form\" padding={4} onSubmit={handleSubmit(onSubmit)}>\n {/* Hidden button to enable enter key submissions */}\n <button style={{display: 'none'}} tabIndex={-1} type=\"submit\" />\n\n {/* Form fields */}\n <Stack space={5}>\n {/* Title */}\n <FormFieldInputText\n disabled={formUpdating}\n description=\"Name displayed in this plugin (e.g. production, staging)\"\n error={errors?.name}\n label=\"Name\"\n name=\"name\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.token}\n label=\"Vercel Account Token\"\n name=\"token\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.projectId}\n label=\"Vercel Project ID\"\n name=\"projectId\"\n ref={register}\n />\n\n <FormFieldInputText\n description=\"Required only if your project is owned by a team account\"\n disabled={formUpdating}\n error={errors?.teamId}\n label=\"Vercel Team ID (optional)\"\n name=\"teamId\"\n ref={register}\n />\n\n <FormFieldInputText\n description=\"Enter a valid deploy hook URL to enable manual deploys\"\n disabled={formUpdating}\n error={errors?.deployHook}\n label=\"Vercel Deploy Hook (optional)\"\n name=\"deployHook\"\n ref={register}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.deployLimit}\n label=\"Number of deploys to display\"\n name=\"deployLimit\"\n ref={register({valueAsNumber: true})}\n />\n </Stack>\n </Box>\n </Dialog>\n )\n}\n\nexport default DialogForm\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n editDeploymentTarget?: Sanity.DeploymentTarget\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'CLOSE'}\n | {type: 'EDIT'; deploymentTarget: Sanity.DeploymentTarget}\n\ntype Schema = {\n states: {\n idle: {}\n edit: {}\n create: {}\n }\n}\n\nconst dialogMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n editDeploymentTarget: undefined,\n },\n initial: 'idle',\n states: {\n idle: {\n entry: assign({\n editDeploymentTarget: () => undefined,\n }),\n on: {\n CREATE: 'create',\n EDIT: {\n actions: ['setEditDeploymentTarget'],\n target: 'edit',\n },\n },\n },\n edit: {\n on: {\n CLOSE: 'idle',\n },\n },\n create: {\n on: {\n CLOSE: 'idle',\n },\n },\n },\n },\n {\n actions: {\n setEditDeploymentTarget: assign((_context, event: any) => ({\n editDeploymentTarget: event.deploymentTarget,\n })),\n },\n }\n )\n\nexport default dialogMachine\n","import {AddIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, ToastProvider, Tooltip} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React from 'react'\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query'\n\nimport StateDebug from './components/StateDebug'\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_TOAST_PROVIDER} from './constants'\nimport deploymentTargetListMachine from './machines/deploymentTargetList'\nimport DeploymentTargets from './components/DeploymentTargets'\nimport DialogForm from './components/DialogForm'\nimport dialogMachine from './machines/dialog'\nimport {Sanity} from './types'\nimport {useSanityClient} from './client'\n\nconst Widget = () => {\n const client = useSanityClient()\n // xstate\n const [deploymentTargetListState, deploymentTargetListStateTransition] = useMachine(\n deploymentTargetListMachine,\n {\n services: {\n fetchDataService: () => {\n return client\n .fetch(`*[_type == \"${DEPLOYMENT_TARGET_DOCUMENT_TYPE}\"] | order(name asc)`)\n .then((result: any) => result)\n },\n },\n }\n )\n const [dialogState, dialogStateTransition] = useMachine(dialogMachine)\n\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n gcTime: 0,\n staleTime: 0,\n },\n },\n })\n\n // Callbacks\n const handleDialogClose = () => {\n dialogStateTransition('CLOSE')\n }\n const handleDialogShowCreate = () => {\n dialogStateTransition('CREATE')\n }\n const handleDialogShowEdit = (deploymentTarget: Sanity.DeploymentTarget) => {\n dialogStateTransition('EDIT', {deploymentTarget})\n }\n const handleTargetCreate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('CREATE', {deploymentTarget})\n }\n const handleTargetDelete = (id: string) => {\n deploymentTargetListStateTransition('DELETE', {id})\n }\n const handleTargetUpdate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('UPDATE', {deploymentTarget})\n }\n\n return (\n <ToastProvider zOffset={Z_INDEX_TOAST_PROVIDER}>\n <QueryClientProvider client={queryClient}>\n <Card radius={2} style={{overflow: 'hidden '}}>\n {/* xstate debug */}\n <StateDebug name=\"List\" state={deploymentTargetListState} />\n\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" paddingX={3} paddingY={2}>\n <Text size={5} weight=\"semibold\">\n Vercel deployments\n </Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Create new deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={AddIcon} onClick={handleDialogShowCreate} mode=\"bleed\" />\n </Tooltip>\n </Flex>\n\n <Box>\n {deploymentTargetListState.matches('pending') && (\n <Box paddingX={3} paddingY={4}>\n <Text>Loading...</Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withoutData') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n No deployment targets found.{' '}\n <a onClick={handleDialogShowCreate} style={{cursor: 'pointer'}}>\n Create a new target?\n </a>\n </Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withData') && (\n <DeploymentTargets\n items={deploymentTargetListState.context.results}\n onDialogEdit={handleDialogShowEdit}\n />\n )}\n\n {deploymentTargetListState.matches('failed') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n Failed to retrieve deployment targets. Please check the developer console log for\n more information.\n </Text>\n </Box>\n )}\n </Box>\n </Card>\n\n {/* Dialogs */}\n {dialogState.matches('create') && (\n <DialogForm onClose={handleDialogClose} onCreate={handleTargetCreate} />\n )}\n\n {dialogState.matches('edit') && (\n <DialogForm\n deploymentTarget={dialogState.context.editDeploymentTarget}\n onClose={handleDialogClose}\n onDelete={handleTargetDelete}\n onUpdate={handleTargetUpdate}\n />\n )}\n </QueryClientProvider>\n </ToastProvider>\n )\n}\n\nexport default Widget\n","import Widget from './app'\n\n// Initialize `javascript-time-ago` locale (required for react-time-ago)\nimport TimeAgo from 'javascript-time-ago'\nimport en from 'javascript-time-ago/locale/en'\nimport {DashboardWidget, type LayoutConfig} from '@sanity/dashboard'\n\nTimeAgo.addDefaultLocale(en)\n\nexport function vercelWidget(config: {layout?: LayoutConfig} = {}): DashboardWidget {\n return {\n name: 'vercel',\n component: Widget,\n layout: config.layout ?? {width: 'full'},\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/constants.ts","../src/components/StateDebug/index.tsx","../src/machines/deploymentTargetList.ts","../src/utils/fetcher.ts","../src/hooks/useDeployments.ts","../src/machines/refresh.ts","../src/utils/useCardColor.ts","../src/components/TableCell/index.tsx","../src/components/StatusDot/index.tsx","../src/components/Deployment/index.tsx","../src/machines/deploy.ts","../src/components/DeployButton/index.tsx","../src/components/PlaceholderAvatar/index.tsx","../src/components/PlaceholderText/index.tsx","../src/components/DeploymentPlaceholder/index.tsx","../src/components/Deployments/index.tsx","../src/components/DeploymentTarget/index.tsx","../src/components/DeploymentTargets/index.tsx","../src/machines/form.ts","../src/utils/sanitizeFormData.ts","../src/components/FormFieldInputLabel/index.tsx","../src/components/FormFieldInputText/index.tsx","../src/client.ts","../src/components/DialogForm/index.tsx","../src/machines/dialog.ts","../src/app.tsx","../src/index.ts"],"sourcesContent":["// https://vercel.com/docs/platform/limits\nexport const API_ENDPOINT_DEPLOYMENTS = 'https://api.vercel.com/v5/now/deployments'\nexport const API_ENDPOINT_ALIASES = 'https://api.vercel.com/v3/now/aliases'\n\n// Sanity API version\nexport const API_VERSION = '1'\n\nexport const DEBUG_MODE = false\n\nexport const DEPLOYMENT_TARGET_DOCUMENT_TYPE = 'vercel.deploymentTarget'\n\nexport const VERCEL_STATUS_COLORS = {\n BUILDING: '#f5a623',\n CANCELED: '#ff0000',\n ERROR: '#ff0000',\n READY: '#50e3c2',\n QUEUED: '#333',\n}\n\n// Name displayed in toasts\nexport const WIDGET_NAME = 'Vercel (dashboard)'\n\n// NOTE: Manually set plugin z-index values to be higher than Sanity's header search field\n// (which is currently 500202). Also ensure toasts always sit above dialogs.\nexport const Z_INDEX_DIALOG = 600001\nexport const Z_INDEX_TOAST_PROVIDER = 600002\n","import {Box, Card, Stack, Text} from '@sanity/ui'\nimport React from 'react'\n\nimport {DEBUG_MODE} from '../../constants'\n\ntype Props = {\n name: string\n state: any // TODO: type correctly\n}\n\nconst StateDebug = (props: Props) => {\n const {name, state} = props\n\n if (!DEBUG_MODE) {\n return null\n }\n\n return (\n <Card\n scheme=\"dark\"\n style={{\n backgroundColor: 'rgba(0, 0, 255, 0.9)',\n borderRadius: '3px',\n fontSize: 1,\n fontWeight: 500,\n lineHeight: 'body',\n right: 0,\n opacity: 0.75,\n pointerEvents: 'none',\n position: 'absolute',\n textAlign: 'left',\n top: 0,\n zIndex: 9000,\n }}\n >\n <Box padding={2}>\n <Stack space={2}>\n <Text size={0}>Name: {name}</Text>\n <Text size={0}>state.value: {JSON.stringify(state.value)}</Text>\n </Stack>\n </Box>\n </Card>\n )\n}\n\nexport default StateDebug\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n message: string\n results: Sanity.DeploymentTarget[] // TODO: type correctly\n}\n\ntype Event =\n | {type: 'CLOSE'}\n | {type: 'CREATE'; deploymentTarget: Sanity.DeploymentTarget}\n | {type: 'DELETE'; id: string}\n | {type: 'FETCH'}\n | {type: 'REJECT'; message: string}\n | {type: 'RESOLVE'; results: any[]}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n failed: {}\n pending: {}\n ready: {\n states: {\n unknown: {}\n withData: {}\n withoutData: {}\n }\n }\n }\n}\n\nconst sortByTargetName = (items: Sanity.DeploymentTarget[]) => {\n return items.sort((a, b) => {\n if (a.name > b.name) {\n return 1\n }\n\n if (a.name < b.name) {\n return -1\n }\n\n return 0\n })\n}\n\nconst deploymentTargetListMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n message: '',\n results: [],\n },\n initial: 'pending',\n states: {\n pending: {\n invoke: {\n src: 'fetchDataService',\n onDone: {actions: ['setResults'], target: 'ready'},\n onError: {actions: ['setMessage'], target: 'failed'},\n },\n },\n ready: {\n initial: 'unknown',\n on: {\n CREATE: {actions: ['targetCreate']},\n DELETE: {actions: ['targetDelete']},\n UPDATE: {actions: ['targetUpdate']},\n },\n states: {\n unknown: {\n always: [\n {cond: 'hasData', target: 'withData'},\n {cond: 'hasNoData', target: 'withoutData'},\n ],\n },\n withData: {\n always: [{cond: 'hasNoData', target: 'withoutData'}],\n },\n withoutData: {\n always: [{cond: 'hasData', target: 'withData'}],\n },\n },\n },\n failed: {\n type: 'final',\n },\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n setResults: assign((_context, event: any) => ({\n results: event.data,\n })),\n targetCreate: assign((context, event: any) => ({\n results: sortByTargetName([...context.results, event.deploymentTarget]),\n })),\n targetDelete: assign((context, event: any) => ({\n results: context.results.filter((target) => target._id !== event.id),\n })),\n targetUpdate: assign((context, event: any) => {\n const {deploymentTarget} = event\n const index = context.results.findIndex((target) => target._id === deploymentTarget._id)\n const updatedResults = Object.assign([], context.results, {\n [index]: event.deploymentTarget,\n })\n\n return {\n results: sortByTargetName(updatedResults),\n }\n }),\n },\n guards: {\n hasData: (context) => {\n return context?.results?.length > 0\n },\n hasNoData: (context) => {\n return context?.results?.length === 0\n },\n },\n }\n )\n\nexport default deploymentTargetListMachine\n","import fetch from 'unfetch'\nimport {Sanity} from '../types'\n\nconst fetcher =\n (deploymentTarget: Sanity.DeploymentTarget) =>\n async (url: string, extraParams?: URLSearchParams) => {\n const params = new URLSearchParams()\n params.set('projectId', deploymentTarget.projectId)\n if (deploymentTarget.teamId) {\n params.set('teamId', deploymentTarget.teamId)\n }\n\n if (extraParams) {\n for (const [k, v] of extraParams.entries()) {\n params.append(k, v)\n }\n }\n\n const response = await fetch(`${url}?${params.toString()}`, {\n headers: {\n Authorization: `Bearer ${deploymentTarget.token}`,\n },\n })\n\n // Manually throw on non-OK responses for react-query\n // https://react-query.tanstack.com/guides/query-functions#usage-with-fetch-and-others-clients-that-do-not-throw-by-default\n if (!response.ok) {\n throw new Error('Response not OK')\n }\n\n try {\n return response.json()\n } catch (err) {\n throw new Error(err as string)\n }\n }\n\nexport default fetcher\n","import hash from 'object-hash'\nimport {useQuery} from '@tanstack/react-query'\n\nimport fetcher from '../utils/fetcher'\nimport {API_ENDPOINT_ALIASES, API_ENDPOINT_DEPLOYMENTS} from '../constants'\nimport {Sanity, Vercel} from '../types'\n\ntype Options = {\n enabled?: boolean\n}\n\nconst useDeployments = (deploymentTarget: Sanity.DeploymentTarget, options?: Options) => {\n const fetchUrl = fetcher(deploymentTarget)\n\n // Fetch deployments\n const deployParams = new URLSearchParams()\n deployParams.set('limit', String(deploymentTarget?.deployLimit))\n\n const {\n data: deploymentsData,\n isFetching: deploymentsIsFetching,\n isSuccess: deploymentsIsSuccess,\n error: deploymentsError,\n refetch,\n } = useQuery<{deployments: Vercel.Deployment[]}, Error>({\n queryKey: [hash(deploymentTarget)],\n queryFn: () => fetchUrl(API_ENDPOINT_DEPLOYMENTS, deployParams),\n enabled: options?.enabled ?? true,\n refetchInterval: 20000, // ms\n refetchIntervalInBackground: false,\n refetchOnMount: true,\n refetchOnReconnect: 'always',\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n // Fetch aliases (only if deployments have been retrieved)\n const aliasParams = new URLSearchParams()\n aliasParams.set('limit', '20')\n\n const {\n data: aliasesData,\n isFetching: aliasesIsFetching,\n isSuccess: aliasesIsSuccess,\n error: aliasesError,\n } = useQuery<\n {\n aliases: Vercel.Alias[]\n pagination: {\n count: number\n next?: number\n prev?: number\n }\n },\n Error\n >({\n queryKey: [hash(deploymentTarget), 'aliases'],\n queryFn: () => fetchUrl(API_ENDPOINT_ALIASES, aliasParams),\n enabled: !!deploymentsData,\n refetchOnMount: false,\n refetchOnReconnect: false,\n refetchOnWindowFocus: false,\n retry: false,\n })\n\n const aliases = aliasesData?.aliases as Vercel.Alias[]\n\n let deploymentsWithAlias: Vercel.DeploymentWithAlias[] | undefined\n\n if (aliases) {\n deploymentsWithAlias = deploymentsData?.deployments?.map((val: Vercel.DeploymentWithAlias) => {\n const alias = aliases.find((a) => a.deploymentId === val.uid)\n return {\n ...val,\n alias: alias?.alias,\n }\n })\n }\n\n return {\n deployments: deploymentsWithAlias,\n error: aliasesError || deploymentsError,\n isFetching: aliasesIsFetching || deploymentsIsFetching,\n isSuccess: aliasesIsSuccess && deploymentsIsSuccess,\n refetch,\n }\n}\n\nexport default useDeployments\n","import {Machine} from 'xstate'\n\ntype Context = {}\n\ntype Event = {type: 'ERROR'} | {type: 'REFRESH'} | {type: 'REFRESHED'} | {type: 'RETRY'}\n\ntype Schema = {\n states: {\n idle: {}\n refreshing: {}\n refreshed: {}\n error: {}\n }\n}\n\nconst refreshMachine = Machine<Context, Schema, Event>({\n initial: 'idle',\n states: {\n idle: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n refreshing: {\n on: {\n ERROR: 'error',\n REFRESHED: 'refreshed',\n },\n },\n refreshed: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n error: {\n on: {\n REFRESH: 'refreshing',\n },\n },\n },\n})\n\nexport default refreshMachine\n","import {useTheme} from '@sanity/ui'\n\nexport function useCardColor() {\n return useTheme().sanity.color.card.enabled\n}\n","import {Box, Label} from '@sanity/ui'\nimport React, {ReactNode} from 'react'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n children: ReactNode\n colSpan?: number\n header?: boolean\n variant?: 'age' | 'branch' | 'creator' | 'state'\n}\n\nconst TableCell = (props: Props) => {\n const {children, colSpan, header, variant} = props\n\n let display: Sanity.BoxDisplay | Sanity.BoxDisplay[] = 'table-cell'\n let cellWidth: string = 'auto'\n\n switch (variant) {\n case 'age':\n cellWidth = '50px'\n break\n case 'branch':\n cellWidth = '300px'\n display = ['none', 'none', 'none', 'table-cell']\n break\n case 'creator':\n cellWidth = '80px'\n break\n case 'state':\n cellWidth = '110px'\n display = ['none', 'none', 'none', 'none', 'table-cell']\n break\n default:\n break\n }\n\n const {border} = useCardColor()\n\n if (header) {\n return (\n <Box\n as=\"th\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={2}\n style={{\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n <Label size={0}>{children}</Label>\n </Box>\n )\n }\n return (\n <Box\n as=\"td\"\n colSpan={colSpan}\n // @ts-ignore\n display={display}\n paddingX={3}\n paddingY={[2, 2, 3]}\n style={{\n borderTop: `1px solid ${border}`,\n maxWidth: cellWidth,\n position: 'relative',\n textAlign: 'left',\n width: cellWidth,\n }}\n >\n {children}\n </Box>\n )\n}\n\nexport default TableCell\n","import {Box} from '@sanity/ui'\nimport React from 'react'\n\nimport {VERCEL_STATUS_COLORS} from '../../constants'\nimport {Vercel} from '../../types'\n\ntype Props = {\n state: Vercel.DeploymentState\n}\n\nconst StatusDot = ({state}: Props) => (\n <Box\n style={{\n backgroundColor: `${VERCEL_STATUS_COLORS[state]}`,\n borderRadius: '20px',\n height: '9px',\n width: '9px',\n }}\n />\n)\n\nexport default StatusDot\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport ReactTimeAgo from 'react-time-ago'\n\nimport TableCell from '../TableCell'\nimport StatusDot from '../StatusDot'\nimport {LinkIcon} from '@sanity/icons'\nimport {Vercel} from '../../types'\n\ntype Props = {\n deployment: Vercel.DeploymentWithAlias\n}\n\nconst Deployment = (props: Props) => {\n const {deployment} = props\n\n const date = useRef(new Date(deployment.created))\n\n const commitMessage = deployment?.meta?.githubCommitMessage\n const commitRef = deployment?.meta?.githubCommitRef\n\n const targetUrl = deployment.alias ?? deployment.url\n\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <Flex align=\"center\">\n <Box\n display={['block', 'block', 'block', 'block', 'none']}\n marginRight={3}\n style={{flexShrink: 0}}\n >\n <StatusDot state={deployment.state} />\n </Box>\n\n {targetUrl ? (\n <>\n {/* Alias icon */}\n {deployment.alias && <LinkIcon />}\n\n <Box marginLeft={deployment.alias ? 1 : 0}>\n <Text\n muted={!(deployment.state === 'READY')}\n size={1}\n style={{\n textDecoration:\n deployment.state === 'CANCELED' || deployment.state === 'ERROR'\n ? 'line-through'\n : 'normal',\n }}\n textOverflow=\"ellipsis\"\n >\n {deployment.state === 'READY' ? (\n <a href={`https://${targetUrl}`} rel=\"noopener noreferrer\" target=\"_blank\">\n {targetUrl}\n </a>\n ) : (\n targetUrl\n )}\n </Text>\n </Box>\n </>\n ) : (\n <Text size={1}>Uploading...</Text>\n )}\n </Flex>\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <Flex align=\"center\">\n <StatusDot state={deployment.state} />\n <Box marginLeft={2}>\n <Text size={1}>\n {deployment.state\n .trim()\n .toLowerCase()\n .replace(/^[a-z]/i, (t) => t.toUpperCase())}\n </Text>\n </Box>\n </Flex>\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <Stack space={2}>\n <Text size={1} textOverflow=\"ellipsis\">\n {commitRef}\n </Text>\n {commitMessage && (\n <Text muted size={1} textOverflow=\"ellipsis\">\n {commitMessage}\n </Text>\n )}\n </Stack>\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <Flex align=\"center\">\n <Text size={1}>\n <ReactTimeAgo date={date.current} locale=\"en-US\" timeStyle=\"mini\" />\n </Text>\n </Flex>\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex align=\"center\" justify=\"center\">\n <img\n draggable={false}\n src={`https://vercel.com/api/www/avatar/${deployment?.creator?.uid}?&s=48`}\n style={{\n borderRadius: '20px',\n height: '20px',\n width: '20px',\n }}\n />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default Deployment\n","import fetch from 'unfetch'\nimport {assign, Machine} from 'xstate'\nimport {Vercel} from '../types'\n\ntype Context = {\n disabled: boolean\n feedback?: string\n label?: string\n error?: string\n}\n\ntype Event = {type: 'DEPLOY'}\n\ntype Schema = {\n states: {\n idle: {}\n deploying: {}\n success: {}\n error: {}\n }\n}\n\nconst deployMachine = (deployHook: string) =>\n Machine<Context, Schema, Event>(\n // Machine\n {\n id: 'deploy',\n initial: 'idle',\n context: {\n disabled: false,\n feedback: undefined,\n label: undefined,\n error: undefined,\n },\n states: {\n idle: {\n entry: assign({\n feedback: () => undefined,\n label: () => 'Deploy',\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n deploying: {\n entry: assign({\n disabled: () => true,\n label: () => 'Deploying',\n }),\n exit: assign({\n disabled: () => false,\n label: () => 'Deploy',\n }),\n invoke: {\n onDone: {\n target: 'success',\n },\n onError: {\n target: 'error',\n actions: assign({\n error: (_context, event) => {\n return event.data\n },\n }),\n },\n src: 'deploy',\n },\n },\n success: {\n entry: [assign({feedback: () => 'Succesfully started!'})],\n exit: assign({\n feedback: () => undefined,\n }),\n on: {\n DEPLOY: 'deploying',\n },\n },\n error: {\n on: {\n DEPLOY: 'deploying',\n },\n },\n },\n },\n // Config\n {\n services: {\n deploy: (): Promise<void> => {\n return new Promise(async (resolve, reject) => {\n try {\n if (!deployHook) {\n return reject(new Error('No deployHook URL defined'))\n }\n\n const res = await fetch(deployHook, {method: 'POST'})\n const data = await res.json()\n\n if (!res.ok) {\n const errorMessage = (data?.error as Vercel.Error).message || res.statusText\n return reject(errorMessage)\n }\n\n return resolve()\n } catch (err) {\n console.error('Unable to deploy with error:', err)\n return reject(new Error('Please check the developer console for more information'))\n }\n })\n },\n },\n }\n )\n\nexport default deployMachine\n","import {UploadIcon} from '@sanity/icons'\nimport {Box, Button, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useMemo} from 'react'\n\nimport {WIDGET_NAME} from '../../constants'\nimport deployMachine from '../../machines/deploy'\nimport StateDebug from '../StateDebug'\n\ntype Props = {\n deployHook: string\n onDeploySuccess?: () => void\n targetName: string\n}\n\nconst DeployButton = (props: Props) => {\n const {deployHook, onDeploySuccess, targetName} = props\n\n const machine = useMemo(() => deployMachine(deployHook), [deployHook])\n\n const [deployState, deployStateTransition, deployStateInterpreter] = useMachine(machine)\n\n const toast = useToast()\n\n const isError = deployState.matches('error')\n const isSuccess = deployState.matches('success')\n\n // Callbacks\n const handleDeploy = () => {\n deployStateTransition({type: 'DEPLOY'})\n }\n\n // Effects\n useEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to queue deploy for ${targetName}: ${deployState.context.error}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n\n if (isSuccess) {\n toast.push({\n closable: true,\n description: `Deploy queued for ${targetName}`,\n duration: 8000,\n status: 'success',\n title: WIDGET_NAME,\n })\n }\n }, [isError, isSuccess, toast, targetName, deployState.context.error])\n\n useEffect(() => {\n deployStateInterpreter.onTransition((state) => {\n if (state.value === 'success') {\n if (onDeploySuccess) {\n onDeploySuccess()\n }\n }\n })\n }, [deployStateInterpreter, onDeploySuccess])\n\n return (\n <Box padding={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Deploy\" state={deployState} />\n\n <Button\n disabled={deployState.context.disabled}\n fontSize={1}\n icon={UploadIcon}\n mode=\"ghost\"\n onClick={handleDeploy}\n padding={3}\n text={`${deployState.context.label} ${targetName}`}\n tone=\"default\"\n />\n </Box>\n )\n}\n\nexport default DeployButton\n","import {Box} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\nconst PlaceholderAvatar = () => {\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '20px',\n height: '20px',\n userSelect: 'none',\n width: '20px',\n }}\n />\n )\n}\n\nexport default PlaceholderAvatar\n","import {Box, Stack, Text} from '@sanity/ui'\nimport React from 'react'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n rows: number\n}\n\nconst PlaceholderText = (props: Props) => {\n const {rows} = props\n const {border} = useCardColor()\n return (\n <Box\n style={{\n backgroundColor: border,\n borderRadius: '3px',\n userSelect: 'none',\n width: '100%',\n }}\n >\n <Stack space={2}>\n {new Array(rows).fill(undefined).map((_, index) => (\n <Text key={index} size={1}>\n &nbsp;\n </Text>\n ))}\n </Stack>\n </Box>\n )\n}\n\nexport default PlaceholderText\n","import {Flex} from '@sanity/ui'\nimport React from 'react'\n\nimport PlaceholderAvatar from '../PlaceholderAvatar'\nimport PlaceholderText from '../PlaceholderText'\nimport TableCell from '../TableCell'\n\nconst DeploymentPlaceholder = () => {\n return (\n <tr>\n {/* Deployment - alias or regular deployment URL */}\n <TableCell>\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* State */}\n <TableCell variant=\"state\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Branch */}\n <TableCell variant=\"branch\">\n <PlaceholderText rows={2} />\n </TableCell>\n\n {/* Age */}\n <TableCell variant=\"age\">\n <PlaceholderText rows={1} />\n </TableCell>\n\n {/* Creator */}\n <TableCell variant=\"creator\">\n <Flex justify=\"center\">\n <PlaceholderAvatar />\n </Flex>\n </TableCell>\n </tr>\n )\n}\n\nexport default DeploymentPlaceholder\n","import {Box, Text, useToast} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React, {useEffect, useRef} from 'react'\nimport useDeepCompareEffect from 'use-deep-compare-effect'\n\nimport {WIDGET_NAME} from '../../constants'\nimport useDeployments from '../../hooks/useDeployments'\nimport refreshMachine from '../../machines/refresh'\nimport Deployment from '../Deployment'\nimport DeployButton from '../DeployButton'\nimport DeploymentPlaceholder from '../DeploymentPlaceholder'\nimport StateDebug from '../StateDebug'\nimport TableCell from '../TableCell'\nimport {Sanity} from '../../types'\nimport {useCardColor} from '../../utils/useCardColor'\n\ntype Props = {\n deploymentTarget: Sanity.DeploymentTarget\n}\n\nconst Deployments = (props: Props) => {\n const {deploymentTarget} = props\n\n // Refs\n const refTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // XState\n const [refreshState, refreshStateTransition] = useMachine(refreshMachine)\n\n // Fetch deployments - disable hook / auto-refetching on error state\n const {deployments, error, isFetching, isSuccess, refetch} = useDeployments(deploymentTarget, {\n enabled: !refreshState.matches('error'),\n })\n\n const toast = useToast()\n const isError = refreshState.matches('error')\n\n const handleDeploySuccess = () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n refTimeout.current = setTimeout(() => {\n refetch({\n cancelRefetch: true,\n throwOnError: true,\n })\n }, 4000)\n }\n\n useEffect(() => {\n return () => {\n if (refTimeout.current) {\n clearTimeout(refTimeout.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (error) {\n refreshStateTransition({type: 'ERROR'})\n }\n\n if (isFetching) {\n refreshStateTransition({type: 'REFRESH'})\n }\n\n if (!isFetching && isSuccess) {\n refreshStateTransition({type: 'REFRESHED'})\n }\n }, [error, isFetching, isSuccess, refreshStateTransition])\n\n useDeepCompareEffect(() => {\n if (!refreshState.matches('refreshing')) {\n refreshStateTransition({type: 'REFRESH'})\n }\n }, [deploymentTarget])\n\n useDeepCompareEffect(() => {\n if (isError) {\n toast.push({\n closable: true,\n description: `Unable to fetch deployments for ${deploymentTarget.name}`,\n duration: 8000,\n status: 'error',\n title: WIDGET_NAME,\n })\n }\n }, [deploymentTarget, isError])\n\n const hasFetched = typeof deployments !== 'undefined'\n const hasDeployments = deployments && deployments.length > 0\n\n const {border} = useCardColor()\n return (\n <Box marginTop={3} style={{position: 'relative'}}>\n {/* xstate debug */}\n <StateDebug name=\"Refresh\" state={refreshState} />\n\n {!refreshState.matches('error') && (\n <>\n <Box\n as=\"table\"\n style={{\n borderBottom: `1px solid ${border}`,\n borderCollapse: 'collapse',\n display: 'table',\n tableLayout: 'fixed',\n width: '100%',\n }}\n >\n <Box as=\"thead\" style={{display: 'table-header-group'}}>\n <tr>\n {/* Deployment */}\n <TableCell header>Deployment</TableCell>\n\n {/* State */}\n <TableCell header variant=\"state\">\n State\n </TableCell>\n\n {/* Branch */}\n <TableCell header variant=\"branch\">\n Branch\n </TableCell>\n\n {/* Age */}\n <TableCell header variant=\"age\">\n Age\n </TableCell>\n\n {/* Creator */}\n <TableCell header variant=\"age\">\n Creator\n </TableCell>\n </tr>\n </Box>\n\n <Box as=\"tbody\" style={{display: 'table-header-group'}}>\n {/* Placeholders */}\n {!deployments &&\n new Array(deploymentTarget?.deployLimit)\n .fill(undefined)\n .map((_, index) => <DeploymentPlaceholder key={index} />)}\n {/* Deployments */}\n {hasDeployments &&\n deployments?.map((deployment) => (\n <Deployment deployment={deployment} key={deployment.uid} />\n ))}\n </Box>\n </Box>\n\n {/* No results */}\n {hasFetched && !hasDeployments && (\n <Box padding={3} style={{width: '100%'}}>\n <Text muted size={1}>\n No deployments found. Don't forget to specify a valid team ID if your project\n belongs to a team.\n </Text>\n </Box>\n )}\n </>\n )}\n\n {/* Error message */}\n {refreshState.matches('error') && (\n <Box padding={3}>\n <Text muted size={1}>\n Unable to fetch recent deployments. Please check your network and deployment settings.\n </Text>\n </Box>\n )}\n\n {/* Deploy button */}\n {!refreshState.matches('error') && deploymentTarget.deployHook && (\n <Box>\n <DeployButton\n deployHook={deploymentTarget.deployHook}\n onDeploySuccess={handleDeploySuccess}\n targetName={deploymentTarget.name}\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport default Deployments\n","import {EditIcon} from '@sanity/icons'\nimport {Box, Button, Flex, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\n\nimport Deployments from '../Deployments'\nimport {Sanity} from '../../types'\n\ntype Props = {\n item: Sanity.DeploymentTarget\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTarget: FC<Props> = (props: Props) => {\n const {item, onDialogEdit} = props\n\n const deploymentTarget = {\n deployHook: item.deployHook,\n deployLimit: item.deployLimit,\n name: item.name,\n projectId: item.projectId,\n teamId: item.teamId,\n token: item.token,\n } as Sanity.DeploymentTarget\n\n return (\n <Box style={{position: 'relative'}}>\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" marginTop={2} paddingX={3}>\n <Text size={2}>{item.name}</Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Edit deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={EditIcon} mode=\"bleed\" onClick={() => onDialogEdit(item)} />\n </Tooltip>\n </Flex>\n\n {/* Content */}\n <Deployments deploymentTarget={deploymentTarget} />\n </Box>\n )\n}\n\nexport default DeploymentTarget\n","import React from 'react'\nimport {Stack} from '@sanity/ui'\n\nimport DeploymentTarget from '../DeploymentTarget'\nimport {Sanity} from '../../types'\n\ntype Props = {\n items: Sanity.DeploymentTarget[]\n onDialogEdit: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\nconst DeploymentTargets = (props: Props) => {\n const {items, onDialogEdit} = props\n\n return (\n <Stack space={5}>\n {items?.map((item) => (\n <DeploymentTarget item={item} key={item._id} onDialogEdit={onDialogEdit} />\n ))}\n </Stack>\n )\n}\n\nexport default DeploymentTargets\n","import {assign, Machine} from 'xstate'\n\ntype Context = {\n formData?: Record<string, any>\n message: string\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'DELETE'}\n | {type: 'REJECT'}\n | {type: 'RESOLVE'}\n | {type: 'SUBMIT'}\n | {type: 'UPDATE'}\n\ntype Schema = {\n states: {\n idle: {}\n creating: {}\n updating: {}\n deleting: {}\n success: {}\n error: {}\n }\n}\n\nconst formMachine = Machine<Context, Schema, Event>(\n {\n context: {\n formData: {},\n message: '',\n },\n initial: 'idle',\n states: {\n idle: {\n on: {\n CREATE: {\n actions: ['createDocument'],\n target: 'creating',\n },\n DELETE: {\n actions: ['deleteDocument'],\n target: 'deleting',\n },\n UPDATE: {\n actions: ['updateDocument'],\n target: 'updating',\n },\n },\n },\n creating: {\n invoke: {\n src: 'createDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n updating: {\n invoke: {\n src: 'updateDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n deleting: {\n invoke: {\n src: 'deleteDocumentService',\n onDone: {target: 'success'},\n onError: {actions: ['setMessage'], target: 'error'},\n },\n on: {\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n success: {\n invoke: {\n src: 'formSubmittedService',\n },\n },\n error: {},\n },\n },\n {\n actions: {\n setMessage: assign((_context, event: any) => ({\n message: event.data.details.description,\n })),\n createDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n deleteDocument: assign(() => ({\n // id: event.id,\n })),\n updateDocument: assign((_context, event: any) => ({\n formData: event.formData,\n })),\n },\n }\n)\n\nexport default formMachine\n","// Recursively sanitize form data:\n// - convert empty strings, undefined values and empty arrays to null (to correctly unset / delete fields)\n// - trim whitespace on string fleids\n\ntype FormData = Record<string, any>\n\nconst sanitizeFormData = (formData: FormData): FormData => {\n return Object.keys(formData).reduce((acc: FormData, key) => {\n const val = formData[key]\n\n // TODO: refactor\n if (typeof val === 'object' && val !== null && val.constructor !== Array) {\n acc[key] = sanitizeFormData(val)\n } else if (val === '' || typeof val === 'undefined' || val?.length === 0) {\n acc[key] = null\n } else if (typeof val === 'string' && val) {\n acc[key] = formData[key].trim()\n } else {\n acc[key] = formData[key]\n }\n\n return acc\n }, {})\n}\n\nexport default sanitizeFormData\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Inline, Text, Tooltip} from '@sanity/ui'\nimport React, {FC} from 'react'\nimport {FieldError} from 'react-hook-form'\nimport {styled} from 'styled-components'\n\ntype Props = {\n description?: string\n error?: FieldError\n label: string\n name: string\n}\n\nconst StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({theme}) => {\n return {\n color: theme.sanity.color.spot.red,\n }\n})\n\nconst FormFieldInputLabel: FC<Props> = (props: Props) => {\n const {description, error, label, name} = props\n\n return (\n <Box marginBottom={3}>\n {/* Label */}\n <Inline space={2}>\n <Text as=\"label\" htmlFor={name} size={1} weight=\"semibold\">\n {label}\n </Text>\n\n {/* Error icon + tooltip */}\n {error && (\n <Text size={1}>\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n <StyledErrorOutlineIcon style={{marginRight: '0.1em'}} />\n {error.message}\n </Text>\n </Box>\n }\n fallbackPlacements={['top', 'left']}\n placement=\"right\"\n portal\n >\n <StyledErrorOutlineIcon />\n </Tooltip>\n </Text>\n )}\n </Inline>\n\n {/* Description */}\n {description && (\n <Box marginY={3}>\n <Text htmlFor={name} muted size={1}>\n {description}\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n\nexport default FormFieldInputLabel\n","import {Box, TextInput} from '@sanity/ui'\nimport React, {forwardRef} from 'react'\nimport {FieldError} from 'react-hook-form'\n\nimport FormFieldInputLabel from '../FormFieldInputLabel'\n\ntype Props = {\n description?: string\n disabled?: boolean\n error?: FieldError\n label: string\n name: string\n placeholder?: string\n value?: string\n onChange?: React.ChangeEventHandler<HTMLInputElement>\n onBlur?: React.FocusEventHandler<HTMLInputElement>\n}\n\nconst FormFieldInputText = forwardRef<HTMLInputElement, Props>((props: Props, ref) => {\n const {description, disabled, error, label, name, placeholder, value, onChange, onBlur} = props\n\n return (\n <Box>\n {/* Label */}\n <FormFieldInputLabel description={description} error={error} label={label} name={name} />\n {/* Input */}\n <TextInput\n autoComplete=\"off\"\n autoFocus\n defaultValue={value}\n disabled={disabled}\n id={name}\n name={name}\n placeholder={placeholder}\n onChange={onChange}\n onBlur={onBlur}\n ref={ref}\n />\n </Box>\n )\n})\n\nexport default FormFieldInputText\n","import type {SanityClient} from '@sanity/client'\nimport {API_VERSION} from './constants'\nimport {useClient} from 'sanity'\n\nexport function useSanityClient(): SanityClient {\n return useClient({apiVersion: API_VERSION})\n}\n","import {yupResolver} from '@hookform/resolvers/yup'\nimport {Box, Button, Dialog, Flex, Stack} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport {useMachine} from '@xstate/react'\nimport React, {FC} from 'react'\nimport {useForm} from 'react-hook-form'\nimport * as yup from 'yup'\n\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_DIALOG} from '../../constants'\nimport formMachine from '../../machines/form'\nimport sanitizeFormData from '../../utils/sanitizeFormData'\nimport FormFieldInputText from '../FormFieldInputText'\nimport {Sanity} from '../../types'\nimport {useSanityClient} from '../../client'\n\ntype Props = {\n deploymentTarget?: Sanity.DeploymentTarget\n onClose: () => void\n onCreate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n onDelete?: (id: string) => void\n onUpdate?: (deploymentTarget: Sanity.DeploymentTarget) => void\n}\n\ntype FormData = yup.InferType<typeof formSchema>\n\nconst formSchema = yup.object().shape({\n deployHook: yup.string().url('Deploy hook must be a valid URL'),\n deployLimit: yup\n .number()\n .positive()\n .integer()\n .min(1, 'Deploy limit must no less than 1')\n .max(15, 'Deploy limit must no higher than 15')\n .typeError('Deploy limit must be a number')\n .required('Deploy limit must be a positive integer between 1 and 15'),\n name: yup.string().required('Name cannot be empty'),\n projectId: yup.string().required('Vercel Project ID cannot be empty'),\n teamId: yup.string(),\n token: yup.string().required('Vercel Account Token cannot be empty'),\n})\n\nconst DialogForm: FC<Props> = (props: Props) => {\n const {deploymentTarget, onClose, onCreate, onDelete, onUpdate} = props\n const client = useSanityClient()\n\n // xstate\n const [formState, formStateTransition] = useMachine(formMachine, {\n services: {\n formSubmittedService: async () => {\n onClose()\n },\n // TODO: refactor\n createDocumentService: async (_context, event: any) => {\n let document\n try {\n document = await client.create({\n _id: `vercel.${uuid()}`,\n _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,\n ...event.formData,\n })\n if (onCreate) {\n onCreate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n },\n // TODO: refactor\n deleteDocumentService: async () => {\n if (deploymentTarget) {\n try {\n await client.delete(deploymentTarget._id)\n if (onDelete) {\n onDelete(deploymentTarget._id)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n // TODO: refactor\n updateDocumentService: async (_context, event: any) => {\n let document\n if (deploymentTarget) {\n try {\n document = await client.patch(deploymentTarget._id).set(event.formData).commit()\n if (onUpdate) {\n onUpdate(document as Sanity.DeploymentTarget)\n }\n return Promise.resolve()\n } catch (e) {\n return Promise.reject(e)\n }\n }\n return Promise.resolve()\n },\n },\n })\n\n const formUpdating =\n formState.matches('creating') || formState.matches('deleting') || formState.matches('updating')\n\n // react-hook-form v7\n const {\n formState: {errors, isDirty, isValid},\n handleSubmit,\n register,\n } = useForm<FormData>({\n // @ts-expect-error - fix typings later\n defaultValues: {\n deployHook: deploymentTarget?.deployHook || '',\n deployLimit: deploymentTarget?.deployLimit || 5,\n name: deploymentTarget?.name || '',\n projectId: deploymentTarget?.projectId || '',\n teamId: deploymentTarget?.teamId || '',\n token: deploymentTarget?.token || '',\n },\n mode: 'onChange',\n resolver: yupResolver(formSchema),\n })\n\n // Callbacks\n // - submit react-hook-form\n const onSubmit = async (formData: FormData) => {\n const sanitizedFormData = sanitizeFormData(formData)\n await formStateTransition(deploymentTarget ? 'UPDATE' : 'CREATE', {\n formData: sanitizedFormData,\n })\n }\n\n const handleDelete = () => {\n formStateTransition('DELETE', {id: deploymentTarget?._id})\n }\n\n const Footer = () => (\n <Box padding={3}>\n <Flex justify={deploymentTarget ? 'space-between' : 'flex-end'}>\n {/* Delete button */}\n {deploymentTarget && (\n <Button\n disabled={formUpdating}\n fontSize={1}\n mode=\"bleed\"\n onClick={handleDelete}\n text=\"Delete\"\n tone=\"critical\"\n />\n )}\n\n {/* Submit button */}\n <Button\n disabled={formUpdating || !isDirty || !isValid}\n fontSize={1}\n onClick={handleSubmit(onSubmit)}\n text={deploymentTarget ? 'Update and close' : 'Create'}\n tone=\"primary\"\n />\n </Flex>\n </Box>\n )\n\n return (\n <Dialog\n footer={<Footer />}\n header={`${deploymentTarget ? 'Edit' : 'Create'} deployment target`}\n id=\"create\"\n onClose={onClose}\n width={1}\n zOffset={Z_INDEX_DIALOG}\n >\n {/* We reverse direction to ensure that inline links dont autofocus before other form elements */}\n <Box as=\"form\" padding={4} onSubmit={handleSubmit(onSubmit)}>\n {/* Hidden button to enable enter key submissions */}\n <button style={{display: 'none'}} tabIndex={-1} type=\"submit\" />\n\n {/* Form fields */}\n <Stack space={5}>\n {/* Title */}\n <FormFieldInputText\n disabled={formUpdating}\n description=\"Name displayed in this plugin (e.g. production, staging)\"\n error={errors?.name}\n label=\"Name\"\n // @ts-expect-error - fix typings later\n {...register('name')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.token}\n label=\"Vercel Account Token\"\n // @ts-expect-error - fix typings later\n {...register('token')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.projectId}\n label=\"Vercel Project ID\"\n // @ts-expect-error - fix typings later\n {...register('projectId')}\n />\n\n <FormFieldInputText\n description=\"Required only if your project is owned by a team account\"\n disabled={formUpdating}\n error={errors?.teamId}\n label=\"Vercel Team ID (optional)\"\n // @ts-expect-error - fix typings later\n {...register('teamId')}\n />\n\n <FormFieldInputText\n description=\"Enter a valid deploy hook URL to enable manual deploys\"\n disabled={formUpdating}\n error={errors?.deployHook}\n label=\"Vercel Deploy Hook (optional)\"\n // @ts-expect-error - fix typings later\n {...register('deployHook')}\n />\n\n <FormFieldInputText\n disabled={formUpdating}\n error={errors?.deployLimit}\n label=\"Number of deploys to display\"\n // @ts-expect-error - fix typings later\n {...register('deployLimit', {valueAsNumber: true})}\n />\n </Stack>\n </Box>\n </Dialog>\n )\n}\n\nexport default DialogForm\n","import {assign, Machine} from 'xstate'\nimport {Sanity} from '../types'\n\ntype Context = {\n editDeploymentTarget?: Sanity.DeploymentTarget\n}\n\ntype Event =\n | {type: 'CREATE'}\n | {type: 'CLOSE'}\n | {type: 'EDIT'; deploymentTarget: Sanity.DeploymentTarget}\n\ntype Schema = {\n states: {\n idle: {}\n edit: {}\n create: {}\n }\n}\n\nconst dialogMachine = () =>\n Machine<Context, Schema, Event>(\n {\n context: {\n editDeploymentTarget: undefined,\n },\n initial: 'idle',\n states: {\n idle: {\n entry: assign({\n editDeploymentTarget: () => undefined,\n }),\n on: {\n CREATE: 'create',\n EDIT: {\n actions: ['setEditDeploymentTarget'],\n target: 'edit',\n },\n },\n },\n edit: {\n on: {\n CLOSE: 'idle',\n },\n },\n create: {\n on: {\n CLOSE: 'idle',\n },\n },\n },\n },\n {\n actions: {\n setEditDeploymentTarget: assign((_context, event: any) => ({\n editDeploymentTarget: event.deploymentTarget,\n })),\n },\n }\n )\n\nexport default dialogMachine\n","import {AddIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, ToastProvider, Tooltip} from '@sanity/ui'\nimport {useMachine} from '@xstate/react'\nimport React from 'react'\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query'\n\nimport StateDebug from './components/StateDebug'\nimport {DEPLOYMENT_TARGET_DOCUMENT_TYPE, Z_INDEX_TOAST_PROVIDER} from './constants'\nimport deploymentTargetListMachine from './machines/deploymentTargetList'\nimport DeploymentTargets from './components/DeploymentTargets'\nimport DialogForm from './components/DialogForm'\nimport dialogMachine from './machines/dialog'\nimport {Sanity} from './types'\nimport {useSanityClient} from './client'\n\nconst Widget = () => {\n const client = useSanityClient()\n // xstate\n const [deploymentTargetListState, deploymentTargetListStateTransition] = useMachine(\n deploymentTargetListMachine,\n {\n services: {\n fetchDataService: () => {\n return client\n .fetch(`*[_type == \"${DEPLOYMENT_TARGET_DOCUMENT_TYPE}\"] | order(name asc)`)\n .then((result: any) => result)\n },\n },\n }\n )\n const [dialogState, dialogStateTransition] = useMachine(dialogMachine)\n\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n gcTime: 0,\n staleTime: 0,\n },\n },\n })\n\n // Callbacks\n const handleDialogClose = () => {\n dialogStateTransition('CLOSE')\n }\n const handleDialogShowCreate = () => {\n dialogStateTransition('CREATE')\n }\n const handleDialogShowEdit = (deploymentTarget: Sanity.DeploymentTarget) => {\n dialogStateTransition('EDIT', {deploymentTarget})\n }\n const handleTargetCreate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('CREATE', {deploymentTarget})\n }\n const handleTargetDelete = (id: string) => {\n deploymentTargetListStateTransition('DELETE', {id})\n }\n const handleTargetUpdate = (deploymentTarget: Sanity.DeploymentTarget) => {\n deploymentTargetListStateTransition('UPDATE', {deploymentTarget})\n }\n\n return (\n <ToastProvider zOffset={Z_INDEX_TOAST_PROVIDER}>\n <QueryClientProvider client={queryClient}>\n <Card radius={2} style={{overflow: 'hidden '}}>\n {/* xstate debug */}\n <StateDebug name=\"List\" state={deploymentTargetListState} />\n\n {/* Header */}\n <Flex align=\"center\" justify=\"space-between\" paddingX={3} paddingY={2}>\n <Text size={5} weight=\"semibold\">\n Vercel deployments\n </Text>\n\n <Tooltip\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Create new deployment target\n </Text>\n </Box>\n }\n placement=\"left\"\n >\n <Button fontSize={1} icon={AddIcon} onClick={handleDialogShowCreate} mode=\"bleed\" />\n </Tooltip>\n </Flex>\n\n <Box>\n {deploymentTargetListState.matches('pending') && (\n <Box paddingX={3} paddingY={4}>\n <Text>Loading...</Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withoutData') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n No deployment targets found.{' '}\n <a onClick={handleDialogShowCreate} style={{cursor: 'pointer'}}>\n Create a new target?\n </a>\n </Text>\n </Box>\n )}\n\n {deploymentTargetListState.matches('ready.withData') && (\n <DeploymentTargets\n items={deploymentTargetListState.context.results}\n onDialogEdit={handleDialogShowEdit}\n />\n )}\n\n {deploymentTargetListState.matches('failed') && (\n <Box paddingX={3} paddingY={4}>\n <Text>\n Failed to retrieve deployment targets. Please check the developer console log for\n more information.\n </Text>\n </Box>\n )}\n </Box>\n </Card>\n\n {/* Dialogs */}\n {dialogState.matches('create') && (\n <DialogForm onClose={handleDialogClose} onCreate={handleTargetCreate} />\n )}\n\n {dialogState.matches('edit') && (\n <DialogForm\n deploymentTarget={dialogState.context.editDeploymentTarget}\n onClose={handleDialogClose}\n onDelete={handleTargetDelete}\n onUpdate={handleTargetUpdate}\n />\n )}\n </QueryClientProvider>\n </ToastProvider>\n )\n}\n\nexport default Widget\n","import Widget from './app'\n\n// Initialize `javascript-time-ago` locale (required for react-time-ago)\nimport TimeAgo from 'javascript-time-ago'\nimport en from 'javascript-time-ago/locale/en'\nimport {DashboardWidget, type LayoutConfig} from '@sanity/dashboard'\n\nTimeAgo.addDefaultLocale(en)\n\nexport function vercelWidget(config: {layout?: LayoutConfig} = {}): DashboardWidget {\n return {\n name: 'vercel',\n component: Widget,\n layout: config.layout ?? {width: 'full'},\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-dashboard-widget-vercel",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "description": "View your recent Vercel deployments and manually trigger builds directly from your Sanity dashboard.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -58,7 +58,7 @@
58
58
  }
59
59
  },
60
60
  "dependencies": {
61
- "@hookform/resolvers": "2.0.0-beta.3",
61
+ "@hookform/resolvers": "^3.3.2",
62
62
  "@sanity/icons": "^3.7.0",
63
63
  "@sanity/incompatible-plugin": "^1.0.5",
64
64
  "@sanity/ui": "^2.15.2",
@@ -67,7 +67,7 @@
67
67
  "@tanstack/react-query": "^5.67.2",
68
68
  "javascript-time-ago": "^2.5.7",
69
69
  "object-hash": "3.0.0",
70
- "react-hook-form": "^6.15.8",
70
+ "react-hook-form": "^7.48.2",
71
71
  "react-time-ago": "^7.2.1",
72
72
  "unfetch": "^4.2.0",
73
73
  "use-deep-compare-effect": "^1.8.1",
@@ -1,10 +1,8 @@
1
- // @ts-expect-error - fix typings later
2
1
  import {yupResolver} from '@hookform/resolvers/yup'
3
2
  import {Box, Button, Dialog, Flex, Stack} from '@sanity/ui'
4
3
  import {uuid} from '@sanity/uuid'
5
4
  import {useMachine} from '@xstate/react'
6
5
  import React, {FC} from 'react'
7
- // @ts-expect-error - fix typings later
8
6
  import {useForm} from 'react-hook-form'
9
7
  import * as yup from 'yup'
10
8
 
@@ -105,20 +103,20 @@ const DialogForm: FC<Props> = (props: Props) => {
105
103
  const formUpdating =
106
104
  formState.matches('creating') || formState.matches('deleting') || formState.matches('updating')
107
105
 
108
- // react-hook-form
106
+ // react-hook-form v7
109
107
  const {
110
- // Read the formState before render to subscribe the form state through Proxy
111
108
  formState: {errors, isDirty, isValid},
112
109
  handleSubmit,
113
110
  register,
114
- } = useForm({
111
+ } = useForm<FormData>({
112
+ // @ts-expect-error - fix typings later
115
113
  defaultValues: {
116
114
  deployHook: deploymentTarget?.deployHook || '',
117
115
  deployLimit: deploymentTarget?.deployLimit || 5,
118
- name: deploymentTarget?.name,
119
- projectId: deploymentTarget?.projectId,
116
+ name: deploymentTarget?.name || '',
117
+ projectId: deploymentTarget?.projectId || '',
120
118
  teamId: deploymentTarget?.teamId || '',
121
- token: deploymentTarget?.token,
119
+ token: deploymentTarget?.token || '',
122
120
  },
123
121
  mode: 'onChange',
124
122
  resolver: yupResolver(formSchema),
@@ -186,24 +184,24 @@ const DialogForm: FC<Props> = (props: Props) => {
186
184
  description="Name displayed in this plugin (e.g. production, staging)"
187
185
  error={errors?.name}
188
186
  label="Name"
189
- name="name"
190
- ref={register}
187
+ // @ts-expect-error - fix typings later
188
+ {...register('name')}
191
189
  />
192
190
 
193
191
  <FormFieldInputText
194
192
  disabled={formUpdating}
195
193
  error={errors?.token}
196
194
  label="Vercel Account Token"
197
- name="token"
198
- ref={register}
195
+ // @ts-expect-error - fix typings later
196
+ {...register('token')}
199
197
  />
200
198
 
201
199
  <FormFieldInputText
202
200
  disabled={formUpdating}
203
201
  error={errors?.projectId}
204
202
  label="Vercel Project ID"
205
- name="projectId"
206
- ref={register}
203
+ // @ts-expect-error - fix typings later
204
+ {...register('projectId')}
207
205
  />
208
206
 
209
207
  <FormFieldInputText
@@ -211,8 +209,8 @@ const DialogForm: FC<Props> = (props: Props) => {
211
209
  disabled={formUpdating}
212
210
  error={errors?.teamId}
213
211
  label="Vercel Team ID (optional)"
214
- name="teamId"
215
- ref={register}
212
+ // @ts-expect-error - fix typings later
213
+ {...register('teamId')}
216
214
  />
217
215
 
218
216
  <FormFieldInputText
@@ -220,16 +218,16 @@ const DialogForm: FC<Props> = (props: Props) => {
220
218
  disabled={formUpdating}
221
219
  error={errors?.deployHook}
222
220
  label="Vercel Deploy Hook (optional)"
223
- name="deployHook"
224
- ref={register}
221
+ // @ts-expect-error - fix typings later
222
+ {...register('deployHook')}
225
223
  />
226
224
 
227
225
  <FormFieldInputText
228
226
  disabled={formUpdating}
229
227
  error={errors?.deployLimit}
230
228
  label="Number of deploys to display"
231
- name="deployLimit"
232
- ref={register({valueAsNumber: true})}
229
+ // @ts-expect-error - fix typings later
230
+ {...register('deployLimit', {valueAsNumber: true})}
233
231
  />
234
232
  </Stack>
235
233
  </Box>
@@ -1,7 +1,6 @@
1
1
  import {ErrorOutlineIcon} from '@sanity/icons'
2
2
  import {Box, Inline, Text, Tooltip} from '@sanity/ui'
3
3
  import React, {FC} from 'react'
4
- // @ts-expect-error - fix typings later
5
4
  import {FieldError} from 'react-hook-form'
6
5
  import {styled} from 'styled-components'
7
6
 
@@ -1,6 +1,5 @@
1
1
  import {Box, TextInput} from '@sanity/ui'
2
2
  import React, {forwardRef} from 'react'
3
- // @ts-expect-error - fix typings later
4
3
  import {FieldError} from 'react-hook-form'
5
4
 
6
5
  import FormFieldInputLabel from '../FormFieldInputLabel'
@@ -13,12 +12,12 @@ type Props = {
13
12
  name: string
14
13
  placeholder?: string
15
14
  value?: string
15
+ onChange?: React.ChangeEventHandler<HTMLInputElement>
16
+ onBlur?: React.FocusEventHandler<HTMLInputElement>
16
17
  }
17
18
 
18
- type Ref = HTMLInputElement
19
-
20
- const FormFieldInputText = forwardRef<Ref, Props>((props: Props, ref) => {
21
- const {description, disabled, error, label, name, placeholder, value} = props
19
+ const FormFieldInputText = forwardRef<HTMLInputElement, Props>((props: Props, ref) => {
20
+ const {description, disabled, error, label, name, placeholder, value, onChange, onBlur} = props
22
21
 
23
22
  return (
24
23
  <Box>
@@ -33,6 +32,8 @@ const FormFieldInputText = forwardRef<Ref, Props>((props: Props, ref) => {
33
32
  id={name}
34
33
  name={name}
35
34
  placeholder={placeholder}
35
+ onChange={onChange}
36
+ onBlur={onBlur}
36
37
  ref={ref}
37
38
  />
38
39
  </Box>