@sanity/cross-dataset-duplicator 0.4.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +53 -57
- package/lib/index.esm.js +1 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/index.js +1 -21
- package/lib/index.js.map +1 -1
- package/lib/src/index.d.ts +548 -0
- package/package.json +64 -38
- package/sanity.json +2 -10
- package/src/actions/DuplicateToAction.tsx +20 -8
- package/src/components/CrossDatasetDuplicator.tsx +34 -49
- package/src/components/CrossDatasetDuplicatorAction.tsx +14 -0
- package/src/components/CrossDatasetDuplicatorTool.tsx +18 -0
- package/src/components/{DuplicatorTool.tsx → Duplicator.tsx} +179 -181
- package/src/components/DuplicatorQuery.tsx +36 -13
- package/src/components/DuplicatorWrapper.tsx +66 -0
- package/src/components/ResetSecret.tsx +9 -9
- package/src/components/SelectButtons.tsx +13 -9
- package/src/components/StatusBadge.tsx +13 -9
- package/src/context/ConfigProvider.tsx +30 -0
- package/src/helpers/clientConfig.ts +1 -1
- package/src/helpers/constants.ts +10 -1
- package/src/helpers/getDocumentsInArray.ts +28 -21
- package/src/helpers/index.ts +6 -10
- package/src/index.ts +5 -0
- package/src/plugin.tsx +31 -0
- package/src/tool/index.ts +11 -10
- package/src/types/index.ts +17 -7
- package/v2-incompatible.js +11 -0
- package/.babelrc +0 -3
- package/.eslintignore +0 -1
- package/config.dist.json +0 -5
- package/lib/actions/DuplicateToAction.js +0 -44
- package/lib/actions/DuplicateToAction.js.map +0 -1
- package/lib/actions/index.js +0 -29
- package/lib/actions/index.js.map +0 -1
- package/lib/components/CrossDatasetDuplicator.js +0 -81
- package/lib/components/CrossDatasetDuplicator.js.map +0 -1
- package/lib/components/DuplicatorQuery.js +0 -105
- package/lib/components/DuplicatorQuery.js.map +0 -1
- package/lib/components/DuplicatorTool.js +0 -556
- package/lib/components/DuplicatorTool.js.map +0 -1
- package/lib/components/Feedback.js +0 -23
- package/lib/components/Feedback.js.map +0 -1
- package/lib/components/ResetSecret.js +0 -34
- package/lib/components/ResetSecret.js.map +0 -1
- package/lib/components/SelectButtons.js +0 -84
- package/lib/components/SelectButtons.js.map +0 -1
- package/lib/components/StatusBadge.js +0 -85
- package/lib/components/StatusBadge.js.map +0 -1
- package/lib/helpers/clientConfig.js +0 -11
- package/lib/helpers/clientConfig.js.map +0 -1
- package/lib/helpers/constants.js +0 -9
- package/lib/helpers/constants.js.map +0 -1
- package/lib/helpers/getDocumentsInArray.js +0 -74
- package/lib/helpers/getDocumentsInArray.js.map +0 -1
- package/lib/helpers/index.js +0 -27
- package/lib/helpers/index.js.map +0 -1
- package/lib/tool/index.js +0 -18
- package/lib/tool/index.js.map +0 -1
- package/lib/types/index.js +0 -2
- package/lib/types/index.js.map +0 -1
- package/src/actions/index.ts +0 -22
- package/src/index.js +0 -7
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# Cross Dataset Duplicator
|
|
2
2
|
|
|
3
|
-
Sanity Studio Tool and Document Action for empowering content editors to migrate Documents and Assets between Sanity Datasets and Projects from inside the Studio.
|
|
3
|
+
Sanity Studio v3 Tool and Document Action for empowering content editors to migrate Documents and Assets between Sanity Datasets and Projects from inside the Studio.
|
|
4
|
+
## Installation
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
```
|
|
7
|
+
npm install --save @sanity/cross-dataset-duplicator
|
|
8
|
+
```
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
or
|
|
8
11
|
|
|
9
12
|
```
|
|
10
|
-
|
|
13
|
+
yarn add @sanity/cross-dataset-duplicator
|
|
11
14
|
```
|
|
12
15
|
|
|
13
16
|
### Important Notes
|
|
@@ -16,54 +19,61 @@ This plugin is designed as a convenience for Authors to make small, infrequent c
|
|
|
16
19
|
|
|
17
20
|
- This plugin should be used in conjunction with a reliable backup strategy.
|
|
18
21
|
- Proceed with caution as this plugin can instantly write changes to Datasets.
|
|
19
|
-
- Larger migrations may take more time, especially with Assets.
|
|
22
|
+
- Larger migrations may take more time, especially with Assets. Trying to upload them all at once could result in a rate-limiting issue, so the plugin mitigates this by limiting simultaneous asset uploads to 3.
|
|
20
23
|
- If an Asset is already present at the destination, there's no need to duplicate it again.
|
|
21
|
-
- Before starting a Duplication you can select which Documents and Assets to include. Migrations will fail if every Referenced Document or Asset is not included in the transaction or already present at the destination Dataset.
|
|
24
|
+
- Before starting a Duplication you can select which Documents and Assets to include. Migrations will fail if every Referenced Document or Asset is not included in the transaction or is already present at the destination Dataset.
|
|
22
25
|
|
|
23
26
|
## Tool
|
|
24
27
|
|
|
25
28
|
The **Duplicate** Tool allows you to migrate Documents that are returned from any GROQ query.
|
|
26
29
|
|
|
27
|
-

|
|
28
31
|
|
|
29
32
|
## Document Action
|
|
30
33
|
|
|
31
34
|
The **Duplicate to...** Document Action allows you to migrate an individual Document.
|
|
32
35
|
|
|
33
|
-

|
|
36
37
|
|
|
37
38
|
## Required Setup
|
|
38
39
|
|
|
39
|
-
### 1.
|
|
40
|
+
### 1. Workspaces
|
|
40
41
|
|
|
41
|
-
You must have [
|
|
42
|
+
You must have more than one [Workspace configured](https://www.sanity.io/docs/config-api-reference#37c85e3072b2) to use this plugin.
|
|
42
43
|
|
|
43
|
-
All Datasets
|
|
44
|
+
All Datasets and Project IDs set up as Workspaces will become selectable "destinations" for Migrations.
|
|
44
45
|
|
|
45
|
-
Once
|
|
46
|
+
Once set up, you will see a dropdown menu next to the Search bar in the Studio with the Datasets you have configured.
|
|
46
47
|
|
|
47
48
|
### 2. Configuration
|
|
48
49
|
|
|
49
50
|
The plugin has some configuration options. These can be set by adding a config file to your Studio
|
|
50
51
|
|
|
51
|
-
```
|
|
52
|
-
// ./
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
```ts
|
|
53
|
+
// ./sanity.config.ts
|
|
54
|
+
|
|
55
|
+
import {defineConfig} from 'sanity'
|
|
56
|
+
import {crossDatasetDuplicator} from '@sanity/cross-dataset-duplicator'
|
|
57
|
+
|
|
58
|
+
export const defineConfig({
|
|
59
|
+
// all other settings...
|
|
60
|
+
plugins: [
|
|
61
|
+
// all other plugins...
|
|
62
|
+
crossDatasetDuplicator({
|
|
63
|
+
// Required settings to show document action
|
|
64
|
+
types: ['article', 'page'],
|
|
65
|
+
// Optional settings
|
|
66
|
+
tool: true,
|
|
67
|
+
filter: '_type != "product"',
|
|
68
|
+
follow: []
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
})
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
Options:
|
|
65
75
|
|
|
66
|
-
- `tool` (boolean, default: true) – Set whether the Migration Tool is enabled.
|
|
76
|
+
- `tool` (boolean, default: true) – Set whether the Migration **Tool** is enabled.
|
|
67
77
|
- `types` (Array[String], default: []) – Set which Schema Types the Migration Action should be enabled in.
|
|
68
78
|
- `filter` (String, default: undefined) - Set a predicate for documents when gathering dependencies.
|
|
69
79
|
- `follow` (("inbound" | "outbound")[], default: []) – Add buttons to allow the user to begin with just the existing document or first fetch all inbound references.
|
|
@@ -74,47 +84,33 @@ To Duplicate the original files of Assets, an API Token with Viewer permissions
|
|
|
74
84
|
|
|
75
85
|
This plugin uses [Sanity Secrets](https://github.com/sanity-io/sanity-studio-secrets/) to store the token in the Dataset itself.
|
|
76
86
|
|
|
77
|
-
You can [create API tokens in
|
|
87
|
+
You can [create API tokens in Manage](https://sanity.io/manage)
|
|
78
88
|
|
|
79
89
|
### 4. CORS origins
|
|
80
90
|
|
|
81
|
-
If you want to duplicate data across different projects, you need to enable CORS for the different hosts. This allows different projects to connect
|
|
82
|
-
|
|
83
|
-
## Importing the Document Action
|
|
91
|
+
If you want to duplicate data across different projects, you need to enable CORS for the different hosts. This allows different projects to connect through the project API. CORS origins configuration can be found on your project page, under the API tab.
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
## Future feature ideas
|
|
86
94
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"path": "./src/document-actions"
|
|
91
|
-
}
|
|
92
|
-
```
|
|
95
|
+
- Save predefined GROQ queries in the Tool to make bulk repeated Migrations simpler
|
|
96
|
+
- Config options for allowed migrations (eg Dev -> Staging but not Dev -> Live)
|
|
97
|
+
- Config options for permissions/user role checks
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
## License
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
import defaultResolve from 'part:@sanity/base/document-actions'
|
|
98
|
-
import {DuplicateToAction} from '@sanity/cross-dataset-duplicator'
|
|
99
|
-
import config from 'config:@sanity/cross-dataset-duplicator'
|
|
101
|
+
MIT-licensed. See LICENSE.
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
const defaultActions = defaultResolve(props)
|
|
103
|
+
## Develop & test
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (config?.types?.length && config.types.includes(props.type)) {
|
|
107
|
-
return [...defaultActions, DuplicateToAction]
|
|
108
|
-
}
|
|
105
|
+
This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
|
|
106
|
+
with default configuration for build & watch scripts.
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
|
|
109
|
+
on how to run this plugin with hotreload in the studio.
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
```
|
|
111
|
+
### Release new version
|
|
115
112
|
|
|
116
|
-
|
|
113
|
+
Run ["CI & Release" workflow](https://github.com/sanity-io/cross-dataset-duplicator/actions/workflows/main.yml).
|
|
114
|
+
Make sure to select the main branch and check "Release new version".
|
|
117
115
|
|
|
118
|
-
|
|
119
|
-
- Config options for allowed migrations (eg Dev -> Staging but not Dev -> Live)
|
|
120
|
-
- Config options for permissions/user role checks
|
|
116
|
+
Semantic release will only release on configured branches, so it is safe to run release on any branch.
|
package/lib/index.esm.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=["pluginConfig"];function t(e,t){if(null==e)return{};var n,i,o=function(e,t){if(null==e)return{};var n,i,o={},r=Object.keys(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function i(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?n(Object(i),!0).forEach((function(t){o(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):n(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var i=n.call(e,t||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}import{useClient as r,useSchema as a,useWorkspaces as l,Preview as d,definePlugin as c}from"sanity";import{jsx as s,jsxs as u,Fragment as h}from"react/jsx-runtime";import p,{useState as f,useEffect as g,createContext as m,useContext as b}from"react";import{ArrowRightIcon as y,SearchIcon as v,LaunchIcon as w}from"@sanity/icons";import{useSecrets as D,SettingsView as E}from"@sanity/studio-secrets";import{Card as T,Flex as S,Button as A,Badge as I,Tooltip as O,Box as _,Text as C,useTheme as x,Container as j,Stack as k,Label as P,Select as R,Checkbox as U,Grid as z,TextInput as B,Spinner as N}from"@sanity/ui";import L from"async/mapLimit";import X from"async/asyncify";import{extractWithPath as V}from"@sanity/mutator";import{dset as W}from"dset";import{isAssetId as q,isSanityFileAsset as H}from"@sanity/asset-utils";function G(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return[1===e?"This Document contains":"These ".concat(e," Documents contain"),1===t?"1 Reference.":"".concat(t," References."),1===t?"That Document":"Those Documents","may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail."].join(" ")}const F=function(){return{position:"sticky",top:0,zIndex:100,backgroundColor:!(arguments.length>0&&void 0!==arguments[0])||arguments[0]?"rgba(10,10,10,0.95)":"rgba(255,255,255,0.95)"}};async function Q(e){const{fetchIds:t,client:n,pluginConfig:i,currentIds:o,projection:r}=e,a=[],l=["_id in $fetchIds",i.filter].filter(Boolean).join(" && "),d="*[".concat(l,"]").concat(null!=r?r:""),c=await n.fetch(d,{fetchIds:null!=t?t:[]});if(!(null==c?void 0:c.length))return[];const s=null!=o?o:new Set,u=new Set(c.map((e=>e._id)).filter((e=>(null==o?void 0:o.size)?!s.has(e):Boolean(e))));u.size&&(a.push(...c),s.add(...u),await Promise.all(c.map((async e=>{const t=V(".._ref",e).map((e=>e.value));if(t.length){const e=new Set(t.filter((e=>!s.has(e))));if(e.size){const t=await Q({fetchIds:Array.from(e),currentIds:s,client:n,pluginConfig:i});(null==t?void 0:t.length)&&a.push(...t)}}}))));return a.filter(Boolean).reduce(((e,t)=>e.some((e=>e._id===t._id))?e:[...e,t]),[])}const $=["All","None",null,"New","Existing","Older",null,"Documents","Assets"];function M(e){const{payload:t,setPayload:n}=e,[i,o]=f([]);return g((()=>{!(null==i?void 0:i.length)&&t.every((e=>e.include))&&o(["ALL"])}),[null==i?void 0:i.length,t]),s(T,{padding:1,radius:3,shadow:1,children:s(S,{gap:2,children:$.map(((e,r)=>e?s(A,{fontSize:1,mode:"bleed",padding:2,text:e,disabled:i.includes(e.toUpperCase()),onClick:()=>function(e){if(!e||!t.length)return;const i=[...t];switch(e){case"ALL":i.map((e=>e.include=!0));break;case"NONE":i.map((e=>e.include=!1));break;case"NEW":i.map((e=>e.include=Boolean("CREATE"===e.status)));break;case"EXISTING":i.map((e=>e.include=Boolean("EXISTS"===e.status)));break;case"OLDER":i.map((e=>e.include=Boolean("OVERWRITE"===e.status)));break;case"ASSETS":i.map((e=>e.include=q(e.doc._id)));break;case"DOCUMENTS":i.map((e=>e.include=!q(e.doc._id)))}o([e]),n(i)}(e.toUpperCase())},e):s(T,{borderLeft:!0},"divider-".concat(r))))})})}const Y={EXISTS:"primary",OVERWRITE:"critical",UPDATE:"caution",CREATE:"positive",UNPUBLISHED:"caution"},J={EXISTS:"critical",OVERWRITE:"critical",UPDATE:"critical",CREATE:"positive",UNPUBLISHED:"default"},K={EXISTS:"This document already exists at the Destination with the same ID with the same Updated time.",OVERWRITE:"A newer version of this document exists at the Destination, and it will be overwritten with this version.",UPDATE:"An older version of this document exists at the Destination, and it will be overwritten with this version.",CREATE:"This document will be created at the destination.",UNPUBLISHED:"A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination."},Z={EXISTS:"This Asset already exists at the Destination",OVERWRITE:"This Asset already exists at the Destination",UPDATE:"This Asset already exists at the Destination",CREATE:"This Asset does not yet exist at the Destination",UNPUBLISHED:""},ee={EXISTS:"RE-UPLOAD",OVERWRITE:"RE-UPLOAD",UPDATE:"RE-UPLOAD",CREATE:"UPLOAD",UNPUBLISHED:""};function te(e){const{status:t,isAsset:n}=e;if(!t)return null;const i=n?J[t]:Y[t];if(!i)return s(I,{muted:!0,padding:2,fontSize:1,mode:"outline",children:"Checking..."});const o=n?Z[t]:K[t],r=n?ee[t]:t;return s(O,{content:s(_,{padding:3,style:{maxWidth:200},children:s(C,{size:1,children:o})}),fallbackPlacements:["right","left"],placement:"top",portal:!0,children:s(I,{muted:!0,padding:2,fontSize:1,tone:i,mode:"outline",children:r})})}function ne(e){const{children:t,tone:n="caution"}=e;return s(T,{padding:3,radius:2,shadow:1,tone:n,children:s(C,{size:1,children:t})})}const ie={apiVersion:"2021-05-19"};function oe(e){var t,n,o;const{docs:c,token:m,pluginConfig:b}=e,D=x().sanity.color.dark,E=r(ie),I=a(),O=l(),z=O.map((e=>i(i({},e),{},{disabled:e.dataset===E.config().dataset}))),[B,N]=f(O.length&&null!=(t=z.find((e=>!e.disabled)))?t:null),[$,Y]=f(null),[J,K]=f([]),[Z,ee]=f(!1),[oe,re]=f(!1),[ae,le]=f(!1),[de,ce]=f([0,0]);async function se(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const t=e.length?e:J;if(!t.length||!(null==B?void 0:B.name))return;const n=t.map((e=>{let{doc:t}=e;return t._id})),o=E.withConfig(i(i({},ie),{},{dataset:B.dataset,projectId:B.projectId})),r=await o.fetch("*[_id in $payloadIds]{ _id, _updatedAt }",{payloadIds:n}),a=t.map((e=>{var t;const n=r.find((t=>t._id===e.doc._id));return(null==n?void 0:n._updatedAt)&&(null==(t=null==e?void 0:e.doc)?void 0:t._updatedAt)?n._updatedAt===e.doc._updatedAt?e.status="EXISTS":n._updatedAt&&e.doc._updatedAt&&(e.status=new Date(n._updatedAt)>new Date(e.doc._updatedAt)?"OVERWRITE":"UPDATE"):e.status="CREATE",e}));K(a)}g((()=>{const e=[],t=[];c.forEach((n=>{const i=V(".._ref",n).map((e=>e.value));e.push(...i),t.push({include:!0,doc:n})})),K(t);const n=c.length,i=e.length;e.length&&(ee(!0),Y({tone:"caution",text:G(n,i)}))}),[c]),g((()=>{se()}),[B]);const ue=J.length,he=J.findIndex((e=>{let{doc:t}=e;return"svg"===t.extension})),pe=J.filter((e=>e.include&&!q(e.doc._id))).length,fe=J.filter((e=>e.include&&q(e.doc._id))).length,ge=pe+fe,me=null!=(n=null==B?void 0:B.title)?n:null==B?void 0:B.name,be=new Set(z.map((e=>null==e?void 0:e.projectId)).filter(Boolean)).size>1,ye=[ge,"/",ue,"Documents and Assets selected"].join(" "),ve=p.useMemo((()=>{const e=["Duplicate"];return pe>1&&e.push(String(pe),1===pe?"Document":"Documents"),fe>1&&e.push("and",String(fe),1===fe?"Asset":"Assets"),E.config().projectId!==(null==B?void 0:B.projectId)&&e.push("between Projects"),e.push("to",String(me)),e.join(" ")}),[pe,fe,E,null==B?void 0:B.projectId,me]);return z.length<2?u(ne,{tone:"critical",children:[s("code",{children:"sanity.config.ts"})," must contain at least two Workspaces to use this plugin."]}):s(j,{width:1,children:s(T,{border:!0,children:s(k,{children:u(h,{children:[s(T,{borderBottom:!0,padding:4,style:F(D),children:u(k,{space:4,children:[u(S,{gap:3,children:[u(k,{style:{flex:1},space:3,children:[s(P,{children:"Duplicate from"}),s(R,{readOnly:!0,value:null==(o=z.find((e=>e.disabled)))?void 0:o.name,children:z.filter((e=>e.disabled)).map((e=>{var t;return u("option",{value:e.name,disabled:e.disabled,children:[null!=(t=e.title)?t:e.name,be?" (".concat(e.projectId,")"):""]},e.name)}))})]}),s(_,{padding:4,paddingTop:5,paddingBottom:0,children:s(C,{size:3,children:s(y,{})})}),u(k,{style:{flex:1},space:3,children:[s(P,{children:"To Destination"}),s(R,{onChange:function(e){if(!z.length)return;const t=z.find((t=>t.name===e.currentTarget.value));t&&N(t)},children:z.map((e=>{var t;return u("option",{value:e.name,disabled:e.disabled,children:[null!=(t=e.title)?t:e.name,be?" (".concat(e.projectId,")"):"",e.disabled?" (Current)":""]},e.name)}))})]})]}),oe&&s(T,{border:!0,radius:2,children:s(T,{style:{width:"100%",transform:"scaleX(".concat(de[0]/de[1],")"),transformOrigin:"left",transition:"transform .2s ease",boxSizing:"border-box"},padding:1,tone:"positive"})}),J.length>0&&u(h,{children:[s(P,{children:ye}),s(M,{payload:J,setPayload:K})]})]})}),$&&s(_,{paddingX:4,paddingTop:4,children:s(T,{padding:3,radius:2,shadow:1,tone:$.tone,children:s(C,{size:1,children:$.text})})}),J.length>0&&s(k,{padding:4,space:3,children:J.map(((e,t)=>{let{doc:n,include:i,status:o,hasDraft:r}=e;const a=I.get(n._type);return u(p.Fragment,{children:[u(S,{align:"center",children:[s(U,{checked:i,onChange:()=>function(e){const t=J.map((t=>(t.doc._id===e&&(t.include=!t.include),t)));K(t)}(n._id)}),s(_,{flex:1,paddingX:3,children:a?s(d,{value:n,schemaType:a}):s(T,{tone:"caution",children:"Invalid schema type"})}),u(S,{align:"center",gap:2,children:[r?s(te,{status:"UNPUBLISHED",isAsset:!1}):null,s(te,{status:o,isAsset:q(n._id)})]})]}),"svg"===(null==n?void 0:n.extension)&&t===he&&s(T,{padding:3,radius:2,shadow:1,tone:"caution",children:u(C,{size:1,children:["Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new ",s("code",{children:"_id"}),"'s at the destination. The newly generated ",s("code",{children:"_id"})," will be the same in each duplication, but it will never be the same ",s("code",{children:"_id"})," as the first time this Asset was uploaded. References to the asset will be updated to use the new"," ",s("code",{children:"_id"}),"."]})})]},n._id)}))}),u(k,{space:2,padding:4,paddingTop:0,children:[Z&&s(A,{fontSize:2,padding:4,tone:"positive",mode:"ghost",icon:v,onClick:async function(){le(!0);const e=c.map((e=>e._id)),t=await Q({fetchIds:e,client:E,pluginConfig:b}),n=await Q({fetchIds:e.map((e=>"drafts.".concat(e))),client:E,projection:"{_id}",pluginConfig:b}),i=new Set(n.map((e=>{let{_id:t}=e;return t}))),o=t.map((e=>({doc:e,include:!0,status:void 0,hasDraft:i.has("drafts.".concat(e._id))})));K(o),se(o),le(!1)},text:"Gather References",disabled:oe||!ge||ae}),s(A,{fontSize:2,padding:4,tone:"positive",icon:w,onClick:async function(){if(!B)return;re(!0);const e=J.filter((e=>{let{doc:t,include:n}=e;return n&&q(t._id)})).length;let t=0;ce([t,e]),Y({text:"Duplicating...",tone:"default"});const n=E.withConfig(i(i({},ie),{},{dataset:B.dataset,projectId:B.projectId})),o=[],r=[];async function a(i){if(q(i._id)){const a=H(i),l=a?i.url:"".concat(i.url,"?dlRaw=true"),d=a?{}:{headers:{Authorization:"Bearer ".concat(m)}};return await fetch(l,d).then((async e=>{const t=await e.blob(),l={filename:i.originalFilename},d=await n.assets.upload(a?"file":"image",t,l);"svg"===(null==i?void 0:i.extension)&&r.push({old:i._id,new:d._id}),o.push(d)})),t+=1,Y({text:"Duplicating ".concat(t,"/").concat(e," ").concat("Assets"),tone:"default"}),ce([t,e])}return o.push(i)}const l=new Promise(((e,t)=>{const n=J.filter((e=>e.include)).map((e=>e.doc));L(n,3,X(a),(n=>{n&&(re(!1),Y({tone:"critical",text:"Duplication Failed"}),console.error(n),t(new Error("Duplication Failed"))),e()}))}));await l;const d=o.map((e=>{const t=V(".._ref",e);return t.length?(t.forEach((t=>{var n;const i=null==(n=r.find((e=>e.old===t.value)))?void 0:n.new;if(i){const n=t.path.join(".");W(e,n,i)}})),e):e})),c=n.transaction();d.forEach((e=>{c.createOrReplace(e)})),await c.commit().then((e=>{Y({tone:"positive",text:"Duplication complete!"}),se()})).catch((e=>{Y({tone:"critical",text:e.details.description})})),re(!1),ce([0,0])},text:ve,disabled:oe||!ge||ae})]})]})})})})}function re(e){var t,n;const{token:i,pluginConfig:o}=e,l=r(ie),d=a().getTypeNames(),[c,h]=f(""),[p,m]=f({docs:[]});function b(e){e&&e.preventDefault(),l.fetch(c).then((e=>{const t=e.length?e.filter((e=>d.includes(e._type))).filter((e=>!e._id.startsWith("drafts."))):[];m({docs:t})})).catch((e=>console.error(e)))}return g((()=>{var e;!(null==(e=p.docs)?void 0:e.length)&&c&&b()}),[]),s(j,{width:[1,1,1,3],padding:[0,0,0,5],children:u(z,{columns:[1,1,1,2],gap:[1,1,1,4],children:[s(_,{padding:[2,2,2,0],children:s(T,{padding:4,radius:3,border:!0,children:u(k,{space:4,children:[s(_,{children:s(P,{children:"Initial Documents Query"})}),s(_,{children:s(C,{children:"Start with a valid GROQ query to load initial documents. The query will need to return an Array of Objects. Drafts will be removed from the results."})}),s("form",{onSubmit:b,children:u(S,{children:[s(_,{flex:1,paddingRight:2,children:s(B,{style:{fontFamily:"monospace"},fontSize:2,onChange:e=>h(e.currentTarget.value),padding:4,placeholder:'*[_type == "article"]',value:null!=c?c:""})}),s(A,{padding:2,paddingX:4,tone:"primary",onClick:b,text:"Query",disabled:!c})]})})]})})}),!(null==(t=p.docs)?void 0:t.length)||p.docs.length<1&&s(j,{width:1,children:s(T,{padding:5,children:c?"No Documents registered to the Schema match this query":"Start with a valid GROQ query"})}),(null==(n=p.docs)?void 0:n.length)>0&&s(oe,{docs:p.docs,token:i,pluginConfig:o})]})})}function ae(e){const{docs:t,token:n,pluginConfig:i}=e,[o,a]=f([]),{follow:l=[]}=i,[d,c]=f(1===l.length?l[0]:"outbound"),h=r();return g((()=>{(async()=>{if(l.includes("inbound")){const n=await h.fetch("*[references($id)]",{id:t[0]._id});a([...e.docs,...n])}})()}),[]),u(j,{children:[l.length>1&&(l.includes("inbound")||l.includes("outbound"))?s(T,{paddingX:4,paddingBottom:4,marginBottom:4,borderBottom:!0,children:u(z,{columns:2,gap:4,children:[l.includes("outbound")?s(A,{mode:"ghost",tone:"primary",selected:"outbound"===d,onClick:()=>c("outbound"),text:"Outbound"}):null,l.includes("inbound")?s(A,{mode:"ghost",tone:"primary",selected:"inbound"===d,onClick:()=>c("inbound"),disabled:0===o.length,text:o.length>0?"Inbound (".concat(o.length,")"):"No inbound references"}):null]})}):null,s(oe,{docs:"outbound"===d?t:o,token:n,pluginConfig:i})]})}const le="CrossDatasetDuplicator",de={tool:!0,types:[],filter:"",follow:["outbound"]};function ce(){const e=r(ie),t=p.useCallback((()=>{e.delete({query:'*[_id == "secrets.'.concat(le,'"]')})}),[e]);return s(S,{align:"center",justify:"flex-end",paddingX:[2,2,2,5],paddingY:5,children:s(A,{text:"Reset Secret",onClick:t,mode:"ghost",tone:"critical",fontSize:1,padding:2})})}const se=m(de);function ue(){return b(se)}const he=[{key:"bearerToken",title:"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",description:""}];function pe(e){const{mode:t="tool",docs:n=[]}=null!=e?e:{},i=ue(),{loading:o,secrets:r}=D(le),[a,l]=f(!1);return g((()=>{r&&l(!(null==r?void 0:r.bearerToken))}),[r]),o?s(S,{justify:"center",align:"center",children:s(_,{padding:5,children:s(N,{})})}):!o&&a||!(null==r?void 0:r.bearerToken)?s(E,{title:"Token Required",namespace:le,keys:he,onClose:()=>l(!1)}):"tool"===t&&i?u(h,{children:[s(re,{token:null==r?void 0:r.bearerToken,pluginConfig:i}),s(ce,{})]}):(null==n?void 0:n.length)?i?s(ae,{docs:n,token:null==r?void 0:r.bearerToken,pluginConfig:i}):s(ne,{children:"No plugin config"}):s(ne,{children:"No docs passed into Duplicator Tool"})}function fe(e){const{docs:t=[]}=e;return s(pe,{mode:"action",docs:t})}const ge=e=>{const{draft:t,published:n,onComplete:i}=e,[o,r]=f(!1);return{disabled:t,title:t?"Document must be Published to begin":null,label:"Duplicate to...",dialog:o&&n&&{type:"modal",title:"Cross Dataset Duplicator",content:s(fe,{docs:[n]}),onClose:()=>{i(),r(!1)}},onHandle:()=>r(!0),icon:w}};function me(e){var t;const{docs:n=[]}=null!=(t=e.tool.options)?t:{};return s(pe,{mode:"tool",docs:n})}ge.action="duplicateTo";const be=c((function(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const o=i(i({},de),n),{types:r}=o;return{name:"@sanity/cross-dataset-duplicator",tools:e=>o.tool?[...e,{title:"Duplicator",name:"duplicator",icon:w,component:me,options:{docs:[]}}]:e,studio:{components:{layout:n=>function(n){const{pluginConfig:i}=n,o=t(n,e);return s(se.Provider,{value:i,children:n.renderDefault(o)})}(i(i({},n),{},{pluginConfig:o}))}},document:{actions:(e,t)=>{let{schemaType:n}=t;return r&&r.includes(n)?[...e,ge]:e}}}}));export{fe as CrossDatasetDuplicatorAction,ge as DuplicateToAction,be as crossDatasetDuplicator,ue as useCrossDatasetDuplicatorConfig};//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/lib/index.js
CHANGED
|
@@ -1,21 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "CrossDatasetDuplicator", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function get() {
|
|
9
|
-
return _CrossDatasetDuplicator.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "DuplicateToAction", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function get() {
|
|
15
|
-
return _DuplicateToAction.default;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
var _DuplicateToAction = _interopRequireDefault(require("./actions/DuplicateToAction"));
|
|
19
|
-
var _CrossDatasetDuplicator = _interopRequireDefault(require("./components/CrossDatasetDuplicator"));
|
|
20
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";const e=["pluginConfig"];function t(e,t){if(null==e)return{};var n,i,o=function(e,t){if(null==e)return{};var n,i,o={},s=Object.keys(e);for(i=0;i<s.length;i++)n=s[i],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i<s.length;i++)n=s[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function i(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?n(Object(i),!0).forEach((function(t){o(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):n(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var i=n.call(e,t||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(exports,"__esModule",{value:!0});var s=require("sanity"),a=require("react/jsx-runtime"),r=require("react"),d=require("@sanity/icons"),l=require("@sanity/studio-secrets"),c=require("@sanity/ui"),u=require("async/mapLimit"),h=require("async/asyncify"),p=require("@sanity/mutator"),f=require("dset"),g=require("@sanity/asset-utils");function x(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var m=x(r),j=x(u),b=x(h);function y(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return[1===e?"This Document contains":"These ".concat(e," Documents contain"),1===t?"1 Reference.":"".concat(t," References."),1===t?"That Document":"Those Documents","may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail."].join(" ")}const v=function(){return{position:"sticky",top:0,zIndex:100,backgroundColor:!(arguments.length>0&&void 0!==arguments[0])||arguments[0]?"rgba(10,10,10,0.95)":"rgba(255,255,255,0.95)"}};async function S(e){const{fetchIds:t,client:n,pluginConfig:i,currentIds:o,projection:s}=e,a=[],r=["_id in $fetchIds",i.filter].filter(Boolean).join(" && "),d="*[".concat(r,"]").concat(null!=s?s:""),l=await n.fetch(d,{fetchIds:null!=t?t:[]});if(!(null==l?void 0:l.length))return[];const c=null!=o?o:new Set,u=new Set(l.map((e=>e._id)).filter((e=>(null==o?void 0:o.size)?!c.has(e):Boolean(e))));u.size&&(a.push(...l),c.add(...u),await Promise.all(l.map((async e=>{const t=p.extractWithPath(".._ref",e).map((e=>e.value));if(t.length){const e=new Set(t.filter((e=>!c.has(e))));if(e.size){const t=await S({fetchIds:Array.from(e),currentIds:c,client:n,pluginConfig:i});(null==t?void 0:t.length)&&a.push(...t)}}}))));return a.filter(Boolean).reduce(((e,t)=>e.some((e=>e._id===t._id))?e:[...e,t]),[])}const w=["All","None",null,"New","Existing","Older",null,"Documents","Assets"];function D(e){const{payload:t,setPayload:n}=e,[i,o]=r.useState([]);return r.useEffect((()=>{!(null==i?void 0:i.length)&&t.every((e=>e.include))&&o(["ALL"])}),[null==i?void 0:i.length,t]),a.jsx(c.Card,{padding:1,radius:3,shadow:1,children:a.jsx(c.Flex,{gap:2,children:w.map(((e,s)=>e?a.jsx(c.Button,{fontSize:1,mode:"bleed",padding:2,text:e,disabled:i.includes(e.toUpperCase()),onClick:()=>function(e){if(!e||!t.length)return;const i=[...t];switch(e){case"ALL":i.map((e=>e.include=!0));break;case"NONE":i.map((e=>e.include=!1));break;case"NEW":i.map((e=>e.include=Boolean("CREATE"===e.status)));break;case"EXISTING":i.map((e=>e.include=Boolean("EXISTS"===e.status)));break;case"OLDER":i.map((e=>e.include=Boolean("OVERWRITE"===e.status)));break;case"ASSETS":i.map((e=>e.include=g.isAssetId(e.doc._id)));break;case"DOCUMENTS":i.map((e=>e.include=!g.isAssetId(e.doc._id)))}o([e]),n(i)}(e.toUpperCase())},e):a.jsx(c.Card,{borderLeft:!0},"divider-".concat(s))))})})}const C={EXISTS:"primary",OVERWRITE:"critical",UPDATE:"caution",CREATE:"positive",UNPUBLISHED:"caution"},E={EXISTS:"critical",OVERWRITE:"critical",UPDATE:"critical",CREATE:"positive",UNPUBLISHED:"default"},T={EXISTS:"This document already exists at the Destination with the same ID with the same Updated time.",OVERWRITE:"A newer version of this document exists at the Destination, and it will be overwritten with this version.",UPDATE:"An older version of this document exists at the Destination, and it will be overwritten with this version.",CREATE:"This document will be created at the destination.",UNPUBLISHED:"A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination."},I={EXISTS:"This Asset already exists at the Destination",OVERWRITE:"This Asset already exists at the Destination",UPDATE:"This Asset already exists at the Destination",CREATE:"This Asset does not yet exist at the Destination",UNPUBLISHED:""},A={EXISTS:"RE-UPLOAD",OVERWRITE:"RE-UPLOAD",UPDATE:"RE-UPLOAD",CREATE:"UPLOAD",UNPUBLISHED:""};function O(e){const{status:t,isAsset:n}=e;if(!t)return null;const i=n?E[t]:C[t];if(!i)return a.jsx(c.Badge,{muted:!0,padding:2,fontSize:1,mode:"outline",children:"Checking..."});const o=n?I[t]:T[t],s=n?A[t]:t;return a.jsx(c.Tooltip,{content:a.jsx(c.Box,{padding:3,style:{maxWidth:200},children:a.jsx(c.Text,{size:1,children:o})}),fallbackPlacements:["right","left"],placement:"top",portal:!0,children:a.jsx(c.Badge,{muted:!0,padding:2,fontSize:1,tone:i,mode:"outline",children:s})})}function _(e){const{children:t,tone:n="caution"}=e;return a.jsx(c.Card,{padding:3,radius:2,shadow:1,tone:n,children:a.jsx(c.Text,{size:1,children:t})})}const k={apiVersion:"2021-05-19"};function P(e){var t,n,o;const{docs:l,token:u,pluginConfig:h}=e,x=c.useTheme().sanity.color.dark,w=s.useClient(k),C=s.useSchema(),E=s.useWorkspaces(),T=E.map((e=>i(i({},e),{},{disabled:e.dataset===w.config().dataset}))),[I,A]=r.useState(E.length&&null!=(t=T.find((e=>!e.disabled)))?t:null),[P,R]=r.useState(null),[B,U]=r.useState([]),[L,z]=r.useState(!1),[N,q]=r.useState(!1),[F,W]=r.useState(!1),[X,V]=r.useState([0,0]);async function G(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const t=e.length?e:B;if(!t.length||!(null==I?void 0:I.name))return;const n=t.map((e=>{let{doc:t}=e;return t._id})),o=w.withConfig(i(i({},k),{},{dataset:I.dataset,projectId:I.projectId})),s=await o.fetch("*[_id in $payloadIds]{ _id, _updatedAt }",{payloadIds:n}),a=t.map((e=>{var t;const n=s.find((t=>t._id===e.doc._id));return(null==n?void 0:n._updatedAt)&&(null==(t=null==e?void 0:e.doc)?void 0:t._updatedAt)?n._updatedAt===e.doc._updatedAt?e.status="EXISTS":n._updatedAt&&e.doc._updatedAt&&(e.status=new Date(n._updatedAt)>new Date(e.doc._updatedAt)?"OVERWRITE":"UPDATE"):e.status="CREATE",e}));U(a)}r.useEffect((()=>{const e=[],t=[];l.forEach((n=>{const i=p.extractWithPath(".._ref",n).map((e=>e.value));e.push(...i),t.push({include:!0,doc:n})})),U(t);const n=l.length,i=e.length;e.length&&(z(!0),R({tone:"caution",text:y(n,i)}))}),[l]),r.useEffect((()=>{G()}),[I]);const H=B.length,Q=B.findIndex((e=>{let{doc:t}=e;return"svg"===t.extension})),M=B.filter((e=>e.include&&!g.isAssetId(e.doc._id))).length,$=B.filter((e=>e.include&&g.isAssetId(e.doc._id))).length,Y=M+$,J=null!=(n=null==I?void 0:I.title)?n:null==I?void 0:I.name,K=new Set(T.map((e=>null==e?void 0:e.projectId)).filter(Boolean)).size>1,Z=[Y,"/",H,"Documents and Assets selected"].join(" "),ee=m.default.useMemo((()=>{const e=["Duplicate"];return M>1&&e.push(String(M),1===M?"Document":"Documents"),$>1&&e.push("and",String($),1===$?"Asset":"Assets"),w.config().projectId!==(null==I?void 0:I.projectId)&&e.push("between Projects"),e.push("to",String(J)),e.join(" ")}),[M,$,w,null==I?void 0:I.projectId,J]);return T.length<2?a.jsxs(_,{tone:"critical",children:[a.jsx("code",{children:"sanity.config.ts"})," must contain at least two Workspaces to use this plugin."]}):a.jsx(c.Container,{width:1,children:a.jsx(c.Card,{border:!0,children:a.jsx(c.Stack,{children:a.jsxs(a.Fragment,{children:[a.jsx(c.Card,{borderBottom:!0,padding:4,style:v(x),children:a.jsxs(c.Stack,{space:4,children:[a.jsxs(c.Flex,{gap:3,children:[a.jsxs(c.Stack,{style:{flex:1},space:3,children:[a.jsx(c.Label,{children:"Duplicate from"}),a.jsx(c.Select,{readOnly:!0,value:null==(o=T.find((e=>e.disabled)))?void 0:o.name,children:T.filter((e=>e.disabled)).map((e=>{var t;return a.jsxs("option",{value:e.name,disabled:e.disabled,children:[null!=(t=e.title)?t:e.name,K?" (".concat(e.projectId,")"):""]},e.name)}))})]}),a.jsx(c.Box,{padding:4,paddingTop:5,paddingBottom:0,children:a.jsx(c.Text,{size:3,children:a.jsx(d.ArrowRightIcon,{})})}),a.jsxs(c.Stack,{style:{flex:1},space:3,children:[a.jsx(c.Label,{children:"To Destination"}),a.jsx(c.Select,{onChange:function(e){if(!T.length)return;const t=T.find((t=>t.name===e.currentTarget.value));t&&A(t)},children:T.map((e=>{var t;return a.jsxs("option",{value:e.name,disabled:e.disabled,children:[null!=(t=e.title)?t:e.name,K?" (".concat(e.projectId,")"):"",e.disabled?" (Current)":""]},e.name)}))})]})]}),N&&a.jsx(c.Card,{border:!0,radius:2,children:a.jsx(c.Card,{style:{width:"100%",transform:"scaleX(".concat(X[0]/X[1],")"),transformOrigin:"left",transition:"transform .2s ease",boxSizing:"border-box"},padding:1,tone:"positive"})}),B.length>0&&a.jsxs(a.Fragment,{children:[a.jsx(c.Label,{children:Z}),a.jsx(D,{payload:B,setPayload:U})]})]})}),P&&a.jsx(c.Box,{paddingX:4,paddingTop:4,children:a.jsx(c.Card,{padding:3,radius:2,shadow:1,tone:P.tone,children:a.jsx(c.Text,{size:1,children:P.text})})}),B.length>0&&a.jsx(c.Stack,{padding:4,space:3,children:B.map(((e,t)=>{let{doc:n,include:i,status:o,hasDraft:r}=e;const d=C.get(n._type);return a.jsxs(m.default.Fragment,{children:[a.jsxs(c.Flex,{align:"center",children:[a.jsx(c.Checkbox,{checked:i,onChange:()=>function(e){const t=B.map((t=>(t.doc._id===e&&(t.include=!t.include),t)));U(t)}(n._id)}),a.jsx(c.Box,{flex:1,paddingX:3,children:d?a.jsx(s.Preview,{value:n,schemaType:d}):a.jsx(c.Card,{tone:"caution",children:"Invalid schema type"})}),a.jsxs(c.Flex,{align:"center",gap:2,children:[r?a.jsx(O,{status:"UNPUBLISHED",isAsset:!1}):null,a.jsx(O,{status:o,isAsset:g.isAssetId(n._id)})]})]}),"svg"===(null==n?void 0:n.extension)&&t===Q&&a.jsx(c.Card,{padding:3,radius:2,shadow:1,tone:"caution",children:a.jsxs(c.Text,{size:1,children:["Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new ",a.jsx("code",{children:"_id"}),"'s at the destination. The newly generated ",a.jsx("code",{children:"_id"})," will be the same in each duplication, but it will never be the same ",a.jsx("code",{children:"_id"})," as the first time this Asset was uploaded. References to the asset will be updated to use the new"," ",a.jsx("code",{children:"_id"}),"."]})})]},n._id)}))}),a.jsxs(c.Stack,{space:2,padding:4,paddingTop:0,children:[L&&a.jsx(c.Button,{fontSize:2,padding:4,tone:"positive",mode:"ghost",icon:d.SearchIcon,onClick:async function(){W(!0);const e=l.map((e=>e._id)),t=await S({fetchIds:e,client:w,pluginConfig:h}),n=await S({fetchIds:e.map((e=>"drafts.".concat(e))),client:w,projection:"{_id}",pluginConfig:h}),i=new Set(n.map((e=>{let{_id:t}=e;return t}))),o=t.map((e=>({doc:e,include:!0,status:void 0,hasDraft:i.has("drafts.".concat(e._id))})));U(o),G(o),W(!1)},text:"Gather References",disabled:N||!Y||F}),a.jsx(c.Button,{fontSize:2,padding:4,tone:"positive",icon:d.LaunchIcon,onClick:async function(){if(!I)return;q(!0);const e=B.filter((e=>{let{doc:t,include:n}=e;return n&&g.isAssetId(t._id)})).length;let t=0;V([t,e]),R({text:"Duplicating...",tone:"default"});const n=w.withConfig(i(i({},k),{},{dataset:I.dataset,projectId:I.projectId})),o=[],s=[];async function a(i){if(g.isAssetId(i._id)){const a=g.isSanityFileAsset(i),r=a?i.url:"".concat(i.url,"?dlRaw=true"),d=a?{}:{headers:{Authorization:"Bearer ".concat(u)}};return await fetch(r,d).then((async e=>{const t=await e.blob(),r={filename:i.originalFilename},d=await n.assets.upload(a?"file":"image",t,r);"svg"===(null==i?void 0:i.extension)&&s.push({old:i._id,new:d._id}),o.push(d)})),t+=1,R({text:"Duplicating ".concat(t,"/").concat(e," ").concat("Assets"),tone:"default"}),V([t,e])}return o.push(i)}const r=new Promise(((e,t)=>{const n=B.filter((e=>e.include)).map((e=>e.doc));j.default(n,3,b.default(a),(n=>{n&&(q(!1),R({tone:"critical",text:"Duplication Failed"}),console.error(n),t(new Error("Duplication Failed"))),e()}))}));await r;const d=o.map((e=>{const t=p.extractWithPath(".._ref",e);return t.length?(t.forEach((t=>{var n;const i=null==(n=s.find((e=>e.old===t.value)))?void 0:n.new;if(i){const n=t.path.join(".");f.dset(e,n,i)}})),e):e})),l=n.transaction();d.forEach((e=>{l.createOrReplace(e)})),await l.commit().then((e=>{R({tone:"positive",text:"Duplication complete!"}),G()})).catch((e=>{R({tone:"critical",text:e.details.description})})),q(!1),V([0,0])},text:ee,disabled:N||!Y||F})]})]})})})})}function R(e){var t,n;const{token:i,pluginConfig:o}=e,d=s.useClient(k),l=s.useSchema().getTypeNames(),[u,h]=r.useState(""),[p,f]=r.useState({docs:[]});function g(e){e&&e.preventDefault(),d.fetch(u).then((e=>{const t=e.length?e.filter((e=>l.includes(e._type))).filter((e=>!e._id.startsWith("drafts."))):[];f({docs:t})})).catch((e=>console.error(e)))}return r.useEffect((()=>{var e;!(null==(e=p.docs)?void 0:e.length)&&u&&g()}),[]),a.jsx(c.Container,{width:[1,1,1,3],padding:[0,0,0,5],children:a.jsxs(c.Grid,{columns:[1,1,1,2],gap:[1,1,1,4],children:[a.jsx(c.Box,{padding:[2,2,2,0],children:a.jsx(c.Card,{padding:4,radius:3,border:!0,children:a.jsxs(c.Stack,{space:4,children:[a.jsx(c.Box,{children:a.jsx(c.Label,{children:"Initial Documents Query"})}),a.jsx(c.Box,{children:a.jsx(c.Text,{children:"Start with a valid GROQ query to load initial documents. The query will need to return an Array of Objects. Drafts will be removed from the results."})}),a.jsx("form",{onSubmit:g,children:a.jsxs(c.Flex,{children:[a.jsx(c.Box,{flex:1,paddingRight:2,children:a.jsx(c.TextInput,{style:{fontFamily:"monospace"},fontSize:2,onChange:e=>h(e.currentTarget.value),padding:4,placeholder:'*[_type == "article"]',value:null!=u?u:""})}),a.jsx(c.Button,{padding:2,paddingX:4,tone:"primary",onClick:g,text:"Query",disabled:!u})]})})]})})}),!(null==(t=p.docs)?void 0:t.length)||p.docs.length<1&&a.jsx(c.Container,{width:1,children:a.jsx(c.Card,{padding:5,children:u?"No Documents registered to the Schema match this query":"Start with a valid GROQ query"})}),(null==(n=p.docs)?void 0:n.length)>0&&a.jsx(P,{docs:p.docs,token:i,pluginConfig:o})]})})}function B(e){const{docs:t,token:n,pluginConfig:i}=e,[o,d]=r.useState([]),{follow:l=[]}=i,[u,h]=r.useState(1===l.length?l[0]:"outbound"),p=s.useClient();return r.useEffect((()=>{(async()=>{if(l.includes("inbound")){const n=await p.fetch("*[references($id)]",{id:t[0]._id});d([...e.docs,...n])}})()}),[]),a.jsxs(c.Container,{children:[l.length>1&&(l.includes("inbound")||l.includes("outbound"))?a.jsx(c.Card,{paddingX:4,paddingBottom:4,marginBottom:4,borderBottom:!0,children:a.jsxs(c.Grid,{columns:2,gap:4,children:[l.includes("outbound")?a.jsx(c.Button,{mode:"ghost",tone:"primary",selected:"outbound"===u,onClick:()=>h("outbound"),text:"Outbound"}):null,l.includes("inbound")?a.jsx(c.Button,{mode:"ghost",tone:"primary",selected:"inbound"===u,onClick:()=>h("inbound"),disabled:0===o.length,text:o.length>0?"Inbound (".concat(o.length,")"):"No inbound references"}):null]})}):null,a.jsx(P,{docs:"outbound"===u?t:o,token:n,pluginConfig:i})]})}const U="CrossDatasetDuplicator",L={tool:!0,types:[],filter:"",follow:["outbound"]};function z(){const e=s.useClient(k),t=m.default.useCallback((()=>{e.delete({query:'*[_id == "secrets.'.concat(U,'"]')})}),[e]);return a.jsx(c.Flex,{align:"center",justify:"flex-end",paddingX:[2,2,2,5],paddingY:5,children:a.jsx(c.Button,{text:"Reset Secret",onClick:t,mode:"ghost",tone:"critical",fontSize:1,padding:2})})}const N=r.createContext(L);function q(){return r.useContext(N)}const F=[{key:"bearerToken",title:"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",description:""}];function W(e){const{mode:t="tool",docs:n=[]}=null!=e?e:{},i=q(),{loading:o,secrets:s}=l.useSecrets(U),[d,u]=r.useState(!1);return r.useEffect((()=>{s&&u(!(null==s?void 0:s.bearerToken))}),[s]),o?a.jsx(c.Flex,{justify:"center",align:"center",children:a.jsx(c.Box,{padding:5,children:a.jsx(c.Spinner,{})})}):!o&&d||!(null==s?void 0:s.bearerToken)?a.jsx(l.SettingsView,{title:"Token Required",namespace:U,keys:F,onClose:()=>u(!1)}):"tool"===t&&i?a.jsxs(a.Fragment,{children:[a.jsx(R,{token:null==s?void 0:s.bearerToken,pluginConfig:i}),a.jsx(z,{})]}):(null==n?void 0:n.length)?i?a.jsx(B,{docs:n,token:null==s?void 0:s.bearerToken,pluginConfig:i}):a.jsx(_,{children:"No plugin config"}):a.jsx(_,{children:"No docs passed into Duplicator Tool"})}function X(e){const{docs:t=[]}=e;return a.jsx(W,{mode:"action",docs:t})}const V=e=>{const{draft:t,published:n,onComplete:i}=e,[o,s]=r.useState(!1);return{disabled:t,title:t?"Document must be Published to begin":null,label:"Duplicate to...",dialog:o&&n&&{type:"modal",title:"Cross Dataset Duplicator",content:a.jsx(X,{docs:[n]}),onClose:()=>{i(),s(!1)}},onHandle:()=>s(!0),icon:d.LaunchIcon}};function G(e){var t;const{docs:n=[]}=null!=(t=e.tool.options)?t:{};return a.jsx(W,{mode:"tool",docs:n})}V.action="duplicateTo";const H=s.definePlugin((function(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const o=i(i({},L),n),{types:s}=o;return{name:"@sanity/cross-dataset-duplicator",tools:e=>o.tool?[...e,{title:"Duplicator",name:"duplicator",icon:d.LaunchIcon,component:G,options:{docs:[]}}]:e,studio:{components:{layout:n=>function(n){const{pluginConfig:i}=n,o=t(n,e);return a.jsx(N.Provider,{value:i,children:n.renderDefault(o)})}(i(i({},n),{},{pluginConfig:o}))}},document:{actions:(e,t)=>{let{schemaType:n}=t;return s&&s.includes(n)?[...e,V]:e}}}}));exports.CrossDatasetDuplicatorAction=X,exports.DuplicateToAction=V,exports.crossDatasetDuplicator=H,exports.useCrossDatasetDuplicatorConfig=q;//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|