@ossy/sdk-react 0.0.1-beta.3
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/README.md +100 -0
- package/build/index.cjs.js +1 -0
- package/build/index.esm.js +1 -0
- package/package.json +51 -0
- package/rollup.config.js +30 -0
- package/src/Cache.jsx +81 -0
- package/src/WorkspaceProvider.jsx +22 -0
- package/src/asyncStatus.js +6 -0
- package/src/index.js +13 -0
- package/src/removeBy.js +7 -0
- package/src/replaceBy.js +6 -0
- package/src/useApiTokens.js +59 -0
- package/src/useAuthentication.js +105 -0
- package/src/useQuery.js +51 -0
- package/src/useResource.js +91 -0
- package/src/useResourceTemplate.js +8 -0
- package/src/useResources.js +163 -0
- package/src/useSdk.js +7 -0
- package/src/useUser.js +55 -0
- package/src/useUsers.js +38 -0
- package/src/useWorkspace.js +67 -0
- package/src/useWorkspaces.js +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# React bindings
|
|
2
|
+
|
|
3
|
+
To make it as easy as possible to use our cms we have created a library
|
|
4
|
+
with react hooks you can use to fetch data.
|
|
5
|
+
|
|
6
|
+
## Getting started
|
|
7
|
+
|
|
8
|
+
To use these hooks install the package **@ossy/cms-client-react**
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
npm install @ossy/cms-client-react
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then we simply need to wrap our app in a <WorkspaceProvider /> that will
|
|
15
|
+
handle data storage and configuration for us.
|
|
16
|
+
You will need the workspaceId for the workspace you want to fetch data from.
|
|
17
|
+
The workspaceId can be found in the list of workspaces you have access to or
|
|
18
|
+
in the url when you view the resources in the UI.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
// App.jsx
|
|
22
|
+
import { WorkspaceProvider } from '@ossy/cms-client-react'
|
|
23
|
+
import { MyComponent } from './MyComponent.jsx'
|
|
24
|
+
|
|
25
|
+
export const App = () => (
|
|
26
|
+
<WorkspaceProvider workspaceId="your-workspace-id">
|
|
27
|
+
<MyComponent />
|
|
28
|
+
</WorkspaceProvider>
|
|
29
|
+
)
|
|
30
|
+
```
|
|
31
|
+
```
|
|
32
|
+
// MyComponent.jsx
|
|
33
|
+
import { useResources } from '@ossy/cms-client-react'
|
|
34
|
+
|
|
35
|
+
export const MyComponent = () => {
|
|
36
|
+
const { status, resources } = useResources('/folder/path/in/cms')
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<>
|
|
40
|
+
{ status === 'Error' && (
|
|
41
|
+
<>Something went wrong</>
|
|
42
|
+
)}
|
|
43
|
+
|
|
44
|
+
{ status === 'Loading' && (
|
|
45
|
+
<>Loading...</>
|
|
46
|
+
)}
|
|
47
|
+
|
|
48
|
+
{ status === 'Success' && (
|
|
49
|
+
resources.map(resource => (
|
|
50
|
+
<div key={resource.id}>
|
|
51
|
+
{resource.name}
|
|
52
|
+
</div>
|
|
53
|
+
))
|
|
54
|
+
)}
|
|
55
|
+
</>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Reference
|
|
61
|
+
|
|
62
|
+
### useResources
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
const { status, resources } = useResources('/')
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Parameters**
|
|
69
|
+
|
|
70
|
+
- **path** - Folder path in the cms UI
|
|
71
|
+
|
|
72
|
+
**Returns**
|
|
73
|
+
|
|
74
|
+
Returns an object containing
|
|
75
|
+
|
|
76
|
+
- **status** - String value that indicates loading status.
|
|
77
|
+
Can be used to show loading indicators or error screens.
|
|
78
|
+
Possible values are: NotInitialized, Loading, Success, Error
|
|
79
|
+
- **resources** - Array of resources, defaults to an empty array when
|
|
80
|
+
loading is not Success
|
|
81
|
+
|
|
82
|
+
### useResource
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
const { status, resource } = useResource('resourceId')
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Parameters**
|
|
89
|
+
|
|
90
|
+
- **resourceId** - Id of the resource you want to fetch
|
|
91
|
+
|
|
92
|
+
**Returns**
|
|
93
|
+
|
|
94
|
+
Returns an object containing
|
|
95
|
+
|
|
96
|
+
- **status** - String value that indicates loading status.
|
|
97
|
+
Can be used to show loading indicators or error screens.
|
|
98
|
+
Possible values are: NotInitialized, Loading, Success, Error
|
|
99
|
+
- **resource** - The fetched resource, defaults to an empty object
|
|
100
|
+
when status is not Success
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=e(t);const n={NotInitialized:"NotInitialized",Loading:"Loading",Success:"Success",Error:"Error"};function a(){return a=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)({}).hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},a.apply(null,arguments)}const u=t.createContext(),s="SET",o=(e,r)=>{const{get:n,set:a}=t.useContext(u);return{data:(()=>{const t=n(e);return null==t?r:t})(),set:a(e)}};function c(t){return null!=t&&"object"==typeof t&&!0===t["@@functional/placeholder"]}function i(t){return function e(r){return 0===arguments.length||c(r)?e:t.apply(this,arguments)}}function l(t){return function e(r,n){switch(arguments.length){case 0:return e;case 1:return c(r)?e:i((function(e){return t(r,e)}));default:return c(r)&&c(n)?e:c(r)?i((function(e){return t(e,n)})):c(n)?i((function(e){return t(r,e)})):t(r,n)}}}function f(t,e){switch(t){case 0:return function(){return e.apply(this,arguments)};case 1:return function(t){return e.apply(this,arguments)};case 2:return function(t,r){return e.apply(this,arguments)};case 3:return function(t,r,n){return e.apply(this,arguments)};case 4:return function(t,r,n,a){return e.apply(this,arguments)};case 5:return function(t,r,n,a,u){return e.apply(this,arguments)};case 6:return function(t,r,n,a,u,s){return e.apply(this,arguments)};case 7:return function(t,r,n,a,u,s,o){return e.apply(this,arguments)};case 8:return function(t,r,n,a,u,s,o,c){return e.apply(this,arguments)};case 9:return function(t,r,n,a,u,s,o,c,i){return e.apply(this,arguments)};case 10:return function(t,r,n,a,u,s,o,c,i,l){return e.apply(this,arguments)};default:throw new Error("First argument to _arity must be a non-negative integer no greater than ten")}}function d(t,e,r){return function(){for(var n=[],a=0,u=t,s=0;s<e.length||a<arguments.length;){var o;s<e.length&&(!c(e[s])||a>=arguments.length)?o=e[s]:(o=arguments[a],a+=1),n[s]=o,c(o)||(u-=1),s+=1}return u<=0?r.apply(this,n):f(u,d(t,n,r))}}var p=l((function(t,e){return 1===t?i(e):f(t,d(t,[],e))}));function h(t){return function e(r,n,a){switch(arguments.length){case 0:return e;case 1:return c(r)?e:l((function(e,n){return t(r,e,n)}));case 2:return c(r)&&c(n)?e:c(r)?l((function(e,r){return t(e,n,r)})):c(n)?l((function(e,n){return t(r,e,n)})):i((function(e){return t(r,n,e)}));default:return c(r)&&c(n)&&c(a)?e:c(r)&&c(n)?l((function(e,r){return t(e,r,a)})):c(r)&&c(a)?l((function(e,r){return t(e,n,r)})):c(n)&&c(a)?l((function(e,n){return t(r,e,n)})):c(r)?i((function(e){return t(e,n,a)})):c(n)?i((function(e){return t(r,e,a)})):c(a)?i((function(e){return t(r,n,e)})):t(r,n,a)}}}var y=Array.isArray||function(t){return null!=t&&t.length>=0&&"[object Array]"===Object.prototype.toString.call(t)};function g(t,e,r){return function(){if(0===arguments.length)return r();var n=Array.prototype.slice.call(arguments,0),a=n.pop();if(!y(a)){for(var u=0;u<t.length;){if("function"==typeof a[t[u]])return a[t[u]].apply(a,n);u+=1}if(function(t){return null!=t&&"function"==typeof t["@@transducer/step"]}(a))return e.apply(null,n)(a)}return r.apply(this,arguments)}}var k=function(){return this.xf["@@transducer/init"]()},b=function(t){return this.xf["@@transducer/result"](t)};function v(t){return"[object String]"===Object.prototype.toString.call(t)}var m=i((function(t){return!!y(t)||!!t&&("object"==typeof t&&(!v(t)&&(1===t.nodeType?!!t.length:0===t.length||t.length>0&&(t.hasOwnProperty(0)&&t.hasOwnProperty(t.length-1)))))})),A=function(){function t(t){this.f=t}return t.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},t.prototype["@@transducer/result"]=function(t){return t},t.prototype["@@transducer/step"]=function(t,e){return this.f(t,e)},t}();var I=l((function(t,e){return f(t.length,(function(){return t.apply(e,arguments)}))}));function C(t,e,r){for(var n=r.next();!n.done;){if((e=t["@@transducer/step"](e,n.value))&&e["@@transducer/reduced"]){e=e["@@transducer/value"];break}n=r.next()}return t["@@transducer/result"](e)}function w(t,e,r,n){return t["@@transducer/result"](r[n](I(t["@@transducer/step"],t),e))}var E="undefined"!=typeof Symbol?Symbol.iterator:"@@iterator";function x(t,e,r){if("function"==typeof t&&(t=function(t){return new A(t)}(t)),m(r))return function(t,e,r){for(var n=0,a=r.length;n<a;){if((e=t["@@transducer/step"](e,r[n]))&&e["@@transducer/reduced"]){e=e["@@transducer/value"];break}n+=1}return t["@@transducer/result"](e)}(t,e,r);if("function"==typeof r["fantasy-land/reduce"])return w(t,e,r,"fantasy-land/reduce");if(null!=r[E])return C(t,e,r[E]());if("function"==typeof r.next)return C(t,e,r);if("function"==typeof r.reduce)return w(t,e,r,"reduce");throw new TypeError("reduce: list must be array or iterable")}var S=function(){function t(t,e){this.xf=e,this.f=t}return t.prototype["@@transducer/init"]=k,t.prototype["@@transducer/result"]=b,t.prototype["@@transducer/step"]=function(t,e){return this.xf["@@transducer/step"](t,this.f(e))},t}(),j=l((function(t,e){return new S(t,e)}));function N(t,e){return Object.prototype.hasOwnProperty.call(e,t)}var O=Object.prototype.toString,z=function(){return"[object Arguments]"===O.call(arguments)?function(t){return"[object Arguments]"===O.call(t)}:function(t){return N("callee",t)}}(),P=!{toString:null}.propertyIsEnumerable("toString"),R=["constructor","valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],T=function(){return arguments.propertyIsEnumerable("length")}(),q=function(t,e){for(var r=0;r<t.length;){if(t[r]===e)return!0;r+=1}return!1},L="function"!=typeof Object.keys||T?i((function(t){if(Object(t)!==t)return[];var e,r,n=[],a=T&&z(t);for(e in t)!N(e,t)||a&&"length"===e||(n[n.length]=e);if(P)for(r=R.length-1;r>=0;)N(e=R[r],t)&&!q(n,e)&&(n[n.length]=e),r-=1;return n})):i((function(t){return Object(t)!==t?[]:Object.keys(t)})),U=l(g(["fantasy-land/map","map"],j,(function(t,e){switch(Object.prototype.toString.call(e)){case"[object Function]":return p(e.length,(function(){return t.call(this,e.apply(this,arguments))}));case"[object Object]":return x((function(r,n){return r[n]=t(e[n]),r}),{},L(e));default:return function(t,e){for(var r=0,n=e.length,a=Array(n);r<n;)a[r]=t(e[r]),r+=1;return a}(t,e)}}))),M=Number.isInteger||function(t){return(t|0)===t},V=l((function(t,e){var r=t<0?e.length+t:t;return v(e)?e.charAt(r):e[r]})),W=l((function(t,e){return t.map((function(t){for(var r,n=e,a=0;a<t.length;){if(null==n)return;r=t[a],n=M(r)?V(r,n):n[r],a+=1}return n}))})),D=l((function(t,e){return W([t],e)[0]})),F=i((function(t){return function(){return t}})),B=h((function(t,e,r){var n={};for(var a in r)n[a]=r[a];return n[t]=e,n})),Q=i((function(t){return null==t})),_=h((function t(e,r,n){if(0===e.length)return r;var a=e[0];if(e.length>1){var u=!Q(n)&&N(a,n)?n[a]:M(e[1])?[]:{};r=t(Array.prototype.slice.call(e,1),r,u)}if(M(a)&&y(n)){var s=[].concat(n);return s[a]=r,s}return B(a,r,n)})),X=_,G=i((function(t){return p(t.length,t)})),H=i((function(t){return null===t?"Null":void 0===t?"Undefined":Object.prototype.toString.call(t).slice(8,-1)}));function J(t){for(var e,r=[];!(e=t.next()).done;)r.push(e.value);return r}function K(t,e,r){for(var n=0,a=r.length;n<a;){if(t(e,r[n]))return!0;n+=1}return!1}var Y="function"==typeof Object.is?Object.is:function(t,e){return t===e?0!==t||1/t==1/e:t!=t&&e!=e};function Z(t,e,r,n){var a=J(t);function u(t,e){return $(t,e,r.slice(),n.slice())}return!K((function(t,e){return!K(u,e,t)}),J(e),a)}function $(t,e,r,n){if(Y(t,e))return!0;var a,u,s=H(t);if(s!==H(e))return!1;if(null==t||null==e)return!1;if("function"==typeof t["fantasy-land/equals"]||"function"==typeof e["fantasy-land/equals"])return"function"==typeof t["fantasy-land/equals"]&&t["fantasy-land/equals"](e)&&"function"==typeof e["fantasy-land/equals"]&&e["fantasy-land/equals"](t);if("function"==typeof t.equals||"function"==typeof e.equals)return"function"==typeof t.equals&&t.equals(e)&&"function"==typeof e.equals&&e.equals(t);switch(s){case"Arguments":case"Array":case"Object":if("function"==typeof t.constructor&&"Promise"===(a=t.constructor,null==(u=String(a).match(/^function (\w*)/))?"":u[1]))return t===e;break;case"Boolean":case"Number":case"String":if(typeof t!=typeof e||!Y(t.valueOf(),e.valueOf()))return!1;break;case"Date":if(!Y(t.valueOf(),e.valueOf()))return!1;break;case"Error":return t.name===e.name&&t.message===e.message;case"RegExp":if(t.source!==e.source||t.global!==e.global||t.ignoreCase!==e.ignoreCase||t.multiline!==e.multiline||t.sticky!==e.sticky||t.unicode!==e.unicode)return!1}for(var o=r.length-1;o>=0;){if(r[o]===t)return n[o]===e;o-=1}switch(s){case"Map":return t.size===e.size&&Z(t.entries(),e.entries(),r.concat([t]),n.concat([e]));case"Set":return t.size===e.size&&Z(t.values(),e.values(),r.concat([t]),n.concat([e]));case"Arguments":case"Array":case"Object":case"Boolean":case"Number":case"String":case"Date":case"Error":case"RegExp":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"ArrayBuffer":break;default:return!1}var c=L(t);if(c.length!==L(e).length)return!1;var i=r.concat([t]),l=n.concat([e]);for(o=c.length-1;o>=0;){var f=c[o];if(!N(f,e)||!$(e[f],t[f],i,l))return!1;o-=1}return!0}var tt=l((function(t,e){return $(t,e,[],[])})),et=h((function(t,e,r){var n=Array.prototype.slice.call(r,0);return n.splice(t,e),n})),rt=function(){function t(t,e){this.xf=e,this.f=t,this.idx=-1,this.found=!1}return t.prototype["@@transducer/init"]=k,t.prototype["@@transducer/result"]=function(t){return this.found||(t=this.xf["@@transducer/step"](t,-1)),this.xf["@@transducer/result"](t)},t.prototype["@@transducer/step"]=function(t,e){var r;return this.idx+=1,this.f(e)&&(this.found=!0,t=(r=this.xf["@@transducer/step"](t,this.idx))&&r["@@transducer/reduced"]?r:{"@@transducer/value":r,"@@transducer/reduced":!0}),t},t}(),nt=l(g([],l((function(t,e){return new rt(t,e)})),(function(t,e){for(var r=0,n=e.length;r<n;){if(t(e[r]))return r;r+=1}return-1}))),at=l((function(t,e){return function(r){return function(n){return U((function(t){return e(t,n)}),r(t(n)))}}})),ut=i((function(t){return at(D(t),X(t))})),st=function(t){return{value:t,map:function(e){return st(e(t))}}},ot=h((function(t,e,r){return t((function(t){return st(e(t))}))(r).value})),ct=ot,it=h((function(t,e,r){return tt(e,r[t])})),lt=h((function(t,e,r){return ct(t,F(e),r)})),ft=lt;const dt=t.createContext({}),pt=(({get:e,set:n})=>o=>{const[c,i]=t.useReducer((({set:t,get:e})=>(r={},n)=>{if(n.type===s){let a;if("function"==typeof n.data){const t=e(n.cachePath,r);a=n.data(t)}else a=n.data;return t(n.cachePath,a,r)}return{...r}})({set:n,get:e}),{}),l=t.useCallback((t=>e=>{i({type:s,cachePath:t,data:e})}),[i]),f=t.useCallback((t=>e(t,c)),[c,e]);return r.default.createElement(u.Provider,a({value:{get:f,set:l}},o))})({get:D,set:(t,e,r)=>ft(ut(t),e,r)});function ht(){return t.useContext(dt).sdk}const yt=G(((t,e,r)=>{const n=nt(it(t,e),r);return-1===n?r:et(n,1,r)})),gt=["apiTokens","status"],kt=["apiTokens","data"],bt={AuthenticationError:"AuthenticationError",NotInitialized:"NotInitialized",NotAuthenticated:"NotAuthenticated",Verifying:"Verifying",Authenticated:"Authenticated",VerifySignIn:"VerifySignIn"},vt=["auth","status"],mt=()=>{const e=ht(),r=e.workspaceId,a=t.useMemo((()=>["workspace",r]),[r]),{data:u={status:n.NotInitialized,data:{}},set:s}=o(a),c=t.useCallback((()=>{s({status:n.Loading,data:{}}),e.workspaces.byId(r).then((t=>s({data:t,status:n.Success}))).catch((()=>s({status:n.Error,data:{}})))}),[e,r]),i=t.useCallback((t=>e.workspaces.createApiToken(r,t).then((({id:e,token:r})=>(s({status:workspaces.status,data:{...u,apiTokens:[...u.apiTokens,{id:e,description:t}]}}),r)))),[e]),l=t.useCallback((t=>e.workspaces.inviteUser(r,t)),[e]);return t.useEffect((()=>{r&&u.status===n.NotInitialized&&c()}),[r,u]),{status:u.status,workspace:u.data,loadWorkspace:c,createApiToken:i,inviteUser:l}},At=["workspaces"],It=G(((t,e,r)=>U((r=>r[t]===e[t]?e:r),r))),Ct=e=>{const r=ht(),a=r.workspaceId,u=t.useMemo((()=>["resources",a,"status",e]),[a,e]),s=t.useMemo((()=>["resources",a,"data"]),[a]),{data:c,set:i}=o(u,n.NotInitialized),{data:l,set:f}=o(s,[]),d=t.useMemo((()=>l.filter((t=>t.location===e))),[l,e]),p=t.useCallback((t=>{const e=l.find((e=>e.id===t));return e?Promise.resolve(e):r.resources.byId(t).then((t=>(f(((e=[])=>It("id",t,e))),t)))}),[r,l,f]),h=t.useCallback((()=>{i(n.Loading),r.resources.byLocation(e).then((t=>{i(n.Success),f(((e=[])=>{const r=t.map((t=>t.id)),n=e.filter((t=>!r.includes(t.id)));return[...t,...n]}))})).catch((()=>{i(n.Error)}))}),[r,e,i,f]),y=t.useCallback((t=>r.resources.create({type:t.type,location:t.location,name:t.name,content:t.content}).then((t=>(f(((e=[])=>[...e,t])),t)))),[r,f]),g=t.useCallback(((t,e)=>r.resources.upload({location:t,file:e}).then((t=>(f(((e=[])=>[...e,t])),t)))),[r,f]),k=t.useCallback((({location:t,name:e})=>r.resources.createDirectory({location:t,name:e}).then((t=>(f(((e=[])=>[...e,t])),t)))),[r,f]),b=t.useCallback((t=>r.resources.remove(t).then((()=>f(((e=[])=>yt("id",t,e)))))),[r,f]),v=t.useCallback(((t,e)=>r.resources.updateContent(t,e).then((t=>(f(((e=[])=>It("id",t,e))),t)))),[r,a,f]),m=t.useCallback(((t,e)=>r.resources.move(t,e).then((t=>(f(((e=[])=>It("id",t,e))),t)))),[r,a,f]),A=t.useCallback(((t,e)=>r.resources.rename(t,e).then((t=>(f(((e=[])=>It("id",t,e))),t)))),[r,a,f]);return t.useEffect((()=>{a&&e&&c===n.NotInitialized&&h()}),[a,e,c]),{status:c,resources:d,removeResource:b,createDocument:y,createDirectory:k,loadResource:p,updateResourceContent:v,moveResource:m,renameResource:A,uploadFile:g}},wt=["user","status"],Et=["user","data"];exports.AsyncStatus=n,exports.AuthenticationStatus=bt,exports.Context=dt,exports.WorkspaceProvider=({sdk:t,children:e})=>r.default.createElement(pt,null,r.default.createElement(dt.Provider,{value:{sdk:t}},e)),exports.useApiTokens=()=>{const e=ht(),{data:r=n.NotInitialized,set:a}=o(gt),{data:u=[],set:s}=o(kt),c=t.useCallback((t=>e.apiTokens.create(t).then((t=>(s((e=>[...e,t])),t)))),[e]),i=t.useCallback((t=>e.apiTokens.invalidate(t).then((()=>s((e=>yt("id",t,e)))))),[e]),l=t.useCallback((()=>{a(n.Loading),e.apiTokens.getAll().then((t=>{s(t),a(n.Success)})).catch((()=>{a(n.Error)}))}),[e]);return t.useEffect((()=>{r===n.NotInitialized&&l()}),[r]),{status:r,tokens:u,createApiToken:c,invalidateApiToken:i}},exports.useAuthentication=()=>{const e=ht(),{data:r=bt.NotInitialized,set:n}=o(vt),a=t.useCallback((t=>(n((()=>bt.Verifying)),e.auth.signUp(t).then((()=>n(bt.VerifySignIn))).catch((t=>(n(bt.AuthenticationError),Promise.reject(t)))))),[e]),u=t.useCallback((t=>(n((()=>bt.Verifying)),e.auth.signIn(t).then((()=>n(bt.VerifySignIn))).catch((t=>(n(bt.AuthenticationError),Promise.reject(t)))))),[e]),s=t.useCallback((t=>(n((()=>bt.Verifying)),e.auth.verifySignIn(t).then((()=>n(bt.Authenticated))).catch((t=>(n(bt.AuthenticationError),Promise.reject(t)))))),[e]),c=t.useCallback(((t,r)=>(n((()=>bt.Verifying)),e.auth.verifyInvitation(t,r).then((()=>n(bt.Authenticated))).catch((t=>(n(bt.AuthenticationError),Promise.reject(t)))))),[e]),i=t.useCallback((()=>e.auth.signOff().then((()=>n(bt.NotAuthenticated)))),[e]);return t.useEffect((()=>{r===bt.NotInitialized&&(n((()=>bt.Verifying)),e.auth.getAuthenticatedUser().then((t=>{if(!t)return Promise.reject();n((()=>bt.Authenticated))})).catch((()=>{n((()=>bt.NotAuthenticated))})))}),[r]),{status:r,signUp:a,signIn:u,signOff:i,verifySignIn:s,verifyInvitation:c}},exports.useQuery=e=>{const r=ht(),a=r.workspaceId,u=new URLSearchParams(e).toString();console.log("useQuery",e,u);const s=t.useMemo((()=>[a,"queries",u,"status"]),[a,u]),c=t.useMemo((()=>[a,"queries",u,"data"]),[a,u]),{data:i,set:l}=o(s,n.NotInitialized),{data:f,set:d}=o(c,[]),p=t.useCallback((t=>{l(n.Loading),r.resources.get(t).then((t=>{l(n.Success),d(t)})).catch((()=>{l(n.Error)}))}),[r]);return t.useEffect((()=>{console.log("useQuery effect",a,e,i),a&&e&&i===n.NotInitialized&&p(e)}),[a,e,i]),{status:i,resources:f}},exports.useResource=e=>{const r=ht().workspaceId,a=t.useMemo((()=>["resource",r,e,"status"]),[e,r]),u=t.useMemo((()=>["resource",r,e,"data"]),[e,r]),{data:s=n.NotInitialized,set:c}=o(a),{data:i={},set:l}=o(u),{loadResource:f,removeResource:d,updateResourceContent:p,renameResource:h}=Ct(),y=t.useCallback((()=>{c(n.Loading),l({}),f(e).then((t=>{c(n.Success),l(t)})).catch((()=>{c(n.Error),l({})}))}),[e,f]),g=t.useCallback((()=>d(e).then((()=>{c(n.NotInitialized),l({})}))),[e,d]),k=t.useCallback((t=>p(e,t).then((t=>l(t)))),[e,p]),b=t.useCallback((t=>h(e,t).then((t=>l(t)))),[e,h]);return t.useEffect((()=>{r&&e&&s===n.NotInitialized&&y()}),[r,e,y]),{status:s,resource:i,loadResource:y,removeResource:g,updateResourceContent:k,renameResource:b}},exports.useResourceTemplate=t=>{const{workspace:e}=mt();return e.resourceTemplates.find((e=>e.id===t))},exports.useResources=Ct,exports.useSdk=ht,exports.useUser=()=>{const e=ht(),{data:r=n.NotInitialized,set:a}=o(wt),{data:u={},set:s}=o(Et),c=t.useCallback((t=>e.user.update(t).then((t=>(s(t),t)))),[e]);return t.useEffect((()=>{r===n.NotInitialized&&(a((()=>n.Loading)),e.user.details().then((t=>{if(!t)return Promise.reject();s(t),a((()=>n.Success))})).catch((()=>{s({}),a((()=>n.Error))})))}),[r]),{status:r,user:u,update:c}},exports.useUsers=()=>{const e=ht(),r=e.workspaceId,a=t.useMemo((()=>["workspace",r,"users"]),[r]),{data:u={status:n.NotInitialized,data:[]},set:s}=o(a),c=t.useCallback((()=>{s({status:n.Loading,data:[]}),e.workspaces.users().then((t=>s({data:t,status:n.Success}))).catch((()=>s({status:n.Error,data:[]})))}),[e]);return t.useEffect((()=>{r&&u.status===n.NotInitialized&&c()}),[r,u]),{status:u.status,users:u.data,load:c}},exports.useWorkspace=mt,exports.useWorkspaces=()=>{const e=ht(),{set:r,data:a={status:n.NotInitialized,data:[]}}=o(At),u=t.useCallback((()=>{r({status:n.Loading,data:[]}),e.workspaces.getAll().then((t=>r({status:n.Success,data:t}))).catch((()=>r({status:n.Error,data:[]})))}),[e]),s=t.useCallback((t=>e.workspaces.create(t).then((t=>(r({status:a.status,data:[...a.data,t]}),t)))),[e]);return t.useEffect((()=>{a.status===n.NotInitialized&&u()}),[a,u]),{status:a.status,workspaces:a.data,loadWorkspaces:u,createWorkspace:s}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t,{useContext as e,createContext as r,useReducer as n,useCallback as a,useEffect as u,useMemo as o}from"react";const i={NotInitialized:"NotInitialized",Loading:"Loading",Success:"Success",Error:"Error"};function c(){return c=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)({}).hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},c.apply(null,arguments)}const s=r(),f="SET",l=(t,r)=>{const{get:n,set:a}=e(s);return{data:(()=>{const e=n(t);return null==e?r:e})(),set:a(t)}};function d(t){return null!=t&&"object"==typeof t&&!0===t["@@functional/placeholder"]}function p(t){return function e(r){return 0===arguments.length||d(r)?e:t.apply(this,arguments)}}function h(t){return function e(r,n){switch(arguments.length){case 0:return e;case 1:return d(r)?e:p((function(e){return t(r,e)}));default:return d(r)&&d(n)?e:d(r)?p((function(e){return t(e,n)})):d(n)?p((function(e){return t(r,e)})):t(r,n)}}}function y(t,e){switch(t){case 0:return function(){return e.apply(this,arguments)};case 1:return function(t){return e.apply(this,arguments)};case 2:return function(t,r){return e.apply(this,arguments)};case 3:return function(t,r,n){return e.apply(this,arguments)};case 4:return function(t,r,n,a){return e.apply(this,arguments)};case 5:return function(t,r,n,a,u){return e.apply(this,arguments)};case 6:return function(t,r,n,a,u,o){return e.apply(this,arguments)};case 7:return function(t,r,n,a,u,o,i){return e.apply(this,arguments)};case 8:return function(t,r,n,a,u,o,i,c){return e.apply(this,arguments)};case 9:return function(t,r,n,a,u,o,i,c,s){return e.apply(this,arguments)};case 10:return function(t,r,n,a,u,o,i,c,s,f){return e.apply(this,arguments)};default:throw new Error("First argument to _arity must be a non-negative integer no greater than ten")}}function g(t,e,r){return function(){for(var n=[],a=0,u=t,o=0;o<e.length||a<arguments.length;){var i;o<e.length&&(!d(e[o])||a>=arguments.length)?i=e[o]:(i=arguments[a],a+=1),n[o]=i,d(i)||(u-=1),o+=1}return u<=0?r.apply(this,n):y(u,g(t,n,r))}}var v=h((function(t,e){return 1===t?p(e):y(t,g(t,[],e))}));function m(t){return function e(r,n,a){switch(arguments.length){case 0:return e;case 1:return d(r)?e:h((function(e,n){return t(r,e,n)}));case 2:return d(r)&&d(n)?e:d(r)?h((function(e,r){return t(e,n,r)})):d(n)?h((function(e,n){return t(r,e,n)})):p((function(e){return t(r,n,e)}));default:return d(r)&&d(n)&&d(a)?e:d(r)&&d(n)?h((function(e,r){return t(e,r,a)})):d(r)&&d(a)?h((function(e,r){return t(e,n,r)})):d(n)&&d(a)?h((function(e,n){return t(r,e,n)})):d(r)?p((function(e){return t(e,n,a)})):d(n)?p((function(e){return t(r,e,a)})):d(a)?p((function(e){return t(r,n,e)})):t(r,n,a)}}}var b=Array.isArray||function(t){return null!=t&&t.length>=0&&"[object Array]"===Object.prototype.toString.call(t)};function k(t,e,r){return function(){if(0===arguments.length)return r();var n=Array.prototype.slice.call(arguments,0),a=n.pop();if(!b(a)){for(var u=0;u<t.length;){if("function"==typeof a[t[u]])return a[t[u]].apply(a,n);u+=1}if(function(t){return null!=t&&"function"==typeof t["@@transducer/step"]}(a))return e.apply(null,n)(a)}return r.apply(this,arguments)}}var I=function(){return this.xf["@@transducer/init"]()},A=function(t){return this.xf["@@transducer/result"](t)};function w(t){return"[object String]"===Object.prototype.toString.call(t)}var S=p((function(t){return!!b(t)||!!t&&("object"==typeof t&&(!w(t)&&(1===t.nodeType?!!t.length:0===t.length||t.length>0&&(t.hasOwnProperty(0)&&t.hasOwnProperty(t.length-1)))))})),j=function(){function t(t){this.f=t}return t.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},t.prototype["@@transducer/result"]=function(t){return t},t.prototype["@@transducer/step"]=function(t,e){return this.f(t,e)},t}();var N=h((function(t,e){return y(t.length,(function(){return t.apply(e,arguments)}))}));function E(t,e,r){for(var n=r.next();!n.done;){if((e=t["@@transducer/step"](e,n.value))&&e["@@transducer/reduced"]){e=e["@@transducer/value"];break}n=r.next()}return t["@@transducer/result"](e)}function O(t,e,r,n){return t["@@transducer/result"](r[n](N(t["@@transducer/step"],t),e))}var z="undefined"!=typeof Symbol?Symbol.iterator:"@@iterator";function P(t,e,r){if("function"==typeof t&&(t=function(t){return new j(t)}(t)),S(r))return function(t,e,r){for(var n=0,a=r.length;n<a;){if((e=t["@@transducer/step"](e,r[n]))&&e["@@transducer/reduced"]){e=e["@@transducer/value"];break}n+=1}return t["@@transducer/result"](e)}(t,e,r);if("function"==typeof r["fantasy-land/reduce"])return O(t,e,r,"fantasy-land/reduce");if(null!=r[z])return E(t,e,r[z]());if("function"==typeof r.next)return E(t,e,r);if("function"==typeof r.reduce)return O(t,e,r,"reduce");throw new TypeError("reduce: list must be array or iterable")}var x=function(){function t(t,e){this.xf=e,this.f=t}return t.prototype["@@transducer/init"]=I,t.prototype["@@transducer/result"]=A,t.prototype["@@transducer/step"]=function(t,e){return this.xf["@@transducer/step"](t,this.f(e))},t}(),R=h((function(t,e){return new x(t,e)}));function T(t,e){return Object.prototype.hasOwnProperty.call(e,t)}var q=Object.prototype.toString,L=function(){return"[object Arguments]"===q.call(arguments)?function(t){return"[object Arguments]"===q.call(t)}:function(t){return T("callee",t)}}(),U=!{toString:null}.propertyIsEnumerable("toString"),V=["constructor","valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],C=function(){return arguments.propertyIsEnumerable("length")}(),D=function(t,e){for(var r=0;r<t.length;){if(t[r]===e)return!0;r+=1}return!1},F="function"!=typeof Object.keys||C?p((function(t){if(Object(t)!==t)return[];var e,r,n=[],a=C&&L(t);for(e in t)!T(e,t)||a&&"length"===e||(n[n.length]=e);if(U)for(r=V.length-1;r>=0;)T(e=V[r],t)&&!D(n,e)&&(n[n.length]=e),r-=1;return n})):p((function(t){return Object(t)!==t?[]:Object.keys(t)})),W=h(k(["fantasy-land/map","map"],R,(function(t,e){switch(Object.prototype.toString.call(e)){case"[object Function]":return v(e.length,(function(){return t.call(this,e.apply(this,arguments))}));case"[object Object]":return P((function(r,n){return r[n]=t(e[n]),r}),{},F(e));default:return function(t,e){for(var r=0,n=e.length,a=Array(n);r<n;)a[r]=t(e[r]),r+=1;return a}(t,e)}}))),B=Number.isInteger||function(t){return(t|0)===t},Q=h((function(t,e){var r=t<0?e.length+t:t;return w(e)?e.charAt(r):e[r]})),M=h((function(t,e){return t.map((function(t){for(var r,n=e,a=0;a<t.length;){if(null==n)return;r=t[a],n=B(r)?Q(r,n):n[r],a+=1}return n}))})),X=h((function(t,e){return M([t],e)[0]})),_=p((function(t){return function(){return t}})),G=m((function(t,e,r){var n={};for(var a in r)n[a]=r[a];return n[t]=e,n})),H=p((function(t){return null==t})),J=m((function t(e,r,n){if(0===e.length)return r;var a=e[0];if(e.length>1){var u=!H(n)&&T(a,n)?n[a]:B(e[1])?[]:{};r=t(Array.prototype.slice.call(e,1),r,u)}if(B(a)&&b(n)){var o=[].concat(n);return o[a]=r,o}return G(a,r,n)})),K=J,Y=p((function(t){return v(t.length,t)})),Z=p((function(t){return null===t?"Null":void 0===t?"Undefined":Object.prototype.toString.call(t).slice(8,-1)}));function $(t){for(var e,r=[];!(e=t.next()).done;)r.push(e.value);return r}function tt(t,e,r){for(var n=0,a=r.length;n<a;){if(t(e,r[n]))return!0;n+=1}return!1}var et="function"==typeof Object.is?Object.is:function(t,e){return t===e?0!==t||1/t==1/e:t!=t&&e!=e};function rt(t,e,r,n){var a=$(t);function u(t,e){return nt(t,e,r.slice(),n.slice())}return!tt((function(t,e){return!tt(u,e,t)}),$(e),a)}function nt(t,e,r,n){if(et(t,e))return!0;var a,u,o=Z(t);if(o!==Z(e))return!1;if(null==t||null==e)return!1;if("function"==typeof t["fantasy-land/equals"]||"function"==typeof e["fantasy-land/equals"])return"function"==typeof t["fantasy-land/equals"]&&t["fantasy-land/equals"](e)&&"function"==typeof e["fantasy-land/equals"]&&e["fantasy-land/equals"](t);if("function"==typeof t.equals||"function"==typeof e.equals)return"function"==typeof t.equals&&t.equals(e)&&"function"==typeof e.equals&&e.equals(t);switch(o){case"Arguments":case"Array":case"Object":if("function"==typeof t.constructor&&"Promise"===(a=t.constructor,null==(u=String(a).match(/^function (\w*)/))?"":u[1]))return t===e;break;case"Boolean":case"Number":case"String":if(typeof t!=typeof e||!et(t.valueOf(),e.valueOf()))return!1;break;case"Date":if(!et(t.valueOf(),e.valueOf()))return!1;break;case"Error":return t.name===e.name&&t.message===e.message;case"RegExp":if(t.source!==e.source||t.global!==e.global||t.ignoreCase!==e.ignoreCase||t.multiline!==e.multiline||t.sticky!==e.sticky||t.unicode!==e.unicode)return!1}for(var i=r.length-1;i>=0;){if(r[i]===t)return n[i]===e;i-=1}switch(o){case"Map":return t.size===e.size&&rt(t.entries(),e.entries(),r.concat([t]),n.concat([e]));case"Set":return t.size===e.size&&rt(t.values(),e.values(),r.concat([t]),n.concat([e]));case"Arguments":case"Array":case"Object":case"Boolean":case"Number":case"String":case"Date":case"Error":case"RegExp":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"ArrayBuffer":break;default:return!1}var c=F(t);if(c.length!==F(e).length)return!1;var s=r.concat([t]),f=n.concat([e]);for(i=c.length-1;i>=0;){var l=c[i];if(!T(l,e)||!nt(e[l],t[l],s,f))return!1;i-=1}return!0}var at=h((function(t,e){return nt(t,e,[],[])})),ut=m((function(t,e,r){var n=Array.prototype.slice.call(r,0);return n.splice(t,e),n})),ot=function(){function t(t,e){this.xf=e,this.f=t,this.idx=-1,this.found=!1}return t.prototype["@@transducer/init"]=I,t.prototype["@@transducer/result"]=function(t){return this.found||(t=this.xf["@@transducer/step"](t,-1)),this.xf["@@transducer/result"](t)},t.prototype["@@transducer/step"]=function(t,e){var r;return this.idx+=1,this.f(e)&&(this.found=!0,t=(r=this.xf["@@transducer/step"](t,this.idx))&&r["@@transducer/reduced"]?r:{"@@transducer/value":r,"@@transducer/reduced":!0}),t},t}(),it=h(k([],h((function(t,e){return new ot(t,e)})),(function(t,e){for(var r=0,n=e.length;r<n;){if(t(e[r]))return r;r+=1}return-1}))),ct=h((function(t,e){return function(r){return function(n){return W((function(t){return e(t,n)}),r(t(n)))}}})),st=p((function(t){return ct(X(t),K(t))})),ft=function(t){return{value:t,map:function(e){return ft(e(t))}}},lt=m((function(t,e,r){return t((function(t){return ft(e(t))}))(r).value})),dt=lt,pt=m((function(t,e,r){return at(e,r[t])})),ht=m((function(t,e,r){return dt(t,_(e),r)})),yt=ht;const gt=r({}),vt=(({get:e,set:r})=>u=>{const[o,i]=n((({set:t,get:e})=>(r={},n)=>{if(n.type===f){let a;if("function"==typeof n.data){const t=e(n.cachePath,r);a=n.data(t)}else a=n.data;return t(n.cachePath,a,r)}return{...r}})({set:r,get:e}),{}),l=a((t=>e=>{i({type:f,cachePath:t,data:e})}),[i]),d=a((t=>e(t,o)),[o,e]);return t.createElement(s.Provider,c({value:{get:d,set:l}},u))})({get:X,set:(t,e,r)=>yt(st(t),e,r)}),mt=({sdk:e,children:r})=>t.createElement(vt,null,t.createElement(gt.Provider,{value:{sdk:e}},r));function bt(){return e(gt).sdk}const kt=Y(((t,e,r)=>{const n=it(pt(t,e),r);return-1===n?r:ut(n,1,r)})),It=["apiTokens","status"],At=["apiTokens","data"],wt=()=>{const t=bt(),{data:e=i.NotInitialized,set:r}=l(It),{data:n=[],set:o}=l(At),c=a((e=>t.apiTokens.create(e).then((t=>(o((e=>[...e,t])),t)))),[t]),s=a((e=>t.apiTokens.invalidate(e).then((()=>o((t=>kt("id",e,t)))))),[t]),f=a((()=>{r(i.Loading),t.apiTokens.getAll().then((t=>{o(t),r(i.Success)})).catch((()=>{r(i.Error)}))}),[t]);return u((()=>{e===i.NotInitialized&&f()}),[e]),{status:e,tokens:n,createApiToken:c,invalidateApiToken:s}},St={AuthenticationError:"AuthenticationError",NotInitialized:"NotInitialized",NotAuthenticated:"NotAuthenticated",Verifying:"Verifying",Authenticated:"Authenticated",VerifySignIn:"VerifySignIn"},jt=["auth","status"],Nt=()=>{const t=bt(),{data:e=St.NotInitialized,set:r}=l(jt),n=a((e=>(r((()=>St.Verifying)),t.auth.signUp(e).then((()=>r(St.VerifySignIn))).catch((t=>(r(St.AuthenticationError),Promise.reject(t)))))),[t]),o=a((e=>(r((()=>St.Verifying)),t.auth.signIn(e).then((()=>r(St.VerifySignIn))).catch((t=>(r(St.AuthenticationError),Promise.reject(t)))))),[t]),i=a((e=>(r((()=>St.Verifying)),t.auth.verifySignIn(e).then((()=>r(St.Authenticated))).catch((t=>(r(St.AuthenticationError),Promise.reject(t)))))),[t]),c=a(((e,n)=>(r((()=>St.Verifying)),t.auth.verifyInvitation(e,n).then((()=>r(St.Authenticated))).catch((t=>(r(St.AuthenticationError),Promise.reject(t)))))),[t]),s=a((()=>t.auth.signOff().then((()=>r(St.NotAuthenticated)))),[t]);return u((()=>{e===St.NotInitialized&&(r((()=>St.Verifying)),t.auth.getAuthenticatedUser().then((t=>{if(!t)return Promise.reject();r((()=>St.Authenticated))})).catch((()=>{r((()=>St.NotAuthenticated))})))}),[e]),{status:e,signUp:n,signIn:o,signOff:s,verifySignIn:i,verifyInvitation:c}},Et=()=>{const t=bt(),e=t.workspaceId,r=o((()=>["workspace",e]),[e]),{data:n={status:i.NotInitialized,data:{}},set:c}=l(r),s=a((()=>{c({status:i.Loading,data:{}}),t.workspaces.byId(e).then((t=>c({data:t,status:i.Success}))).catch((()=>c({status:i.Error,data:{}})))}),[t,e]),f=a((r=>t.workspaces.createApiToken(e,r).then((({id:t,token:e})=>(c({status:workspaces.status,data:{...n,apiTokens:[...n.apiTokens,{id:t,description:r}]}}),e)))),[t]),d=a((r=>t.workspaces.inviteUser(e,r)),[t]);return u((()=>{e&&n.status===i.NotInitialized&&s()}),[e,n]),{status:n.status,workspace:n.data,loadWorkspace:s,createApiToken:f,inviteUser:d}},Ot=["workspaces"],zt=()=>{const t=bt(),{set:e,data:r={status:i.NotInitialized,data:[]}}=l(Ot),n=a((()=>{e({status:i.Loading,data:[]}),t.workspaces.getAll().then((t=>e({status:i.Success,data:t}))).catch((()=>e({status:i.Error,data:[]})))}),[t]),o=a((n=>t.workspaces.create(n).then((t=>(e({status:r.status,data:[...r.data,t]}),t)))),[t]);return u((()=>{r.status===i.NotInitialized&&n()}),[r,n]),{status:r.status,workspaces:r.data,loadWorkspaces:n,createWorkspace:o}},Pt=t=>{const e=bt(),r=e.workspaceId,n=new URLSearchParams(t).toString();console.log("useQuery",t,n);const c=o((()=>[r,"queries",n,"status"]),[r,n]),s=o((()=>[r,"queries",n,"data"]),[r,n]),{data:f,set:d}=l(c,i.NotInitialized),{data:p,set:h}=l(s,[]),y=a((t=>{d(i.Loading),e.resources.get(t).then((t=>{d(i.Success),h(t)})).catch((()=>{d(i.Error)}))}),[e]);return u((()=>{console.log("useQuery effect",r,t,f),r&&t&&f===i.NotInitialized&&y(t)}),[r,t,f]),{status:f,resources:p}},xt=Y(((t,e,r)=>W((r=>r[t]===e[t]?e:r),r))),Rt=t=>{const e=bt(),r=e.workspaceId,n=o((()=>["resources",r,"status",t]),[r,t]),c=o((()=>["resources",r,"data"]),[r]),{data:s,set:f}=l(n,i.NotInitialized),{data:d,set:p}=l(c,[]),h=o((()=>d.filter((e=>e.location===t))),[d,t]),y=a((t=>{const r=d.find((e=>e.id===t));return r?Promise.resolve(r):e.resources.byId(t).then((t=>(p(((e=[])=>xt("id",t,e))),t)))}),[e,d,p]),g=a((()=>{f(i.Loading),e.resources.byLocation(t).then((t=>{f(i.Success),p(((e=[])=>{const r=t.map((t=>t.id)),n=e.filter((t=>!r.includes(t.id)));return[...t,...n]}))})).catch((()=>{f(i.Error)}))}),[e,t,f,p]),v=a((t=>e.resources.create({type:t.type,location:t.location,name:t.name,content:t.content}).then((t=>(p(((e=[])=>[...e,t])),t)))),[e,p]),m=a(((t,r)=>e.resources.upload({location:t,file:r}).then((t=>(p(((e=[])=>[...e,t])),t)))),[e,p]),b=a((({location:t,name:r})=>e.resources.createDirectory({location:t,name:r}).then((t=>(p(((e=[])=>[...e,t])),t)))),[e,p]),k=a((t=>e.resources.remove(t).then((()=>p(((e=[])=>kt("id",t,e)))))),[e,p]),I=a(((t,r)=>e.resources.updateContent(t,r).then((t=>(p(((e=[])=>xt("id",t,e))),t)))),[e,r,p]),A=a(((t,r)=>e.resources.move(t,r).then((t=>(p(((e=[])=>xt("id",t,e))),t)))),[e,r,p]),w=a(((t,r)=>e.resources.rename(t,r).then((t=>(p(((e=[])=>xt("id",t,e))),t)))),[e,r,p]);return u((()=>{r&&t&&s===i.NotInitialized&&g()}),[r,t,s]),{status:s,resources:h,removeResource:k,createDocument:v,createDirectory:b,loadResource:y,updateResourceContent:I,moveResource:A,renameResource:w,uploadFile:m}},Tt=t=>{const e=bt().workspaceId,r=o((()=>["resource",e,t,"status"]),[t,e]),n=o((()=>["resource",e,t,"data"]),[t,e]),{data:c=i.NotInitialized,set:s}=l(r),{data:f={},set:d}=l(n),{loadResource:p,removeResource:h,updateResourceContent:y,renameResource:g}=Rt(),v=a((()=>{s(i.Loading),d({}),p(t).then((t=>{s(i.Success),d(t)})).catch((()=>{s(i.Error),d({})}))}),[t,p]),m=a((()=>h(t).then((()=>{s(i.NotInitialized),d({})}))),[t,h]),b=a((e=>y(t,e).then((t=>d(t)))),[t,y]),k=a((e=>g(t,e).then((t=>d(t)))),[t,g]);return u((()=>{e&&t&&c===i.NotInitialized&&v()}),[e,t,v]),{status:c,resource:f,loadResource:v,removeResource:m,updateResourceContent:b,renameResource:k}},qt=t=>{const{workspace:e}=Et();return e.resourceTemplates.find((e=>e.id===t))},Lt=["user","status"],Ut=["user","data"],Vt=()=>{const t=bt(),{data:e=i.NotInitialized,set:r}=l(Lt),{data:n={},set:o}=l(Ut),c=a((e=>t.user.update(e).then((t=>(o(t),t)))),[t]);return u((()=>{e===i.NotInitialized&&(r((()=>i.Loading)),t.user.details().then((t=>{if(!t)return Promise.reject();o(t),r((()=>i.Success))})).catch((()=>{o({}),r((()=>i.Error))})))}),[e]),{status:e,user:n,update:c}},Ct=()=>{const t=bt(),e=t.workspaceId,r=o((()=>["workspace",e,"users"]),[e]),{data:n={status:i.NotInitialized,data:[]},set:c}=l(r),s=a((()=>{c({status:i.Loading,data:[]}),t.workspaces.users().then((t=>c({data:t,status:i.Success}))).catch((()=>c({status:i.Error,data:[]})))}),[t]);return u((()=>{e&&n.status===i.NotInitialized&&s()}),[e,n]),{status:n.status,users:n.data,load:s}};export{i as AsyncStatus,St as AuthenticationStatus,gt as Context,mt as WorkspaceProvider,wt as useApiTokens,Nt as useAuthentication,Pt as useQuery,Tt as useResource,qt as useResourceTemplate,Rt as useResources,bt as useSdk,Vt as useUser,Ct as useUsers,Et as useWorkspace,zt as useWorkspaces};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ossy/sdk-react",
|
|
3
|
+
"description": "Sofware Development Kit for interactive with our services in React",
|
|
4
|
+
"version": "0.0.1-beta.3",
|
|
5
|
+
"url": "git://github.com/ossy-se/packages/sdk-react",
|
|
6
|
+
"source": "src/index.js",
|
|
7
|
+
"main": "build/index.cjs.js",
|
|
8
|
+
"module": "build/index.esm.js",
|
|
9
|
+
"author": "Ossy <yourfriends@ossy.se> (https://ossy.se)",
|
|
10
|
+
"repository": "github:ossy-se/packages/router",
|
|
11
|
+
"license": "MIT License",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"start": "",
|
|
14
|
+
"build": "rm -rf && rollup -c rollup.config.js",
|
|
15
|
+
"test": ""
|
|
16
|
+
},
|
|
17
|
+
"browserslist": {
|
|
18
|
+
"production": [
|
|
19
|
+
">0.2%",
|
|
20
|
+
"not dead",
|
|
21
|
+
"not op_mini all"
|
|
22
|
+
],
|
|
23
|
+
"development": [
|
|
24
|
+
"last 1 chrome version",
|
|
25
|
+
"last 1 firefox version",
|
|
26
|
+
"last 1 safari version"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"jwt-decode": "^3.1.2",
|
|
31
|
+
"ramda": "^0.27.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@babel/core": "^7.14.5",
|
|
35
|
+
"@babel/eslint-parser": "^7.15.8",
|
|
36
|
+
"@babel/preset-react": "^7.14.5",
|
|
37
|
+
"@rollup/plugin-commonjs": "^21.0.1",
|
|
38
|
+
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
39
|
+
"babel-loader": "^8.2.2",
|
|
40
|
+
"react": "^17.0.2",
|
|
41
|
+
"react-dom": "^17.0.2",
|
|
42
|
+
"rollup": "^2.37.1",
|
|
43
|
+
"rollup-plugin-babel": "^4.4.0",
|
|
44
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
45
|
+
"rollup-plugin-terser": "^7.0.2"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": "18 || ^19.0.0",
|
|
49
|
+
"react-dom": "18 || ^19.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import babel from 'rollup-plugin-babel'
|
|
2
|
+
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
|
3
|
+
import removeOwnPeerDependencies from 'rollup-plugin-peer-deps-external'
|
|
4
|
+
import commonjs from '@rollup/plugin-commonjs'
|
|
5
|
+
import { terser as minifyJS } from 'rollup-plugin-terser'
|
|
6
|
+
import pkg from './package.json'
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
input: pkg.source,
|
|
10
|
+
output: [
|
|
11
|
+
{
|
|
12
|
+
file: pkg.main,
|
|
13
|
+
format: 'cjs'
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
file: pkg.module,
|
|
17
|
+
format: 'esm'
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
plugins: [
|
|
21
|
+
nodeResolve(),
|
|
22
|
+
commonjs(),
|
|
23
|
+
babel({
|
|
24
|
+
exclude: ['**/node_modules/**/*'],
|
|
25
|
+
presets: ['@babel/preset-react']
|
|
26
|
+
}),
|
|
27
|
+
removeOwnPeerDependencies(),
|
|
28
|
+
minifyJS()
|
|
29
|
+
]
|
|
30
|
+
}
|
package/src/Cache.jsx
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// TODO: We should use Cache from @ossy-se/components when it becomes public
|
|
2
|
+
|
|
3
|
+
import React, {
|
|
4
|
+
createContext,
|
|
5
|
+
useReducer,
|
|
6
|
+
useContext,
|
|
7
|
+
useCallback
|
|
8
|
+
} from 'react'
|
|
9
|
+
|
|
10
|
+
const getInitialState = () => ({})
|
|
11
|
+
export const CacheContext = createContext()
|
|
12
|
+
|
|
13
|
+
const Actions = {
|
|
14
|
+
Set: 'SET'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// get: (path, state)
|
|
18
|
+
// set: (path, value, state)
|
|
19
|
+
|
|
20
|
+
const createReducer = ({ set, get }) => (
|
|
21
|
+
state = getInitialState(),
|
|
22
|
+
action
|
|
23
|
+
) => {
|
|
24
|
+
switch (action.type) {
|
|
25
|
+
|
|
26
|
+
case Actions.Set: {
|
|
27
|
+
let data
|
|
28
|
+
|
|
29
|
+
if (typeof action.data === 'function') {
|
|
30
|
+
const previousValue = get(action.cachePath, state)
|
|
31
|
+
data = action.data(previousValue)
|
|
32
|
+
} else {
|
|
33
|
+
data = action.data
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return set(action.cachePath, data, state)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
default:
|
|
40
|
+
return ({ ...state })
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const createCache = ({ get: _get, set: _set }) => props => {
|
|
46
|
+
|
|
47
|
+
const [state, updateState] = useReducer(
|
|
48
|
+
createReducer({ set: _set, get: _get }),
|
|
49
|
+
getInitialState()
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const set = useCallback(cachePath => data => {
|
|
53
|
+
updateState({ type: Actions.Set, cachePath, data })
|
|
54
|
+
}, [updateState])
|
|
55
|
+
|
|
56
|
+
const get = useCallback(cachePath =>
|
|
57
|
+
_get(cachePath, state),
|
|
58
|
+
[state, _get]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<CacheContext.Provider value={{ get, set }} {...props} />
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const useCache = (cachePath, defaultValue) => {
|
|
67
|
+
// TODO: Add default value to context here, otherwise it will be undefined in the set((data) => { ... }) function
|
|
68
|
+
const { get, set } = useContext(CacheContext)
|
|
69
|
+
|
|
70
|
+
const getData = () => {
|
|
71
|
+
const data = get(cachePath)
|
|
72
|
+
return data === undefined || data === null
|
|
73
|
+
? defaultValue
|
|
74
|
+
: data
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return ({
|
|
78
|
+
data: getData(),
|
|
79
|
+
set: set(cachePath)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { createContext } from 'react'
|
|
2
|
+
import { createCache } from './Cache.jsx' // TODO: We should use Cache from @ossy-se/components when it becomes public
|
|
3
|
+
import { path, set, lensPath } from 'ramda' // TODO: not be dependent on ramda
|
|
4
|
+
|
|
5
|
+
export const Context = createContext({})
|
|
6
|
+
|
|
7
|
+
const Cache = createCache({
|
|
8
|
+
get: path,
|
|
9
|
+
set: (path, value, data) => set(lensPath(path), value, data)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
export const WorkspaceProvider = ({ sdk, children }) => {
|
|
13
|
+
return (
|
|
14
|
+
<Cache>
|
|
15
|
+
<Context.Provider value={{ sdk }}>
|
|
16
|
+
{children}
|
|
17
|
+
</Context.Provider>
|
|
18
|
+
</Cache>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
package/src/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './asyncStatus.js'
|
|
2
|
+
export * from './useApiTokens.js'
|
|
3
|
+
export * from './useAuthentication.js'
|
|
4
|
+
export * from './useWorkspace.js'
|
|
5
|
+
export * from './useWorkspaces.js'
|
|
6
|
+
export * from './useQuery.js'
|
|
7
|
+
export * from './useResource.js'
|
|
8
|
+
export * from './useResourceTemplate.js'
|
|
9
|
+
export * from './useResources.js'
|
|
10
|
+
export * from './WorkspaceProvider.jsx'
|
|
11
|
+
export * from './useSdk.js'
|
|
12
|
+
export * from './useUser.js'
|
|
13
|
+
export * from './useUsers.js'
|
package/src/removeBy.js
ADDED
package/src/replaceBy.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useSdk } from './useSdk.js'
|
|
5
|
+
import { removeBy } from './removeBy.js'
|
|
6
|
+
|
|
7
|
+
const statusPath = ['apiTokens', 'status']
|
|
8
|
+
const dataPath = ['apiTokens', 'data']
|
|
9
|
+
|
|
10
|
+
export const useApiTokens = () => {
|
|
11
|
+
const sdk = useSdk()
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
data: status = AsyncStatus.NotInitialized,
|
|
15
|
+
set: setStatus
|
|
16
|
+
} = useCache(statusPath)
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
data: tokens = [],
|
|
20
|
+
set: setTokens
|
|
21
|
+
} = useCache(dataPath)
|
|
22
|
+
|
|
23
|
+
const createApiToken = useCallback(
|
|
24
|
+
description => sdk.apiTokens.create(description)
|
|
25
|
+
.then(newToken => {
|
|
26
|
+
setTokens(tokens => [...tokens, newToken])
|
|
27
|
+
return newToken
|
|
28
|
+
}),
|
|
29
|
+
[sdk]
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const invalidateApiToken = useCallback(
|
|
33
|
+
tokenId => sdk.apiTokens.invalidate(tokenId)
|
|
34
|
+
.then(() => setTokens(tokens => removeBy('id', tokenId, tokens))),
|
|
35
|
+
[sdk]
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
const loadApiTokens = useCallback(() => {
|
|
39
|
+
setStatus(AsyncStatus.Loading)
|
|
40
|
+
sdk.apiTokens.getAll()
|
|
41
|
+
.then(tokens => {
|
|
42
|
+
setTokens(tokens)
|
|
43
|
+
setStatus(AsyncStatus.Success)
|
|
44
|
+
})
|
|
45
|
+
.catch(() => { setStatus(AsyncStatus.Error) })
|
|
46
|
+
}, [sdk])
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (status !== AsyncStatus.NotInitialized) return
|
|
50
|
+
loadApiTokens()
|
|
51
|
+
}, [status])
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
status,
|
|
55
|
+
tokens,
|
|
56
|
+
createApiToken,
|
|
57
|
+
invalidateApiToken,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { useSdk } from './useSdk.js'
|
|
4
|
+
|
|
5
|
+
export const AuthenticationStatus = {
|
|
6
|
+
AuthenticationError: 'AuthenticationError',
|
|
7
|
+
NotInitialized: 'NotInitialized',
|
|
8
|
+
NotAuthenticated: 'NotAuthenticated',
|
|
9
|
+
Verifying: 'Verifying',
|
|
10
|
+
Authenticated: 'Authenticated',
|
|
11
|
+
VerifySignIn: 'VerifySignIn'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const statusPath = ['auth', 'status']
|
|
15
|
+
|
|
16
|
+
export const useAuthentication = () => {
|
|
17
|
+
const sdk = useSdk()
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
data: status = AuthenticationStatus.NotInitialized,
|
|
21
|
+
set: setStatus
|
|
22
|
+
} = useCache(statusPath)
|
|
23
|
+
|
|
24
|
+
const signUp = useCallback(
|
|
25
|
+
email => {
|
|
26
|
+
setStatus(() => AuthenticationStatus.Verifying)
|
|
27
|
+
return sdk.auth.signUp(email)
|
|
28
|
+
.then(() => setStatus(AuthenticationStatus.VerifySignIn))
|
|
29
|
+
.catch(error => {
|
|
30
|
+
setStatus(AuthenticationStatus.AuthenticationError)
|
|
31
|
+
return Promise.reject(error)
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
[sdk]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const signIn = useCallback(
|
|
38
|
+
email => {
|
|
39
|
+
setStatus(() => AuthenticationStatus.Verifying)
|
|
40
|
+
return sdk.auth.signIn(email)
|
|
41
|
+
.then(() => setStatus(AuthenticationStatus.VerifySignIn))
|
|
42
|
+
.catch((error) => {
|
|
43
|
+
setStatus(AuthenticationStatus.AuthenticationError)
|
|
44
|
+
return Promise.reject(error)
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
[sdk]
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const verifySignIn = useCallback(
|
|
51
|
+
token => {
|
|
52
|
+
setStatus(() => AuthenticationStatus.Verifying)
|
|
53
|
+
return sdk.auth.verifySignIn(token)
|
|
54
|
+
.then(() => setStatus(AuthenticationStatus.Authenticated))
|
|
55
|
+
.catch((error) => {
|
|
56
|
+
setStatus(AuthenticationStatus.AuthenticationError)
|
|
57
|
+
return Promise.reject(error)
|
|
58
|
+
})
|
|
59
|
+
},
|
|
60
|
+
[sdk]
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const verifyInvitation = useCallback(
|
|
64
|
+
(workspaceId, token) => {
|
|
65
|
+
setStatus(() => AuthenticationStatus.Verifying)
|
|
66
|
+
return sdk.auth.verifyInvitation(workspaceId, token)
|
|
67
|
+
.then(() => setStatus(AuthenticationStatus.Authenticated))
|
|
68
|
+
.catch((error) => {
|
|
69
|
+
setStatus(AuthenticationStatus.AuthenticationError)
|
|
70
|
+
return Promise.reject(error)
|
|
71
|
+
})
|
|
72
|
+
},
|
|
73
|
+
[sdk]
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
const signOff = useCallback(
|
|
77
|
+
() => sdk.auth.signOff()
|
|
78
|
+
.then(() => setStatus(AuthenticationStatus.NotAuthenticated)),
|
|
79
|
+
[sdk]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (status !== AuthenticationStatus.NotInitialized) return
|
|
84
|
+
setStatus(() => AuthenticationStatus.Verifying)
|
|
85
|
+
|
|
86
|
+
sdk.auth.getAuthenticatedUser()
|
|
87
|
+
.then(user => {
|
|
88
|
+
if (!user) return Promise.reject()
|
|
89
|
+
setStatus(() => AuthenticationStatus.Authenticated)
|
|
90
|
+
})
|
|
91
|
+
.catch(() => {
|
|
92
|
+
setStatus(() => AuthenticationStatus.NotAuthenticated)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
}, [status])
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
status,
|
|
99
|
+
signUp,
|
|
100
|
+
signIn,
|
|
101
|
+
signOff,
|
|
102
|
+
verifySignIn,
|
|
103
|
+
verifyInvitation
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/useQuery.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useCallback, useMemo, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useSdk } from './useSdk.js'
|
|
5
|
+
|
|
6
|
+
export const useQuery = incomingQuery => {
|
|
7
|
+
const sdk = useSdk()
|
|
8
|
+
const workspaceId = sdk.workspaceId
|
|
9
|
+
const queryString = new URLSearchParams(incomingQuery).toString()
|
|
10
|
+
console.log('useQuery', incomingQuery, queryString)
|
|
11
|
+
|
|
12
|
+
const statusCachePath = useMemo(
|
|
13
|
+
() => [workspaceId, 'queries', queryString, 'status'],
|
|
14
|
+
[workspaceId, queryString]
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const dataCachePath = useMemo(
|
|
18
|
+
() => [workspaceId, 'queries', queryString, 'data'],
|
|
19
|
+
[workspaceId, queryString]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
data: status,
|
|
24
|
+
set: setStatus
|
|
25
|
+
} = useCache(statusCachePath, AsyncStatus.NotInitialized)
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
data: resources,
|
|
29
|
+
set: setResources
|
|
30
|
+
} = useCache(dataCachePath, [])
|
|
31
|
+
|
|
32
|
+
const loadResources = useCallback(query => {
|
|
33
|
+
setStatus(AsyncStatus.Loading)
|
|
34
|
+
sdk.resources.get(query)
|
|
35
|
+
.then(matchedResources => {
|
|
36
|
+
setStatus(AsyncStatus.Success)
|
|
37
|
+
setResources(matchedResources)
|
|
38
|
+
})
|
|
39
|
+
.catch(() => { setStatus(AsyncStatus.Error) })
|
|
40
|
+
}, [sdk])
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
console.log('useQuery effect', workspaceId, incomingQuery, status)
|
|
44
|
+
if (!workspaceId) return
|
|
45
|
+
if (!incomingQuery) return
|
|
46
|
+
if (status !== AsyncStatus.NotInitialized) return
|
|
47
|
+
loadResources(incomingQuery)
|
|
48
|
+
}, [workspaceId, incomingQuery, status])
|
|
49
|
+
|
|
50
|
+
return { status, resources }
|
|
51
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useCallback, useMemo, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useResources } from './useResources.js'
|
|
5
|
+
import { useSdk } from './useSdk.js'
|
|
6
|
+
|
|
7
|
+
export const useResource = (resourceId) => {
|
|
8
|
+
const sdk = useSdk()
|
|
9
|
+
const workspaceId = sdk.workspaceId
|
|
10
|
+
|
|
11
|
+
const statusCachePath = useMemo(
|
|
12
|
+
() => ['resource', workspaceId, resourceId, 'status'],
|
|
13
|
+
[resourceId, workspaceId]
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
const dataCachePath = useMemo(
|
|
17
|
+
() => ['resource', workspaceId, resourceId, 'data'],
|
|
18
|
+
[resourceId, workspaceId]
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
data: status = AsyncStatus.NotInitialized,
|
|
23
|
+
set: setStatus
|
|
24
|
+
} = useCache(statusCachePath)
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
data: resource = {},
|
|
28
|
+
set: setResource
|
|
29
|
+
} = useCache(dataCachePath)
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
loadResource: _loadResource,
|
|
33
|
+
removeResource: _removeResource,
|
|
34
|
+
updateResourceContent: _updateResourceContent,
|
|
35
|
+
renameResource: _renameResource
|
|
36
|
+
} = useResources()
|
|
37
|
+
|
|
38
|
+
const loadResource = useCallback(() => {
|
|
39
|
+
setStatus(AsyncStatus.Loading)
|
|
40
|
+
setResource({})
|
|
41
|
+
_loadResource(resourceId)
|
|
42
|
+
.then(resource => {
|
|
43
|
+
setStatus(AsyncStatus.Success)
|
|
44
|
+
setResource(resource)
|
|
45
|
+
})
|
|
46
|
+
.catch(() => {
|
|
47
|
+
setStatus(AsyncStatus.Error)
|
|
48
|
+
setResource({})
|
|
49
|
+
})
|
|
50
|
+
}, [resourceId, _loadResource])
|
|
51
|
+
|
|
52
|
+
const removeResource = useCallback(
|
|
53
|
+
() => _removeResource(resourceId)
|
|
54
|
+
.then(() => {
|
|
55
|
+
setStatus(AsyncStatus.NotInitialized)
|
|
56
|
+
setResource({})
|
|
57
|
+
}),
|
|
58
|
+
[resourceId, _removeResource]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const updateResourceContent = useCallback(
|
|
62
|
+
resourceContent => _updateResourceContent(resourceId, resourceContent)
|
|
63
|
+
.then(updatedResource => setResource(updatedResource)),
|
|
64
|
+
[resourceId, _updateResourceContent]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const renameResource = useCallback(
|
|
68
|
+
newName => _renameResource(resourceId, newName)
|
|
69
|
+
.then(updatedResource => setResource(updatedResource)),
|
|
70
|
+
[resourceId, _renameResource]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
|
|
75
|
+
if (!workspaceId) return
|
|
76
|
+
if (!resourceId) return
|
|
77
|
+
if (status !== AsyncStatus.NotInitialized) return
|
|
78
|
+
|
|
79
|
+
loadResource()
|
|
80
|
+
|
|
81
|
+
}, [workspaceId, resourceId, loadResource])
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
status,
|
|
85
|
+
resource,
|
|
86
|
+
loadResource,
|
|
87
|
+
removeResource,
|
|
88
|
+
updateResourceContent,
|
|
89
|
+
renameResource
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useWorkspace } from './useWorkspace.js'
|
|
2
|
+
|
|
3
|
+
export const useResourceTemplate = templateId => {
|
|
4
|
+
const { workspace } = useWorkspace()
|
|
5
|
+
// TODO: workspace.resourceTemplates might not exist yet
|
|
6
|
+
const template = workspace.resourceTemplates.find(template => template.id === templateId)
|
|
7
|
+
return template
|
|
8
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { useCallback, useMemo, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { removeBy } from './removeBy.js'
|
|
4
|
+
import { replaceBy } from './replaceBy.js'
|
|
5
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
6
|
+
import { useSdk } from './useSdk.js'
|
|
7
|
+
|
|
8
|
+
export const useResources = (location) => {
|
|
9
|
+
const sdk = useSdk()
|
|
10
|
+
const workspaceId = sdk.workspaceId
|
|
11
|
+
|
|
12
|
+
const statusCachePath = useMemo(
|
|
13
|
+
() => ['resources', workspaceId, 'status', location],
|
|
14
|
+
[workspaceId, location]
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const dataCachePath = useMemo(
|
|
18
|
+
() => ['resources', workspaceId, 'data'],
|
|
19
|
+
[workspaceId]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
data: status,
|
|
24
|
+
set: setStatus
|
|
25
|
+
} = useCache(statusCachePath, AsyncStatus.NotInitialized)
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
data: resources,
|
|
29
|
+
set: setResources
|
|
30
|
+
} = useCache(dataCachePath, [])
|
|
31
|
+
|
|
32
|
+
const locationSpecificResources = useMemo(
|
|
33
|
+
() => resources.filter(resource => resource.location === location),
|
|
34
|
+
[resources, location]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const loadResource = useCallback(
|
|
38
|
+
resourceId => {
|
|
39
|
+
const cachedResource = resources.find(resource => resource.id === resourceId)
|
|
40
|
+
return !!cachedResource
|
|
41
|
+
? Promise.resolve(cachedResource)
|
|
42
|
+
: sdk.resources.byId(resourceId)
|
|
43
|
+
.then(requestedResource => {
|
|
44
|
+
setResources((resources = []) => replaceBy('id', requestedResource, resources))
|
|
45
|
+
return requestedResource
|
|
46
|
+
})
|
|
47
|
+
},
|
|
48
|
+
[sdk, resources, setResources]
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const loadResources = useCallback(() => {
|
|
52
|
+
setStatus(AsyncStatus.Loading)
|
|
53
|
+
sdk.resources.byLocation(location)
|
|
54
|
+
.then(requestedResources => {
|
|
55
|
+
setStatus(AsyncStatus.Success)
|
|
56
|
+
// TODO: Duplicated resources can occur when you move a resource into a directory
|
|
57
|
+
// then navigate to that directory, causing it to load the recently moved resource from BE into the resources list
|
|
58
|
+
// Should probably use another data structure that ensures uniqueness.
|
|
59
|
+
// temp fix is the resourcesWithStaleResourcesRemoved
|
|
60
|
+
setResources((resources = []) => {
|
|
61
|
+
const requestedResourcesIds = requestedResources.map(resource => resource.id)
|
|
62
|
+
|
|
63
|
+
const resourcesWithStaleResourcesRemoved = resources.filter(
|
|
64
|
+
resource => !requestedResourcesIds.includes(resource.id)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return [...requestedResources, ...resourcesWithStaleResourcesRemoved]
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
.catch(() => { setStatus(AsyncStatus.Error) })
|
|
71
|
+
}, [sdk, location, setStatus, setResources])
|
|
72
|
+
|
|
73
|
+
const createDocument = useCallback(
|
|
74
|
+
document => sdk.resources.create({
|
|
75
|
+
type: document.type,
|
|
76
|
+
location: document.location,
|
|
77
|
+
name: document.name,
|
|
78
|
+
content: document.content
|
|
79
|
+
})
|
|
80
|
+
.then(newResource => {
|
|
81
|
+
setResources((resources = []) => [...resources, newResource])
|
|
82
|
+
return newResource
|
|
83
|
+
}),
|
|
84
|
+
[sdk, setResources]
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const uploadFile = useCallback(
|
|
88
|
+
(location, file) => sdk.resources.upload({ location, file })
|
|
89
|
+
.then(newResource => {
|
|
90
|
+
setResources((resources = []) => [...resources, newResource])
|
|
91
|
+
return newResource
|
|
92
|
+
}),
|
|
93
|
+
[sdk, setResources]
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const createDirectory = useCallback(
|
|
97
|
+
({ location, name }) => sdk.resources.createDirectory({ location, name })
|
|
98
|
+
.then(newResource => {
|
|
99
|
+
setResources((resources = []) => [...resources, newResource])
|
|
100
|
+
return newResource
|
|
101
|
+
}),
|
|
102
|
+
[sdk, setResources]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const removeResource = useCallback(
|
|
106
|
+
resourceId => sdk.resources.remove(resourceId)
|
|
107
|
+
.then(() => setResources((resources = []) => removeBy('id', resourceId, resources))),
|
|
108
|
+
[sdk, setResources]
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
const updateResourceContent = useCallback(
|
|
112
|
+
(resourceId, content) => sdk.resources.updateContent(resourceId, content)
|
|
113
|
+
.then(updatedResource => {
|
|
114
|
+
setResources((resources = []) => replaceBy('id', updatedResource, resources))
|
|
115
|
+
return updatedResource
|
|
116
|
+
}),
|
|
117
|
+
[sdk, workspaceId, setResources]
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
const moveResource = useCallback(
|
|
121
|
+
// TODO: how should we add this to the new location in cache?
|
|
122
|
+
// TODO: if recource is a direcotry, how should we move the nested resources from cache?
|
|
123
|
+
(resourceId, newLocation) => sdk.resources.move(resourceId, newLocation)
|
|
124
|
+
.then(movedResource => {
|
|
125
|
+
setResources((resources = []) => replaceBy('id', movedResource, resources))
|
|
126
|
+
return movedResource
|
|
127
|
+
}),
|
|
128
|
+
[sdk, workspaceId, setResources]
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
const renameResource = useCallback(
|
|
132
|
+
// TODO: how should we update the cache for individual resources
|
|
133
|
+
// mabye by making this an internal function and only use it through useResource?
|
|
134
|
+
(resourceId, newName) => sdk.resources.rename(resourceId, newName)
|
|
135
|
+
.then(updatedResource => {
|
|
136
|
+
setResources((resources = []) => replaceBy('id', updatedResource, resources))
|
|
137
|
+
return updatedResource
|
|
138
|
+
}),
|
|
139
|
+
[sdk, workspaceId, setResources]
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (!workspaceId) return
|
|
144
|
+
if (!location) return
|
|
145
|
+
if (status !== AsyncStatus.NotInitialized) return
|
|
146
|
+
|
|
147
|
+
loadResources()
|
|
148
|
+
|
|
149
|
+
}, [workspaceId, location, status])
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
status,
|
|
153
|
+
resources: locationSpecificResources,
|
|
154
|
+
removeResource,
|
|
155
|
+
createDocument,
|
|
156
|
+
createDirectory,
|
|
157
|
+
loadResource,
|
|
158
|
+
updateResourceContent,
|
|
159
|
+
moveResource,
|
|
160
|
+
renameResource,
|
|
161
|
+
uploadFile
|
|
162
|
+
}
|
|
163
|
+
}
|
package/src/useSdk.js
ADDED
package/src/useUser.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { useSdk } from './useSdk.js'
|
|
4
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
5
|
+
|
|
6
|
+
const statusPath = ['user', 'status']
|
|
7
|
+
const userPath = ['user', 'data']
|
|
8
|
+
|
|
9
|
+
export const useUser = () => {
|
|
10
|
+
const sdk = useSdk()
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
data: status = AsyncStatus.NotInitialized,
|
|
14
|
+
set: setStatus
|
|
15
|
+
} = useCache(statusPath)
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
data: user = {},
|
|
19
|
+
set: setUser
|
|
20
|
+
} = useCache(userPath)
|
|
21
|
+
|
|
22
|
+
const update = useCallback(
|
|
23
|
+
user => {
|
|
24
|
+
return sdk.user.update(user)
|
|
25
|
+
.then((updatedUser) => {
|
|
26
|
+
setUser(updatedUser)
|
|
27
|
+
return updatedUser
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
[sdk]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (status !== AsyncStatus.NotInitialized) return
|
|
35
|
+
setStatus(() => AsyncStatus.Loading)
|
|
36
|
+
|
|
37
|
+
sdk.user.details()
|
|
38
|
+
.then(user => {
|
|
39
|
+
if (!user) return Promise.reject()
|
|
40
|
+
setUser(user)
|
|
41
|
+
setStatus(() => AsyncStatus.Success)
|
|
42
|
+
})
|
|
43
|
+
.catch(() => {
|
|
44
|
+
setUser({})
|
|
45
|
+
setStatus(() => AsyncStatus.Error)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
}, [status])
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
status,
|
|
52
|
+
user,
|
|
53
|
+
update
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/useUsers.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useSdk } from './useSdk.js'
|
|
5
|
+
|
|
6
|
+
export const useUsers = () => {
|
|
7
|
+
const sdk = useSdk()
|
|
8
|
+
const workspaceId = sdk.workspaceId
|
|
9
|
+
const cachePath = useMemo(() => ['workspace', workspaceId, 'users'], [workspaceId])
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
data: users = { status: AsyncStatus.NotInitialized, data: [] },
|
|
13
|
+
set: setUsers
|
|
14
|
+
} = useCache(cachePath)
|
|
15
|
+
|
|
16
|
+
const load = useCallback(() => {
|
|
17
|
+
setUsers({ status: AsyncStatus.Loading, data: [] })
|
|
18
|
+
|
|
19
|
+
sdk.workspaces.users()
|
|
20
|
+
.then(users => setUsers({ data: users, status: AsyncStatus.Success }))
|
|
21
|
+
.catch(() => setUsers({ status: AsyncStatus.Error, data: [] }))
|
|
22
|
+
|
|
23
|
+
}, [sdk])
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!workspaceId) return
|
|
27
|
+
if (users.status === AsyncStatus.NotInitialized) {
|
|
28
|
+
load()
|
|
29
|
+
}
|
|
30
|
+
}, [workspaceId, users])
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
status: users.status,
|
|
34
|
+
users: users.data,
|
|
35
|
+
load,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useSdk } from './useSdk.js'
|
|
5
|
+
|
|
6
|
+
export const useWorkspace = () => {
|
|
7
|
+
const sdk = useSdk()
|
|
8
|
+
const workspaceId = sdk.workspaceId
|
|
9
|
+
const cachePath = useMemo(() => ['workspace', workspaceId], [workspaceId])
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
data: workspace = { status: AsyncStatus.NotInitialized, data: {} },
|
|
13
|
+
set: setWorkspace
|
|
14
|
+
} = useCache(cachePath)
|
|
15
|
+
|
|
16
|
+
const loadWorkspace = useCallback(() => {
|
|
17
|
+
setWorkspace({ status: AsyncStatus.Loading, data: {} })
|
|
18
|
+
sdk.workspaces.byId(workspaceId)
|
|
19
|
+
.then(workspace => setWorkspace({ data: workspace, status: AsyncStatus.Success }))
|
|
20
|
+
.catch(() => setWorkspace({ status: AsyncStatus.Error, data: {} }))
|
|
21
|
+
}, [sdk, workspaceId])
|
|
22
|
+
|
|
23
|
+
const createApiToken = useCallback(
|
|
24
|
+
description => sdk.workspaces.createApiToken(workspaceId, description)
|
|
25
|
+
.then(({ id, token }) => {
|
|
26
|
+
|
|
27
|
+
setWorkspace({
|
|
28
|
+
status: workspaces.status,
|
|
29
|
+
data: {
|
|
30
|
+
...workspace,
|
|
31
|
+
apiTokens: [...workspace.apiTokens, { id, description }]
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return token
|
|
36
|
+
}),
|
|
37
|
+
[sdk]
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const inviteUser = useCallback(
|
|
41
|
+
email => sdk.workspaces.inviteUser(workspaceId, email),
|
|
42
|
+
[sdk]
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const enableService = () => {
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const disabledService = () => {
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (!workspaceId) return
|
|
55
|
+
if (workspace.status === AsyncStatus.NotInitialized) {
|
|
56
|
+
loadWorkspace()
|
|
57
|
+
}
|
|
58
|
+
}, [workspaceId, workspace])
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
status: workspace.status,
|
|
62
|
+
workspace: workspace.data,
|
|
63
|
+
loadWorkspace,
|
|
64
|
+
createApiToken,
|
|
65
|
+
inviteUser
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react'
|
|
2
|
+
import { useCache } from './Cache.jsx'
|
|
3
|
+
import { AsyncStatus } from './asyncStatus.js'
|
|
4
|
+
import { useSdk } from './useSdk.js'
|
|
5
|
+
|
|
6
|
+
const cachePath = ['workspaces']
|
|
7
|
+
|
|
8
|
+
export const useWorkspaces = () => {
|
|
9
|
+
const sdk = useSdk()
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
set: setWorkspaces,
|
|
13
|
+
data: workspaces = { status: AsyncStatus.NotInitialized, data: [] }
|
|
14
|
+
} = useCache(cachePath)
|
|
15
|
+
|
|
16
|
+
const loadWorkspaces = useCallback(() => {
|
|
17
|
+
setWorkspaces({ status: AsyncStatus.Loading, data: [] })
|
|
18
|
+
sdk.workspaces.getAll()
|
|
19
|
+
.then(workspaces => setWorkspaces({ status: AsyncStatus.Success, data: workspaces }))
|
|
20
|
+
.catch(() => setWorkspaces({ status: AsyncStatus.Error, data: [] }))
|
|
21
|
+
}, [sdk])
|
|
22
|
+
|
|
23
|
+
const createWorkspace = useCallback(
|
|
24
|
+
workspaceName => sdk.workspaces.create(workspaceName)
|
|
25
|
+
.then(workspace => {
|
|
26
|
+
|
|
27
|
+
setWorkspaces({
|
|
28
|
+
status: workspaces.status,
|
|
29
|
+
data: [...workspaces.data, workspace]
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return workspace
|
|
33
|
+
}),
|
|
34
|
+
[sdk]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (workspaces.status === AsyncStatus.NotInitialized) {
|
|
39
|
+
loadWorkspaces()
|
|
40
|
+
}
|
|
41
|
+
}, [workspaces, loadWorkspaces])
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
status: workspaces.status,
|
|
45
|
+
workspaces: workspaces.data,
|
|
46
|
+
loadWorkspaces,
|
|
47
|
+
createWorkspace
|
|
48
|
+
}
|
|
49
|
+
}
|