@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 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
+ }
@@ -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
+
@@ -0,0 +1,6 @@
1
+ export const AsyncStatus = {
2
+ NotInitialized: 'NotInitialized',
3
+ Loading: 'Loading',
4
+ Success: 'Success',
5
+ Error: 'Error'
6
+ }
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'
@@ -0,0 +1,7 @@
1
+ import { remove, findIndex, propEq, curry } from 'ramda'
2
+
3
+ export const removeBy = curry((prop, propValue, list) => {
4
+ const index = findIndex(propEq(prop, propValue), list)
5
+ const temp = index === -1 ? list : remove(index, 1, list)
6
+ return temp
7
+ })
@@ -0,0 +1,6 @@
1
+ import { curry, map } from 'ramda'
2
+
3
+ export const replaceBy = curry((prop, item, list) => map(
4
+ oldItem => oldItem[prop] === item[prop] ? item : oldItem,
5
+ list
6
+ ))
@@ -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
+ }
@@ -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
@@ -0,0 +1,7 @@
1
+ import { useContext } from 'react'
2
+ import { Context } from './WorkspaceProvider.jsx'
3
+
4
+ export function useSdk() {
5
+ return useContext(Context).sdk
6
+ }
7
+
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
+ }
@@ -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
+ }