@sanity/cross-dataset-duplicator
2.1.62.1.7
dist/index.js.map~
dist/index.js.mapModified+1−1
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["CrossDatasetDuplicatorContext.Provider","pluginConfig","props.renderDefault(rest)","<CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>","_c","tone = 'caution'","<Text size={1}>{children}</Text>","<Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>","_c","() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : []","payload.length","(item) => item.include","function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }","length","item","buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )","<Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>","_c","_temp","<Badge padding={2} fontSize={1}>\n Checking...\n </Badge>","{maxWidth: 200}","<Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>","['right', 'left']","<Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>","<Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>","<Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>","_c","{apiVersion: pluginConfig.apiVersion}","apiVersion","workspace","(space) => !space.disabled","[]","[0, 0]","(acc, doc) => acc + extractWithPath(`.._ref`, doc).length","hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null","length","async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }","({doc}) => doc._id","(doc) => [doc._id, doc]","(nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n }","(doc) => ({include: true, doc})","() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }","[docs]","function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }","item","async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }","(doc) => doc._id","(id) => `drafts.${id}`","({_id}) => _id","doc","err","async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }","pluginConfig.apiVersion","({doc, include}) => include && isAssetId(doc._id)","destinationClient","(item) => item.include","(item) => item.doc","({old, new: next}) => [old, next]","(item) => !item.include","(item) => item.doc._id","error","space","payload.findIndex(({doc}) => doc['extension'] === 'svg')","({doc}) => doc['extension'] === 'svg'","payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n )","(item) => item.include && !isAssetId(item.doc._id)","payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n )","(item) => item.include && isAssetId(item.doc._id)","(space) => space?.projectId","[selectedTotal, `/`, payloadCount, `Documents and Assets selected`]","projectId","<Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>","<Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>","{flex: 1}","<Label>Duplicate from</Label>","<Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>","<Label>To Destination</Label>","<Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>","Select","workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))","<Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>","Stack","3","isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )","progress[1]","payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )","payload.length","displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )","payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )","{doc, include, status, hasDraft}","include","status","hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )","() => void handleDuplicate()","<Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />","isDuplicating || !selectedTotal || isGathering","<Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>","<Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>","stickyStyles(isDarkMode)","{doc}","{old, new: next}","{doc, include}","{_id}","_id","_c","_temp","initialMessage","err","_Fragment","{apiVersion}","schema.getTypeNames()","{\n docs: [],\n }","function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }","(doc) => !doc._id.startsWith(`drafts.`)","err","[0, 0, 0, 5]","[1, 1, 1, 2]","[1, 1, 1, 4]","[2, 2, 2, 0]","<Box>\n <Label>Initial Documents Query</Label>\n </Box>","<Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>","{fontFamily: 'monospace'}","(event) => setValue(event.currentTarget.value)","<Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>","value ?? ``","() => handleSubmit()","<Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />","!value","<Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>","<Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>","preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )","<Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>","fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )","docs","initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )","<Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>","doc","_c","_temp","err","[]","{apiVersion}","() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }","[client, docs, follow]","docs[0]?._id","follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null","inbound.length","follow.length","<Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","mode === 'outbound' ? docs : inbound","<Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>","_c","{apiVersion}: ResetSecretProps","{apiVersion}","() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }","useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])","[2, 2, 2, 5]","<Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>","_c","<Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>","<SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />","() => null","<DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />","bearerToken","<ResetSecret apiVersion={pluginConfig.apiVersion} />","apiVersion","<>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>","<Feedback>No docs passed into Duplicator Tool</Feedback>","<Feedback>No plugin config</Feedback>","<DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","_c","_Fragment","<CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />","_c","props.tool.options ?? {}","options","docs = []","<CrossDatasetDuplicator mode=\"tool\" docs={docs} />","_c","\"details\"","\"items\"","\"error\"","\"description\"","\"message\"","\"type\"","\"referenceID\"","\"referencedId\"","\"referenceId\"","\"extension\""],"sources":["../src/helpers/constants.ts","../src/context/ConfigProvider.tsx","../src/helpers/index.ts","../src/helpers/getDocumentsInArray.ts","../src/helpers/migrationFilters.ts","../src/components/Feedback.tsx","../src/components/SelectButtons.tsx","../src/components/StatusBadge.tsx","../src/components/Duplicator.tsx","../src/components/DuplicatorQuery.tsx","../src/components/DuplicatorWrapper.tsx","../src/components/ResetSecret.tsx","../src/components/CrossDatasetDuplicator.tsx","../src/components/CrossDatasetDuplicatorAction.tsx","../src/actions/DuplicateToAction.tsx","../src/components/CrossDatasetDuplicatorTool.tsx","../src/tool/index.ts","../src/plugin.tsx"],"sourcesContent":["import type {PluginConfig} from '../types'\n\nexport const SECRET_NAMESPACE = `CrossDatasetDuplicator`\n\nexport const DEFAULT_CONFIG: Required<PluginConfig> = {\n apiVersion: '2025-02-19',\n tool: true,\n types: [],\n filter: '',\n follow: ['outbound'],\n queries: [],\n migrationFilters: [],\n}\n","import {createContext, useContext} from 'react'\nimport type {LayoutProps} from 'sanity'\n\nimport {DEFAULT_CONFIG} from '../helpers/constants'\nimport type {PluginConfig} from '../types'\n\nconst CrossDatasetDuplicatorContext = createContext(DEFAULT_CONFIG)\n\ntype ConfigProviderProps = LayoutProps & {pluginConfig: Required<PluginConfig>}\n\n/**\n * Plugin config context hook from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function useCrossDatasetDuplicatorConfig() {\n const pluginConfig = useContext(CrossDatasetDuplicatorContext)\n\n return pluginConfig\n}\n\nexport function ConfigProvider(props: ConfigProviderProps) {\n const {pluginConfig, ...rest} = props\n\n return (\n <CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>\n )\n}\n","import type {CSSProperties} from 'react'\n\nexport function createInitialMessage(docCount = 0, refsCount = 0): string {\n const message = [\n docCount === 1 ? `This Document contains` : `These ${docCount} Documents contain`,\n refsCount === 1 ? `1 Reference.` : `${refsCount} References.`,\n refsCount === 1 ? `That Document` : `Those Documents`,\n `may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail.`,\n ]\n\n return message.join(` `)\n}\n\nexport const stickyStyles = (isDarkMode = true): CSSProperties => ({\n position: 'sticky',\n top: 0,\n zIndex: 100,\n backgroundColor: isDarkMode ? `rgba(10,10,10,0.95)` : `rgba(255,255,255,0.95)`,\n})\n","import {extractWithPath} from '@sanity/mutator'\nimport type {SanityClient, SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\ntype OptionsBag = {\n fetchIds: string[]\n client: SanityClient\n pluginConfig: PluginConfig\n currentIds?: Set<string> | null\n projection?: string\n}\n\n// Recursively fetch Documents from an array of _id's and their references\n// Heavy use of Set is to avoid recursively querying for id's already in the payload\nexport async function getDocumentsInArray(options: OptionsBag): Promise<SanityDocument[]> {\n const {fetchIds, client, pluginConfig, currentIds, projection} = options\n const collection: SanityDocument[] = []\n\n // Find initial docs\n const filter = ['_id in $fetchIds', pluginConfig.filter].filter(Boolean).join(' && ')\n const query = `*[${filter}]${projection ?? ``}`\n const data = await client.fetch<SanityDocument[]>(query, {\n fetchIds: fetchIds ?? [],\n })\n\n if (!data?.length) {\n return []\n }\n\n const localCurrentIds = currentIds ?? new Set<string>()\n\n // Find new ids in the returned data\n // Unless we started with an empty set, get the _ids from the data\n const newDataIds = new Set<string>(\n data\n .map((dataDoc) => dataDoc._id)\n .filter((id) => (currentIds?.size ? !localCurrentIds.has(id) : Boolean(id))),\n )\n\n if (newDataIds.size) {\n collection.push(...data)\n for (const id of newDataIds) {\n localCurrentIds.add(id)\n }\n\n // Check new data for more references\n await Promise.all(\n data.map(async (doc) => {\n const expr = `.._ref`\n const references = extractWithPath(expr, doc).flatMap((ref) =>\n typeof ref.value === 'string' ? [ref.value] : [],\n )\n\n if (references.length) {\n // Find references not already in the Collection\n const newReferenceIds = new Set<string>(\n references.filter((ref) => !localCurrentIds.has(ref)),\n )\n\n if (newReferenceIds.size) {\n // Recursive query for new documents\n const referenceDocs = await getDocumentsInArray({\n fetchIds: Array.from(newReferenceIds),\n currentIds: localCurrentIds,\n client,\n pluginConfig,\n })\n\n if (referenceDocs?.length) {\n collection.push(...referenceDocs)\n }\n }\n }\n }),\n )\n }\n\n // Create a unique array of documents, keeping the first occurrence of each _id\n const seenIds = new Set<string>()\n const uniqueCollection: SanityDocument[] = []\n\n for (const doc of collection) {\n if (doc && !seenIds.has(doc._id)) {\n seenIds.add(doc._id)\n uniqueCollection.push(doc)\n }\n }\n\n return uniqueCollection\n}\n","import type {MigrationFilter} from '../types'\n\ntype IsAllowedMigrationTargetOptions = {\n migrationFilters: MigrationFilter[] | undefined\n sourceProjectId: string | undefined\n sourceDataset: string | undefined\n targetProjectId: string\n targetDataset: string\n}\n\n/**\n * Determine whether a Workspace is an allowed Migration destination for the\n * current source Dataset, based on the optional `migrationFilters` config.\n *\n * If no filter is configured for the source Dataset, every target is allowed\n * (the default behaviour). When a filter is configured, only the listed targets\n * are allowed.\n */\nexport function isAllowedMigrationTarget(options: IsAllowedMigrationTargetOptions): boolean {\n const {migrationFilters, sourceProjectId, sourceDataset, targetProjectId, targetDataset} = options\n\n const migrationFilter = migrationFilters?.find((filter) => filter.sourceDataset === sourceDataset)\n\n // If no migrationFilter is configured for this dataset, allow all migration targets.\n if (!migrationFilter) {\n return true\n }\n\n return migrationFilter.targets.some((target) => {\n if (target.dataset !== targetDataset) {\n return false\n }\n\n // If a project ID is configured for the target, check that it matches.\n if (target.projectId) {\n return target.projectId === targetProjectId\n }\n\n // If a project ID is not configured for the target, only allow targets in\n // the same project as the source.\n return targetProjectId === sourceProjectId\n })\n}\n","import {Card, Text} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport type {ReactNode} from 'react'\n\ntype FeedbackProps = {\n children?: ReactNode\n tone?: BadgeTone\n}\n\nexport default function Feedback(props: FeedbackProps) {\n const {children, tone = 'caution'} = props\n\n return (\n <Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>\n )\n}\n","import {isAssetId} from '@sanity/asset-utils'\nimport {Button, Card, Flex} from '@sanity/ui'\nimport {type Dispatch, type SetStateAction, useState} from 'react'\n\nimport type {PayloadItem} from './Duplicator'\n\ntype Action = 'ALL' | 'NONE' | 'NEW' | 'EXISTING' | 'OLDER' | 'ASSETS' | 'DOCUMENTS'\n\ntype ButtonItem = {label: string; action: Action} | {divider: string}\n\nconst buttons: ButtonItem[] = [\n {label: 'All', action: 'ALL'},\n {label: 'None', action: 'NONE'},\n {divider: 'divider-1'},\n {label: 'New', action: 'NEW'},\n {label: 'Existing', action: 'EXISTING'},\n {label: 'Older', action: 'OLDER'},\n {divider: 'divider-2'},\n {label: 'Documents', action: 'DOCUMENTS'},\n {label: 'Assets', action: 'ASSETS'},\n]\n\nfunction shouldInclude(item: PayloadItem, action: Action): boolean {\n switch (action) {\n case 'ALL':\n return true\n case 'NONE':\n return false\n case 'NEW':\n return item.status === 'CREATE'\n case 'EXISTING':\n return item.status === 'EXISTS'\n case 'OLDER':\n return item.status === 'OVERWRITE'\n case 'ASSETS':\n return isAssetId(item.doc._id)\n case 'DOCUMENTS':\n return !isAssetId(item.doc._id)\n default:\n return item.include\n }\n}\n\ntype SelectButtonsProps = {\n payload: PayloadItem[]\n setPayload: Dispatch<SetStateAction<PayloadItem[]>>\n}\n\nexport default function SelectButtons(props: SelectButtonsProps) {\n const {payload, setPayload} = props\n const [disabledActions, setDisabledActions] = useState<Action[]>(() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : [],\n )\n\n function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }\n\n return (\n <Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>\n )\n}\n","import {InfoOutlineIcon} from '@sanity/icons/InfoOutline'\nimport {Box, Text, Badge} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\n\ntype StatusTones = {\n EXISTS: BadgeTone\n OVERWRITE: BadgeTone\n UPDATE: BadgeTone\n CREATE: BadgeTone\n UNPUBLISHED: BadgeTone\n}\n\nconst documentTones: StatusTones = {\n EXISTS: `primary`,\n OVERWRITE: `critical`,\n UPDATE: `caution`,\n CREATE: `positive`,\n UNPUBLISHED: `caution`,\n}\n\nconst assetTones: StatusTones = {\n EXISTS: `critical`,\n OVERWRITE: `critical`,\n UPDATE: `critical`,\n CREATE: `positive`,\n UNPUBLISHED: `default`,\n}\n\nexport type MessageTypes = {\n EXISTS: string\n OVERWRITE: string\n UPDATE: string\n CREATE: string\n UNPUBLISHED: string\n}\n\nconst documentMessages: MessageTypes = {\n // Only happens once document is copied the first time, and _updatedAt is the same\n EXISTS: `This document already exists at the Destination with the same ID and Updated time.`,\n // Is true immediately after transaction as _updatedAt is updated by API after mutation\n // Is also true if the document at the destination has been manually modified\n // Presently, the plugin doesn't actually compare the two documents\n OVERWRITE: `A newer version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination is older\n UPDATE: `An older version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination doesn't exist\n CREATE: `This document will be created at the destination.`,\n UNPUBLISHED: `A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination.`,\n}\n\nconst assetMessages: MessageTypes = {\n EXISTS: `This Asset already exists at the Destination`,\n OVERWRITE: `This Asset already exists at the Destination`,\n UPDATE: `This Asset already exists at the Destination`,\n CREATE: `This Asset does not yet exist at the Destination`,\n UNPUBLISHED: ``,\n}\n\nconst assetStatus: MessageTypes = {\n EXISTS: `RE-UPLOAD`,\n OVERWRITE: `RE-UPLOAD`,\n UPDATE: `RE-UPLOAD`,\n CREATE: `UPLOAD`,\n UNPUBLISHED: ``,\n}\n\ntype StatusBadgeProps = {\n isAsset: boolean\n status?: keyof MessageTypes\n}\n\nexport default function StatusBadge(props: StatusBadgeProps) {\n const {status, isAsset} = props\n\n if (!status) {\n return null\n }\n\n const badgeTone = isAsset ? assetTones[status] : documentTones[status]\n\n if (!badgeTone) {\n return (\n <Badge padding={2} fontSize={1}>\n Checking...\n </Badge>\n )\n }\n\n const badgeText = isAsset ? assetMessages[status] : documentMessages[status]\n const badgeStatus = isAsset ? assetStatus[status] : status\n\n return (\n <Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>\n )\n}\n","import {isAssetId, isSanityFileAsset} from '@sanity/asset-utils'\nimport type {SanityAssetDocument, SanityClient} from '@sanity/client'\nimport {ArrowRightIcon} from '@sanity/icons/ArrowRight'\nimport {LaunchIcon} from '@sanity/icons/Launch'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {extractWithPath} from '@sanity/mutator'\nimport {\n Card,\n Container,\n Text,\n Box,\n Button,\n Label,\n Stack,\n Select,\n Flex,\n Checkbox,\n type CardTone,\n useTheme,\n Spinner,\n} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {dset} from 'dset'\nimport {type ChangeEvent, Fragment, useEffect, useEffectEvent, useMemo, useState} from 'react'\nimport {\n useClient,\n Preview,\n useSchema,\n useWorkspaces,\n type WorkspaceSummary,\n type SanityDocument,\n} from 'sanity'\n\nimport {stickyStyles, createInitialMessage} from '../helpers'\nimport {getDocumentsInArray} from '../helpers/getDocumentsInArray'\nimport {isAllowedMigrationTarget} from '../helpers/migrationFilters'\nimport type {PluginConfig} from '../types'\nimport Feedback from './Feedback'\nimport SelectButtons from './SelectButtons'\nimport StatusBadge, {type MessageTypes} from './StatusBadge'\n\nexport type DuplicatorProps = {\n docs: SanityDocument[]\n token: string\n pluginConfig: Required<PluginConfig>\n onDuplicated?: () => Promise<void>\n}\n\nexport type PayloadItem = {\n doc: SanityDocument\n include: boolean\n status?: keyof MessageTypes\n hasDraft?: boolean\n}\n\ntype WorkspaceOption = WorkspaceSummary & {\n disabled: boolean\n}\n\ntype Message = {\n text: string\n tone: CardTone\n}\n\nfunction isAssetDocument(doc: SanityDocument): doc is SanityDocument & SanityAssetDocument {\n return isAssetId(doc._id)\n}\n\n// Run an async function over every item with a maximum concurrency\nasync function mapWithConcurrency<T>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<void>,\n): Promise<void> {\n const queue = [...items]\n\n async function work(): Promise<void> {\n const item = queue.shift()\n\n if (item === undefined) {\n return undefined\n }\n\n await fn(item)\n\n return work()\n }\n\n const workers = Array.from({length: Math.min(limit, queue.length)}, () => work())\n\n await Promise.all(workers)\n}\n\ntype SetMessage = (msg: Message) => void\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction isUnknownArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\n// Pull a human-readable description out of a Sanity mutation error.\n// Prefer the richest text available: item-level descriptions (which carry the\n// \"references non-existent document\" phrasing) over a possibly-generic top-level\n// `details.description` like \"Mutation(s) failed with N error(s)\".\nfunction getErrorDescription(err: unknown): string {\n if (!isRecord(err)) {\n return ''\n }\n\n const details = err['details']\n const itemDescriptions: string[] = []\n\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n const itemDescription = item['error']['description']\n\n if (typeof itemDescription === 'string' && itemDescription) {\n itemDescriptions.push(itemDescription)\n }\n }\n }\n }\n\n if (itemDescriptions.length) {\n return itemDescriptions.join('\\n')\n }\n\n const message = err['message']\n\n if (typeof message === 'string' && message) {\n return message\n }\n\n if (isRecord(details)) {\n const description = details['description']\n\n if (typeof description === 'string') {\n return description\n }\n }\n\n return ''\n}\n\nfunction isReferenceMutationError(err: unknown): boolean {\n if (!isRecord(err)) {\n return false\n }\n\n const details = err['details']\n\n // Most reliable: structured mutation item type from the Content Lake API\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n if (item['error']['type'] === 'documentReferenceDoesNotExistError') {\n return true\n }\n\n const itemDescription = item['error']['description']\n\n if (\n typeof itemDescription === 'string' &&\n (itemDescription.toLowerCase().includes('references non-existent document') ||\n itemDescription.toLowerCase().includes('reference non-existent'))\n ) {\n return true\n }\n }\n }\n }\n\n const description = getErrorDescription(err).toLowerCase()\n\n return (\n description.includes('references non-existent document') ||\n description.includes('reference non-existent')\n )\n}\n\n// Collect the _id's of referenced documents that are missing at the destination,\n// reading both the structured error payload and the human-readable description\nfunction getMissingReferenceIds(err: unknown, description: string): string[] {\n const missingIds: string[] = []\n\n const details = isRecord(err) ? err['details'] : undefined\n const rawItems = isRecord(details) ? details['items'] : undefined\n const items = isUnknownArray(rawItems) ? rawItems : []\n\n for (const item of items) {\n if (isRecord(item)) {\n const error = item['error']\n\n if (isRecord(error)) {\n // Sanity returns `referenceID`; keep the other spellings as fallbacks\n const refId = error['referenceID'] ?? error['referencedId'] ?? error['referenceId']\n\n if (typeof refId === 'string' && !missingIds.includes(refId)) {\n missingIds.push(refId)\n }\n }\n }\n }\n\n const refRegex = /references non-existent document [`'\"]?([^`'\"\\s)]+)[`'\"]?/gi\n let match = refRegex.exec(description)\n\n while (match !== null) {\n const id = match[1]\n\n if (id && !missingIds.includes(id)) {\n missingIds.push(id)\n }\n\n match = refRegex.exec(description)\n }\n\n return missingIds\n}\n\n// Commit documents individually so a single failing document doesn't block the rest.\n// Runs sequentially (concurrency 1) so referenced documents can land before the\n// documents that point at them.\nasync function commitOneByOne(\n docs: SanityDocument[],\n client: SanityClient,\n setMessage: SetMessage,\n onSuccess: () => void,\n): Promise<void> {\n let successCount = 0\n let failCount = 0\n\n await mapWithConcurrency(docs, 1, async (doc) => {\n try {\n const tx = client.transaction()\n tx.createOrReplace(doc)\n await tx.commit()\n successCount += 1\n } catch (commitErr) {\n failCount += 1\n console.error(`Failed to duplicate document \"${doc._id}\"`, commitErr)\n }\n })\n\n if (failCount === 0) {\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n\n return\n }\n\n setMessage({\n tone: 'critical',\n text: `Duplication finished with ${failCount} error(s). ${successCount} document(s) duplicated successfully.`,\n })\n\n if (successCount > 0) {\n onSuccess()\n }\n}\n\ntype ReferenceErrorOptions = {\n err: unknown\n transactionDocs: SanityDocument[]\n originClient: SanityClient\n destinationClient: SanityClient\n pluginConfig: Required<PluginConfig>\n token: string\n setMessage: SetMessage\n onSuccess: () => void\n /** Caps recursive recovery so a pathological reference loop can't hang forever */\n depth?: number\n /** Document ids the user explicitly deselected — never auto-commit these during recovery */\n excludedIds?: Set<string>\n /**\n * SVG _id remaps already applied by the caller. Recovered documents are fetched\n * fresh from the origin, so they still point at origin SVG _id's that only exist\n * at the destination under their uploaded _id.\n */\n svgMaps?: {old: string; new: string}[]\n}\n\n// Only attach the studio token when downloading from a Sanity host so a crafted\n// asset `url` cannot exfiltrate credentials to an attacker-controlled endpoint.\nfunction assetDownloadInit(url: string, token: string, typeIsFile: boolean): RequestInit {\n if (typeIsFile) {\n return {}\n }\n\n try {\n const {hostname} = new URL(url)\n\n if (hostname === 'cdn.sanity.io' || hostname.endsWith('.sanity.io')) {\n return {headers: {Authorization: `Bearer ${token}`}}\n }\n } catch {\n // Invalid URL — fetch without credentials\n }\n\n return {}\n}\n\n// Upload a recovered asset to the destination, rewriting url/path for the new dataset\nasync function uploadAssetForRecovery(\n doc: SanityDocument & SanityAssetDocument,\n destinationClient: SanityClient,\n token: string,\n): Promise<{docs: SanityDocument[]; svgMap?: {old: string; new: string}}> {\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc._id}\" from origin (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n const assetDoc = await destinationClient.assets.upload(typeIsFile ? `file` : `image`, assetData, {\n filename: doc.originalFilename,\n })\n\n // Merge the original asset document's editorial metadata (e.g. `altText`) with\n // the uploaded asset's canonical fields, matching the main duplication path.\n // Keeping this to a single document at the uploaded `_id` avoids leaving an\n // orphaned asset behind when an SVG's `_id` changes on upload; references are\n // repointed via `svgMap`.\n return {\n docs: [{...doc, ...assetDoc}],\n svgMap: doc.extension === 'svg' ? {old: doc._id, new: assetDoc._id} : undefined,\n }\n}\n\n// Rewrite _ref values that point at remapped SVG asset ids.\n// Clones each doc so caller-held / payload objects are not mutated.\nfunction remapSvgRefs(\n docs: SanityDocument[],\n svgMaps: {old: string; new: string}[],\n): SanityDocument[] {\n if (!svgMaps.length) {\n return docs\n }\n\n return docs.map((original) => {\n const references = extractWithPath(`.._ref`, original)\n\n if (!references.length) {\n return original\n }\n\n const doc = structuredClone(original)\n\n references.forEach((ref) => {\n const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new\n\n if (newRefValue) {\n dset(doc, ref.path.join('.'), newRefValue)\n }\n })\n\n return doc\n })\n}\n\n// Order docs so referenced documents come before the documents that point at\n// them. Used by the sequential one-by-one fallback where commit order matters.\nfunction orderDocsDependenciesFirst(docs: SanityDocument[]): SanityDocument[] {\n const byId = new Map(docs.map((doc) => [doc._id, doc]))\n const visiting = new Set<string>()\n const visited = new Set<string>()\n const ordered: SanityDocument[] = []\n\n function visit(id: string): void {\n if (visited.has(id) || visiting.has(id)) {\n return\n }\n\n const doc = byId.get(id)\n\n if (!doc) {\n return\n }\n\n visiting.add(id)\n\n for (const ref of extractWithPath(`.._ref`, doc)) {\n if (typeof ref.value === 'string') {\n visit(ref.value)\n }\n }\n\n visiting.delete(id)\n visited.add(id)\n ordered.push(doc)\n }\n\n for (const doc of docs) {\n visit(doc._id)\n }\n\n return ordered\n}\n\n// When a transaction fails because of missing references, fetch the referenced\n// documents (and their transitive refs) from the origin — respecting\n// pluginConfig.filter — upload any assets, then retry. Falls back to one-by-one\n// commits if the retry still fails.\nasync function handleReferenceError(options: ReferenceErrorOptions): Promise<void> {\n const {\n err,\n transactionDocs,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess,\n depth = 0,\n excludedIds = new Set(),\n svgMaps: inheritedSvgMaps = [],\n } = options\n const description = getErrorDescription(err)\n const missingIds = getMissingReferenceIds(err, description)\n\n // If the only missing refs are ones the user deselected, surface that instead of\n // silently re-committing them\n const autoFetchIds = missingIds.filter((id) => !excludedIds.has(id))\n const blockedIds = missingIds.filter((id) => excludedIds.has(id))\n\n if (blockedIds.length && !autoFetchIds.length) {\n setMessage({\n tone: 'critical',\n text: `Duplication failed because deselected document(s) are still referenced: ${blockedIds.join(', ')}. Re-select them or remove the references.`,\n })\n\n return\n }\n\n if (!missingIds.length || depth >= 5) {\n // Couldn't parse the missing _id's (or we hit the recursion cap) — retry each document on its own\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({\n tone: 'default',\n text: `Fetching ${autoFetchIds.length} missing referenced document(s) and retrying...`,\n })\n\n let missingDocs: SanityDocument[] = []\n\n try {\n // Recursively gather referenced docs (and apply pluginConfig.filter), same\n // as the \"Gather References\" path — so nested refs aren't left behind\n missingDocs = await getDocumentsInArray({\n fetchIds: autoFetchIds,\n client: originClient,\n pluginConfig,\n })\n } catch (fetchErr) {\n setMessage({\n tone: 'critical',\n text:\n (fetchErr instanceof Error ? fetchErr.message : '') || description || 'Duplication Failed',\n })\n\n return\n }\n\n if (!missingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n // Don't re-commit documents already in the failed transaction, or ones the\n // user explicitly deselected (including transitive refs of those)\n const existingIds = new Set(transactionDocs.map((doc) => doc._id))\n // Reverse so transitive refs (appended last by getDocumentsInArray) are processed first\n const newMissingDocs = [...missingDocs]\n .reverse()\n .filter((doc) => !existingIds.has(doc._id) && !excludedIds.has(doc._id))\n\n // Nothing new to add — retrying the same transaction would just loop until the depth cap\n if (!newMissingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({tone: 'default', text: `Duplicating ${newMissingDocs.length} missing document(s)...`})\n\n // Seed with the caller's remaps so recovered documents referencing an SVG that\n // was uploaded earlier are repointed at its destination _id, even when that\n // asset isn't re-fetched here (e.g. `pluginConfig.filter` excludes assets)\n const svgMaps: {old: string; new: string}[] = [...inheritedSvgMaps]\n\n // Process with the same concurrency limit as the main duplication path, while\n // writing into index slots so dependency-first order is preserved\n const recoveredChunks: SanityDocument[][] = Array.from({length: newMissingDocs.length}, () => [])\n\n try {\n await mapWithConcurrency(\n newMissingDocs.map((doc, index) => ({doc, index})),\n 3,\n async ({doc, index}) => {\n if (!isAssetDocument(doc)) {\n recoveredChunks[index] = [doc]\n\n return\n }\n\n const {docs, svgMap} = await uploadAssetForRecovery(doc, destinationClient, token)\n recoveredChunks[index] = docs\n\n if (svgMap) {\n svgMaps.push(svgMap)\n }\n },\n )\n } catch (uploadErr) {\n setMessage({\n tone: 'critical',\n text:\n (uploadErr instanceof Error ? uploadErr.message : '') ||\n description ||\n 'Duplication Failed',\n })\n\n return\n }\n\n const recoveredDocs = recoveredChunks.flat()\n\n // Remap SVG _ref's in both recovered and original transaction docs\n const remappedRecoveredDocs = remapSvgRefs(recoveredDocs, svgMaps)\n const remappedTransactionDocs = remapSvgRefs(transactionDocs, svgMaps)\n\n // Put recovered (referenced) docs first so sequential commits land\n // dependencies before the documents that point at them\n const allDocs = orderDocsDependenciesFirst([...remappedRecoveredDocs, ...remappedTransactionDocs])\n\n const retryTransaction = destinationClient.transaction()\n allDocs.forEach((doc) => retryTransaction.createOrReplace(doc))\n\n try {\n await retryTransaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n } catch (retryErr) {\n if (isReferenceMutationError(retryErr)) {\n // Another layer of missing refs — recurse with the expanded set\n await handleReferenceError({\n ...options,\n err: retryErr,\n transactionDocs: allDocs,\n depth: depth + 1,\n svgMaps,\n })\n\n return\n }\n\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(allDocs, destinationClient, setMessage, onSuccess)\n }\n}\n\nexport default function Duplicator(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const theme = useTheme()\n const isDarkMode = getTheme_v2({sanity: theme.sanity}).color._dark\n\n // Prepare origin (this Studio) client\n const originClient = useClient({apiVersion: pluginConfig.apiVersion})\n\n const schema = useSchema()\n\n // Create list of dataset options\n // and set initial value of dropdown\n const workspaces = useWorkspaces()\n const {projectId: sourceProjectId, dataset: sourceDataset} = originClient.config()\n const workspacesOptions: WorkspaceOption[] = workspaces.map((workspace) => {\n const isSourceWorkspace =\n workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset\n const isAllowedMigration = isAllowedMigrationTarget({\n migrationFilters: pluginConfig.migrationFilters,\n sourceProjectId,\n sourceDataset,\n targetProjectId: workspace.projectId,\n targetDataset: workspace.dataset,\n })\n\n return {\n ...workspace,\n disabled: isSourceWorkspace || !isAllowedMigration,\n }\n })\n\n const currentWorkspace = workspacesOptions.find(\n (workspace) => workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset,\n )\n\n const [destination, setDestination] = useState<WorkspaceOption | null>(\n workspaces.length ? (workspacesOptions.find((space) => !space.disabled) ?? null) : null,\n )\n const [message, setMessage] = useState<Message | null>(null)\n const [payload, setPayload] = useState<PayloadItem[]>([])\n\n const [isDuplicating, setIsDuplicating] = useState(false)\n const [isGathering, setIsGathering] = useState(false)\n const [progress, setProgress] = useState<[number, number]>([0, 0])\n\n // References found in the initial docs\n const initialRefsCount = useMemo(\n () => docs.reduce((acc, doc) => acc + extractWithPath(`.._ref`, doc).length, 0),\n [docs],\n )\n const hasReferences = initialRefsCount > 0\n const initialMessage: Message | null = hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null\n const displayMessage = message ?? initialMessage\n\n // Check if payload documents exist at destination\n async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }\n\n // Build the initial payload and check statuses at the current destination\n const initializePayload = useEffectEvent((nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n })\n\n // Sync the payload with the docs prop and the destination dataset.\n // setPayload only runs after fetching document statuses from the\n // destination resolves, not synchronously within the effect.\n // See: https://github.com/facebook/react/issues/34743\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }, [docs])\n\n function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }\n\n // Find and recursively follow references beginning with this document\n async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }\n\n // Duplicate payload to destination dataset\n async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLSelectElement>) {\n if (!workspacesOptions.length) {\n return\n }\n\n const targeted = workspacesOptions.find((space) => space.name === e.currentTarget.value)\n\n if (targeted) {\n setDestination(targeted)\n updatePayloadStatuses(payload, targeted).catch(console.error)\n }\n }\n\n const payloadCount = payload.length\n const firstSvgIndex = payload.findIndex(({doc}) => doc['extension'] === 'svg')\n const selectedDocumentsCount = payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n ).length\n const selectedAssetsCount = payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n ).length\n const selectedTotal = selectedDocumentsCount + selectedAssetsCount\n const destinationTitle = destination?.title ?? destination?.name\n const hasMultipleProjectIds =\n new Set(workspacesOptions.map((space) => space?.projectId).filter(Boolean)).size > 1\n\n const headingText = [selectedTotal, `/`, payloadCount, `Documents and Assets selected`].join(` `)\n\n const buttonTextParts = [`Duplicate`]\n\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(\n String(selectedDocumentsCount),\n selectedDocumentsCount === 1 ? `Document` : `Documents`,\n )\n }\n\n if (selectedAssetsCount > 0) {\n // Only join with \"and\" when documents are also part of the selection.\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(`and`)\n }\n\n buttonTextParts.push(\n String(selectedAssetsCount),\n selectedAssetsCount === 1 ? `Asset` : `Assets`,\n )\n }\n\n if (originClient.config().projectId !== destination?.projectId) {\n buttonTextParts.push(`between Projects`)\n }\n\n buttonTextParts.push(`to`, String(destinationTitle))\n\n const buttonText = buttonTextParts.join(` `)\n\n if (workspacesOptions.length < 2) {\n return (\n <Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>\n )\n }\n\n if (!destination) {\n return (\n <Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>\n )\n }\n\n return (\n <Container width={1}>\n <Card border>\n <Stack>\n <Card padding={4} style={stickyStyles(isDarkMode)}>\n <Stack gap={4}>\n <Flex gap={3}>\n <Stack style={{flex: 1}} gap={3}>\n <Label>Duplicate from</Label>\n <Select readOnly value={currentWorkspace?.name}>\n {currentWorkspace ? (\n <option value={currentWorkspace.name}>\n {currentWorkspace.title ?? currentWorkspace.name}\n {hasMultipleProjectIds ? ` (${currentWorkspace.projectId})` : ``}\n </option>\n ) : null}\n </Select>\n </Stack>\n <Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>\n <Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>\n </Flex>\n\n {isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )}\n {payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )}\n </Stack>\n </Card>\n <Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>\n </Stack>\n </Card>\n </Container>\n )\n}\n","import {Button, Stack, Box, Label, Text, Card, Flex, Grid, Container, TextInput} from '@sanity/ui'\nimport {type SubmitEvent, useState} from 'react'\nimport {useSchema, useClient, type SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport Duplicator from './Duplicator'\n\ntype DuplicatorQueryProps = {\n token: string\n pluginConfig: Required<PluginConfig>\n}\n\ntype InitialData = {\n docs: SanityDocument[]\n}\n\nexport default function DuplicatorQuery(props: DuplicatorQueryProps) {\n const {token, pluginConfig} = props\n\n const {queries: preDefinedQueries, apiVersion} = pluginConfig\n const originClient = useClient({apiVersion})\n\n const schema = useSchema()\n const schemaTypes = schema.getTypeNames()\n\n const [value, setValue] = useState(``)\n const [fetched, setFetched] = useState(false)\n const [initialData, setInitialData] = useState<InitialData>({\n docs: [],\n })\n\n async function runQuery() {\n try {\n const res = await originClient.fetch<SanityDocument[]>(value)\n\n // Ensure queried docs are registered to the schema\n const registeredAndPublishedDocs = res.length\n ? res\n .filter((doc) => schemaTypes.includes(doc._type))\n .filter((doc) => !doc._id.startsWith(`drafts.`))\n : []\n\n setInitialData({\n docs: registeredAndPublishedDocs,\n })\n setFetched(true)\n } catch (err) {\n console.error(err)\n }\n }\n\n function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }\n\n return (\n <Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>\n )\n}\n","import {Grid, Card, Container, Button} from '@sanity/ui'\nimport {useState, useEffect} from 'react'\nimport {type SanityDocument, useClient} from 'sanity'\n\nimport type {DuplicatorProps} from './Duplicator'\nimport Duplicator from './Duplicator'\n\nexport default function DuplicatorWrapper(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const [inbound, setInbound] = useState<SanityDocument[]>([])\n const {follow, apiVersion} = pluginConfig\n\n // Make the first mode the default if there's only one\n const [mode, setMode] = useState<'inbound' | 'outbound'>(\n follow.length === 1 ? (follow[0] ?? 'outbound') : 'outbound',\n )\n const client = useClient({apiVersion})\n\n // \"Inbound\" will start with all documents that reference the first one\n // And then you can gather \"Outbound\" references thereafter\n useEffect(() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }, [client, docs, follow])\n\n return (\n <Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>\n )\n}\n","import {Button, Flex} from '@sanity/ui'\nimport {useCallback} from 'react'\nimport {useClient} from 'sanity'\n\nimport {SECRET_NAMESPACE} from '../helpers/constants'\n\ntype ResetSecretProps = {\n apiVersion: string\n}\n\nexport default function ResetSecret({apiVersion}: ResetSecretProps) {\n const client = useClient({apiVersion})\n\n const handleClick = useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])\n\n return (\n <Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>\n )\n}\n","import {useSecrets, SettingsView} from '@sanity/studio-secrets'\nimport {Flex, Box, Spinner} from '@sanity/ui'\nimport type {SanityDocument} from 'sanity'\n\nimport {useCrossDatasetDuplicatorConfig} from '../context/ConfigProvider'\nimport {SECRET_NAMESPACE} from '../helpers/constants'\nimport DuplicatorQuery from './DuplicatorQuery'\nimport DuplicatorWrapper from './DuplicatorWrapper'\nimport Feedback from './Feedback'\nimport ResetSecret from './ResetSecret'\n\n// Check for auth secret (required for asset uploads)\nconst secretConfigKeys = [\n {\n key: 'bearerToken',\n title:\n 'An API token with Viewer permissions is required to duplicate the original files of assets, and will be used for all Duplications. Create one at sanity.io/manage',\n description: '',\n },\n]\n\ntype Secrets = {\n bearerToken?: string\n}\n\ntype CrossDatasetDuplicatorProps = {\n mode: 'tool' | 'action'\n docs: SanityDocument[]\n onDuplicated?: () => Promise<void>\n}\n\nexport default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProps) {\n const {mode, docs, onDuplicated} = props\n const pluginConfig = useCrossDatasetDuplicatorConfig()\n\n const {loading, secrets} = useSecrets<Secrets>(SECRET_NAMESPACE)\n\n if (loading) {\n return (\n <Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>\n )\n }\n\n // A bearer token is required to duplicate assets, so the prompt cannot be\n // dismissed until one is saved\n if (!secrets?.bearerToken) {\n return (\n <SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />\n )\n }\n\n if (mode === 'tool' && pluginConfig) {\n return (\n <>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>\n )\n }\n\n if (!docs?.length) {\n return <Feedback>No docs passed into Duplicator Tool</Feedback>\n }\n\n if (!pluginConfig) {\n return <Feedback>No plugin config</Feedback>\n }\n\n return (\n <DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n )\n}\n","import type {CrossDatasetDuplicatorActionProps} from '../types'\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\n/**\n * Component to perform a migration from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function CrossDatasetDuplicatorAction(props: CrossDatasetDuplicatorActionProps) {\n const {docs, onDuplicated} = props\n\n return <CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport {useState} from 'react'\nimport type {DocumentActionProps} from 'sanity'\n\nimport {CrossDatasetDuplicatorAction} from '../components/CrossDatasetDuplicatorAction'\n\n/**\n * Document action from the Cross Dataset Duplicator plugin\n * @public\n */\nexport const DuplicateToAction = (props: DocumentActionProps) => {\n const {draft, published} = props\n const [dialogOpen, setDialogOpen] = useState(false)\n\n return {\n disabled: Boolean(draft),\n title: draft ? `Document must be Published to begin` : null,\n label: 'Duplicate to...',\n dialog: dialogOpen &&\n published && {\n type: 'modal',\n title: 'Cross Dataset Duplicator',\n content: <CrossDatasetDuplicatorAction docs={[published]} />,\n onClose: () => setDialogOpen(false),\n },\n onHandle: () => setDialogOpen(true),\n icon: LaunchIcon,\n }\n}\n\nDuplicateToAction.action = 'duplicateTo'\n","import type {SanityDocument, Tool} from 'sanity'\n\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\nexport type MultiToolConfig = {\n docs: SanityDocument[]\n}\n\ntype CrossDatasetDuplicatorProps = {\n tool: Tool<MultiToolConfig>\n}\n\nexport function CrossDatasetDuplicatorTool(props: CrossDatasetDuplicatorProps) {\n const {docs = []} = props.tool.options ?? {}\n\n return <CrossDatasetDuplicator mode=\"tool\" docs={docs} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport type {Tool} from 'sanity'\n\nimport {\n CrossDatasetDuplicatorTool,\n type MultiToolConfig,\n} from '../components/CrossDatasetDuplicatorTool'\n\nexport const crossDatasetDuplicatorTool = (): Tool<MultiToolConfig> => ({\n title: 'Duplicator',\n name: 'duplicator',\n icon: LaunchIcon,\n component: CrossDatasetDuplicatorTool,\n options: {\n docs: [],\n },\n})\n","import {definePlugin} from 'sanity'\n\nimport {DuplicateToAction} from './actions/DuplicateToAction'\nimport {ConfigProvider} from './context/ConfigProvider'\nimport {DEFAULT_CONFIG} from './helpers/constants'\nimport {crossDatasetDuplicatorTool} from './tool'\nimport type {PluginConfig} from './types'\n\n/**\n * Plugin: Cross Dataset Duplicator\n * @public\n */\nexport const crossDatasetDuplicator = definePlugin<Partial<PluginConfig> | void>((config = {}) => {\n const pluginConfig = {...DEFAULT_CONFIG, ...config}\n const {types} = pluginConfig\n\n return {\n name: '@sanity/cross-dataset-duplicator',\n tools: (prev) => (pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev),\n studio: {\n components: {\n layout: (props) => <ConfigProvider {...props} pluginConfig={pluginConfig} />,\n },\n },\n document: {\n actions: (prev, {schemaType}) => {\n return types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev\n },\n },\n }\n})\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["CrossDatasetDuplicatorContext.Provider","pluginConfig","props.renderDefault(rest)","<CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>","_c","tone = 'caution'","<Text size={1}>{children}</Text>","<Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>","_c","() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : []","payload.length","(item) => item.include","function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }","length","item","buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )","<Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>","_c","_temp","<Badge padding={2} fontSize={1}>\n Checking...\n </Badge>","{maxWidth: 200}","<Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>","['right', 'left']","<Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>","<Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>","<Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>","_c","{apiVersion: pluginConfig.apiVersion}","apiVersion","workspace","(space) => !space.disabled","[]","[0, 0]","(acc, doc) => acc + extractWithPath(`.._ref`, doc).length","hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null","length","async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }","({doc}) => doc._id","(doc) => [doc._id, doc]","(nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n }","(doc) => ({include: true, doc})","() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }","[docs]","function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }","item","async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }","(doc) => doc._id","(id) => `drafts.${id}`","({_id}) => _id","doc","err","async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }","pluginConfig.apiVersion","({doc, include}) => include && isAssetId(doc._id)","destinationClient","(item) => item.include","(item) => item.doc","({old, new: next}) => [old, next]","(item) => !item.include","(item) => item.doc._id","error","space","payload.findIndex(({doc}) => doc['extension'] === 'svg')","({doc}) => doc['extension'] === 'svg'","payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n )","(item) => item.include && !isAssetId(item.doc._id)","payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n )","(item) => item.include && isAssetId(item.doc._id)","(space) => space?.projectId","[selectedTotal, `/`, payloadCount, `Documents and Assets selected`]","projectId","<Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>","<Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>","{flex: 1}","<Label>Duplicate from</Label>","<Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>","<Label>To Destination</Label>","<Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>","Select","workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))","<Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>","Stack","3","isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )","progress[1]","payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )","payload.length","displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )","payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )","{doc, include, status, hasDraft}","include","status","hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )","() => void handleDuplicate()","<Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />","isDuplicating || !selectedTotal || isGathering","<Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>","<Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>","stickyStyles(isDarkMode)","{doc}","{old, new: next}","{doc, include}","{_id}","_id","_c","_temp","initialMessage","err","_Fragment","{apiVersion}","schema.getTypeNames()","{\n docs: [],\n }","function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }","(doc) => !doc._id.startsWith(`drafts.`)","err","[0, 0, 0, 5]","[1, 1, 1, 2]","[1, 1, 1, 4]","[2, 2, 2, 0]","<Box>\n <Label>Initial Documents Query</Label>\n </Box>","<Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>","{fontFamily: 'monospace'}","(event) => setValue(event.currentTarget.value)","<Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>","value ?? ``","() => handleSubmit()","<Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />","!value","<Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>","<Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>","preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )","<Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>","fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )","docs","initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )","<Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>","doc","_c","_temp","err","[]","{apiVersion}","() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }","[client, docs, follow]","docs[0]?._id","follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null","inbound.length","follow.length","<Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","mode === 'outbound' ? docs : inbound","<Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>","_c","{apiVersion}: ResetSecretProps","{apiVersion}","() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }","useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])","[2, 2, 2, 5]","<Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>","_c","<Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>","<SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />","() => null","<DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />","bearerToken","<ResetSecret apiVersion={pluginConfig.apiVersion} />","apiVersion","<>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>","<Feedback>No docs passed into Duplicator Tool</Feedback>","<Feedback>No plugin config</Feedback>","<DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","_c","_Fragment","<CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />","_c","props.tool.options ?? {}","options","docs = []","<CrossDatasetDuplicator mode=\"tool\" docs={docs} />","_c","\"details\"","\"items\"","\"error\"","\"description\"","\"message\"","\"type\"","\"referenceID\"","\"referencedId\"","\"referenceId\"","\"extension\""],"sources":["../src/helpers/constants.ts","../src/context/ConfigProvider.tsx","../src/helpers/index.ts","../src/helpers/getDocumentsInArray.ts","../src/helpers/migrationFilters.ts","../src/components/Feedback.tsx","../src/components/SelectButtons.tsx","../src/components/StatusBadge.tsx","../src/components/Duplicator.tsx","../src/components/DuplicatorQuery.tsx","../src/components/DuplicatorWrapper.tsx","../src/components/ResetSecret.tsx","../src/components/CrossDatasetDuplicator.tsx","../src/components/CrossDatasetDuplicatorAction.tsx","../src/actions/DuplicateToAction.tsx","../src/components/CrossDatasetDuplicatorTool.tsx","../src/tool/index.ts","../src/plugin.tsx"],"sourcesContent":["import type {PluginConfig} from '../types'\n\nexport const SECRET_NAMESPACE = `CrossDatasetDuplicator`\n\nexport const DEFAULT_CONFIG: Required<PluginConfig> = {\n apiVersion: '2025-02-19',\n tool: true,\n types: [],\n filter: '',\n follow: ['outbound'],\n queries: [],\n migrationFilters: [],\n}\n","import {createContext, useContext} from 'react'\nimport type {LayoutProps} from 'sanity'\n\nimport {DEFAULT_CONFIG} from '../helpers/constants'\nimport type {PluginConfig} from '../types'\n\nconst CrossDatasetDuplicatorContext = createContext(DEFAULT_CONFIG)\n\ntype ConfigProviderProps = LayoutProps & {pluginConfig: Required<PluginConfig>}\n\n/**\n * Plugin config context hook from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function useCrossDatasetDuplicatorConfig() {\n const pluginConfig = useContext(CrossDatasetDuplicatorContext)\n\n return pluginConfig\n}\n\nexport function ConfigProvider(props: ConfigProviderProps) {\n const {pluginConfig, ...rest} = props\n\n return (\n <CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>\n )\n}\n","import type {CSSProperties} from 'react'\n\nexport function createInitialMessage(docCount = 0, refsCount = 0): string {\n const message = [\n docCount === 1 ? `This Document contains` : `These ${docCount} Documents contain`,\n refsCount === 1 ? `1 Reference.` : `${refsCount} References.`,\n refsCount === 1 ? `That Document` : `Those Documents`,\n `may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail.`,\n ]\n\n return message.join(` `)\n}\n\nexport const stickyStyles = (isDarkMode = true): CSSProperties => ({\n position: 'sticky',\n top: 0,\n zIndex: 100,\n backgroundColor: isDarkMode ? `rgba(10,10,10,0.95)` : `rgba(255,255,255,0.95)`,\n})\n","import {extractWithPath} from '@sanity/mutator'\nimport type {SanityClient, SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\ntype OptionsBag = {\n fetchIds: string[]\n client: SanityClient\n pluginConfig: PluginConfig\n currentIds?: Set<string> | null\n projection?: string\n}\n\n// Recursively fetch Documents from an array of _id's and their references\n// Heavy use of Set is to avoid recursively querying for id's already in the payload\nexport async function getDocumentsInArray(options: OptionsBag): Promise<SanityDocument[]> {\n const {fetchIds, client, pluginConfig, currentIds, projection} = options\n const collection: SanityDocument[] = []\n\n // Find initial docs\n const filter = ['_id in $fetchIds', pluginConfig.filter].filter(Boolean).join(' && ')\n const query = `*[${filter}]${projection ?? ``}`\n const data = await client.fetch<SanityDocument[]>(query, {\n fetchIds: fetchIds ?? [],\n })\n\n if (!data?.length) {\n return []\n }\n\n const localCurrentIds = currentIds ?? new Set<string>()\n\n // Find new ids in the returned data\n // Unless we started with an empty set, get the _ids from the data\n const newDataIds = new Set<string>(\n data\n .map((dataDoc) => dataDoc._id)\n .filter((id) => (currentIds?.size ? !localCurrentIds.has(id) : Boolean(id))),\n )\n\n if (newDataIds.size) {\n collection.push(...data)\n for (const id of newDataIds) {\n localCurrentIds.add(id)\n }\n\n // Check new data for more references\n await Promise.all(\n data.map(async (doc) => {\n const expr = `.._ref`\n const references = extractWithPath(expr, doc).flatMap((ref) =>\n typeof ref.value === 'string' ? [ref.value] : [],\n )\n\n if (references.length) {\n // Find references not already in the Collection\n const newReferenceIds = new Set<string>(\n references.filter((ref) => !localCurrentIds.has(ref)),\n )\n\n if (newReferenceIds.size) {\n // Recursive query for new documents\n const referenceDocs = await getDocumentsInArray({\n fetchIds: Array.from(newReferenceIds),\n currentIds: localCurrentIds,\n client,\n pluginConfig,\n })\n\n if (referenceDocs?.length) {\n collection.push(...referenceDocs)\n }\n }\n }\n }),\n )\n }\n\n // Create a unique array of documents, keeping the first occurrence of each _id\n const seenIds = new Set<string>()\n const uniqueCollection: SanityDocument[] = []\n\n for (const doc of collection) {\n if (doc && !seenIds.has(doc._id)) {\n seenIds.add(doc._id)\n uniqueCollection.push(doc)\n }\n }\n\n return uniqueCollection\n}\n","import type {MigrationFilter} from '../types'\n\ntype IsAllowedMigrationTargetOptions = {\n migrationFilters: MigrationFilter[] | undefined\n sourceProjectId: string | undefined\n sourceDataset: string | undefined\n targetProjectId: string\n targetDataset: string\n}\n\n/**\n * Determine whether a Workspace is an allowed Migration destination for the\n * current source Dataset, based on the optional `migrationFilters` config.\n *\n * If no filter is configured for the source Dataset, every target is allowed\n * (the default behaviour). When a filter is configured, only the listed targets\n * are allowed.\n */\nexport function isAllowedMigrationTarget(options: IsAllowedMigrationTargetOptions): boolean {\n const {migrationFilters, sourceProjectId, sourceDataset, targetProjectId, targetDataset} = options\n\n const migrationFilter = migrationFilters?.find((filter) => filter.sourceDataset === sourceDataset)\n\n // If no migrationFilter is configured for this dataset, allow all migration targets.\n if (!migrationFilter) {\n return true\n }\n\n return migrationFilter.targets.some((target) => {\n if (target.dataset !== targetDataset) {\n return false\n }\n\n // If a project ID is configured for the target, check that it matches.\n if (target.projectId) {\n return target.projectId === targetProjectId\n }\n\n // If a project ID is not configured for the target, only allow targets in\n // the same project as the source.\n return targetProjectId === sourceProjectId\n })\n}\n","import {Card, Text} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport type {ReactNode} from 'react'\n\ntype FeedbackProps = {\n children?: ReactNode\n tone?: BadgeTone\n}\n\nexport default function Feedback(props: FeedbackProps) {\n const {children, tone = 'caution'} = props\n\n return (\n <Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>\n )\n}\n","import {isAssetId} from '@sanity/asset-utils'\nimport {Button, Card, Flex} from '@sanity/ui'\nimport {type Dispatch, type SetStateAction, useState} from 'react'\n\nimport type {PayloadItem} from './Duplicator'\n\ntype Action = 'ALL' | 'NONE' | 'NEW' | 'EXISTING' | 'OLDER' | 'ASSETS' | 'DOCUMENTS'\n\ntype ButtonItem = {label: string; action: Action} | {divider: string}\n\nconst buttons: ButtonItem[] = [\n {label: 'All', action: 'ALL'},\n {label: 'None', action: 'NONE'},\n {divider: 'divider-1'},\n {label: 'New', action: 'NEW'},\n {label: 'Existing', action: 'EXISTING'},\n {label: 'Older', action: 'OLDER'},\n {divider: 'divider-2'},\n {label: 'Documents', action: 'DOCUMENTS'},\n {label: 'Assets', action: 'ASSETS'},\n]\n\nfunction shouldInclude(item: PayloadItem, action: Action): boolean {\n switch (action) {\n case 'ALL':\n return true\n case 'NONE':\n return false\n case 'NEW':\n return item.status === 'CREATE'\n case 'EXISTING':\n return item.status === 'EXISTS'\n case 'OLDER':\n return item.status === 'OVERWRITE'\n case 'ASSETS':\n return isAssetId(item.doc._id)\n case 'DOCUMENTS':\n return !isAssetId(item.doc._id)\n default:\n return item.include\n }\n}\n\ntype SelectButtonsProps = {\n payload: PayloadItem[]\n setPayload: Dispatch<SetStateAction<PayloadItem[]>>\n}\n\nexport default function SelectButtons(props: SelectButtonsProps) {\n const {payload, setPayload} = props\n const [disabledActions, setDisabledActions] = useState<Action[]>(() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : [],\n )\n\n function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }\n\n return (\n <Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>\n )\n}\n","import {InfoOutlineIcon} from '@sanity/icons/InfoOutline'\nimport {Box, Text, Badge} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\n\ntype StatusTones = {\n EXISTS: BadgeTone\n OVERWRITE: BadgeTone\n UPDATE: BadgeTone\n CREATE: BadgeTone\n UNPUBLISHED: BadgeTone\n}\n\nconst documentTones: StatusTones = {\n EXISTS: `primary`,\n OVERWRITE: `critical`,\n UPDATE: `caution`,\n CREATE: `positive`,\n UNPUBLISHED: `caution`,\n}\n\nconst assetTones: StatusTones = {\n EXISTS: `critical`,\n OVERWRITE: `critical`,\n UPDATE: `critical`,\n CREATE: `positive`,\n UNPUBLISHED: `default`,\n}\n\nexport type MessageTypes = {\n EXISTS: string\n OVERWRITE: string\n UPDATE: string\n CREATE: string\n UNPUBLISHED: string\n}\n\nconst documentMessages: MessageTypes = {\n // Only happens once document is copied the first time, and _updatedAt is the same\n EXISTS: `This document already exists at the Destination with the same ID and Updated time.`,\n // Is true immediately after transaction as _updatedAt is updated by API after mutation\n // Is also true if the document at the destination has been manually modified\n // Presently, the plugin doesn't actually compare the two documents\n OVERWRITE: `A newer version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination is older\n UPDATE: `An older version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination doesn't exist\n CREATE: `This document will be created at the destination.`,\n UNPUBLISHED: `A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination.`,\n}\n\nconst assetMessages: MessageTypes = {\n EXISTS: `This Asset already exists at the Destination`,\n OVERWRITE: `This Asset already exists at the Destination`,\n UPDATE: `This Asset already exists at the Destination`,\n CREATE: `This Asset does not yet exist at the Destination`,\n UNPUBLISHED: ``,\n}\n\nconst assetStatus: MessageTypes = {\n EXISTS: `RE-UPLOAD`,\n OVERWRITE: `RE-UPLOAD`,\n UPDATE: `RE-UPLOAD`,\n CREATE: `UPLOAD`,\n UNPUBLISHED: ``,\n}\n\ntype StatusBadgeProps = {\n isAsset: boolean\n status?: keyof MessageTypes\n}\n\nexport default function StatusBadge(props: StatusBadgeProps) {\n const {status, isAsset} = props\n\n if (!status) {\n return null\n }\n\n const badgeTone = isAsset ? assetTones[status] : documentTones[status]\n\n if (!badgeTone) {\n return (\n <Badge padding={2} fontSize={1}>\n Checking...\n </Badge>\n )\n }\n\n const badgeText = isAsset ? assetMessages[status] : documentMessages[status]\n const badgeStatus = isAsset ? assetStatus[status] : status\n\n return (\n <Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>\n )\n}\n","import {isAssetId, isSanityFileAsset} from '@sanity/asset-utils'\nimport type {SanityAssetDocument, SanityClient} from '@sanity/client'\nimport {ArrowRightIcon} from '@sanity/icons/ArrowRight'\nimport {LaunchIcon} from '@sanity/icons/Launch'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {extractWithPath} from '@sanity/mutator'\nimport {\n Card,\n Container,\n Text,\n Box,\n Button,\n Label,\n Stack,\n Select,\n Flex,\n Checkbox,\n type CardTone,\n useTheme,\n Spinner,\n} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {dset} from 'dset'\nimport {type ChangeEvent, Fragment, useEffect, useEffectEvent, useMemo, useState} from 'react'\nimport {\n useClient,\n Preview,\n useSchema,\n useWorkspaces,\n type WorkspaceSummary,\n type SanityDocument,\n} from 'sanity'\n\nimport {stickyStyles, createInitialMessage} from '../helpers'\nimport {getDocumentsInArray} from '../helpers/getDocumentsInArray'\nimport {isAllowedMigrationTarget} from '../helpers/migrationFilters'\nimport type {PluginConfig} from '../types'\nimport Feedback from './Feedback'\nimport SelectButtons from './SelectButtons'\nimport StatusBadge, {type MessageTypes} from './StatusBadge'\n\nexport type DuplicatorProps = {\n docs: SanityDocument[]\n token: string\n pluginConfig: Required<PluginConfig>\n onDuplicated?: () => Promise<void>\n}\n\nexport type PayloadItem = {\n doc: SanityDocument\n include: boolean\n status?: keyof MessageTypes\n hasDraft?: boolean\n}\n\ntype WorkspaceOption = WorkspaceSummary & {\n disabled: boolean\n}\n\ntype Message = {\n text: string\n tone: CardTone\n}\n\nfunction isAssetDocument(doc: SanityDocument): doc is SanityDocument & SanityAssetDocument {\n return isAssetId(doc._id)\n}\n\n// Run an async function over every item with a maximum concurrency\nasync function mapWithConcurrency<T>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<void>,\n): Promise<void> {\n const queue = [...items]\n\n async function work(): Promise<void> {\n const item = queue.shift()\n\n if (item === undefined) {\n return undefined\n }\n\n await fn(item)\n\n return work()\n }\n\n const workers = Array.from({length: Math.min(limit, queue.length)}, () => work())\n\n await Promise.all(workers)\n}\n\ntype SetMessage = (msg: Message) => void\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction isUnknownArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\n// Pull a human-readable description out of a Sanity mutation error.\n// Prefer the richest text available: item-level descriptions (which carry the\n// \"references non-existent document\" phrasing) over a possibly-generic top-level\n// `details.description` like \"Mutation(s) failed with N error(s)\".\nfunction getErrorDescription(err: unknown): string {\n if (!isRecord(err)) {\n return ''\n }\n\n const details = err['details']\n const itemDescriptions: string[] = []\n\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n const itemDescription = item['error']['description']\n\n if (typeof itemDescription === 'string' && itemDescription) {\n itemDescriptions.push(itemDescription)\n }\n }\n }\n }\n\n if (itemDescriptions.length) {\n return itemDescriptions.join('\\n')\n }\n\n const message = err['message']\n\n if (typeof message === 'string' && message) {\n return message\n }\n\n if (isRecord(details)) {\n const description = details['description']\n\n if (typeof description === 'string') {\n return description\n }\n }\n\n return ''\n}\n\nfunction isReferenceMutationError(err: unknown): boolean {\n if (!isRecord(err)) {\n return false\n }\n\n const details = err['details']\n\n // Most reliable: structured mutation item type from the Content Lake API\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n if (item['error']['type'] === 'documentReferenceDoesNotExistError') {\n return true\n }\n\n const itemDescription = item['error']['description']\n\n if (\n typeof itemDescription === 'string' &&\n (itemDescription.toLowerCase().includes('references non-existent document') ||\n itemDescription.toLowerCase().includes('reference non-existent'))\n ) {\n return true\n }\n }\n }\n }\n\n const description = getErrorDescription(err).toLowerCase()\n\n return (\n description.includes('references non-existent document') ||\n description.includes('reference non-existent')\n )\n}\n\n// Collect the _id's of referenced documents that are missing at the destination,\n// reading both the structured error payload and the human-readable description\nfunction getMissingReferenceIds(err: unknown, description: string): string[] {\n const missingIds: string[] = []\n\n const details = isRecord(err) ? err['details'] : undefined\n const rawItems = isRecord(details) ? details['items'] : undefined\n const items = isUnknownArray(rawItems) ? rawItems : []\n\n for (const item of items) {\n if (isRecord(item)) {\n const error = item['error']\n\n if (isRecord(error)) {\n // Sanity returns `referenceID`; keep the other spellings as fallbacks\n const refId = error['referenceID'] ?? error['referencedId'] ?? error['referenceId']\n\n if (typeof refId === 'string' && !missingIds.includes(refId)) {\n missingIds.push(refId)\n }\n }\n }\n }\n\n const refRegex = /references non-existent document [`'\"]?([^`'\"\\s)]+)[`'\"]?/gi\n let match = refRegex.exec(description)\n\n while (match !== null) {\n const id = match[1]\n\n if (id && !missingIds.includes(id)) {\n missingIds.push(id)\n }\n\n match = refRegex.exec(description)\n }\n\n return missingIds\n}\n\n// Commit documents individually so a single failing document doesn't block the rest.\n// Runs sequentially (concurrency 1) so referenced documents can land before the\n// documents that point at them.\nasync function commitOneByOne(\n docs: SanityDocument[],\n client: SanityClient,\n setMessage: SetMessage,\n onSuccess: () => void,\n): Promise<void> {\n let successCount = 0\n let failCount = 0\n\n await mapWithConcurrency(docs, 1, async (doc) => {\n try {\n const tx = client.transaction()\n tx.createOrReplace(doc)\n await tx.commit()\n successCount += 1\n } catch (commitErr) {\n failCount += 1\n console.error(`Failed to duplicate document \"${doc._id}\"`, commitErr)\n }\n })\n\n if (failCount === 0) {\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n\n return\n }\n\n setMessage({\n tone: 'critical',\n text: `Duplication finished with ${failCount} error(s). ${successCount} document(s) duplicated successfully.`,\n })\n\n if (successCount > 0) {\n onSuccess()\n }\n}\n\ntype ReferenceErrorOptions = {\n err: unknown\n transactionDocs: SanityDocument[]\n originClient: SanityClient\n destinationClient: SanityClient\n pluginConfig: Required<PluginConfig>\n token: string\n setMessage: SetMessage\n onSuccess: () => void\n /** Caps recursive recovery so a pathological reference loop can't hang forever */\n depth?: number\n /** Document ids the user explicitly deselected — never auto-commit these during recovery */\n excludedIds?: Set<string>\n /**\n * SVG _id remaps already applied by the caller. Recovered documents are fetched\n * fresh from the origin, so they still point at origin SVG _id's that only exist\n * at the destination under their uploaded _id.\n */\n svgMaps?: {old: string; new: string}[]\n}\n\n// Only attach the studio token when downloading from a Sanity host so a crafted\n// asset `url` cannot exfiltrate credentials to an attacker-controlled endpoint.\nfunction assetDownloadInit(url: string, token: string, typeIsFile: boolean): RequestInit {\n if (typeIsFile) {\n return {}\n }\n\n try {\n const {hostname} = new URL(url)\n\n if (hostname === 'cdn.sanity.io' || hostname.endsWith('.sanity.io')) {\n return {headers: {Authorization: `Bearer ${token}`}}\n }\n } catch {\n // Invalid URL — fetch without credentials\n }\n\n return {}\n}\n\n// Upload a recovered asset to the destination, rewriting url/path for the new dataset\nasync function uploadAssetForRecovery(\n doc: SanityDocument & SanityAssetDocument,\n destinationClient: SanityClient,\n token: string,\n): Promise<{docs: SanityDocument[]; svgMap?: {old: string; new: string}}> {\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc._id}\" from origin (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n const assetDoc = await destinationClient.assets.upload(typeIsFile ? `file` : `image`, assetData, {\n filename: doc.originalFilename,\n })\n\n // Merge the original asset document's editorial metadata (e.g. `altText`) with\n // the uploaded asset's canonical fields, matching the main duplication path.\n // Keeping this to a single document at the uploaded `_id` avoids leaving an\n // orphaned asset behind when an SVG's `_id` changes on upload; references are\n // repointed via `svgMap`.\n return {\n docs: [{...doc, ...assetDoc}],\n svgMap: doc.extension === 'svg' ? {old: doc._id, new: assetDoc._id} : undefined,\n }\n}\n\n// Rewrite _ref values that point at remapped SVG asset ids.\n// Clones each doc so caller-held / payload objects are not mutated.\nfunction remapSvgRefs(\n docs: SanityDocument[],\n svgMaps: {old: string; new: string}[],\n): SanityDocument[] {\n if (!svgMaps.length) {\n return docs\n }\n\n return docs.map((original) => {\n const references = extractWithPath(`.._ref`, original)\n\n if (!references.length) {\n return original\n }\n\n const doc = structuredClone(original)\n\n references.forEach((ref) => {\n const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new\n\n if (newRefValue) {\n dset(doc, ref.path.join('.'), newRefValue)\n }\n })\n\n return doc\n })\n}\n\n// Order docs so referenced documents come before the documents that point at\n// them. Used by the sequential one-by-one fallback where commit order matters.\nfunction orderDocsDependenciesFirst(docs: SanityDocument[]): SanityDocument[] {\n const byId = new Map(docs.map((doc) => [doc._id, doc]))\n const visiting = new Set<string>()\n const visited = new Set<string>()\n const ordered: SanityDocument[] = []\n\n function visit(id: string): void {\n if (visited.has(id) || visiting.has(id)) {\n return\n }\n\n const doc = byId.get(id)\n\n if (!doc) {\n return\n }\n\n visiting.add(id)\n\n for (const ref of extractWithPath(`.._ref`, doc)) {\n if (typeof ref.value === 'string') {\n visit(ref.value)\n }\n }\n\n visiting.delete(id)\n visited.add(id)\n ordered.push(doc)\n }\n\n for (const doc of docs) {\n visit(doc._id)\n }\n\n return ordered\n}\n\n// When a transaction fails because of missing references, fetch the referenced\n// documents (and their transitive refs) from the origin — respecting\n// pluginConfig.filter — upload any assets, then retry. Falls back to one-by-one\n// commits if the retry still fails.\nasync function handleReferenceError(options: ReferenceErrorOptions): Promise<void> {\n const {\n err,\n transactionDocs,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess,\n depth = 0,\n excludedIds = new Set(),\n svgMaps: inheritedSvgMaps = [],\n } = options\n const description = getErrorDescription(err)\n const missingIds = getMissingReferenceIds(err, description)\n\n // If the only missing refs are ones the user deselected, surface that instead of\n // silently re-committing them\n const autoFetchIds = missingIds.filter((id) => !excludedIds.has(id))\n const blockedIds = missingIds.filter((id) => excludedIds.has(id))\n\n if (blockedIds.length && !autoFetchIds.length) {\n setMessage({\n tone: 'critical',\n text: `Duplication failed because deselected document(s) are still referenced: ${blockedIds.join(', ')}. Re-select them or remove the references.`,\n })\n\n return\n }\n\n if (!missingIds.length || depth >= 5) {\n // Couldn't parse the missing _id's (or we hit the recursion cap) — retry each document on its own\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({\n tone: 'default',\n text: `Fetching ${autoFetchIds.length} missing referenced document(s) and retrying...`,\n })\n\n let missingDocs: SanityDocument[] = []\n\n try {\n // Recursively gather referenced docs (and apply pluginConfig.filter), same\n // as the \"Gather References\" path — so nested refs aren't left behind\n missingDocs = await getDocumentsInArray({\n fetchIds: autoFetchIds,\n client: originClient,\n pluginConfig,\n })\n } catch (fetchErr) {\n setMessage({\n tone: 'critical',\n text:\n (fetchErr instanceof Error ? fetchErr.message : '') || description || 'Duplication Failed',\n })\n\n return\n }\n\n if (!missingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n // Don't re-commit documents already in the failed transaction, or ones the\n // user explicitly deselected (including transitive refs of those)\n const existingIds = new Set(transactionDocs.map((doc) => doc._id))\n // Reverse so transitive refs (appended last by getDocumentsInArray) are processed first\n const newMissingDocs = [...missingDocs]\n .reverse()\n .filter((doc) => !existingIds.has(doc._id) && !excludedIds.has(doc._id))\n\n // Nothing new to add — retrying the same transaction would just loop until the depth cap\n if (!newMissingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({tone: 'default', text: `Duplicating ${newMissingDocs.length} missing document(s)...`})\n\n // Seed with the caller's remaps so recovered documents referencing an SVG that\n // was uploaded earlier are repointed at its destination _id, even when that\n // asset isn't re-fetched here (e.g. `pluginConfig.filter` excludes assets)\n const svgMaps: {old: string; new: string}[] = [...inheritedSvgMaps]\n\n // Process with the same concurrency limit as the main duplication path, while\n // writing into index slots so dependency-first order is preserved\n const recoveredChunks: SanityDocument[][] = Array.from({length: newMissingDocs.length}, () => [])\n\n try {\n await mapWithConcurrency(\n newMissingDocs.map((doc, index) => ({doc, index})),\n 3,\n async ({doc, index}) => {\n if (!isAssetDocument(doc)) {\n recoveredChunks[index] = [doc]\n\n return\n }\n\n const {docs, svgMap} = await uploadAssetForRecovery(doc, destinationClient, token)\n recoveredChunks[index] = docs\n\n if (svgMap) {\n svgMaps.push(svgMap)\n }\n },\n )\n } catch (uploadErr) {\n setMessage({\n tone: 'critical',\n text:\n (uploadErr instanceof Error ? uploadErr.message : '') ||\n description ||\n 'Duplication Failed',\n })\n\n return\n }\n\n const recoveredDocs = recoveredChunks.flat()\n\n // Remap SVG _ref's in both recovered and original transaction docs\n const remappedRecoveredDocs = remapSvgRefs(recoveredDocs, svgMaps)\n const remappedTransactionDocs = remapSvgRefs(transactionDocs, svgMaps)\n\n // Put recovered (referenced) docs first so sequential commits land\n // dependencies before the documents that point at them\n const allDocs = orderDocsDependenciesFirst([...remappedRecoveredDocs, ...remappedTransactionDocs])\n\n const retryTransaction = destinationClient.transaction()\n allDocs.forEach((doc) => retryTransaction.createOrReplace(doc))\n\n try {\n await retryTransaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n } catch (retryErr) {\n if (isReferenceMutationError(retryErr)) {\n // Another layer of missing refs — recurse with the expanded set\n await handleReferenceError({\n ...options,\n err: retryErr,\n transactionDocs: allDocs,\n depth: depth + 1,\n svgMaps,\n })\n\n return\n }\n\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(allDocs, destinationClient, setMessage, onSuccess)\n }\n}\n\nexport default function Duplicator(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const theme = useTheme()\n const isDarkMode = getTheme_v2({sanity: theme.sanity}).color._dark\n\n // Prepare origin (this Studio) client\n const originClient = useClient({apiVersion: pluginConfig.apiVersion})\n\n const schema = useSchema()\n\n // Create list of dataset options\n // and set initial value of dropdown\n const workspaces = useWorkspaces()\n const {projectId: sourceProjectId, dataset: sourceDataset} = originClient.config()\n const workspacesOptions: WorkspaceOption[] = workspaces.map((workspace) => {\n const isSourceWorkspace =\n workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset\n const isAllowedMigration = isAllowedMigrationTarget({\n migrationFilters: pluginConfig.migrationFilters,\n sourceProjectId,\n sourceDataset,\n targetProjectId: workspace.projectId,\n targetDataset: workspace.dataset,\n })\n\n return {\n ...workspace,\n disabled: isSourceWorkspace || !isAllowedMigration,\n }\n })\n\n const currentWorkspace = workspacesOptions.find(\n (workspace) => workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset,\n )\n\n const [destination, setDestination] = useState<WorkspaceOption | null>(\n workspaces.length ? (workspacesOptions.find((space) => !space.disabled) ?? null) : null,\n )\n const [message, setMessage] = useState<Message | null>(null)\n const [payload, setPayload] = useState<PayloadItem[]>([])\n\n const [isDuplicating, setIsDuplicating] = useState(false)\n const [isGathering, setIsGathering] = useState(false)\n const [progress, setProgress] = useState<[number, number]>([0, 0])\n\n // References found in the initial docs\n const initialRefsCount = useMemo(\n () => docs.reduce((acc, doc) => acc + extractWithPath(`.._ref`, doc).length, 0),\n [docs],\n )\n const hasReferences = initialRefsCount > 0\n const initialMessage: Message | null = hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null\n const displayMessage = message ?? initialMessage\n\n // Check if payload documents exist at destination\n async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }\n\n // Build the initial payload and check statuses at the current destination\n const initializePayload = useEffectEvent((nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n })\n\n // Sync the payload with the docs prop and the destination dataset.\n // setPayload only runs after fetching document statuses from the\n // destination resolves, not synchronously within the effect.\n // See: https://github.com/facebook/react/issues/34743\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }, [docs])\n\n function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }\n\n // Find and recursively follow references beginning with this document\n async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }\n\n // Duplicate payload to destination dataset\n async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLSelectElement>) {\n if (!workspacesOptions.length) {\n return\n }\n\n const targeted = workspacesOptions.find((space) => space.name === e.currentTarget.value)\n\n if (targeted) {\n setDestination(targeted)\n updatePayloadStatuses(payload, targeted).catch(console.error)\n }\n }\n\n const payloadCount = payload.length\n const firstSvgIndex = payload.findIndex(({doc}) => doc['extension'] === 'svg')\n const selectedDocumentsCount = payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n ).length\n const selectedAssetsCount = payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n ).length\n const selectedTotal = selectedDocumentsCount + selectedAssetsCount\n const destinationTitle = destination?.title ?? destination?.name\n const hasMultipleProjectIds =\n new Set(workspacesOptions.map((space) => space?.projectId).filter(Boolean)).size > 1\n\n const headingText = [selectedTotal, `/`, payloadCount, `Documents and Assets selected`].join(` `)\n\n const buttonTextParts = [`Duplicate`]\n\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(\n String(selectedDocumentsCount),\n selectedDocumentsCount === 1 ? `Document` : `Documents`,\n )\n }\n\n if (selectedAssetsCount > 0) {\n // Only join with \"and\" when documents are also part of the selection.\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(`and`)\n }\n\n buttonTextParts.push(\n String(selectedAssetsCount),\n selectedAssetsCount === 1 ? `Asset` : `Assets`,\n )\n }\n\n if (originClient.config().projectId !== destination?.projectId) {\n buttonTextParts.push(`between Projects`)\n }\n\n buttonTextParts.push(`to`, String(destinationTitle))\n\n const buttonText = buttonTextParts.join(` `)\n\n if (workspacesOptions.length < 2) {\n return (\n <Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>\n )\n }\n\n if (!destination) {\n return (\n <Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>\n )\n }\n\n return (\n <Container width={1}>\n <Card border>\n <Stack>\n <Card padding={4} style={stickyStyles(isDarkMode)}>\n <Stack gap={4}>\n <Flex gap={3}>\n <Stack style={{flex: 1}} gap={3}>\n <Label>Duplicate from</Label>\n <Select readOnly value={currentWorkspace?.name}>\n {currentWorkspace ? (\n <option value={currentWorkspace.name}>\n {currentWorkspace.title ?? currentWorkspace.name}\n {hasMultipleProjectIds ? ` (${currentWorkspace.projectId})` : ``}\n </option>\n ) : null}\n </Select>\n </Stack>\n <Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>\n <Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>\n </Flex>\n\n {isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )}\n {payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )}\n </Stack>\n </Card>\n <Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>\n </Stack>\n </Card>\n </Container>\n )\n}\n","import {Button, Stack, Box, Label, Text, Card, Flex, Grid, Container, TextInput} from '@sanity/ui'\nimport {type SubmitEvent, useState} from 'react'\nimport {useSchema, useClient, type SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport Duplicator from './Duplicator'\n\ntype DuplicatorQueryProps = {\n token: string\n pluginConfig: Required<PluginConfig>\n}\n\ntype InitialData = {\n docs: SanityDocument[]\n}\n\nexport default function DuplicatorQuery(props: DuplicatorQueryProps) {\n const {token, pluginConfig} = props\n\n const {queries: preDefinedQueries, apiVersion} = pluginConfig\n const originClient = useClient({apiVersion})\n\n const schema = useSchema()\n const schemaTypes = schema.getTypeNames()\n\n const [value, setValue] = useState(``)\n const [fetched, setFetched] = useState(false)\n const [initialData, setInitialData] = useState<InitialData>({\n docs: [],\n })\n\n async function runQuery() {\n try {\n const res = await originClient.fetch<SanityDocument[]>(value)\n\n // Ensure queried docs are registered to the schema\n const registeredAndPublishedDocs = res.length\n ? res\n .filter((doc) => schemaTypes.includes(doc._type))\n .filter((doc) => !doc._id.startsWith(`drafts.`))\n : []\n\n setInitialData({\n docs: registeredAndPublishedDocs,\n })\n setFetched(true)\n } catch (err) {\n console.error(err)\n }\n }\n\n function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }\n\n return (\n <Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>\n )\n}\n","import {Grid, Card, Container, Button} from '@sanity/ui'\nimport {useState, useEffect} from 'react'\nimport {type SanityDocument, useClient} from 'sanity'\n\nimport type {DuplicatorProps} from './Duplicator'\nimport Duplicator from './Duplicator'\n\nexport default function DuplicatorWrapper(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const [inbound, setInbound] = useState<SanityDocument[]>([])\n const {follow, apiVersion} = pluginConfig\n\n // Make the first mode the default if there's only one\n const [mode, setMode] = useState<'inbound' | 'outbound'>(\n follow.length === 1 ? (follow[0] ?? 'outbound') : 'outbound',\n )\n const client = useClient({apiVersion})\n\n // \"Inbound\" will start with all documents that reference the first one\n // And then you can gather \"Outbound\" references thereafter\n useEffect(() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }, [client, docs, follow])\n\n return (\n <Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>\n )\n}\n","import {Button, Flex} from '@sanity/ui'\nimport {useCallback} from 'react'\nimport {useClient} from 'sanity'\n\nimport {SECRET_NAMESPACE} from '../helpers/constants'\n\ntype ResetSecretProps = {\n apiVersion: string\n}\n\nexport default function ResetSecret({apiVersion}: ResetSecretProps) {\n const client = useClient({apiVersion})\n\n const handleClick = useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])\n\n return (\n <Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>\n )\n}\n","import {useSecrets, SettingsView} from '@sanity/studio-secrets'\nimport {Flex, Box, Spinner} from '@sanity/ui'\nimport type {SanityDocument} from 'sanity'\n\nimport {useCrossDatasetDuplicatorConfig} from '../context/ConfigProvider'\nimport {SECRET_NAMESPACE} from '../helpers/constants'\nimport DuplicatorQuery from './DuplicatorQuery'\nimport DuplicatorWrapper from './DuplicatorWrapper'\nimport Feedback from './Feedback'\nimport ResetSecret from './ResetSecret'\n\n// Check for auth secret (required for asset uploads)\nconst secretConfigKeys = [\n {\n key: 'bearerToken',\n title:\n 'An API token with Viewer permissions is required to duplicate the original files of assets, and will be used for all Duplications. Create one at sanity.io/manage',\n description: '',\n },\n]\n\ntype Secrets = {\n bearerToken?: string\n}\n\ntype CrossDatasetDuplicatorProps = {\n mode: 'tool' | 'action'\n docs: SanityDocument[]\n onDuplicated?: () => Promise<void>\n}\n\nexport default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProps) {\n const {mode, docs, onDuplicated} = props\n const pluginConfig = useCrossDatasetDuplicatorConfig()\n\n const {loading, secrets} = useSecrets<Secrets>(SECRET_NAMESPACE)\n\n if (loading) {\n return (\n <Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>\n )\n }\n\n // A bearer token is required to duplicate assets, so the prompt cannot be\n // dismissed until one is saved\n if (!secrets?.bearerToken) {\n return (\n <SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />\n )\n }\n\n if (mode === 'tool' && pluginConfig) {\n return (\n <>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>\n )\n }\n\n if (!docs?.length) {\n return <Feedback>No docs passed into Duplicator Tool</Feedback>\n }\n\n if (!pluginConfig) {\n return <Feedback>No plugin config</Feedback>\n }\n\n return (\n <DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n )\n}\n","import type {CrossDatasetDuplicatorActionProps} from '../types'\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\n/**\n * Component to perform a migration from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function CrossDatasetDuplicatorAction(props: CrossDatasetDuplicatorActionProps) {\n const {docs, onDuplicated} = props\n\n return <CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport {useState} from 'react'\nimport type {DocumentActionProps} from 'sanity'\n\nimport {CrossDatasetDuplicatorAction} from '../components/CrossDatasetDuplicatorAction'\n\n/**\n * Document action from the Cross Dataset Duplicator plugin\n * @public\n */\nexport const DuplicateToAction = (props: DocumentActionProps) => {\n const {draft, published} = props\n const [dialogOpen, setDialogOpen] = useState(false)\n\n return {\n disabled: Boolean(draft),\n title: draft ? `Document must be Published to begin` : null,\n label: 'Duplicate to...',\n dialog: dialogOpen &&\n published && {\n type: 'modal',\n title: 'Cross Dataset Duplicator',\n content: <CrossDatasetDuplicatorAction docs={[published]} />,\n onClose: () => setDialogOpen(false),\n },\n onHandle: () => setDialogOpen(true),\n icon: LaunchIcon,\n }\n}\n\nDuplicateToAction.action = 'duplicateTo'\n","import type {SanityDocument, Tool} from 'sanity'\n\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\nexport type MultiToolConfig = {\n docs: SanityDocument[]\n}\n\ntype CrossDatasetDuplicatorProps = {\n tool: Tool<MultiToolConfig>\n}\n\nexport function CrossDatasetDuplicatorTool(props: CrossDatasetDuplicatorProps) {\n const {docs = []} = props.tool.options ?? {}\n\n return <CrossDatasetDuplicator mode=\"tool\" docs={docs} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport type {Tool} from 'sanity'\n\nimport {\n CrossDatasetDuplicatorTool,\n type MultiToolConfig,\n} from '../components/CrossDatasetDuplicatorTool'\n\nexport const crossDatasetDuplicatorTool = (): Tool<MultiToolConfig> => ({\n title: 'Duplicator',\n name: 'duplicator',\n icon: LaunchIcon,\n component: CrossDatasetDuplicatorTool,\n options: {\n docs: [],\n },\n})\n","import {definePlugin} from 'sanity'\n\nimport {DuplicateToAction} from './actions/DuplicateToAction'\nimport {ConfigProvider} from './context/ConfigProvider'\nimport {DEFAULT_CONFIG} from './helpers/constants'\nimport {crossDatasetDuplicatorTool} from './tool'\nimport type {PluginConfig} from './types'\n\n/**\n * Plugin: Cross Dataset Duplicator\n * @public\n */\nexport const crossDatasetDuplicator = definePlugin<Partial<PluginConfig> | void>((config = {}) => {\n const pluginConfig = {...DEFAULT_CONFIG, ...config}\n const {types} = pluginConfig\n\n return {\n name: '@sanity/cross-dataset-duplicator',\n tools: (prev) => (pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev),\n studio: {\n components: {\n layout: (props) => <ConfigProvider {...props} pluginConfig={pluginConfig} />,\n },\n },\n document: {\n actions: (prev, {schemaType}) => {\n return types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev\n },\n },\n }\n})\n"],"mappings":"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"}
\ No newline at end of file