@txstate-mws/sveltekit-utils 1.0.1 → 1.0.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/dist/api.d.ts +38 -10
- package/dist/api.js +56 -13
- package/dist/api.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InteractionEvent } from '@txstate-mws/fastify-shared';
|
|
1
|
+
import type { InteractionEvent, ValidatedResponse } from '@txstate-mws/fastify-shared';
|
|
2
2
|
export type APIBaseQueryPayload = string | Record<string, undefined | string | number | (string | number)[]>;
|
|
3
3
|
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
4
4
|
/**
|
|
@@ -11,26 +11,54 @@ type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
|
11
11
|
export declare function recordNavigations(callback: (evt: InteractionEvent) => void): void;
|
|
12
12
|
export declare class APIBase {
|
|
13
13
|
protected apiBase: string;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
authRedirect: string;
|
|
15
|
+
token?: string;
|
|
16
16
|
fetch: (info: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
17
17
|
protected ready: () => void;
|
|
18
18
|
protected readyPromise: Promise<void>;
|
|
19
19
|
constructor(apiBase: string, authRedirect: string);
|
|
20
20
|
init(token: string | undefined, fetch?: (info: RequestInfo, init?: RequestInit) => Promise<Response>): Promise<void>;
|
|
21
21
|
stringifyQuery(query: undefined | APIBaseQueryPayload): string;
|
|
22
|
-
protected request<ReturnType = any>(path: string, method: string,
|
|
22
|
+
protected request<ReturnType = any>(path: string, method: string, opts?: {
|
|
23
23
|
body?: any;
|
|
24
24
|
query?: APIBaseQueryPayload;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
inlineValidation?: boolean;
|
|
26
|
+
}): Promise<ReturnType>;
|
|
27
|
+
get<ReturnType = any>(path: string, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
28
|
+
/**
|
|
29
|
+
* Remember to use validatedPost when the user is interacting with a form. That way they
|
|
30
|
+
* will get inline errors.
|
|
31
|
+
*/
|
|
32
|
+
post<ReturnType = any>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
33
|
+
/**
|
|
34
|
+
* Remember to use validatedPut when the user is interacting with a form. That way they
|
|
35
|
+
* will get inline errors.
|
|
36
|
+
*/
|
|
37
|
+
put<ReturnType = any>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
38
|
+
/**
|
|
39
|
+
* Remember to use validatedPatch when the user is interacting with a form. That way they
|
|
40
|
+
* will get inline errors.
|
|
41
|
+
*/
|
|
42
|
+
patch<ReturnType = any>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
43
|
+
/**
|
|
44
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
45
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
46
|
+
*/
|
|
47
|
+
validatedPost<ReturnType extends ValidatedResponse = ValidatedResponse>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
48
|
+
/**
|
|
49
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
50
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
51
|
+
*/
|
|
52
|
+
validatedPut<ReturnType extends ValidatedResponse = ValidatedResponse>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
53
|
+
/**
|
|
54
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
55
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
56
|
+
*/
|
|
57
|
+
validatedPatch<ReturnType extends ValidatedResponse = ValidatedResponse>(path: string, body?: any, query?: APIBaseQueryPayload): Promise<ReturnType>;
|
|
30
58
|
/**
|
|
31
59
|
* Sending a JSON body with an HTTP DELETE is not recommended
|
|
32
60
|
*/
|
|
33
|
-
delete<ReturnType = any>(path: string, query?: APIBaseQueryPayload, body?: any): Promise<
|
|
61
|
+
delete<ReturnType = any>(path: string, query?: APIBaseQueryPayload, body?: any): Promise<ReturnType>;
|
|
34
62
|
graphql<ReturnType = any>(query: string, variables?: any, querySignature?: string): Promise<ReturnType>;
|
|
35
63
|
protected analyticsQueue: InteractionEvent[];
|
|
36
64
|
recordInteraction(evt: Optional<InteractionEvent, 'screen'>): void;
|
package/dist/api.js
CHANGED
|
@@ -12,8 +12,17 @@ import { afterNavigate } from '$app/navigation';
|
|
|
12
12
|
* Must be called from a svelte component. Should usually be your root +layout.svelte.
|
|
13
13
|
*/
|
|
14
14
|
export function recordNavigations(callback) {
|
|
15
|
+
let timer = 0;
|
|
16
|
+
let from;
|
|
15
17
|
afterNavigate(navigation => {
|
|
16
|
-
|
|
18
|
+
// save off the navigation.from in case we're debouncing a redirect
|
|
19
|
+
if (timer === 0)
|
|
20
|
+
from = navigation.from;
|
|
21
|
+
clearTimeout(timer); // we are debouncing because sometimes afterNavigate gets called twice
|
|
22
|
+
timer = setTimeout(() => {
|
|
23
|
+
callback({ eventType: 'sveltekit-utils-navigation', screen: (from ?? navigation.to)?.route.id, target: navigation.to?.url.pathname, action: 'navigation', additionalProperties: { fullPageLoad: String(!from) } });
|
|
24
|
+
timer = 0;
|
|
25
|
+
}, 10);
|
|
17
26
|
});
|
|
18
27
|
}
|
|
19
28
|
export class APIBase {
|
|
@@ -29,13 +38,13 @@ export class APIBase {
|
|
|
29
38
|
this.readyPromise = new Promise(resolve => { this.ready = resolve; });
|
|
30
39
|
}
|
|
31
40
|
async init(token, fetch) {
|
|
32
|
-
this.token = token;
|
|
33
41
|
this.fetch = fetch ?? this.fetch;
|
|
34
|
-
if (
|
|
35
|
-
|
|
42
|
+
if (token) {
|
|
43
|
+
this.token = token;
|
|
44
|
+
sessionStorage.setItem('token', token);
|
|
36
45
|
}
|
|
37
46
|
else {
|
|
38
|
-
this.token
|
|
47
|
+
this.token ??= sessionStorage.getItem('token') ?? undefined;
|
|
39
48
|
}
|
|
40
49
|
this.ready();
|
|
41
50
|
}
|
|
@@ -51,19 +60,21 @@ export class APIBase {
|
|
|
51
60
|
}
|
|
52
61
|
return '?' + p.toString();
|
|
53
62
|
}
|
|
54
|
-
async request(path, method,
|
|
63
|
+
async request(path, method, opts) {
|
|
55
64
|
await this.readyPromise;
|
|
56
65
|
try {
|
|
57
|
-
const resp = await this.fetch(this.apiBase + path + this.stringifyQuery(
|
|
66
|
+
const resp = await this.fetch(this.apiBase + path + this.stringifyQuery(opts?.query), {
|
|
58
67
|
method,
|
|
59
68
|
headers: {
|
|
60
69
|
Authorization: `Bearer ${this.token ?? ''}`,
|
|
61
70
|
Accept: 'application/json',
|
|
62
|
-
...(
|
|
71
|
+
...(opts?.body ? { 'Content-Type': 'application/json' } : {})
|
|
63
72
|
},
|
|
64
|
-
body:
|
|
73
|
+
body: opts?.body ? JSON.stringify(opts.body) : undefined
|
|
65
74
|
});
|
|
66
|
-
|
|
75
|
+
const contentType = resp.headers.get("content-type");
|
|
76
|
+
const isJsonResponse = contentType && contentType.indexOf("application/json") !== -1;
|
|
77
|
+
if (!resp.ok && !(resp.status === 422 && opts?.inlineValidation)) {
|
|
67
78
|
if (resp.status === 401) {
|
|
68
79
|
const loginRedirect = new URL(this.authRedirect);
|
|
69
80
|
loginRedirect.searchParams.set('requestedUrl', location.href);
|
|
@@ -71,13 +82,12 @@ export class APIBase {
|
|
|
71
82
|
throw error(401);
|
|
72
83
|
}
|
|
73
84
|
else {
|
|
74
|
-
const message = ((await rescue(resp.json()))?.message ?? resp.statusText);
|
|
85
|
+
const message = ((isJsonResponse ? (await rescue(resp.json()))?.message : await rescue(resp.text())) ?? resp.statusText);
|
|
75
86
|
toasts.add(message);
|
|
76
87
|
throw error(resp.status, message);
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
|
-
|
|
80
|
-
return (contentType && contentType.indexOf("application/json") !== -1) ? await resp.json() : await resp.text();
|
|
90
|
+
return ((isJsonResponse) ? await resp.json() : await resp.text());
|
|
81
91
|
}
|
|
82
92
|
catch (e) {
|
|
83
93
|
toasts.add(e.message);
|
|
@@ -87,15 +97,48 @@ export class APIBase {
|
|
|
87
97
|
async get(path, query) {
|
|
88
98
|
return await this.request(path, 'GET', { query });
|
|
89
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Remember to use validatedPost when the user is interacting with a form. That way they
|
|
102
|
+
* will get inline errors.
|
|
103
|
+
*/
|
|
90
104
|
async post(path, body, query) {
|
|
91
105
|
return await this.request(path, 'POST', { body, query });
|
|
92
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Remember to use validatedPut when the user is interacting with a form. That way they
|
|
109
|
+
* will get inline errors.
|
|
110
|
+
*/
|
|
93
111
|
async put(path, body, query) {
|
|
94
112
|
return await this.request(path, 'PUT', { body, query });
|
|
95
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Remember to use validatedPatch when the user is interacting with a form. That way they
|
|
116
|
+
* will get inline errors.
|
|
117
|
+
*/
|
|
96
118
|
async patch(path, body, query) {
|
|
97
119
|
return await this.request(path, 'PATCH', { body, query });
|
|
98
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
123
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
124
|
+
*/
|
|
125
|
+
async validatedPost(path, body, query) {
|
|
126
|
+
return await this.request(path, 'POST', { body, query, inlineValidation: true });
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
130
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
131
|
+
*/
|
|
132
|
+
async validatedPut(path, body, query) {
|
|
133
|
+
return await this.request(path, 'PUT', { body, query, inlineValidation: true });
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Use this method when the user is interacting with a form. You should expect a ValidatedResponse,
|
|
137
|
+
* e.g. { success: false, messages: [{ type: 'error', message: 'That name is already taken.', path: 'name' }] }
|
|
138
|
+
*/
|
|
139
|
+
async validatedPatch(path, body, query) {
|
|
140
|
+
return await this.request(path, 'PATCH', { body, query, inlineValidation: true });
|
|
141
|
+
}
|
|
99
142
|
/**
|
|
100
143
|
* Sending a JSON body with an HTTP DELETE is not recommended
|
|
101
144
|
*/
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
+
import { LoadEvent } from '@sveltejs/kit';
|
|
2
|
+
import { APIBase } from './api.js';
|
|
1
3
|
export * from './api.js';
|
|
4
|
+
interface HandleOpts {
|
|
5
|
+
/**
|
|
6
|
+
* handleUnifiedAuth redirects users to unified auth by default if they don't have
|
|
7
|
+
* a token yet. If your UI is at least partially available to the public, set
|
|
8
|
+
* allowUnauthenticated to true.
|
|
9
|
+
*/
|
|
10
|
+
allowUnauthenticated?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Your root +layout.ts' load function should call this method to ensure that it
|
|
14
|
+
* handles authentication from Unified Auth. By default it will redirect unauthenticated
|
|
15
|
+
* users to Unified Auth without a screen flash.
|
|
16
|
+
*
|
|
17
|
+
* If you set allowUnauthenticated: true and wait for the API to send a 401, there
|
|
18
|
+
* will often be a screen flash.
|
|
19
|
+
*/
|
|
20
|
+
export declare function handleUnifiedAuth(api: APIBase, input: LoadEvent, opts?: HandleOpts): Promise<void>;
|
|
21
|
+
export declare function requireAuthentication(api: APIBase, input: LoadEvent): void;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,33 @@
|
|
|
1
|
+
import { redirect } from '@sveltejs/kit';
|
|
1
2
|
export * from './api.js';
|
|
3
|
+
/**
|
|
4
|
+
* Your root +layout.ts' load function should call this method to ensure that it
|
|
5
|
+
* handles authentication from Unified Auth. By default it will redirect unauthenticated
|
|
6
|
+
* users to Unified Auth without a screen flash.
|
|
7
|
+
*
|
|
8
|
+
* If you set allowUnauthenticated: true and wait for the API to send a 401, there
|
|
9
|
+
* will often be a screen flash.
|
|
10
|
+
*/
|
|
11
|
+
export async function handleUnifiedAuth(api, input, opts) {
|
|
12
|
+
const unifiedJwt = input.url.searchParams.get('unifiedJwt') ?? undefined;
|
|
13
|
+
await api.init(unifiedJwt);
|
|
14
|
+
if (unifiedJwt) {
|
|
15
|
+
let redirectUrl = input.url.searchParams.get('requestedUrl') ?? undefined;
|
|
16
|
+
if (!redirectUrl) {
|
|
17
|
+
const currentUrl = new URL(input.url);
|
|
18
|
+
currentUrl.searchParams.delete('unifiedJwt');
|
|
19
|
+
redirectUrl = currentUrl.toString();
|
|
20
|
+
}
|
|
21
|
+
throw redirect(302, redirectUrl);
|
|
22
|
+
}
|
|
23
|
+
if (!opts?.allowUnauthenticated)
|
|
24
|
+
requireAuthentication(api, input);
|
|
25
|
+
}
|
|
26
|
+
export function requireAuthentication(api, input) {
|
|
27
|
+
if (!api.token) {
|
|
28
|
+
const loginRedirect = new URL(api.authRedirect);
|
|
29
|
+
loginRedirect.searchParams.set('requestedUrl', input.url.toString());
|
|
30
|
+
throw redirect(302, loginRedirect);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
2
33
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGpD,cAAc,UAAU,CAAA;AAWxB;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAE,GAAY,EAAE,KAAgB,EAAE,IAAiB;IACxF,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAA;IACxE,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC1B,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAA;QACzE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACrC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YAC5C,WAAW,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAA;QACrC,CAAC;QACD,MAAM,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAClC,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,oBAAoB;QAAE,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAE,GAAY,EAAE,KAAgB;IACnE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC/C,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;QACpE,MAAM,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IACpC,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@txstate-mws/sveltekit-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Shared library for code that is specifically tied to sveltekit in addition to svelte.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
|
-
".":
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
8
11
|
},
|
|
9
12
|
"types": "./dist/index.d.ts",
|
|
10
13
|
"dependencies": {
|