@tailor-platform/app-shell 0.18.0 → 0.20.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/dist/app-shell.css +1 -1
- package/dist/app-shell.js +560 -415
- package/dist/index.d.ts +144 -75
- package/package.json +13 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { AuthState } from '@tailor-platform/auth-browser-client';
|
|
2
|
+
import { DocumentNode } from 'graphql';
|
|
1
3
|
import { JSX } from 'react/jsx-runtime';
|
|
2
4
|
import { Link } from 'react-router';
|
|
3
|
-
import { PropsWithChildren } from 'react';
|
|
4
5
|
import { ReactNode } from 'react';
|
|
5
6
|
import { useLocation } from 'react-router';
|
|
6
7
|
import { useNavigate } from 'react-router';
|
|
@@ -89,32 +90,129 @@ export declare type AppShellProps = React.PropsWithChildren<{
|
|
|
89
90
|
errorBoundary?: ErrorBoundaryComponent;
|
|
90
91
|
}>;
|
|
91
92
|
|
|
93
|
+
declare type AuthContextType = {
|
|
94
|
+
/**
|
|
95
|
+
* Current authentication state.
|
|
96
|
+
*/
|
|
97
|
+
authState: AuthState<User>;
|
|
98
|
+
/**
|
|
99
|
+
* Initiates the login process.
|
|
100
|
+
*
|
|
101
|
+
* This redirects the user to the Tailor Platform authentication page.
|
|
102
|
+
*/
|
|
103
|
+
login: () => Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Logs out the current user.
|
|
106
|
+
*
|
|
107
|
+
* This clears the authentication tokens and user session.
|
|
108
|
+
*/
|
|
109
|
+
logout: () => Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Checks the current authentication status.
|
|
112
|
+
*
|
|
113
|
+
* Remember that this method always makes a network request to verify the auth status.
|
|
114
|
+
* If the user is authenticated, returns the user information and updates `authState` in the context.
|
|
115
|
+
*
|
|
116
|
+
* This also attempts to refresh tokens internally if they are expired.
|
|
117
|
+
*/
|
|
118
|
+
checkAuthStatus: () => Promise<AuthState<User>>;
|
|
119
|
+
/**
|
|
120
|
+
* OAuth callback handler.
|
|
121
|
+
*/
|
|
122
|
+
handleCallback: () => Promise<void>;
|
|
123
|
+
};
|
|
124
|
+
|
|
92
125
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
126
|
+
* Authentication provider component.
|
|
127
|
+
*
|
|
128
|
+
* Wrap your application with this component to provide authentication context.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```tsx
|
|
132
|
+
* import { AuthProvider } from "@tailor-platform/app-shell";
|
|
133
|
+
*
|
|
134
|
+
* function App() {
|
|
135
|
+
* return (
|
|
136
|
+
* <AuthProvider
|
|
137
|
+
* apiEndpoint="https://xyz.erp.dev"
|
|
138
|
+
* clientId="your-client-id"
|
|
139
|
+
* >
|
|
140
|
+
* <YourAppComponents />
|
|
141
|
+
* </AuthProvider>
|
|
142
|
+
* );
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
95
145
|
*/
|
|
96
|
-
export declare const
|
|
146
|
+
export declare const AuthProvider: (props: React.PropsWithChildren<AuthProviderProps>) => JSX.Element;
|
|
97
147
|
|
|
98
|
-
declare
|
|
148
|
+
declare type AuthProviderProps = {
|
|
149
|
+
/**
|
|
150
|
+
* API endpoint of your Tailor Platform application. No `/query` suffix needed.
|
|
151
|
+
*
|
|
152
|
+
* @example https://xyz.erp.dev
|
|
153
|
+
*/
|
|
99
154
|
apiEndpoint: string;
|
|
155
|
+
/**
|
|
156
|
+
* OAuth2 Client ID of your Tailor Platform application.
|
|
157
|
+
*/
|
|
100
158
|
clientId: string;
|
|
101
|
-
|
|
102
|
-
|
|
159
|
+
/**
|
|
160
|
+
* GraphQL query to fetch the current authenticated user.
|
|
161
|
+
*
|
|
162
|
+
* The result of this query should return the user object.
|
|
163
|
+
* If you override `AuthRegister["user"]`, make sure to have the fields match your custom user type.
|
|
164
|
+
*
|
|
165
|
+
* @defaults
|
|
166
|
+
* ```graphql
|
|
167
|
+
* query {
|
|
168
|
+
* me {
|
|
169
|
+
* id
|
|
170
|
+
* email
|
|
171
|
+
* name
|
|
172
|
+
* }
|
|
173
|
+
* }
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
meQuery?: string | DocumentNode;
|
|
177
|
+
/**
|
|
178
|
+
* Redirect URI after login is successful.
|
|
179
|
+
*
|
|
180
|
+
* @defaults `window.location.origin`
|
|
181
|
+
*/
|
|
103
182
|
redirectUri?: string;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
declare interface BuiltinIdPAuthContextType {
|
|
107
183
|
/**
|
|
108
|
-
*
|
|
184
|
+
* Enable automatic login on initialization.
|
|
109
185
|
*/
|
|
110
|
-
|
|
186
|
+
autoLogin?: boolean;
|
|
111
187
|
/**
|
|
112
|
-
*
|
|
188
|
+
* Guard UI component to show when loading or unauthenticated.
|
|
189
|
+
*
|
|
190
|
+
* If not provided, children will be just rendered in any auth state.
|
|
113
191
|
*/
|
|
114
|
-
|
|
192
|
+
guardComponent?: () => React.ReactNode;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Registerable interface for type extension via module augmentation.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* // In your project's TypeScript file (e.g., app-shell.d.ts, App.tsx, etc.)
|
|
200
|
+
* declare module "@tailor-platform/app-shell" {
|
|
201
|
+
* interface AuthRegister {
|
|
202
|
+
* user: {
|
|
203
|
+
* id: string;
|
|
204
|
+
* email: string;
|
|
205
|
+
* name?: string;
|
|
206
|
+
* role: "admin" | "user";
|
|
207
|
+
* organizationId: string;
|
|
208
|
+
* }
|
|
209
|
+
* }
|
|
210
|
+
* }
|
|
211
|
+
*/
|
|
212
|
+
export declare interface AuthRegister {
|
|
115
213
|
}
|
|
116
214
|
|
|
117
|
-
export declare
|
|
215
|
+
export declare function CommandPalette(): JSX.Element;
|
|
118
216
|
|
|
119
217
|
declare type CommonModuleProps = {
|
|
120
218
|
/**
|
|
@@ -157,6 +255,26 @@ declare type DefaultSidebarProps = {
|
|
|
157
255
|
footer?: React.ReactNode;
|
|
158
256
|
};
|
|
159
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Default user type when no custom user type is registered.
|
|
260
|
+
*
|
|
261
|
+
* You can extend this type via module augmentation:
|
|
262
|
+
* @example
|
|
263
|
+
* declare module "@tailor-platform/app-shell" {
|
|
264
|
+
* interface Register {
|
|
265
|
+
* user: DefaultUser & {
|
|
266
|
+
* role: "admin" | "user";
|
|
267
|
+
* organizationId: string;
|
|
268
|
+
* }
|
|
269
|
+
* }
|
|
270
|
+
* }
|
|
271
|
+
*/
|
|
272
|
+
export declare type DefaultUser = {
|
|
273
|
+
id: string;
|
|
274
|
+
email: string;
|
|
275
|
+
name?: string;
|
|
276
|
+
};
|
|
277
|
+
|
|
160
278
|
/**
|
|
161
279
|
* Defines internationalization labels for multiple locales.
|
|
162
280
|
*
|
|
@@ -353,33 +471,6 @@ declare type DynamicLocales<Def extends Record<string, LabelValue>> = {
|
|
|
353
471
|
*/
|
|
354
472
|
export declare type ErrorBoundaryComponent = ReactNode;
|
|
355
473
|
|
|
356
|
-
/**
|
|
357
|
-
* We need to exchange the code and state we received from the OAuth endpoint
|
|
358
|
-
* for an actual authorization token, in Browser Client case, we get the token
|
|
359
|
-
* inside of a cookie so there is nothing else to do beyond that point
|
|
360
|
-
*/
|
|
361
|
-
export declare const exchangeCodeForToken: ({ code, returnedState, apiEndpoint, clientId, redirectUri, }: ExchangeCodeForTokenParams) => Promise<string>;
|
|
362
|
-
|
|
363
|
-
declare interface ExchangeCodeForTokenParams {
|
|
364
|
-
apiEndpoint: string;
|
|
365
|
-
clientId: string;
|
|
366
|
-
returnedState: string | null;
|
|
367
|
-
code: string | null;
|
|
368
|
-
redirectUri?: string;
|
|
369
|
-
silent?: boolean;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* When redirected from our IdP Provider, we need to exchange code and state
|
|
374
|
-
* for a token and clean up the URL params
|
|
375
|
-
*/
|
|
376
|
-
export declare const handleOAuthCallback: ({ currentUrl, apiEndpoint, clientId, redirectUri, }: {
|
|
377
|
-
currentUrl: URL;
|
|
378
|
-
apiEndpoint: string;
|
|
379
|
-
clientId: string;
|
|
380
|
-
redirectUri: string;
|
|
381
|
-
}) => Promise<void>;
|
|
382
|
-
|
|
383
474
|
export declare type I18nLabels<Def extends Record<string, LabelValue> = Record<string, LabelValue>, L extends string = never> = {
|
|
384
475
|
en: Def;
|
|
385
476
|
} & {
|
|
@@ -432,38 +523,6 @@ declare type NavItem = {
|
|
|
432
523
|
items?: Array<NavChildItem>;
|
|
433
524
|
};
|
|
434
525
|
|
|
435
|
-
export declare const OAUTH_STATE_KEY = "oauth_state";
|
|
436
|
-
|
|
437
|
-
export declare const PKCE_VERIFIER_KEY = "oauth_pkce_verifier";
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* We need to generate a challenge and state key for OAuth login
|
|
441
|
-
* and stores them in sessionStorage for verification on callback redirect
|
|
442
|
-
*/
|
|
443
|
-
export declare const prepareLogin: () => Promise<{
|
|
444
|
-
codeChallenge: string;
|
|
445
|
-
state: string;
|
|
446
|
-
}>;
|
|
447
|
-
|
|
448
|
-
declare type Props = {
|
|
449
|
-
/**
|
|
450
|
-
* API endpoint of your Tailor Platform application. No `/query` suffix needed.
|
|
451
|
-
*
|
|
452
|
-
* @example https://xyz.erp.dev
|
|
453
|
-
*/
|
|
454
|
-
apiEndpoint: string;
|
|
455
|
-
/**
|
|
456
|
-
* OAuth2 Client ID of your Tailor Platform application.
|
|
457
|
-
*/
|
|
458
|
-
clientId: string;
|
|
459
|
-
/**
|
|
460
|
-
* Redirect URI after login is successful.
|
|
461
|
-
*
|
|
462
|
-
* @defaults `window.location.origin`
|
|
463
|
-
*/
|
|
464
|
-
redirectUri?: string;
|
|
465
|
-
};
|
|
466
|
-
|
|
467
526
|
declare type ReactResourceProps = {
|
|
468
527
|
/**
|
|
469
528
|
* React component to render.
|
|
@@ -555,7 +614,7 @@ declare type ThemeProviderState = {
|
|
|
555
614
|
|
|
556
615
|
export declare const useAppShell: () => AppShellContextType;
|
|
557
616
|
|
|
558
|
-
export declare const
|
|
617
|
+
export declare const useAuth: () => AuthContextType;
|
|
559
618
|
|
|
560
619
|
export { useLocation }
|
|
561
620
|
|
|
@@ -563,6 +622,16 @@ export { useNavigate }
|
|
|
563
622
|
|
|
564
623
|
export { useParams }
|
|
565
624
|
|
|
625
|
+
/**
|
|
626
|
+
* User type that can be extended via the AuthRegister interface.
|
|
627
|
+
*
|
|
628
|
+
* If `AuthRegister["user"]` is defined, it will be used as the User type.
|
|
629
|
+
* Otherwise, the DefaultUser type will be used.
|
|
630
|
+
*/
|
|
631
|
+
declare type User = AuthRegister extends {
|
|
632
|
+
user: infer TUser;
|
|
633
|
+
} ? TUser : DefaultUser;
|
|
634
|
+
|
|
566
635
|
export { useRouteError }
|
|
567
636
|
|
|
568
637
|
export { useSearchParams }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/app-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./styles": "./dist/app-shell.css",
|
|
@@ -22,41 +22,40 @@
|
|
|
22
22
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
23
23
|
"@radix-ui/react-collapsible": "^1.1.3",
|
|
24
24
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
25
|
-
"@radix-ui/react-dropdown-menu": "^2.1.
|
|
25
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
26
26
|
"@radix-ui/react-label": "^2.1.8",
|
|
27
27
|
"@radix-ui/react-navigation-menu": "^1.2.5",
|
|
28
|
-
"@radix-ui/react-popover": "^1.1.
|
|
28
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
29
29
|
"@radix-ui/react-select": "^2.1.6",
|
|
30
30
|
"@radix-ui/react-separator": "^1.1.8",
|
|
31
|
-
"@radix-ui/react-slot": "^1.
|
|
32
|
-
"@radix-ui/react-tooltip": "^1.
|
|
31
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
32
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
33
|
+
"@tailor-platform/auth-browser-client": "^0.3.0",
|
|
33
34
|
"@tanstack/react-table": "^8.21.2",
|
|
34
|
-
"@urql/core": "^6.0.0",
|
|
35
|
-
"@urql/exchange-auth": "^3.0.0",
|
|
36
35
|
"change-case": "^5.4.4",
|
|
37
36
|
"class-variance-authority": "^0.7.1",
|
|
38
37
|
"clsx": "^2.1.1",
|
|
39
38
|
"es-toolkit": "^1.41.0",
|
|
40
|
-
"
|
|
39
|
+
"graphql": "^16.12.0",
|
|
40
|
+
"lucide-react": "^0.562.0",
|
|
41
41
|
"next-themes": "^0.4.6",
|
|
42
|
-
"oauth4webapi": "^3.8.
|
|
42
|
+
"oauth4webapi": "^3.8.3",
|
|
43
43
|
"react": "^19.2.1",
|
|
44
44
|
"react-dom": "^19.2.1",
|
|
45
45
|
"react-hook-form": "^7.54.2",
|
|
46
46
|
"react-router": "^7.4.0",
|
|
47
47
|
"sonner": "^2.0.7",
|
|
48
|
-
"tailwind-merge": "^3.4.0"
|
|
49
|
-
"urql": "^5.0.1"
|
|
48
|
+
"tailwind-merge": "^3.4.0"
|
|
50
49
|
},
|
|
51
50
|
"devDependencies": {
|
|
52
51
|
"@tailwindcss/postcss": "^4.1.2",
|
|
53
52
|
"@testing-library/react": "^16.3.0",
|
|
53
|
+
"@testing-library/user-event": "^14.6.1",
|
|
54
54
|
"@types/node": "^22",
|
|
55
55
|
"@types/react": "^19",
|
|
56
56
|
"@types/react-dom": "^19",
|
|
57
|
-
"happy-dom": "^20.0.11",
|
|
58
57
|
"@vitejs/plugin-react": "^5.1.1",
|
|
59
|
-
"
|
|
58
|
+
"happy-dom": "^20.0.11",
|
|
60
59
|
"postcss": "^8",
|
|
61
60
|
"prettier": "^3.6.2",
|
|
62
61
|
"tailwindcss": "^4.1.3",
|
|
@@ -66,7 +65,7 @@
|
|
|
66
65
|
"vite-plugin-dts": "^4.5.0",
|
|
67
66
|
"vite-plugin-externalize-deps": "^0.10.0",
|
|
68
67
|
"vite-tsconfig-paths": "^5.1.4",
|
|
69
|
-
"vitest": "^4.0.
|
|
68
|
+
"vitest": "^4.0.16"
|
|
70
69
|
},
|
|
71
70
|
"scripts": {
|
|
72
71
|
"dev": "vite build --watch --mode development",
|