@cripty2001/utils 0.0.258 → 0.0.260
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/Appserver/client/react.d.ts +52 -0
- package/dist/Appserver/client/react.js +153 -0
- package/dist/Appserver/server.d.ts +2 -1
- package/dist/Appserver/server.js +15 -6
- package/dist/Dispatcher.js +1 -2
- package/package.json +8 -2
- package/dist/Appserver/client.d.ts +0 -1
- package/dist/Appserver/client.js +0 -147
- package/dist/Appserver/common.d.ts +0 -3
- package/dist/Appserver/common.js +0 -2
- package/dist/MailTemplate/image.d.ts +0 -10
- package/dist/MailTemplate/image.js +0 -37
- package/dist/MailTemplate/index.d.ts +0 -31
- package/dist/MailTemplate/index.js +0 -90
- package/dist/MailTemplate/raw.d.ts +0 -7
- package/dist/MailTemplate/raw.js +0 -12
- package/dist/MailTemplate/text.d.ts +0 -13
- package/dist/MailTemplate/text.js +0 -28
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
type LoginSheetPropsConfig = {
|
|
3
|
+
issuer: string;
|
|
4
|
+
clientId: string;
|
|
5
|
+
scopes: string[];
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
};
|
|
8
|
+
type LoginSheetProps = {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
templates: {
|
|
11
|
+
Loading: ({ message }: {
|
|
12
|
+
message: string;
|
|
13
|
+
}) => ReactNode;
|
|
14
|
+
Error: ({ message, callback }: {
|
|
15
|
+
message: string;
|
|
16
|
+
callback: () => Promise<void>;
|
|
17
|
+
}) => ReactNode;
|
|
18
|
+
};
|
|
19
|
+
config: LoginSheetPropsConfig;
|
|
20
|
+
};
|
|
21
|
+
export default function ApiProvider({ children, config, templates }: LoginSheetProps): import("react").JSX.Element;
|
|
22
|
+
export type AppserverData = number | string | boolean | AppserverData[] | null | {
|
|
23
|
+
[key: string]: AppserverData;
|
|
24
|
+
};
|
|
25
|
+
export type ExecOnError = Record<string, (payload: AppserverData) => Promise<void>>;
|
|
26
|
+
export type Exec = <I extends AppserverData, O extends AppserverData>(action: string, data: I, onError?: ExecOnError) => Promise<O>;
|
|
27
|
+
type ApiContextValue = {
|
|
28
|
+
exec: Exec;
|
|
29
|
+
logout: (remote: boolean) => Promise<void>;
|
|
30
|
+
profile: Record<string, unknown> | undefined;
|
|
31
|
+
};
|
|
32
|
+
export declare class ApiError extends Error {
|
|
33
|
+
}
|
|
34
|
+
export declare class AuthApiError extends ApiError {
|
|
35
|
+
readonly recoverable: boolean;
|
|
36
|
+
constructor(recoverable: boolean);
|
|
37
|
+
}
|
|
38
|
+
export declare class ValidationApiError extends ApiError {
|
|
39
|
+
data: AppserverData;
|
|
40
|
+
constructor(data: AppserverData);
|
|
41
|
+
}
|
|
42
|
+
export declare class ClientApiError extends ApiError {
|
|
43
|
+
readonly code: string;
|
|
44
|
+
readonly message: string;
|
|
45
|
+
readonly details?: AppserverData;
|
|
46
|
+
constructor(code: string, message: string, details?: AppserverData);
|
|
47
|
+
}
|
|
48
|
+
export declare class UnknownApiError extends ApiError {
|
|
49
|
+
constructor();
|
|
50
|
+
}
|
|
51
|
+
export declare function useApi(): ApiContextValue;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnknownApiError = exports.ClientApiError = exports.ValidationApiError = exports.AuthApiError = exports.ApiError = void 0;
|
|
4
|
+
exports.default = ApiProvider;
|
|
5
|
+
exports.useApi = useApi;
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const react_oidc_context_1 = require("react-oidc-context");
|
|
9
|
+
function ApiProvider({ children, config, templates }) {
|
|
10
|
+
const oidcConfig = {
|
|
11
|
+
authority: config.issuer,
|
|
12
|
+
client_id: config.clientId,
|
|
13
|
+
redirect_uri: `${window.location.origin}/`,
|
|
14
|
+
scope: [
|
|
15
|
+
"openid", "offline_access",
|
|
16
|
+
...config.scopes
|
|
17
|
+
].join(" "),
|
|
18
|
+
extraQueryParams: {},
|
|
19
|
+
extraTokenParams: { resource: config.apiUrl },
|
|
20
|
+
onSigninCallback: (user) => {
|
|
21
|
+
const state = user?.state;
|
|
22
|
+
window.location.replace(state?.returnTo ?? "/");
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(react_oidc_context_1.AuthProvider, { ...oidcConfig, children: (0, jsx_runtime_1.jsx)(_ApiProvider, { apiUrl: config.apiUrl, children: (0, jsx_runtime_1.jsx)(_LoginSheet, { config: config, templates: templates, children: children }) }) }));
|
|
26
|
+
}
|
|
27
|
+
function _LoginSheet({ children, config, templates }) {
|
|
28
|
+
const auth = (0, react_oidc_context_1.useAuth)();
|
|
29
|
+
const login = (0, react_1.useCallback)(async () => {
|
|
30
|
+
sessionStorage.setItem("auth_redirect_url", window.location.href);
|
|
31
|
+
const state = {
|
|
32
|
+
returnTo: window.location.href
|
|
33
|
+
};
|
|
34
|
+
await auth.signinRedirect({
|
|
35
|
+
extraQueryParams: {
|
|
36
|
+
prompt: "consent",
|
|
37
|
+
resource: config.apiUrl
|
|
38
|
+
},
|
|
39
|
+
state
|
|
40
|
+
});
|
|
41
|
+
}, [auth]);
|
|
42
|
+
(0, react_1.useEffect)(() => {
|
|
43
|
+
if (auth.isLoading)
|
|
44
|
+
return;
|
|
45
|
+
if (auth.isAuthenticated && auth.user)
|
|
46
|
+
return;
|
|
47
|
+
if (auth.error)
|
|
48
|
+
return;
|
|
49
|
+
login();
|
|
50
|
+
}, [auth, login]);
|
|
51
|
+
if (auth.isLoading)
|
|
52
|
+
return (0, jsx_runtime_1.jsx)(templates.Loading, { message: "Restoring your session..." });
|
|
53
|
+
if (auth.isAuthenticated && auth.user)
|
|
54
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
55
|
+
return (0, jsx_runtime_1.jsx)(templates.Error, { message: auth.error?.message ?? "An error occurred while restoring your session.", callback: login });
|
|
56
|
+
}
|
|
57
|
+
const ApiContext = (0, react_1.createContext)(null);
|
|
58
|
+
class ApiError extends Error {
|
|
59
|
+
}
|
|
60
|
+
exports.ApiError = ApiError;
|
|
61
|
+
class AuthApiError extends ApiError {
|
|
62
|
+
recoverable;
|
|
63
|
+
constructor(recoverable) {
|
|
64
|
+
super(recoverable ?
|
|
65
|
+
"Authentication required" :
|
|
66
|
+
"Permission denied");
|
|
67
|
+
this.recoverable = recoverable;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.AuthApiError = AuthApiError;
|
|
71
|
+
class ValidationApiError extends ApiError {
|
|
72
|
+
data;
|
|
73
|
+
constructor(data) {
|
|
74
|
+
super();
|
|
75
|
+
this.data = data;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.ValidationApiError = ValidationApiError;
|
|
79
|
+
class ClientApiError extends ApiError {
|
|
80
|
+
code;
|
|
81
|
+
message;
|
|
82
|
+
details;
|
|
83
|
+
constructor(code, message, details) {
|
|
84
|
+
super();
|
|
85
|
+
this.code = code;
|
|
86
|
+
this.message = message;
|
|
87
|
+
this.details = details;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.ClientApiError = ClientApiError;
|
|
91
|
+
class UnknownApiError extends ApiError {
|
|
92
|
+
constructor() {
|
|
93
|
+
super();
|
|
94
|
+
this.message = "An unknown error occurred";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.UnknownApiError = UnknownApiError;
|
|
98
|
+
function _ApiProvider({ children, apiUrl }) {
|
|
99
|
+
const auth = (0, react_oidc_context_1.useAuth)();
|
|
100
|
+
const profile = (0, react_1.useMemo)(() => {
|
|
101
|
+
if (!auth.user)
|
|
102
|
+
return undefined;
|
|
103
|
+
return auth.user.profile;
|
|
104
|
+
}, [auth]);
|
|
105
|
+
const logout = (0, react_1.useCallback)(async (remote = false) => {
|
|
106
|
+
if (remote) {
|
|
107
|
+
await auth.signoutRedirect();
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
auth.removeUser();
|
|
111
|
+
}
|
|
112
|
+
}, [auth]);
|
|
113
|
+
const exec = (0, react_1.useCallback)(async (action, data, onError) => {
|
|
114
|
+
const res = await fetch(`${apiUrl}/exec/${action.startsWith('/') ? action.slice(1) : action}`, {
|
|
115
|
+
method: "POST",
|
|
116
|
+
headers: {
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
"Authorization": `Bearer ${auth.user?.access_token}`,
|
|
119
|
+
},
|
|
120
|
+
body: JSON.stringify(data)
|
|
121
|
+
});
|
|
122
|
+
if (res.status === 401) {
|
|
123
|
+
auth.removeUser();
|
|
124
|
+
throw new AuthApiError(true);
|
|
125
|
+
}
|
|
126
|
+
if (res.status === 403) {
|
|
127
|
+
throw new AuthApiError(false);
|
|
128
|
+
}
|
|
129
|
+
if (res.status === 422) {
|
|
130
|
+
const body = await res.json();
|
|
131
|
+
throw new ValidationApiError(body);
|
|
132
|
+
}
|
|
133
|
+
if (res.status === 400) {
|
|
134
|
+
const body = await res.json();
|
|
135
|
+
const handler = onError?.[body.code];
|
|
136
|
+
if (handler)
|
|
137
|
+
await handler(body.details ?? {});
|
|
138
|
+
throw new ClientApiError(body.code, body.message, body.details);
|
|
139
|
+
}
|
|
140
|
+
if (res.status === 200) {
|
|
141
|
+
const body = await res.json();
|
|
142
|
+
return body;
|
|
143
|
+
}
|
|
144
|
+
throw new UnknownApiError();
|
|
145
|
+
}, [auth]);
|
|
146
|
+
return (0, jsx_runtime_1.jsxs)(ApiContext.Provider, { value: { exec, logout, profile }, children: [" ", children, " "] });
|
|
147
|
+
}
|
|
148
|
+
function useApi() {
|
|
149
|
+
const ctx = (0, react_1.useContext)(ApiContext);
|
|
150
|
+
if (!ctx)
|
|
151
|
+
throw new Error("useApi must be used within ApiProvider");
|
|
152
|
+
return ctx;
|
|
153
|
+
}
|
|
@@ -12,10 +12,11 @@ export declare class Appserver {
|
|
|
12
12
|
private readonly jwks;
|
|
13
13
|
private readonly issuer;
|
|
14
14
|
private readonly audience;
|
|
15
|
+
private readonly scopesKey;
|
|
15
16
|
private static resolveAuth;
|
|
16
17
|
private readonly rpcBase;
|
|
17
18
|
private constructor();
|
|
18
|
-
static create(audience: string, issuerUrl: string, rpcBase?: string): Promise<Appserver>;
|
|
19
|
+
static create(audience: string, issuerUrl: string, rpcBase?: string, scopesKey?: string): Promise<Appserver>;
|
|
19
20
|
listen(port: number): Promise<void>;
|
|
20
21
|
registerRpc<TInput extends TSchema, TOutput extends TSchema>(route: string, schema: {
|
|
21
22
|
input: TInput;
|
package/dist/Appserver/server.js
CHANGED
|
@@ -16,6 +16,7 @@ class Appserver {
|
|
|
16
16
|
jwks;
|
|
17
17
|
issuer;
|
|
18
18
|
audience;
|
|
19
|
+
scopesKey;
|
|
19
20
|
static async resolveAuth(baseUrl) {
|
|
20
21
|
const res = await fetch(`${baseUrl}/.well-known/openid-configuration`);
|
|
21
22
|
if (!res.ok)
|
|
@@ -34,15 +35,16 @@ class Appserver {
|
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
rpcBase;
|
|
37
|
-
constructor(rpcBase, jwks, issuer, audience) {
|
|
38
|
+
constructor(rpcBase, jwks, issuer, audience, scopesKey) {
|
|
38
39
|
this.rpcBase = rpcBase;
|
|
39
40
|
this.jwks = jwks;
|
|
40
41
|
this.issuer = issuer;
|
|
41
42
|
this.audience = audience;
|
|
43
|
+
this.scopesKey = scopesKey;
|
|
42
44
|
}
|
|
43
|
-
static async create(audience, issuerUrl, rpcBase = '/exec') {
|
|
45
|
+
static async create(audience, issuerUrl, rpcBase = '/exec', scopesKey = 'scope') {
|
|
44
46
|
const { jwks, issuer } = await this.resolveAuth(issuerUrl);
|
|
45
|
-
const appserver = new Appserver(rpcBase, jwks, issuer, audience);
|
|
47
|
+
const appserver = new Appserver(rpcBase, jwks, issuer, audience, scopesKey);
|
|
46
48
|
appserver.fastify.setErrorHandler(appserver.handleError
|
|
47
49
|
.bind(appserver));
|
|
48
50
|
appserver.fastify.addContentTypeParser('application/octet-stream', { parseAs: 'buffer', bodyLimit: 64 * 1024 * 1024 }, (_req, body, done) => {
|
|
@@ -84,7 +86,7 @@ class Appserver {
|
|
|
84
86
|
const { payload } = await (0, jose_1.jwtVerify)(token.slice(7), this.jwks, {
|
|
85
87
|
issuer: this.issuer,
|
|
86
88
|
audience: this.audience,
|
|
87
|
-
requiredClaims: ['sub'],
|
|
89
|
+
requiredClaims: ['sub', 'iat', 'exp'],
|
|
88
90
|
});
|
|
89
91
|
return payload;
|
|
90
92
|
}
|
|
@@ -107,8 +109,15 @@ class Appserver {
|
|
|
107
109
|
});
|
|
108
110
|
}
|
|
109
111
|
})();
|
|
110
|
-
const scopes =
|
|
111
|
-
|
|
112
|
+
const scopes = (() => {
|
|
113
|
+
const data = payload[this.scopesKey];
|
|
114
|
+
if (typeof data === 'string')
|
|
115
|
+
return data.split(' ');
|
|
116
|
+
if (Array.isArray(data))
|
|
117
|
+
return data;
|
|
118
|
+
return [];
|
|
119
|
+
})();
|
|
120
|
+
if (!scopes.includes(scope))
|
|
112
121
|
throw new AppserverAuthHandledError('MISSING_SCOPE', 'Access token scope is not valid.', false);
|
|
113
122
|
if (!payload.sub)
|
|
114
123
|
throw new Error('JOSE assert failed, sub is missing despite being required');
|
package/dist/Dispatcher.js
CHANGED
|
@@ -66,8 +66,7 @@ class Dispatcher {
|
|
|
66
66
|
static create(value, f, DEBOUNCE_INTERVAL = 200) {
|
|
67
67
|
const d = new Dispatcher(value, f, DEBOUNCE_INTERVAL);
|
|
68
68
|
const refresh = async () => {
|
|
69
|
-
d.
|
|
70
|
-
await d.data.wait(d => d.output.loading === false);
|
|
69
|
+
await d.dispatch(d.value.value);
|
|
71
70
|
};
|
|
72
71
|
return [d, refresh];
|
|
73
72
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cripty2001/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.260",
|
|
4
4
|
"description": "Internal Set of utils. If you need them use them, otherwise go to the next package ;)",
|
|
5
5
|
"homepage": "https://github.com/cripty2001/utils#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@cripty2001/whispr": "^0.4.1",
|
|
33
33
|
"@sinclair/typebox": "^0.34.41",
|
|
34
|
-
"lodash": "^4.17.21"
|
|
34
|
+
"lodash": "^4.17.21",
|
|
35
|
+
"react-oidc-context": "^3.3.1"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@types/lodash": "^4.17.21",
|
|
@@ -94,6 +95,11 @@
|
|
|
94
95
|
"types": "./dist/Appserver/server.d.ts",
|
|
95
96
|
"require": "./dist/Appserver/server.js"
|
|
96
97
|
},
|
|
98
|
+
"./appserver/client/react": {
|
|
99
|
+
"import": "./dist/Appserver/client/react.js",
|
|
100
|
+
"types": "./dist/Appserver/client/react.d.ts",
|
|
101
|
+
"require": "./dist/Appserver/client/react.js"
|
|
102
|
+
},
|
|
97
103
|
"./react": {
|
|
98
104
|
"import": "./dist/react/index.js",
|
|
99
105
|
"types": "./dist/react/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/Appserver/client.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// import { Whispr, WhisprSetter } from "@cripty2001/whispr";
|
|
3
|
-
// import { decode, encode } from "@msgpack/msgpack";
|
|
4
|
-
// import { AppserverData } from "./common";
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
// export type { AppserverData };
|
|
7
|
-
// export type ClientCreateOptions = {
|
|
8
|
-
// rpcMount: string;
|
|
9
|
-
// };
|
|
10
|
-
// export class ClientError extends Error {
|
|
11
|
-
// constructor(message: string) {
|
|
12
|
-
// super(message);
|
|
13
|
-
// }
|
|
14
|
-
// }
|
|
15
|
-
// export class ClientAuthError extends ClientError {
|
|
16
|
-
// constructor(
|
|
17
|
-
// public readonly code: string = "PERMISSION_DENIED",
|
|
18
|
-
// message: string = "Permission denied",
|
|
19
|
-
// public readonly payload: AppserverData = {},
|
|
20
|
-
// ) {
|
|
21
|
-
// super(message);
|
|
22
|
-
// }
|
|
23
|
-
// }
|
|
24
|
-
// export class ClientServerError extends ClientError {
|
|
25
|
-
// constructor(public code: string, message: string, public payload: AppserverData = {}) {
|
|
26
|
-
// super(message);
|
|
27
|
-
// }
|
|
28
|
-
// }
|
|
29
|
-
// type ClientValidationErrorError = {
|
|
30
|
-
// path: string;
|
|
31
|
-
// message: string;
|
|
32
|
-
// value: unknown;
|
|
33
|
-
// }
|
|
34
|
-
// export class ClientValidationError extends ClientError {
|
|
35
|
-
// public readonly errors: ClientValidationErrorError[];
|
|
36
|
-
// constructor(errors: ClientValidationErrorError[]) {
|
|
37
|
-
// const first = errors[0] ?? {
|
|
38
|
-
// path: "Internal Error",
|
|
39
|
-
// message: "",
|
|
40
|
-
// value: undefined,
|
|
41
|
-
// };
|
|
42
|
-
// super(`[Validation Error] ${first.path}: ${first.message}`);
|
|
43
|
-
// this.errors = errors;
|
|
44
|
-
// }
|
|
45
|
-
// }
|
|
46
|
-
// export class Client {
|
|
47
|
-
// private readonly token: Whispr<string | null>;
|
|
48
|
-
// private readonly setToken: WhisprSetter<string | null>;
|
|
49
|
-
// public readonly loggedIn: Whispr<boolean>;
|
|
50
|
-
// private constructor(
|
|
51
|
-
// private url: string,
|
|
52
|
-
// private readonly rpcMount: string,
|
|
53
|
-
// ) {
|
|
54
|
-
// const [token, setToken] = Whispr.create<string | null>(''); // This will make sure the loggedin only flips to false when there is really an auth rejected. Server will ignore invalid tokens on public apis anyway
|
|
55
|
-
// this.token = token;
|
|
56
|
-
// this.setToken = setToken;
|
|
57
|
-
// this.loggedIn = token.transform((t) => t !== null);
|
|
58
|
-
// }
|
|
59
|
-
// public static create(url: string, options: ClientCreateOptions): Client {
|
|
60
|
-
// const m = options.rpcMount.startsWith("/") ?
|
|
61
|
-
// options.rpcMount :
|
|
62
|
-
// `/${options.rpcMount}`;
|
|
63
|
-
// return new Client(url, m);
|
|
64
|
-
// }
|
|
65
|
-
// public async login(token: string): Promise<boolean> {
|
|
66
|
-
// this.setToken(token);
|
|
67
|
-
// return true;
|
|
68
|
-
// }
|
|
69
|
-
// public logout(): void {
|
|
70
|
-
// this.setToken(null);
|
|
71
|
-
// }
|
|
72
|
-
// public async exec<I extends AppserverData, O extends AppserverData>(
|
|
73
|
-
// action: string,
|
|
74
|
-
// input: I,
|
|
75
|
-
// onError: Record<string, (payload: AppserverData) => Promise<void>> = {},
|
|
76
|
-
// ): Promise<O> {
|
|
77
|
-
// while (true) {
|
|
78
|
-
// try {
|
|
79
|
-
// return await this.unsafeExec(action, input);
|
|
80
|
-
// } catch (e) {
|
|
81
|
-
// if (e instanceof ClientAuthError) {
|
|
82
|
-
// this.logout();
|
|
83
|
-
// await this.token.load();
|
|
84
|
-
// continue;
|
|
85
|
-
// }
|
|
86
|
-
// if (e instanceof ClientServerError) {
|
|
87
|
-
// const handler = onError[e.code];
|
|
88
|
-
// if (handler) {
|
|
89
|
-
// await handler(e.payload);
|
|
90
|
-
// }
|
|
91
|
-
// }
|
|
92
|
-
// throw e;
|
|
93
|
-
// }
|
|
94
|
-
// }
|
|
95
|
-
// }
|
|
96
|
-
// private async unsafeExec<I extends AppserverData, O extends AppserverData>(
|
|
97
|
-
// action: string,
|
|
98
|
-
// input: I,
|
|
99
|
-
// ): Promise<O> {
|
|
100
|
-
// const testedToken = this.token.value;
|
|
101
|
-
// const actionKey = action;
|
|
102
|
-
// const wireBody = {
|
|
103
|
-
// action: actionKey,
|
|
104
|
-
// payload: input as AppserverData,
|
|
105
|
-
// };
|
|
106
|
-
// const res = await fetch(`${this.url}${this.rpcMount}`, {
|
|
107
|
-
// method: "POST",
|
|
108
|
-
// headers: {
|
|
109
|
-
// "Content-Type": "application/vnd.msgpack",
|
|
110
|
-
// ...(testedToken !== null ? { Authorization: `Bearer ${testedToken}` } : {}),
|
|
111
|
-
// },
|
|
112
|
-
// body: new Uint8Array(encode(wireBody)),
|
|
113
|
-
// });
|
|
114
|
-
// const buf = await res.arrayBuffer();
|
|
115
|
-
// const decoded = decode(buf);
|
|
116
|
-
// if (res.status === 200)
|
|
117
|
-
// return decoded as O;
|
|
118
|
-
// if (res.status === 422) {
|
|
119
|
-
// const data = decoded as {
|
|
120
|
-
// errors: ClientValidationErrorError[];
|
|
121
|
-
// received: AppserverData;
|
|
122
|
-
// }
|
|
123
|
-
// throw new ClientValidationError(data.errors);
|
|
124
|
-
// }
|
|
125
|
-
// const genericError = decoded as {
|
|
126
|
-
// error: string;
|
|
127
|
-
// code: string;
|
|
128
|
-
// payload: AppserverData;
|
|
129
|
-
// }
|
|
130
|
-
// if (res.status === 400 || res.status === 404 || res.status === 500) {
|
|
131
|
-
// throw new ClientServerError(
|
|
132
|
-
// genericError.code,
|
|
133
|
-
// genericError.error,
|
|
134
|
-
// genericError.payload ?? {},
|
|
135
|
-
// );
|
|
136
|
-
// }
|
|
137
|
-
// if (res.status === 401 || res.status === 403) {
|
|
138
|
-
// this.setToken(null);
|
|
139
|
-
// throw new ClientAuthError(
|
|
140
|
-
// genericError.code,
|
|
141
|
-
// genericError.error,
|
|
142
|
-
// genericError.payload,
|
|
143
|
-
// )
|
|
144
|
-
// }
|
|
145
|
-
// throw new ClientError(`Unexpected server response: ${res.status}`);
|
|
146
|
-
// }
|
|
147
|
-
// }
|
package/dist/Appserver/common.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type Static } from "@sinclair/typebox";
|
|
2
|
-
export declare const SCHEMA: import("@sinclair/typebox").TObject<{
|
|
3
|
-
type: import("@sinclair/typebox").TLiteral<"image">;
|
|
4
|
-
mobile: import("@sinclair/typebox").TString;
|
|
5
|
-
desktop: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>;
|
|
6
|
-
link: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>;
|
|
7
|
-
alt: import("@sinclair/typebox").TString;
|
|
8
|
-
}>;
|
|
9
|
-
export type T = Static<typeof SCHEMA>;
|
|
10
|
-
export declare function build(config: T): string;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SCHEMA = void 0;
|
|
4
|
-
exports.build = build;
|
|
5
|
-
const typebox_1 = require("@sinclair/typebox");
|
|
6
|
-
exports.SCHEMA = typebox_1.Type.Object({
|
|
7
|
-
type: typebox_1.Type.Literal("image"),
|
|
8
|
-
mobile: typebox_1.Type.String(),
|
|
9
|
-
desktop: typebox_1.Type.Union([typebox_1.Type.String(), typebox_1.Type.Null()]),
|
|
10
|
-
link: typebox_1.Type.Union([typebox_1.Type.String(), typebox_1.Type.Null()]),
|
|
11
|
-
alt: typebox_1.Type.String()
|
|
12
|
-
});
|
|
13
|
-
function build(config) {
|
|
14
|
-
const img = (breakpoint, url) => `
|
|
15
|
-
<mj-image
|
|
16
|
-
css-class="${breakpoint ?? ''}"
|
|
17
|
-
src="${url}"
|
|
18
|
-
alt="${config.alt}"
|
|
19
|
-
${config.link ? `href="${config.link}"` : ''}
|
|
20
|
-
padding="0"
|
|
21
|
-
/>
|
|
22
|
-
`;
|
|
23
|
-
const imgs = config.desktop === null ?
|
|
24
|
-
img(null, config.mobile) :
|
|
25
|
-
[
|
|
26
|
-
img("onlyDesktop", config.desktop),
|
|
27
|
-
img("onlyMobile", config.mobile)
|
|
28
|
-
].join('\n');
|
|
29
|
-
const toReturn = `
|
|
30
|
-
<mj-section padding="0">
|
|
31
|
-
<mj-column padding="0">
|
|
32
|
-
${imgs}
|
|
33
|
-
</mj-column>
|
|
34
|
-
</mj-section>
|
|
35
|
-
`;
|
|
36
|
-
return toReturn;
|
|
37
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { type Static } from "@sinclair/typebox";
|
|
2
|
-
export declare const TEMPLATE_SCHEMA: import("@sinclair/typebox").TObject<{
|
|
3
|
-
style: import("@sinclair/typebox").TObject<{
|
|
4
|
-
font: import("@sinclair/typebox").TString;
|
|
5
|
-
backgroundColor: import("@sinclair/typebox").TString;
|
|
6
|
-
textColor: import("@sinclair/typebox").TString;
|
|
7
|
-
}>;
|
|
8
|
-
content: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
9
|
-
type: import("@sinclair/typebox").TLiteral<"image">;
|
|
10
|
-
mobile: import("@sinclair/typebox").TString;
|
|
11
|
-
desktop: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>;
|
|
12
|
-
link: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>;
|
|
13
|
-
alt: import("@sinclair/typebox").TString;
|
|
14
|
-
}>, import("@sinclair/typebox").TObject<{
|
|
15
|
-
type: import("@sinclair/typebox").TLiteral<"text">;
|
|
16
|
-
size: import("@sinclair/typebox").TNumber;
|
|
17
|
-
weight: import("@sinclair/typebox").TNumber;
|
|
18
|
-
color: import("@sinclair/typebox").TString;
|
|
19
|
-
padding: import("@sinclair/typebox").TObject<{
|
|
20
|
-
top: import("@sinclair/typebox").TNumber;
|
|
21
|
-
}>;
|
|
22
|
-
content: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
23
|
-
}>, import("@sinclair/typebox").TObject<{
|
|
24
|
-
type: import("@sinclair/typebox").TLiteral<"raw">;
|
|
25
|
-
data: import("@sinclair/typebox").TString;
|
|
26
|
-
}>]>>;
|
|
27
|
-
}>;
|
|
28
|
-
export type Template = Static<typeof TEMPLATE_SCHEMA>;
|
|
29
|
-
export declare function genBuilder<T extends any>(config: Template): (params: T) => {
|
|
30
|
-
html: string;
|
|
31
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TEMPLATE_SCHEMA = void 0;
|
|
7
|
-
exports.genBuilder = genBuilder;
|
|
8
|
-
const handlebars_1 = __importDefault(require("handlebars"));
|
|
9
|
-
const mjml_1 = __importDefault(require("mjml"));
|
|
10
|
-
const typebox_1 = require("@sinclair/typebox");
|
|
11
|
-
const image_1 = require("./image");
|
|
12
|
-
const raw_1 = require("./raw");
|
|
13
|
-
const text_1 = require("./text");
|
|
14
|
-
exports.TEMPLATE_SCHEMA = typebox_1.Type.Object({
|
|
15
|
-
style: typebox_1.Type.Object({
|
|
16
|
-
font: typebox_1.Type.String(),
|
|
17
|
-
backgroundColor: typebox_1.Type.String(),
|
|
18
|
-
textColor: typebox_1.Type.String()
|
|
19
|
-
}),
|
|
20
|
-
content: typebox_1.Type.Array(typebox_1.Type.Union([
|
|
21
|
-
image_1.SCHEMA,
|
|
22
|
-
text_1.SCHEMA,
|
|
23
|
-
raw_1.SCHEMA
|
|
24
|
-
]))
|
|
25
|
-
});
|
|
26
|
-
function genBuilder(config) {
|
|
27
|
-
const mappedContent = config.content
|
|
28
|
-
.map(item => {
|
|
29
|
-
switch (item.type) {
|
|
30
|
-
case "image":
|
|
31
|
-
return (0, image_1.build)(item);
|
|
32
|
-
case "raw":
|
|
33
|
-
return (0, raw_1.build)(item);
|
|
34
|
-
case "text":
|
|
35
|
-
return (0, text_1.build)(item);
|
|
36
|
-
default:
|
|
37
|
-
// @ts-expect-error Should never happen
|
|
38
|
-
throw new Error(`Invalid type ${item.type}`);
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
.join('\n');
|
|
42
|
-
const builder = handlebars_1.default.compile(`
|
|
43
|
-
<mjml>
|
|
44
|
-
<mj-head>
|
|
45
|
-
<mj-style>
|
|
46
|
-
.onlyMobile {
|
|
47
|
-
display: none !important;
|
|
48
|
-
}
|
|
49
|
-
.onlyDesktop {
|
|
50
|
-
display: block !important;
|
|
51
|
-
}
|
|
52
|
-
@media only screen and (max-width: 500px) {
|
|
53
|
-
.onlyMobile {
|
|
54
|
-
display: block !important;
|
|
55
|
-
}
|
|
56
|
-
.onlyDesktop {
|
|
57
|
-
display: none !important;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
</mj-style>
|
|
61
|
-
|
|
62
|
-
<mj-attributes>
|
|
63
|
-
<mj-all
|
|
64
|
-
font-family="${config.style.font}, Arial, Helvetica, sans-serif"
|
|
65
|
-
/>
|
|
66
|
-
<mj-text
|
|
67
|
-
font-size="18px"
|
|
68
|
-
line-height="1.5"
|
|
69
|
-
color="${config.style.textColor}"
|
|
70
|
-
/>
|
|
71
|
-
<mj-body width="700px" />
|
|
72
|
-
</mj-attributes>
|
|
73
|
-
</mj-head>
|
|
74
|
-
|
|
75
|
-
<mj-body background-color="${config.style.backgroundColor}">
|
|
76
|
-
${mappedContent}
|
|
77
|
-
</mj-body>
|
|
78
|
-
</mjml>
|
|
79
|
-
`);
|
|
80
|
-
return (data) => {
|
|
81
|
-
let { html, errors } = (0, mjml_1.default)(builder(data), {
|
|
82
|
-
validationLevel: 'soft'
|
|
83
|
-
});
|
|
84
|
-
if (errors.length > 0)
|
|
85
|
-
throw new Error(`Invalid template: ${errors.map(e => e.message).join(', ')}`);
|
|
86
|
-
return {
|
|
87
|
-
html: html,
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type Static } from "@sinclair/typebox";
|
|
2
|
-
export declare const SCHEMA: import("@sinclair/typebox").TObject<{
|
|
3
|
-
type: import("@sinclair/typebox").TLiteral<"raw">;
|
|
4
|
-
data: import("@sinclair/typebox").TString;
|
|
5
|
-
}>;
|
|
6
|
-
export type T = Static<typeof SCHEMA>;
|
|
7
|
-
export declare function build(config: T): string;
|
package/dist/MailTemplate/raw.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SCHEMA = void 0;
|
|
4
|
-
exports.build = build;
|
|
5
|
-
const typebox_1 = require("@sinclair/typebox");
|
|
6
|
-
exports.SCHEMA = typebox_1.Type.Object({
|
|
7
|
-
type: typebox_1.Type.Literal("raw"),
|
|
8
|
-
data: typebox_1.Type.String()
|
|
9
|
-
});
|
|
10
|
-
function build(config) {
|
|
11
|
-
return config.data;
|
|
12
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type Static } from "@sinclair/typebox";
|
|
2
|
-
export declare const SCHEMA: import("@sinclair/typebox").TObject<{
|
|
3
|
-
type: import("@sinclair/typebox").TLiteral<"text">;
|
|
4
|
-
size: import("@sinclair/typebox").TNumber;
|
|
5
|
-
weight: import("@sinclair/typebox").TNumber;
|
|
6
|
-
color: import("@sinclair/typebox").TString;
|
|
7
|
-
padding: import("@sinclair/typebox").TObject<{
|
|
8
|
-
top: import("@sinclair/typebox").TNumber;
|
|
9
|
-
}>;
|
|
10
|
-
content: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
11
|
-
}>;
|
|
12
|
-
export type T = Static<typeof SCHEMA>;
|
|
13
|
-
export declare function build(config: T): string;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SCHEMA = void 0;
|
|
4
|
-
exports.build = build;
|
|
5
|
-
const typebox_1 = require("@sinclair/typebox");
|
|
6
|
-
exports.SCHEMA = typebox_1.Type.Object({
|
|
7
|
-
type: typebox_1.Type.Literal("text"),
|
|
8
|
-
size: typebox_1.Type.Number(),
|
|
9
|
-
weight: typebox_1.Type.Number(),
|
|
10
|
-
color: typebox_1.Type.String(),
|
|
11
|
-
padding: typebox_1.Type.Object({
|
|
12
|
-
top: typebox_1.Type.Number()
|
|
13
|
-
}),
|
|
14
|
-
content: typebox_1.Type.Array(typebox_1.Type.String())
|
|
15
|
-
});
|
|
16
|
-
function build(config) {
|
|
17
|
-
return `
|
|
18
|
-
<mj-section padding="0">
|
|
19
|
-
<mj-column padding-top="${config.padding.top}px">
|
|
20
|
-
${config.content.map(item => `
|
|
21
|
-
<mj-text font-size="${config.size}px" font-weight="${config.weight}" color="${config.color}">
|
|
22
|
-
${item}
|
|
23
|
-
</mj-text>
|
|
24
|
-
`).join('')}
|
|
25
|
-
</mj-column>
|
|
26
|
-
</mj-section>
|
|
27
|
-
`;
|
|
28
|
-
}
|