@shipfox/client-auth 12.0.2 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +45 -0
- package/dist/components/auth-guard.js +1 -1
- package/dist/components/auth-guard.js.map +1 -1
- package/dist/components/workspace-switcher.d.ts.map +1 -1
- package/dist/components/workspace-switcher.js +4 -2
- package/dist/components/workspace-switcher.js.map +1 -1
- package/dist/components/workspace-switcher.stories.d.ts.map +1 -1
- package/dist/components/workspace-switcher.stories.js +3 -2
- package/dist/components/workspace-switcher.stories.js.map +1 -1
- package/dist/core/auth.d.ts +16 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/hooks/api/workspace-auth.d.ts +4 -1
- package/dist/hooks/api/workspace-auth.d.ts.map +1 -1
- package/dist/hooks/api/workspace-auth.js +45 -3
- package/dist/hooks/api/workspace-auth.js.map +1 -1
- package/dist/hooks/api/workspace-mapper.js +1 -0
- package/dist/hooks/api/workspace-mapper.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/pages/form-errors.d.ts +1 -1
- package/dist/pages/form-errors.d.ts.map +1 -1
- package/dist/pages/form-errors.js +7 -0
- package/dist/pages/form-errors.js.map +1 -1
- package/dist/pages/signup-page.d.ts.map +1 -1
- package/dist/pages/signup-page.js +79 -12
- package/dist/pages/signup-page.js.map +1 -1
- package/dist/pages/workspace-onboarding-page.d.ts.map +1 -1
- package/dist/pages/workspace-onboarding-page.js +81 -27
- package/dist/pages/workspace-onboarding-page.js.map +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -2
- package/dist/routes/index.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +8 -7
- package/src/components/auth-guard.tsx +1 -1
- package/src/components/redirect-target.test.ts +7 -11
- package/src/components/workspace-switcher.stories.tsx +3 -2
- package/src/components/workspace-switcher.tsx +3 -1
- package/src/core/auth.ts +12 -0
- package/src/hooks/api/workspace-auth.test.ts +66 -3
- package/src/hooks/api/workspace-auth.ts +51 -4
- package/src/hooks/api/workspace-mapper.test.ts +2 -1
- package/src/hooks/api/workspace-mapper.ts +1 -1
- package/src/hooks/index.ts +6 -1
- package/src/pages/form-errors.test.ts +11 -1
- package/src/pages/form-errors.ts +6 -1
- package/src/pages/logout-page.test.tsx +2 -2
- package/src/pages/signup-page.test.tsx +78 -0
- package/src/pages/signup-page.tsx +92 -12
- package/src/pages/workspace-onboarding-page.test.tsx +123 -1
- package/src/pages/workspace-onboarding-page.tsx +60 -7
- package/src/redirect-context.test.ts +5 -7
- package/src/routes/index.tsx +4 -1
- package/src/routes/inputs.test.ts +2 -2
- package/test/pages.tsx +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 42 files with swc (
|
|
2
|
+
Successfully compiled: 42 files with swc (467.06ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @shipfox/client-auth
|
|
2
2
|
|
|
3
|
+
## 14.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [baa7594]
|
|
8
|
+
- Updated dependencies [f8a98cb]
|
|
9
|
+
- Updated dependencies [1267eb3]
|
|
10
|
+
- Updated dependencies [b2d4550]
|
|
11
|
+
- @shipfox/react-ui@0.5.0
|
|
12
|
+
- @shipfox/client-ui@14.0.0
|
|
13
|
+
- @shipfox/client-invitations@14.0.0
|
|
14
|
+
- @shipfox/client-shell@14.0.0
|
|
15
|
+
|
|
16
|
+
## 13.0.0
|
|
17
|
+
|
|
18
|
+
### Major Changes
|
|
19
|
+
|
|
20
|
+
- e405e92: Move client routes to slug-based `/w/$workspaceSlug` and `/p/$projectSlug` URLs, enforce the new composition contract, and support bounded project-slug resolution.
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- 3c73365: Add project settings, shared slug rename warnings, and live slug availability checks.
|
|
25
|
+
- e1efaee: Add workspace slugs across the API and client workspace contracts.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- f78740d: Remove Unicode dash punctuation from package prose and source comments.
|
|
30
|
+
- Updated dependencies [e405e92]
|
|
31
|
+
- Updated dependencies [f78740d]
|
|
32
|
+
- Updated dependencies [94aba88]
|
|
33
|
+
- Updated dependencies [9969937]
|
|
34
|
+
- Updated dependencies [3c73365]
|
|
35
|
+
- Updated dependencies [9ebc5b4]
|
|
36
|
+
- Updated dependencies [54c820e]
|
|
37
|
+
- Updated dependencies [6adc228]
|
|
38
|
+
- Updated dependencies [34a5639]
|
|
39
|
+
- Updated dependencies [e1efaee]
|
|
40
|
+
- @shipfox/client-invitations@13.0.0
|
|
41
|
+
- @shipfox/client-shell@13.0.0
|
|
42
|
+
- @shipfox/api-auth-dto@12.0.0
|
|
43
|
+
- @shipfox/api-common-dto@12.0.0
|
|
44
|
+
- @shipfox/client-ui@13.0.0
|
|
45
|
+
- @shipfox/react-ui@0.4.0
|
|
46
|
+
- @shipfox/api-workspaces-dto@12.0.0
|
|
47
|
+
|
|
3
48
|
## 12.0.2
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
|
@@ -27,7 +27,7 @@ export function GuestGuard({ children }) {
|
|
|
27
27
|
const target = sanitizeRedirectPath(search.redirect);
|
|
28
28
|
useEffect(()=>{
|
|
29
29
|
if (auth.isAuthenticated && target !== undefined) {
|
|
30
|
-
// Bypass the typed route matcher
|
|
30
|
+
// Bypass the typed route matcher: `target` is an arbitrary same-origin
|
|
31
31
|
// path resolved at runtime, so we let the URL change drive route resolution.
|
|
32
32
|
router.history.replace(target);
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/auth-guard.tsx"],"sourcesContent":["import {useRouteSearch} from '@shipfox/client-shell/runtime';\nimport {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Navigate, useRouter} from '@tanstack/react-router';\nimport {type PropsWithChildren, useEffect} from 'react';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {WorkspaceOnboardingPage} from '#pages/workspace-onboarding-page.js';\nimport {validateRedirectSearch} from '../routes/inputs.js';\nimport {sanitizeRedirectPath} from './redirect-target.js';\n\nexport function AuthGuard({children}: PropsWithChildren) {\n const auth = useAuthState();\n\n if (auth.isLoading) {\n return <FullPageLoader />;\n }\n\n if (!auth.isAuthenticated) {\n return <Navigate to=\"/auth/login\" replace />;\n }\n\n return children;\n}\n\nexport function GuestGuard({children}: PropsWithChildren) {\n const auth = useAuthState();\n const search = useRouteSearch(validateRedirectSearch);\n const router = useRouter();\n const target = sanitizeRedirectPath(search.redirect);\n\n useEffect(() => {\n if (auth.isAuthenticated && target !== undefined) {\n // Bypass the typed route matcher
|
|
1
|
+
{"version":3,"sources":["../../src/components/auth-guard.tsx"],"sourcesContent":["import {useRouteSearch} from '@shipfox/client-shell/runtime';\nimport {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Navigate, useRouter} from '@tanstack/react-router';\nimport {type PropsWithChildren, useEffect} from 'react';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {WorkspaceOnboardingPage} from '#pages/workspace-onboarding-page.js';\nimport {validateRedirectSearch} from '../routes/inputs.js';\nimport {sanitizeRedirectPath} from './redirect-target.js';\n\nexport function AuthGuard({children}: PropsWithChildren) {\n const auth = useAuthState();\n\n if (auth.isLoading) {\n return <FullPageLoader />;\n }\n\n if (!auth.isAuthenticated) {\n return <Navigate to=\"/auth/login\" replace />;\n }\n\n return children;\n}\n\nexport function GuestGuard({children}: PropsWithChildren) {\n const auth = useAuthState();\n const search = useRouteSearch(validateRedirectSearch);\n const router = useRouter();\n const target = sanitizeRedirectPath(search.redirect);\n\n useEffect(() => {\n if (auth.isAuthenticated && target !== undefined) {\n // Bypass the typed route matcher: `target` is an arbitrary same-origin\n // path resolved at runtime, so we let the URL change drive route resolution.\n router.history.replace(target);\n }\n }, [auth.isAuthenticated, target, router]);\n\n if (auth.isLoading) {\n return <FullPageLoader />;\n }\n\n if (auth.isAuthenticated) {\n if (target !== undefined) {\n return <FullPageLoader />;\n }\n return <Navigate to=\"/\" replace />;\n }\n\n return children;\n}\n\nexport function WorkspaceGuard({children}: PropsWithChildren) {\n const auth = useAuthState();\n\n if (auth.isAuthenticated && !auth.hasWorkspace) {\n return <WorkspaceOnboardingPage />;\n }\n\n return children;\n}\n"],"names":["useRouteSearch","FullPageLoader","Navigate","useRouter","useEffect","useAuthState","WorkspaceOnboardingPage","validateRedirectSearch","sanitizeRedirectPath","AuthGuard","children","auth","isLoading","isAuthenticated","to","replace","GuestGuard","search","router","target","redirect","undefined","history","WorkspaceGuard","hasWorkspace"],"mappings":";AAAA,SAAQA,cAAc,QAAO,gCAAgC;AAC7D,SAAQC,cAAc,QAAO,2BAA2B;AACxD,SAAQC,QAAQ,EAAEC,SAAS,QAAO,yBAAyB;AAC3D,SAAgCC,SAAS,QAAO,QAAQ;AACxD,SAAQC,YAAY,QAAO,2BAA2B;AACtD,SAAQC,uBAAuB,QAAO,sCAAsC;AAC5E,SAAQC,sBAAsB,QAAO,sBAAsB;AAC3D,SAAQC,oBAAoB,QAAO,uBAAuB;AAE1D,OAAO,SAASC,UAAU,EAACC,QAAQ,EAAoB;IACrD,MAAMC,OAAON;IAEb,IAAIM,KAAKC,SAAS,EAAE;QAClB,qBAAO,KAACX;IACV;IAEA,IAAI,CAACU,KAAKE,eAAe,EAAE;QACzB,qBAAO,KAACX;YAASY,IAAG;YAAcC,OAAO;;IAC3C;IAEA,OAAOL;AACT;AAEA,OAAO,SAASM,WAAW,EAACN,QAAQ,EAAoB;IACtD,MAAMC,OAAON;IACb,MAAMY,SAASjB,eAAeO;IAC9B,MAAMW,SAASf;IACf,MAAMgB,SAASX,qBAAqBS,OAAOG,QAAQ;IAEnDhB,UAAU;QACR,IAAIO,KAAKE,eAAe,IAAIM,WAAWE,WAAW;YAChD,uEAAuE;YACvE,6EAA6E;YAC7EH,OAAOI,OAAO,CAACP,OAAO,CAACI;QACzB;IACF,GAAG;QAACR,KAAKE,eAAe;QAAEM;QAAQD;KAAO;IAEzC,IAAIP,KAAKC,SAAS,EAAE;QAClB,qBAAO,KAACX;IACV;IAEA,IAAIU,KAAKE,eAAe,EAAE;QACxB,IAAIM,WAAWE,WAAW;YACxB,qBAAO,KAACpB;QACV;QACA,qBAAO,KAACC;YAASY,IAAG;YAAIC,OAAO;;IACjC;IAEA,OAAOL;AACT;AAEA,OAAO,SAASa,eAAe,EAACb,QAAQ,EAAoB;IAC1D,MAAMC,OAAON;IAEb,IAAIM,KAAKE,eAAe,IAAI,CAACF,KAAKa,YAAY,EAAE;QAC9C,qBAAO,KAAClB;IACV;IAEA,OAAOI;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-switcher.d.ts","sourceRoot":"","sources":["../../src/components/workspace-switcher.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,iBAAiB,CAAC,EAAC,iBAAiB,EAAE,QAAQ,EAAC,EAAE,sBAAsB,+
|
|
1
|
+
{"version":3,"file":"workspace-switcher.d.ts","sourceRoot":"","sources":["../../src/components/workspace-switcher.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,iBAAiB,CAAC,EAAC,iBAAiB,EAAE,QAAQ,EAAC,EAAE,sBAAsB,+BA0DtF"}
|
|
@@ -10,6 +10,8 @@ export function WorkspaceSwitcher({ activeWorkspaceId, onSelect }) {
|
|
|
10
10
|
const navigate = useNavigate();
|
|
11
11
|
const setLastWorkspaceId = useSetAtom(lastWorkspaceIdAtom);
|
|
12
12
|
const handleSelect = (workspaceId)=>{
|
|
13
|
+
const workspace = workspaces.find((candidate)=>candidate.id === workspaceId);
|
|
14
|
+
if (!workspace) return;
|
|
13
15
|
try {
|
|
14
16
|
setLastWorkspaceId(workspaceId);
|
|
15
17
|
if (user?.id) rememberLastWorkspaceId(user.id, workspaceId);
|
|
@@ -17,9 +19,9 @@ export function WorkspaceSwitcher({ activeWorkspaceId, onSelect }) {
|
|
|
17
19
|
// localStorage may throw in private browsing or quota-exceeded; persistence is best-effort.
|
|
18
20
|
}
|
|
19
21
|
navigate({
|
|
20
|
-
to: '/
|
|
22
|
+
to: '/w/$workspaceSlug',
|
|
21
23
|
params: {
|
|
22
|
-
|
|
24
|
+
workspaceSlug: workspace.slug
|
|
23
25
|
}
|
|
24
26
|
});
|
|
25
27
|
onSelect?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/workspace-switcher.tsx"],"sourcesContent":["import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from '@shipfox/react-ui/command';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {useNavigate} from '@tanstack/react-router';\nimport {useSetAtom} from 'jotai';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {lastWorkspaceIdAtom, rememberLastWorkspaceId} from '#state/last-workspace.js';\n\nexport interface WorkspaceSwitcherProps {\n activeWorkspaceId: string | undefined;\n onSelect?: () => void;\n}\n\nexport function WorkspaceSwitcher({activeWorkspaceId, onSelect}: WorkspaceSwitcherProps) {\n const {user, workspaces} = useAuthState();\n const navigate = useNavigate();\n const setLastWorkspaceId = useSetAtom(lastWorkspaceIdAtom);\n\n const handleSelect = (workspaceId: string) => {\n try {\n setLastWorkspaceId(workspaceId);\n if (user?.id) rememberLastWorkspaceId(user.id, workspaceId);\n } catch {\n // localStorage may throw in private browsing or quota-exceeded; persistence is best-effort.\n }\n navigate({to: '/
|
|
1
|
+
{"version":3,"sources":["../../src/components/workspace-switcher.tsx"],"sourcesContent":["import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from '@shipfox/react-ui/command';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {useNavigate} from '@tanstack/react-router';\nimport {useSetAtom} from 'jotai';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {lastWorkspaceIdAtom, rememberLastWorkspaceId} from '#state/last-workspace.js';\n\nexport interface WorkspaceSwitcherProps {\n activeWorkspaceId: string | undefined;\n onSelect?: () => void;\n}\n\nexport function WorkspaceSwitcher({activeWorkspaceId, onSelect}: WorkspaceSwitcherProps) {\n const {user, workspaces} = useAuthState();\n const navigate = useNavigate();\n const setLastWorkspaceId = useSetAtom(lastWorkspaceIdAtom);\n\n const handleSelect = (workspaceId: string) => {\n const workspace = workspaces.find((candidate) => candidate.id === workspaceId);\n if (!workspace) return;\n try {\n setLastWorkspaceId(workspaceId);\n if (user?.id) rememberLastWorkspaceId(user.id, workspaceId);\n } catch {\n // localStorage may throw in private browsing or quota-exceeded; persistence is best-effort.\n }\n navigate({to: '/w/$workspaceSlug', params: {workspaceSlug: workspace.slug}});\n onSelect?.();\n };\n\n const handleCreate = () => {\n navigate({to: '/setup/workspaces/new'});\n onSelect?.();\n };\n\n return (\n <Command>\n <CommandInput placeholder=\"Search workspaces...\" />\n <CommandList className=\"max-h-none overflow-visible overflow-y-visible p-0\">\n <div className=\"max-h-300 overflow-y-auto overflow-x-hidden p-4 scrollbar\">\n <CommandEmpty>No workspaces found.</CommandEmpty>\n <CommandGroup heading=\"Workspaces\">\n {workspaces.map((workspace) => (\n <CommandItem\n key={workspace.id}\n value={workspace.id}\n keywords={[workspace.name]}\n onSelect={() => handleSelect(workspace.id)}\n >\n <Icon\n name=\"check\"\n className={`size-16 mr-8 ${\n activeWorkspaceId === workspace.id ? 'opacity-100' : 'opacity-0'\n }`}\n />\n {workspace.name}\n </CommandItem>\n ))}\n </CommandGroup>\n </div>\n <CommandSeparator alwaysRender className=\"mx-0\" />\n <CommandGroup forceMount className=\"p-4\">\n <CommandItem value=\"__create\" onSelect={handleCreate} forceMount>\n <Icon name=\"addLine\" className=\"size-16\" />\n Create workspace\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n );\n}\n"],"names":["Command","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","CommandSeparator","Icon","useNavigate","useSetAtom","useAuthState","lastWorkspaceIdAtom","rememberLastWorkspaceId","WorkspaceSwitcher","activeWorkspaceId","onSelect","user","workspaces","navigate","setLastWorkspaceId","handleSelect","workspaceId","workspace","find","candidate","id","to","params","workspaceSlug","slug","handleCreate","placeholder","className","div","heading","map","value","keywords","name","alwaysRender","forceMount"],"mappings":";AAAA,SACEA,OAAO,EACPC,YAAY,EACZC,YAAY,EACZC,YAAY,EACZC,WAAW,EACXC,WAAW,EACXC,gBAAgB,QACX,4BAA4B;AACnC,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,WAAW,QAAO,yBAAyB;AACnD,SAAQC,UAAU,QAAO,QAAQ;AACjC,SAAQC,YAAY,QAAO,2BAA2B;AACtD,SAAQC,mBAAmB,EAAEC,uBAAuB,QAAO,2BAA2B;AAOtF,OAAO,SAASC,kBAAkB,EAACC,iBAAiB,EAAEC,QAAQ,EAAyB;IACrF,MAAM,EAACC,IAAI,EAAEC,UAAU,EAAC,GAAGP;IAC3B,MAAMQ,WAAWV;IACjB,MAAMW,qBAAqBV,WAAWE;IAEtC,MAAMS,eAAe,CAACC;QACpB,MAAMC,YAAYL,WAAWM,IAAI,CAAC,CAACC,YAAcA,UAAUC,EAAE,KAAKJ;QAClE,IAAI,CAACC,WAAW;QAChB,IAAI;YACFH,mBAAmBE;YACnB,IAAIL,MAAMS,IAAIb,wBAAwBI,KAAKS,EAAE,EAAEJ;QACjD,EAAE,OAAM;QACN,4FAA4F;QAC9F;QACAH,SAAS;YAACQ,IAAI;YAAqBC,QAAQ;gBAACC,eAAeN,UAAUO,IAAI;YAAA;QAAC;QAC1Ed;IACF;IAEA,MAAMe,eAAe;QACnBZ,SAAS;YAACQ,IAAI;QAAuB;QACrCX;IACF;IAEA,qBACE,MAACf;;0BACC,KAACG;gBAAa4B,aAAY;;0BAC1B,MAAC1B;gBAAY2B,WAAU;;kCACrB,MAACC;wBAAID,WAAU;;0CACb,KAAC/B;0CAAa;;0CACd,KAACC;gCAAagC,SAAQ;0CACnBjB,WAAWkB,GAAG,CAAC,CAACb,0BACf,MAAClB;wCAECgC,OAAOd,UAAUG,EAAE;wCACnBY,UAAU;4CAACf,UAAUgB,IAAI;yCAAC;wCAC1BvB,UAAU,IAAMK,aAAaE,UAAUG,EAAE;;0DAEzC,KAAClB;gDACC+B,MAAK;gDACLN,WAAW,CAAC,aAAa,EACvBlB,sBAAsBQ,UAAUG,EAAE,GAAG,gBAAgB,aACrD;;4CAEHH,UAAUgB,IAAI;;uCAXVhB,UAAUG,EAAE;;;;kCAgBzB,KAACnB;wBAAiBiC,YAAY;wBAACP,WAAU;;kCACzC,KAAC9B;wBAAasC,UAAU;wBAACR,WAAU;kCACjC,cAAA,MAAC5B;4BAAYgC,OAAM;4BAAWrB,UAAUe;4BAAcU,UAAU;;8CAC9D,KAACjC;oCAAK+B,MAAK;oCAAUN,WAAU;;gCAAY;;;;;;;;AAOvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-switcher.stories.d.ts","sourceRoot":"","sources":["../../src/components/workspace-switcher.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAYrD,OAAO,EAAgB,KAAK,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAmB7D,UAAU,2BAA2B;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"workspace-switcher.stories.d.ts","sourceRoot":"","sources":["../../src/components/workspace-switcher.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAYrD,OAAO,EAAgB,KAAK,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAmB7D,UAAU,2BAA2B;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAWD,iBAAS,sBAAsB,CAAC,EAAC,iBAAiB,EAAE,UAAU,EAAC,EAAE,2BAA2B,+BAkC3F;AAED,QAAA,MAAM,IAAI;;;;;;;;;;CAUqC,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AASnC,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAO9B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAazB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAyBlC,CAAC"}
|
|
@@ -23,6 +23,7 @@ function workspace(id, name, index) {
|
|
|
23
23
|
return {
|
|
24
24
|
id,
|
|
25
25
|
name,
|
|
26
|
+
slug: name.toLowerCase().replaceAll(' ', '-'),
|
|
26
27
|
membershipId: `10000000-0000-4000-8000-${String(index).padStart(12, '0')}`
|
|
27
28
|
};
|
|
28
29
|
}
|
|
@@ -43,7 +44,7 @@ function WorkspaceSwitcherStory({ activeWorkspaceId, workspaces }) {
|
|
|
43
44
|
});
|
|
44
45
|
const workspaceRoute = createRoute({
|
|
45
46
|
getParentRoute: ()=>rootRoute,
|
|
46
|
-
path: '/
|
|
47
|
+
path: '/w/$workspaceSlug',
|
|
47
48
|
component: ()=>/*#__PURE__*/ _jsx(JotaiProvider, {
|
|
48
49
|
store: store,
|
|
49
50
|
children: /*#__PURE__*/ _jsx("div", {
|
|
@@ -69,7 +70,7 @@ function WorkspaceSwitcherStory({ activeWorkspaceId, workspaces }) {
|
|
|
69
70
|
]),
|
|
70
71
|
history: createMemoryHistory({
|
|
71
72
|
initialEntries: [
|
|
72
|
-
|
|
73
|
+
'/w/acme'
|
|
73
74
|
]
|
|
74
75
|
})
|
|
75
76
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/workspace-switcher.stories.tsx"],"sourcesContent":["import {argosScreenshot} from '@argos-ci/storybook/vitest';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {\n createMemoryHistory,\n createRootRoute,\n createRoute,\n createRouter,\n Outlet,\n RouterProvider,\n} from '@tanstack/react-router';\nimport {createStore, Provider as JotaiProvider} from 'jotai';\nimport {useMemo} from 'react';\nimport {expect, userEvent, waitFor, within} from 'storybook/test';\nimport {authStateAtom, type Workspace} from '#state/auth.js';\nimport {WorkspaceSwitcher} from './workspace-switcher.js';\n\nconst ACTIVE_WORKSPACE_ID = '00000000-0000-4000-8000-000000000001';\nconst WORKSPACES = [\n workspace(ACTIVE_WORKSPACE_ID, 'Alpha Workspace', 1),\n workspace('00000000-0000-4000-8000-000000000002', 'Beta Workspace', 2),\n workspace('00000000-0000-4000-8000-000000000003', 'Gamma Workspace', 3),\n workspace('00000000-0000-4000-8000-000000000004', 'Delta Workspace', 4),\n];\nconst SINGLE_WORKSPACE = [workspace(ACTIVE_WORKSPACE_ID, 'Alpha Workspace', 1)];\nconst MANY_WORKSPACES = Array.from({length: 20}, (_, index) =>\n workspace(\n `00000000-0000-4000-8000-${String(index + 1).padStart(12, '0')}`,\n `Workspace ${String(index + 1).padStart(2, '0')}`,\n index + 1,\n ),\n);\n\ninterface WorkspaceSwitcherStoryProps {\n activeWorkspaceId: string;\n workspaces: Workspace[];\n}\n\nfunction workspace(id: string, name: string, index: number): Workspace {\n return {\n id,\n name,\n membershipId: `10000000-0000-4000-8000-${String(index).padStart(12, '0')}`,\n };\n}\n\nfunction WorkspaceSwitcherStory({activeWorkspaceId, workspaces}: WorkspaceSwitcherStoryProps) {\n const store = useMemo(() => {\n const nextStore = createStore();\n nextStore.set(authStateAtom, {status: 'authenticated', workspaces});\n return nextStore;\n }, [workspaces]);\n const router = useMemo(() => {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: () => (\n <JotaiProvider store={store}>\n <div className=\"min-h-screen bg-background-neutral-base p-24\">\n <div className=\"w-[280px] rounded-10 bg-background-neutral-overlay shadow-tooltip\">\n <WorkspaceSwitcher activeWorkspaceId={activeWorkspaceId} />\n </div>\n </div>\n </JotaiProvider>\n ),\n });\n const setupRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/setup/workspaces/new',\n component: () => <div />,\n });\n\n return createRouter({\n routeTree: rootRoute.addChildren([workspaceRoute, setupRoute]),\n history: createMemoryHistory({initialEntries: [`/workspaces/${activeWorkspaceId}`]}),\n });\n }, [activeWorkspaceId, store]);\n\n return <RouterProvider router={router} />;\n}\n\nconst meta = {\n title: 'Auth/WorkspaceSwitcher',\n component: WorkspaceSwitcherStory,\n parameters: {\n layout: 'fullscreen',\n },\n args: {\n activeWorkspaceId: ACTIVE_WORKSPACE_ID,\n workspaces: WORKSPACES,\n },\n} satisfies Meta<typeof WorkspaceSwitcherStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\ntype WorkspaceSwitcherStoryContext = Parameters<NonNullable<Story['play']>>[0];\n\nasync function captureSwitcher(ctx: WorkspaceSwitcherStoryContext, screenshotName: string) {\n const canvas = within(ctx.canvasElement);\n await canvas.findByRole('option', {name: 'Create workspace'});\n await argosScreenshot(ctx, screenshotName);\n}\n\nexport const Playground: Story = {\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Open');\n },\n};\n\nexport const SingleWithCreate: Story = {\n args: {\n workspaces: SINGLE_WORKSPACE,\n },\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Single With Create');\n },\n};\n\nexport const EmptySearch: Story = {\n play: async (ctx) => {\n const canvas = within(ctx.canvasElement);\n\n await userEvent.type(\n await canvas.findByPlaceholderText('Search workspaces...'),\n 'zzz-no-match',\n );\n\n await canvas.findByText('No workspaces found.');\n await canvas.findByRole('option', {name: 'Create workspace'});\n await argosScreenshot(ctx, 'Workspace Switcher Empty Search');\n },\n};\n\nexport const ManyOverflow: Story = {\n args: {\n activeWorkspaceId: MANY_WORKSPACES[0]?.id ?? ACTIVE_WORKSPACE_ID,\n workspaces: MANY_WORKSPACES,\n },\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Many Overflow');\n },\n};\n\nexport const ManyOverflowScrolled: Story = {\n args: {\n activeWorkspaceId: MANY_WORKSPACES[0]?.id ?? ACTIVE_WORKSPACE_ID,\n workspaces: MANY_WORKSPACES,\n },\n play: async (ctx) => {\n const canvas = within(ctx.canvasElement);\n\n await canvas.findByRole('option', {name: 'Workspace 01'});\n await canvas.findByRole('option', {name: 'Create workspace'});\n\n await canvas.findByRole('option', {name: 'Workspace 20'});\n const firstOption = canvas.getAllByRole('option')[0];\n let scrollContainer = firstOption?.parentElement ?? null;\n while (scrollContainer && scrollContainer.scrollHeight <= scrollContainer.clientHeight) {\n scrollContainer = scrollContainer.parentElement;\n }\n if (!scrollContainer) {\n throw new Error('Workspace switcher scroll container was not found');\n }\n scrollContainer.scrollTop = scrollContainer.scrollHeight;\n\n await waitFor(() => expect(canvas.getByRole('option', {name: 'Workspace 20'})).toBeVisible());\n await argosScreenshot(ctx, 'Workspace Switcher Many Overflow Scrolled');\n },\n};\n"],"names":["argosScreenshot","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","expect","userEvent","waitFor","within","authStateAtom","WorkspaceSwitcher","ACTIVE_WORKSPACE_ID","WORKSPACES","workspace","SINGLE_WORKSPACE","MANY_WORKSPACES","Array","from","length","_","index","String","padStart","id","name","membershipId","WorkspaceSwitcherStory","activeWorkspaceId","workspaces","store","nextStore","set","status","router","rootRoute","component","workspaceRoute","getParentRoute","path","div","className","setupRoute","routeTree","addChildren","history","initialEntries","meta","title","parameters","layout","args","captureSwitcher","ctx","screenshotName","canvas","canvasElement","findByRole","Playground","play","SingleWithCreate","EmptySearch","type","findByPlaceholderText","findByText","ManyOverflow","ManyOverflowScrolled","firstOption","getAllByRole","scrollContainer","parentElement","scrollHeight","clientHeight","Error","scrollTop","getByRole","toBeVisible"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/workspace-switcher.stories.tsx"],"sourcesContent":["import {argosScreenshot} from '@argos-ci/storybook/vitest';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {\n createMemoryHistory,\n createRootRoute,\n createRoute,\n createRouter,\n Outlet,\n RouterProvider,\n} from '@tanstack/react-router';\nimport {createStore, Provider as JotaiProvider} from 'jotai';\nimport {useMemo} from 'react';\nimport {expect, userEvent, waitFor, within} from 'storybook/test';\nimport {authStateAtom, type Workspace} from '#state/auth.js';\nimport {WorkspaceSwitcher} from './workspace-switcher.js';\n\nconst ACTIVE_WORKSPACE_ID = '00000000-0000-4000-8000-000000000001';\nconst WORKSPACES = [\n workspace(ACTIVE_WORKSPACE_ID, 'Alpha Workspace', 1),\n workspace('00000000-0000-4000-8000-000000000002', 'Beta Workspace', 2),\n workspace('00000000-0000-4000-8000-000000000003', 'Gamma Workspace', 3),\n workspace('00000000-0000-4000-8000-000000000004', 'Delta Workspace', 4),\n];\nconst SINGLE_WORKSPACE = [workspace(ACTIVE_WORKSPACE_ID, 'Alpha Workspace', 1)];\nconst MANY_WORKSPACES = Array.from({length: 20}, (_, index) =>\n workspace(\n `00000000-0000-4000-8000-${String(index + 1).padStart(12, '0')}`,\n `Workspace ${String(index + 1).padStart(2, '0')}`,\n index + 1,\n ),\n);\n\ninterface WorkspaceSwitcherStoryProps {\n activeWorkspaceId: string;\n workspaces: Workspace[];\n}\n\nfunction workspace(id: string, name: string, index: number): Workspace {\n return {\n id,\n name,\n slug: name.toLowerCase().replaceAll(' ', '-'),\n membershipId: `10000000-0000-4000-8000-${String(index).padStart(12, '0')}`,\n };\n}\n\nfunction WorkspaceSwitcherStory({activeWorkspaceId, workspaces}: WorkspaceSwitcherStoryProps) {\n const store = useMemo(() => {\n const nextStore = createStore();\n nextStore.set(authStateAtom, {status: 'authenticated', workspaces});\n return nextStore;\n }, [workspaces]);\n const router = useMemo(() => {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/w/$workspaceSlug',\n component: () => (\n <JotaiProvider store={store}>\n <div className=\"min-h-screen bg-background-neutral-base p-24\">\n <div className=\"w-[280px] rounded-10 bg-background-neutral-overlay shadow-tooltip\">\n <WorkspaceSwitcher activeWorkspaceId={activeWorkspaceId} />\n </div>\n </div>\n </JotaiProvider>\n ),\n });\n const setupRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/setup/workspaces/new',\n component: () => <div />,\n });\n\n return createRouter({\n routeTree: rootRoute.addChildren([workspaceRoute, setupRoute]),\n history: createMemoryHistory({initialEntries: ['/w/acme']}),\n });\n }, [activeWorkspaceId, store]);\n\n return <RouterProvider router={router} />;\n}\n\nconst meta = {\n title: 'Auth/WorkspaceSwitcher',\n component: WorkspaceSwitcherStory,\n parameters: {\n layout: 'fullscreen',\n },\n args: {\n activeWorkspaceId: ACTIVE_WORKSPACE_ID,\n workspaces: WORKSPACES,\n },\n} satisfies Meta<typeof WorkspaceSwitcherStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\ntype WorkspaceSwitcherStoryContext = Parameters<NonNullable<Story['play']>>[0];\n\nasync function captureSwitcher(ctx: WorkspaceSwitcherStoryContext, screenshotName: string) {\n const canvas = within(ctx.canvasElement);\n await canvas.findByRole('option', {name: 'Create workspace'});\n await argosScreenshot(ctx, screenshotName);\n}\n\nexport const Playground: Story = {\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Open');\n },\n};\n\nexport const SingleWithCreate: Story = {\n args: {\n workspaces: SINGLE_WORKSPACE,\n },\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Single With Create');\n },\n};\n\nexport const EmptySearch: Story = {\n play: async (ctx) => {\n const canvas = within(ctx.canvasElement);\n\n await userEvent.type(\n await canvas.findByPlaceholderText('Search workspaces...'),\n 'zzz-no-match',\n );\n\n await canvas.findByText('No workspaces found.');\n await canvas.findByRole('option', {name: 'Create workspace'});\n await argosScreenshot(ctx, 'Workspace Switcher Empty Search');\n },\n};\n\nexport const ManyOverflow: Story = {\n args: {\n activeWorkspaceId: MANY_WORKSPACES[0]?.id ?? ACTIVE_WORKSPACE_ID,\n workspaces: MANY_WORKSPACES,\n },\n play: async (ctx) => {\n await captureSwitcher(ctx, 'Workspace Switcher Many Overflow');\n },\n};\n\nexport const ManyOverflowScrolled: Story = {\n args: {\n activeWorkspaceId: MANY_WORKSPACES[0]?.id ?? ACTIVE_WORKSPACE_ID,\n workspaces: MANY_WORKSPACES,\n },\n play: async (ctx) => {\n const canvas = within(ctx.canvasElement);\n\n await canvas.findByRole('option', {name: 'Workspace 01'});\n await canvas.findByRole('option', {name: 'Create workspace'});\n\n await canvas.findByRole('option', {name: 'Workspace 20'});\n const firstOption = canvas.getAllByRole('option')[0];\n let scrollContainer = firstOption?.parentElement ?? null;\n while (scrollContainer && scrollContainer.scrollHeight <= scrollContainer.clientHeight) {\n scrollContainer = scrollContainer.parentElement;\n }\n if (!scrollContainer) {\n throw new Error('Workspace switcher scroll container was not found');\n }\n scrollContainer.scrollTop = scrollContainer.scrollHeight;\n\n await waitFor(() => expect(canvas.getByRole('option', {name: 'Workspace 20'})).toBeVisible());\n await argosScreenshot(ctx, 'Workspace Switcher Many Overflow Scrolled');\n },\n};\n"],"names":["argosScreenshot","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","expect","userEvent","waitFor","within","authStateAtom","WorkspaceSwitcher","ACTIVE_WORKSPACE_ID","WORKSPACES","workspace","SINGLE_WORKSPACE","MANY_WORKSPACES","Array","from","length","_","index","String","padStart","id","name","slug","toLowerCase","replaceAll","membershipId","WorkspaceSwitcherStory","activeWorkspaceId","workspaces","store","nextStore","set","status","router","rootRoute","component","workspaceRoute","getParentRoute","path","div","className","setupRoute","routeTree","addChildren","history","initialEntries","meta","title","parameters","layout","args","captureSwitcher","ctx","screenshotName","canvas","canvasElement","findByRole","Playground","play","SingleWithCreate","EmptySearch","type","findByPlaceholderText","findByText","ManyOverflow","ManyOverflowScrolled","firstOption","getAllByRole","scrollContainer","parentElement","scrollHeight","clientHeight","Error","scrollTop","getByRole","toBeVisible"],"mappings":"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"}
|
package/dist/core/auth.d.ts
CHANGED
|
@@ -24,10 +24,25 @@ export interface ResendEmailVerificationCommand {
|
|
|
24
24
|
}
|
|
25
25
|
export interface WorkspaceCreateCommand {
|
|
26
26
|
name: string;
|
|
27
|
+
slug: string;
|
|
27
28
|
}
|
|
29
|
+
type WorkspaceUpdateBody = {
|
|
30
|
+
name: string;
|
|
31
|
+
slug?: never;
|
|
32
|
+
} | {
|
|
33
|
+
name?: never;
|
|
34
|
+
slug: string;
|
|
35
|
+
} | {
|
|
36
|
+
name: string;
|
|
37
|
+
slug: string;
|
|
38
|
+
};
|
|
39
|
+
export type WorkspaceUpdateCommand = {
|
|
40
|
+
workspaceId: string;
|
|
41
|
+
} & WorkspaceUpdateBody;
|
|
28
42
|
export interface Workspace {
|
|
29
43
|
id: string;
|
|
30
44
|
name: string;
|
|
45
|
+
slug: string;
|
|
31
46
|
status: 'active' | 'suspended' | 'deleted';
|
|
32
47
|
}
|
|
33
48
|
export interface SignupResult {
|
|
@@ -54,4 +69,5 @@ export interface SignupResult {
|
|
|
54
69
|
export interface EmailVerificationResendResult {
|
|
55
70
|
nextResendAvailableAt: string;
|
|
56
71
|
}
|
|
72
|
+
export {};
|
|
57
73
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/core/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAA;KAAC,CAAC;IAC7D,UAAU,CAAC,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC;IAC/D,WAAW,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAC/C;AAED,MAAM,WAAW,6BAA6B;IAC5C,qBAAqB,EAAE,MAAM,CAAC;CAC/B"}
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,mBAAmB,GACpB;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAC,GAC5B;IAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAC5B;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,MAAM,sBAAsB,GAAG;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,GAAG,mBAAmB,CAAC;AAEjF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAA;KAAC,CAAC;IAC7D,UAAU,CAAC,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC;IAC/D,WAAW,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAC/C;AAED,MAAM,WAAW,6BAA6B;IAC5C,qBAAqB,EAAE,MAAM,CAAC;CAC/B"}
|
package/dist/core/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/auth.ts"],"sourcesContent":["export interface LoginCommand {\n email: string;\n password: string;\n}\n\nexport interface SignupCommand extends LoginCommand {\n name: string;\n invitationToken?: string;\n}\n\nexport interface PasswordResetRequestCommand {\n email: string;\n}\n\nexport interface PasswordResetConfirmCommand {\n token: string;\n newPassword: string;\n}\n\nexport interface VerifyEmailCommand {\n email: string;\n challengeId: string;\n code: string;\n}\n\nexport interface ResendEmailVerificationCommand {\n email: string;\n challengeId: string;\n}\n\nexport interface WorkspaceCreateCommand {\n name: string;\n}\n\nexport interface Workspace {\n id: string;\n name: string;\n status: 'active' | 'suspended' | 'deleted';\n}\n\nexport interface SignupResult {\n user: {\n id: string;\n email: string;\n name?: string;\n emailVerifiedAt?: string;\n };\n emailChallenge?: {id: string; nextResendAvailableAt: string};\n membership?: {id: string; userId: string; workspaceId: string};\n acceptError?: {code: string; message: string};\n}\n\nexport interface EmailVerificationResendResult {\n nextResendAvailableAt: string;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/core/auth.ts"],"sourcesContent":["export interface LoginCommand {\n email: string;\n password: string;\n}\n\nexport interface SignupCommand extends LoginCommand {\n name: string;\n invitationToken?: string;\n}\n\nexport interface PasswordResetRequestCommand {\n email: string;\n}\n\nexport interface PasswordResetConfirmCommand {\n token: string;\n newPassword: string;\n}\n\nexport interface VerifyEmailCommand {\n email: string;\n challengeId: string;\n code: string;\n}\n\nexport interface ResendEmailVerificationCommand {\n email: string;\n challengeId: string;\n}\n\nexport interface WorkspaceCreateCommand {\n name: string;\n slug: string;\n}\n\ntype WorkspaceUpdateBody =\n | {name: string; slug?: never}\n | {name?: never; slug: string}\n | {\n name: string;\n slug: string;\n };\n\nexport type WorkspaceUpdateCommand = {workspaceId: string} & WorkspaceUpdateBody;\n\nexport interface Workspace {\n id: string;\n name: string;\n slug: string;\n status: 'active' | 'suspended' | 'deleted';\n}\n\nexport interface SignupResult {\n user: {\n id: string;\n email: string;\n name?: string;\n emailVerifiedAt?: string;\n };\n emailChallenge?: {id: string; nextResendAvailableAt: string};\n membership?: {id: string; userId: string; workspaceId: string};\n acceptError?: {code: string; message: string};\n}\n\nexport interface EmailVerificationResendResult {\n nextResendAvailableAt: string;\n}\n"],"names":[],"mappings":"AAgEA,WAEC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions } from '@shipfox/client-shell/runtime';
|
|
2
|
-
import type { WorkspaceCreateCommand } from '#core/auth.js';
|
|
2
|
+
import type { WorkspaceCreateCommand, WorkspaceUpdateCommand } from '#core/auth.js';
|
|
3
3
|
export declare function createWorkspace(command: WorkspaceCreateCommand): Promise<import("#core/auth.js").Workspace>;
|
|
4
|
+
export declare function updateWorkspace(command: WorkspaceUpdateCommand): Promise<import("#core/auth.js").Workspace>;
|
|
5
|
+
export declare function checkWorkspaceSlugAvailability(slug: string): Promise<boolean>;
|
|
4
6
|
export { listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions };
|
|
5
7
|
export declare function useCreateWorkspaceAuth(): import("@tanstack/react-query").UseMutationResult<import("#core/auth.js").Workspace, Error, WorkspaceCreateCommand, unknown>;
|
|
8
|
+
export declare function useUpdateWorkspaceMutation(): import("@tanstack/react-query").UseMutationResult<import("#core/auth.js").Workspace, Error, WorkspaceUpdateCommand, unknown>;
|
|
6
9
|
//# sourceMappingURL=workspace-auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-auth.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/workspace-auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-auth.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/workspace-auth.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAC,sBAAsB,EAAE,sBAAsB,EAAC,MAAM,eAAe,CAAC;AAKlF,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,8CAMpE;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,8CAQpE;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMnF;AAED,OAAO,EAAC,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAC,CAAC;AAEhF,wBAAgB,sBAAsB,iIAYrC;AAED,wBAAgB,0BAA0B,iIAqBzC"}
|
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import { workspaceResponseSchema } from '@shipfox/api-workspaces-dto';
|
|
1
|
+
import { updateWorkspaceBodySchema, workspaceResponseSchema, workspaceSlugAvailabilityResponseSchema } from '@shipfox/api-workspaces-dto';
|
|
2
2
|
import { checkedApiRequest } from '@shipfox/client-api';
|
|
3
3
|
import { listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions } from '@shipfox/client-shell/runtime';
|
|
4
|
-
import { useMutation } from '@tanstack/react-query';
|
|
4
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { useSetAtom } from 'jotai';
|
|
6
|
+
import { authStateAtom } from '#state/auth.js';
|
|
5
7
|
import { useRefreshAuth } from './refresh-auth.js';
|
|
6
8
|
import { toWorkspace } from './workspace-mapper.js';
|
|
7
9
|
export async function createWorkspace(command) {
|
|
8
10
|
const response = await checkedApiRequest(workspaceResponseSchema, '/workspaces', {
|
|
9
11
|
method: 'POST',
|
|
10
12
|
body: {
|
|
11
|
-
name: command.name
|
|
13
|
+
name: command.name,
|
|
14
|
+
slug: command.slug
|
|
12
15
|
}
|
|
13
16
|
});
|
|
14
17
|
return toWorkspace(response);
|
|
15
18
|
}
|
|
19
|
+
export async function updateWorkspace(command) {
|
|
20
|
+
const body = updateWorkspaceBodySchema.parse({
|
|
21
|
+
name: command.name,
|
|
22
|
+
slug: command.slug
|
|
23
|
+
});
|
|
24
|
+
const response = await checkedApiRequest(workspaceResponseSchema, `/workspaces/${command.workspaceId}`, {
|
|
25
|
+
method: 'PATCH',
|
|
26
|
+
body
|
|
27
|
+
});
|
|
28
|
+
return toWorkspace(response);
|
|
29
|
+
}
|
|
30
|
+
export async function checkWorkspaceSlugAvailability(slug) {
|
|
31
|
+
const response = await checkedApiRequest(workspaceSlugAvailabilityResponseSchema, `/workspaces/slug-availability?slug=${encodeURIComponent(slug)}`);
|
|
32
|
+
return response.available;
|
|
33
|
+
}
|
|
16
34
|
export { listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions };
|
|
17
35
|
export function useCreateWorkspaceAuth() {
|
|
18
36
|
const refreshAuth = useRefreshAuth();
|
|
@@ -26,5 +44,29 @@ export function useCreateWorkspaceAuth() {
|
|
|
26
44
|
}
|
|
27
45
|
});
|
|
28
46
|
}
|
|
47
|
+
export function useUpdateWorkspaceMutation() {
|
|
48
|
+
const queryClient = useQueryClient();
|
|
49
|
+
const setAuthState = useSetAtom(authStateAtom);
|
|
50
|
+
return useMutation({
|
|
51
|
+
mutationFn: updateWorkspace,
|
|
52
|
+
onSuccess: async (workspace)=>{
|
|
53
|
+
setAuthState((previous)=>{
|
|
54
|
+
if (previous.status !== 'authenticated') return previous;
|
|
55
|
+
return {
|
|
56
|
+
...previous,
|
|
57
|
+
workspaces: (previous.workspaces ?? []).map((candidate)=>candidate.id === workspace.id ? {
|
|
58
|
+
...candidate,
|
|
59
|
+
name: workspace.name,
|
|
60
|
+
slug: workspace.slug,
|
|
61
|
+
status: workspace.status
|
|
62
|
+
} : candidate)
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
await queryClient.invalidateQueries({
|
|
66
|
+
queryKey: userWorkspacesQueryKey
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
29
71
|
|
|
30
72
|
//# sourceMappingURL=workspace-auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/api/workspace-auth.ts"],"sourcesContent":["import {workspaceResponseSchema} from '@shipfox/api-workspaces-dto';\nimport {checkedApiRequest} from '@shipfox/client-api';\nimport {\n listUserWorkspaces,\n userWorkspacesQueryKey,\n userWorkspacesQueryOptions,\n} from '@shipfox/client-shell/runtime';\nimport {useMutation} from '@tanstack/react-query';\nimport type {WorkspaceCreateCommand} from '#core/auth.js';\nimport {useRefreshAuth} from './refresh-auth.js';\nimport {toWorkspace} from './workspace-mapper.js';\n\nexport async function createWorkspace(command: WorkspaceCreateCommand) {\n const response = await checkedApiRequest(workspaceResponseSchema, '/workspaces', {\n method: 'POST',\n body: {name: command.name},\n });\n return toWorkspace(response);\n}\n\nexport {listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions};\n\nexport function useCreateWorkspaceAuth() {\n const refreshAuth = useRefreshAuth();\n\n return useMutation({\n mutationFn: createWorkspace,\n onSuccess: async () => {\n // The new workspace introduces a membership the existing access token\n // doesn't carry. Refresh so the next request includes it in the JWT\n // claim and passes the in-memory canAccess() check on the server.\n await refreshAuth();\n },\n });\n}\n"],"names":["workspaceResponseSchema","checkedApiRequest","listUserWorkspaces","userWorkspacesQueryKey","userWorkspacesQueryOptions","useMutation","useRefreshAuth","toWorkspace","createWorkspace","command","response","method","body","name","useCreateWorkspaceAuth","refreshAuth","mutationFn","onSuccess"],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/api/workspace-auth.ts"],"sourcesContent":["import {\n updateWorkspaceBodySchema,\n workspaceResponseSchema,\n workspaceSlugAvailabilityResponseSchema,\n} from '@shipfox/api-workspaces-dto';\nimport {checkedApiRequest} from '@shipfox/client-api';\nimport {\n listUserWorkspaces,\n userWorkspacesQueryKey,\n userWorkspacesQueryOptions,\n} from '@shipfox/client-shell/runtime';\nimport {useMutation, useQueryClient} from '@tanstack/react-query';\nimport {useSetAtom} from 'jotai';\nimport type {WorkspaceCreateCommand, WorkspaceUpdateCommand} from '#core/auth.js';\nimport {authStateAtom} from '#state/auth.js';\nimport {useRefreshAuth} from './refresh-auth.js';\nimport {toWorkspace} from './workspace-mapper.js';\n\nexport async function createWorkspace(command: WorkspaceCreateCommand) {\n const response = await checkedApiRequest(workspaceResponseSchema, '/workspaces', {\n method: 'POST',\n body: {name: command.name, slug: command.slug},\n });\n return toWorkspace(response);\n}\n\nexport async function updateWorkspace(command: WorkspaceUpdateCommand) {\n const body = updateWorkspaceBodySchema.parse({name: command.name, slug: command.slug});\n const response = await checkedApiRequest(\n workspaceResponseSchema,\n `/workspaces/${command.workspaceId}`,\n {method: 'PATCH', body},\n );\n return toWorkspace(response);\n}\n\nexport async function checkWorkspaceSlugAvailability(slug: string): Promise<boolean> {\n const response = await checkedApiRequest(\n workspaceSlugAvailabilityResponseSchema,\n `/workspaces/slug-availability?slug=${encodeURIComponent(slug)}`,\n );\n return response.available;\n}\n\nexport {listUserWorkspaces, userWorkspacesQueryKey, userWorkspacesQueryOptions};\n\nexport function useCreateWorkspaceAuth() {\n const refreshAuth = useRefreshAuth();\n\n return useMutation({\n mutationFn: createWorkspace,\n onSuccess: async () => {\n // The new workspace introduces a membership the existing access token\n // doesn't carry. Refresh so the next request includes it in the JWT\n // claim and passes the in-memory canAccess() check on the server.\n await refreshAuth();\n },\n });\n}\n\nexport function useUpdateWorkspaceMutation() {\n const queryClient = useQueryClient();\n const setAuthState = useSetAtom(authStateAtom);\n\n return useMutation({\n mutationFn: updateWorkspace,\n onSuccess: async (workspace) => {\n setAuthState((previous) => {\n if (previous.status !== 'authenticated') return previous;\n return {\n ...previous,\n workspaces: (previous.workspaces ?? []).map((candidate) =>\n candidate.id === workspace.id\n ? {...candidate, name: workspace.name, slug: workspace.slug, status: workspace.status}\n : candidate,\n ),\n };\n });\n await queryClient.invalidateQueries({queryKey: userWorkspacesQueryKey});\n },\n });\n}\n"],"names":["updateWorkspaceBodySchema","workspaceResponseSchema","workspaceSlugAvailabilityResponseSchema","checkedApiRequest","listUserWorkspaces","userWorkspacesQueryKey","userWorkspacesQueryOptions","useMutation","useQueryClient","useSetAtom","authStateAtom","useRefreshAuth","toWorkspace","createWorkspace","command","response","method","body","name","slug","updateWorkspace","parse","workspaceId","checkWorkspaceSlugAvailability","encodeURIComponent","available","useCreateWorkspaceAuth","refreshAuth","mutationFn","onSuccess","useUpdateWorkspaceMutation","queryClient","setAuthState","workspace","previous","status","workspaces","map","candidate","id","invalidateQueries","queryKey"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,uBAAuB,EACvBC,uCAAuC,QAClC,8BAA8B;AACrC,SAAQC,iBAAiB,QAAO,sBAAsB;AACtD,SACEC,kBAAkB,EAClBC,sBAAsB,EACtBC,0BAA0B,QACrB,gCAAgC;AACvC,SAAQC,WAAW,EAAEC,cAAc,QAAO,wBAAwB;AAClE,SAAQC,UAAU,QAAO,QAAQ;AAEjC,SAAQC,aAAa,QAAO,iBAAiB;AAC7C,SAAQC,cAAc,QAAO,oBAAoB;AACjD,SAAQC,WAAW,QAAO,wBAAwB;AAElD,OAAO,eAAeC,gBAAgBC,OAA+B;IACnE,MAAMC,WAAW,MAAMZ,kBAAkBF,yBAAyB,eAAe;QAC/Ee,QAAQ;QACRC,MAAM;YAACC,MAAMJ,QAAQI,IAAI;YAAEC,MAAML,QAAQK,IAAI;QAAA;IAC/C;IACA,OAAOP,YAAYG;AACrB;AAEA,OAAO,eAAeK,gBAAgBN,OAA+B;IACnE,MAAMG,OAAOjB,0BAA0BqB,KAAK,CAAC;QAACH,MAAMJ,QAAQI,IAAI;QAAEC,MAAML,QAAQK,IAAI;IAAA;IACpF,MAAMJ,WAAW,MAAMZ,kBACrBF,yBACA,CAAC,YAAY,EAAEa,QAAQQ,WAAW,EAAE,EACpC;QAACN,QAAQ;QAASC;IAAI;IAExB,OAAOL,YAAYG;AACrB;AAEA,OAAO,eAAeQ,+BAA+BJ,IAAY;IAC/D,MAAMJ,WAAW,MAAMZ,kBACrBD,yCACA,CAAC,mCAAmC,EAAEsB,mBAAmBL,OAAO;IAElE,OAAOJ,SAASU,SAAS;AAC3B;AAEA,SAAQrB,kBAAkB,EAAEC,sBAAsB,EAAEC,0BAA0B,GAAE;AAEhF,OAAO,SAASoB;IACd,MAAMC,cAAchB;IAEpB,OAAOJ,YAAY;QACjBqB,YAAYf;QACZgB,WAAW;YACT,sEAAsE;YACtE,oEAAoE;YACpE,kEAAkE;YAClE,MAAMF;QACR;IACF;AACF;AAEA,OAAO,SAASG;IACd,MAAMC,cAAcvB;IACpB,MAAMwB,eAAevB,WAAWC;IAEhC,OAAOH,YAAY;QACjBqB,YAAYR;QACZS,WAAW,OAAOI;YAChBD,aAAa,CAACE;gBACZ,IAAIA,SAASC,MAAM,KAAK,iBAAiB,OAAOD;gBAChD,OAAO;oBACL,GAAGA,QAAQ;oBACXE,YAAY,AAACF,CAAAA,SAASE,UAAU,IAAI,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC,YAC3CA,UAAUC,EAAE,KAAKN,UAAUM,EAAE,GACzB;4BAAC,GAAGD,SAAS;4BAAEpB,MAAMe,UAAUf,IAAI;4BAAEC,MAAMc,UAAUd,IAAI;4BAAEgB,QAAQF,UAAUE,MAAM;wBAAA,IACnFG;gBAER;YACF;YACA,MAAMP,YAAYS,iBAAiB,CAAC;gBAACC,UAAUpC;YAAsB;QACvE;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/api/workspace-mapper.ts"],"sourcesContent":["import type {WorkspaceResponseDto} from '@shipfox/api-workspaces-dto';\nimport type {Workspace} from '#core/auth.js';\n\nexport function toWorkspace(dto: WorkspaceResponseDto): Workspace {\n return {id: dto.id, name: dto.name, status: dto.status};\n}\n"],"names":["toWorkspace","dto","id","name","status"],"mappings":"AAGA,OAAO,SAASA,YAAYC,GAAyB;IACnD,OAAO;QAACC,IAAID,IAAIC,EAAE;QAAEC,MAAMF,IAAIE,IAAI;QAAEC,
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/api/workspace-mapper.ts"],"sourcesContent":["import type {WorkspaceResponseDto} from '@shipfox/api-workspaces-dto';\nimport type {Workspace} from '#core/auth.js';\n\nexport function toWorkspace(dto: WorkspaceResponseDto): Workspace {\n return {id: dto.id, name: dto.name, slug: dto.slug, status: dto.status};\n}\n"],"names":["toWorkspace","dto","id","name","slug","status"],"mappings":"AAGA,OAAO,SAASA,YAAYC,GAAyB;IACnD,OAAO;QAACC,IAAID,IAAIC,EAAE;QAAEC,MAAMF,IAAIE,IAAI;QAAEC,MAAMH,IAAIG,IAAI;QAAEC,QAAQJ,IAAII,MAAM;IAAA;AACxE"}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { useConfirmPasswordResetAuth, useRequestPasswordResetAuth, } from './api
|
|
|
4
4
|
export { useRefreshAuth } from './api/refresh-auth.js';
|
|
5
5
|
export { useSignupAuth } from './api/signup-auth.js';
|
|
6
6
|
export { useResendEmailVerificationAuth, useVerifyEmailAuth } from './api/verify-email-auth.js';
|
|
7
|
-
export { useCreateWorkspaceAuth } from './api/workspace-auth.js';
|
|
7
|
+
export { checkWorkspaceSlugAvailability, updateWorkspace, useCreateWorkspaceAuth, useUpdateWorkspaceMutation, } from './api/workspace-auth.js';
|
|
8
8
|
export { useActiveWorkspace, useMaybeActiveWorkspace } from './use-active-workspace.js';
|
|
9
9
|
export type { AuthStateValue } from './use-auth-state.js';
|
|
10
10
|
export { useAuthState } from './use-auth-state.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,8BAA8B,EAAE,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,8BAA8B,EAAE,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9F,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,kBAAkB,EAAE,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AACtF,YAAY,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { useConfirmPasswordResetAuth, useRequestPasswordResetAuth } from './api/
|
|
|
4
4
|
export { useRefreshAuth } from './api/refresh-auth.js';
|
|
5
5
|
export { useSignupAuth } from './api/signup-auth.js';
|
|
6
6
|
export { useResendEmailVerificationAuth, useVerifyEmailAuth } from './api/verify-email-auth.js';
|
|
7
|
-
export { useCreateWorkspaceAuth } from './api/workspace-auth.js';
|
|
7
|
+
export { checkWorkspaceSlugAvailability, updateWorkspace, useCreateWorkspaceAuth, useUpdateWorkspaceMutation } from './api/workspace-auth.js';
|
|
8
8
|
export { useActiveWorkspace, useMaybeActiveWorkspace } from './use-active-workspace.js';
|
|
9
9
|
export { useAuthState } from './use-auth-state.js';
|
|
10
10
|
|
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/index.ts"],"sourcesContent":["export {useLoginAuth} from './api/login-auth.js';\nexport {useLogoutAuth} from './api/logout-auth.js';\nexport {\n useConfirmPasswordResetAuth,\n useRequestPasswordResetAuth,\n} from './api/password-reset-auth.js';\nexport {useRefreshAuth} from './api/refresh-auth.js';\nexport {useSignupAuth} from './api/signup-auth.js';\nexport {useResendEmailVerificationAuth, useVerifyEmailAuth} from './api/verify-email-auth.js';\nexport {useCreateWorkspaceAuth} from './api/workspace-auth.js';\nexport {useActiveWorkspace, useMaybeActiveWorkspace} from './use-active-workspace.js';\nexport type {AuthStateValue} from './use-auth-state.js';\nexport {useAuthState} from './use-auth-state.js';\n"],"names":["useLoginAuth","useLogoutAuth","useConfirmPasswordResetAuth","useRequestPasswordResetAuth","useRefreshAuth","useSignupAuth","useResendEmailVerificationAuth","useVerifyEmailAuth","useCreateWorkspaceAuth","useActiveWorkspace","useMaybeActiveWorkspace","useAuthState"],"mappings":"AAAA,SAAQA,YAAY,QAAO,sBAAsB;AACjD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SACEC,2BAA2B,EAC3BC,2BAA2B,QACtB,+BAA+B;AACtC,SAAQC,cAAc,QAAO,wBAAwB;AACrD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,8BAA8B,EAAEC,kBAAkB,QAAO,6BAA6B;AAC9F,
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/index.ts"],"sourcesContent":["export {useLoginAuth} from './api/login-auth.js';\nexport {useLogoutAuth} from './api/logout-auth.js';\nexport {\n useConfirmPasswordResetAuth,\n useRequestPasswordResetAuth,\n} from './api/password-reset-auth.js';\nexport {useRefreshAuth} from './api/refresh-auth.js';\nexport {useSignupAuth} from './api/signup-auth.js';\nexport {useResendEmailVerificationAuth, useVerifyEmailAuth} from './api/verify-email-auth.js';\nexport {\n checkWorkspaceSlugAvailability,\n updateWorkspace,\n useCreateWorkspaceAuth,\n useUpdateWorkspaceMutation,\n} from './api/workspace-auth.js';\nexport {useActiveWorkspace, useMaybeActiveWorkspace} from './use-active-workspace.js';\nexport type {AuthStateValue} from './use-auth-state.js';\nexport {useAuthState} from './use-auth-state.js';\n"],"names":["useLoginAuth","useLogoutAuth","useConfirmPasswordResetAuth","useRequestPasswordResetAuth","useRefreshAuth","useSignupAuth","useResendEmailVerificationAuth","useVerifyEmailAuth","checkWorkspaceSlugAvailability","updateWorkspace","useCreateWorkspaceAuth","useUpdateWorkspaceMutation","useActiveWorkspace","useMaybeActiveWorkspace","useAuthState"],"mappings":"AAAA,SAAQA,YAAY,QAAO,sBAAsB;AACjD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SACEC,2BAA2B,EAC3BC,2BAA2B,QACtB,+BAA+B;AACtC,SAAQC,cAAc,QAAO,wBAAwB;AACrD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,8BAA8B,EAAEC,kBAAkB,QAAO,6BAA6B;AAC9F,SACEC,8BAA8B,EAC9BC,eAAe,EACfC,sBAAsB,EACtBC,0BAA0B,QACrB,0BAA0B;AACjC,SAAQC,kBAAkB,EAAEC,uBAAuB,QAAO,4BAA4B;AAEtF,SAAQC,YAAY,QAAO,sBAAsB"}
|
|
@@ -14,6 +14,6 @@ export declare function loginErrorToFormError(error: unknown): FormErrorMapping<
|
|
|
14
14
|
export declare function signupErrorToFormError(error: unknown): FormErrorMapping<SignupField>;
|
|
15
15
|
export declare function passwordResetRequestErrorToFormError(error: unknown): FormErrorMapping<PasswordResetRequestField>;
|
|
16
16
|
export declare function passwordResetConfirmErrorToFormError(error: unknown): FormErrorMapping<PasswordResetConfirmField>;
|
|
17
|
-
export declare function workspaceOnboardingErrorToFormError(error: unknown): FormErrorMapping<'name'>;
|
|
17
|
+
export declare function workspaceOnboardingErrorToFormError(error: unknown): FormErrorMapping<'name' | 'slug'>;
|
|
18
18
|
export {};
|
|
19
19
|
//# sourceMappingURL=form-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-errors.d.ts","sourceRoot":"","sources":["../../src/pages/form-errors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,MAAM,IAC9C;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAC/C;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEpC,KAAK,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AACvC,KAAK,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AACjD,KAAK,yBAAyB,GAAG,OAAO,CAAC;AACzC,KAAK,yBAAyB,GAAG,cAAc,CAAC;AAMhD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAKlF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAKpF;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,GACb,gBAAgB,CAAC,yBAAyB,CAAC,CAE7C;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,GACb,gBAAgB,CAAC,yBAAyB,CAAC,CAE7C;AAED,wBAAgB,mCAAmC,
|
|
1
|
+
{"version":3,"file":"form-errors.d.ts","sourceRoot":"","sources":["../../src/pages/form-errors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,MAAM,IAC9C;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAC/C;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEpC,KAAK,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AACvC,KAAK,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AACjD,KAAK,yBAAyB,GAAG,OAAO,CAAC;AACzC,KAAK,yBAAyB,GAAG,cAAc,CAAC;AAMhD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAKlF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAKpF;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,GACb,gBAAgB,CAAC,yBAAyB,CAAC,CAE7C;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,GACb,gBAAgB,CAAC,yBAAyB,CAAC,CAE7C;AAED,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,GACb,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,CAKnC"}
|
|
@@ -42,6 +42,13 @@ export function passwordResetConfirmErrorToFormError(error) {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
export function workspaceOnboardingErrorToFormError(error) {
|
|
45
|
+
if (apiCode(error) === 'slug-conflict') {
|
|
46
|
+
return {
|
|
47
|
+
kind: 'field',
|
|
48
|
+
field: 'slug',
|
|
49
|
+
message: 'That workspace slug is already taken.'
|
|
50
|
+
};
|
|
51
|
+
}
|
|
45
52
|
return {
|
|
46
53
|
kind: 'form',
|
|
47
54
|
message: authErrorMessage(error)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pages/form-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {authErrorMessage} from './form-utils.js';\n\nexport type FormErrorMapping<TField extends string> =\n | {kind: 'field'; field: TField; message: string}\n | {kind: 'form'; message: string};\n\ntype LoginField = 'email' | 'password';\ntype SignupField = 'email' | 'password' | 'name';\ntype PasswordResetRequestField = 'email';\ntype PasswordResetConfirmField = 'new_password';\n\nfunction apiCode(error: unknown): string | undefined {\n return error instanceof ApiError ? error.code : undefined;\n}\n\nexport function loginErrorToFormError(error: unknown): FormErrorMapping<LoginField> {\n if (apiCode(error) === 'email-not-verified') {\n return {kind: 'field', field: 'email', message: authErrorMessage(error)};\n }\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function signupErrorToFormError(error: unknown): FormErrorMapping<SignupField> {\n if (apiCode(error) === 'email-taken') {\n return {kind: 'field', field: 'email', message: authErrorMessage(error)};\n }\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function passwordResetRequestErrorToFormError(\n error: unknown,\n): FormErrorMapping<PasswordResetRequestField> {\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function passwordResetConfirmErrorToFormError(\n error: unknown,\n): FormErrorMapping<PasswordResetConfirmField> {\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function workspaceOnboardingErrorToFormError(error: unknown): FormErrorMapping<'name'> {\n return {kind: 'form', message: authErrorMessage(error)};\n}\n"],"names":["ApiError","authErrorMessage","apiCode","error","code","undefined","loginErrorToFormError","kind","field","message","signupErrorToFormError","passwordResetRequestErrorToFormError","passwordResetConfirmErrorToFormError","workspaceOnboardingErrorToFormError"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAC7C,SAAQC,gBAAgB,QAAO,kBAAkB;AAWjD,SAASC,QAAQC,KAAc;IAC7B,OAAOA,iBAAiBH,WAAWG,MAAMC,IAAI,GAAGC;AAClD;AAEA,OAAO,SAASC,sBAAsBH,KAAc;IAClD,IAAID,QAAQC,WAAW,sBAAsB;QAC3C,OAAO;YAACI,MAAM;YAASC,OAAO;YAASC,SAASR,iBAAiBE;QAAM;IACzE;IACA,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASO,uBAAuBP,KAAc;IACnD,IAAID,QAAQC,WAAW,eAAe;QACpC,OAAO;YAACI,MAAM;YAASC,OAAO;YAASC,SAASR,iBAAiBE;QAAM;IACzE;IACA,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASQ,qCACdR,KAAc;IAEd,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASS,qCACdT,KAAc;IAEd,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASU,
|
|
1
|
+
{"version":3,"sources":["../../src/pages/form-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {authErrorMessage} from './form-utils.js';\n\nexport type FormErrorMapping<TField extends string> =\n | {kind: 'field'; field: TField; message: string}\n | {kind: 'form'; message: string};\n\ntype LoginField = 'email' | 'password';\ntype SignupField = 'email' | 'password' | 'name';\ntype PasswordResetRequestField = 'email';\ntype PasswordResetConfirmField = 'new_password';\n\nfunction apiCode(error: unknown): string | undefined {\n return error instanceof ApiError ? error.code : undefined;\n}\n\nexport function loginErrorToFormError(error: unknown): FormErrorMapping<LoginField> {\n if (apiCode(error) === 'email-not-verified') {\n return {kind: 'field', field: 'email', message: authErrorMessage(error)};\n }\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function signupErrorToFormError(error: unknown): FormErrorMapping<SignupField> {\n if (apiCode(error) === 'email-taken') {\n return {kind: 'field', field: 'email', message: authErrorMessage(error)};\n }\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function passwordResetRequestErrorToFormError(\n error: unknown,\n): FormErrorMapping<PasswordResetRequestField> {\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function passwordResetConfirmErrorToFormError(\n error: unknown,\n): FormErrorMapping<PasswordResetConfirmField> {\n return {kind: 'form', message: authErrorMessage(error)};\n}\n\nexport function workspaceOnboardingErrorToFormError(\n error: unknown,\n): FormErrorMapping<'name' | 'slug'> {\n if (apiCode(error) === 'slug-conflict') {\n return {kind: 'field', field: 'slug', message: 'That workspace slug is already taken.'};\n }\n return {kind: 'form', message: authErrorMessage(error)};\n}\n"],"names":["ApiError","authErrorMessage","apiCode","error","code","undefined","loginErrorToFormError","kind","field","message","signupErrorToFormError","passwordResetRequestErrorToFormError","passwordResetConfirmErrorToFormError","workspaceOnboardingErrorToFormError"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAC7C,SAAQC,gBAAgB,QAAO,kBAAkB;AAWjD,SAASC,QAAQC,KAAc;IAC7B,OAAOA,iBAAiBH,WAAWG,MAAMC,IAAI,GAAGC;AAClD;AAEA,OAAO,SAASC,sBAAsBH,KAAc;IAClD,IAAID,QAAQC,WAAW,sBAAsB;QAC3C,OAAO;YAACI,MAAM;YAASC,OAAO;YAASC,SAASR,iBAAiBE;QAAM;IACzE;IACA,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASO,uBAAuBP,KAAc;IACnD,IAAID,QAAQC,WAAW,eAAe;QACpC,OAAO;YAACI,MAAM;YAASC,OAAO;YAASC,SAASR,iBAAiBE;QAAM;IACzE;IACA,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASQ,qCACdR,KAAc;IAEd,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASS,qCACdT,KAAc;IAEd,OAAO;QAACI,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD;AAEA,OAAO,SAASU,oCACdV,KAAc;IAEd,IAAID,QAAQC,WAAW,iBAAiB;QACtC,OAAO;YAACI,MAAM;YAASC,OAAO;YAAQC,SAAS;QAAuC;IACxF;IACA,OAAO;QAACF,MAAM;QAAQE,SAASR,iBAAiBE;IAAM;AACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signup-page.d.ts","sourceRoot":"","sources":["../../src/pages/signup-page.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"signup-page.d.ts","sourceRoot":"","sources":["../../src/pages/signup-page.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,UAAU,gCAyWzB"}
|