@vandenberghinc/volt 1.1.5 → 1.1.7
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/backend/dist/cjs/database.d.ts +41 -68
- package/backend/dist/cjs/database.js +127 -76
- package/backend/dist/cjs/endpoint.d.ts +23 -9
- package/backend/dist/cjs/endpoint.js +98 -21
- package/backend/dist/cjs/frontend.d.ts +0 -2
- package/backend/dist/cjs/frontend.js +9 -9
- package/backend/dist/cjs/image_endpoint.d.ts +3 -1
- package/backend/dist/cjs/image_endpoint.js +2 -1
- package/backend/dist/cjs/payments/paddle.js +10 -2
- package/backend/dist/cjs/plugins/css.d.ts +6 -5
- package/backend/dist/cjs/plugins/css.js +32 -7
- package/backend/dist/cjs/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/cjs/plugins/ts/compiler.js +26 -2
- package/backend/dist/cjs/plugins/ts/preprocessing.js +5 -3
- package/backend/dist/cjs/server.d.ts +7 -13
- package/backend/dist/cjs/server.js +184 -303
- package/backend/dist/cjs/status.d.ts +1 -0
- package/backend/dist/cjs/status.js +2 -1
- package/backend/dist/cjs/stream.d.ts +5 -3
- package/backend/dist/cjs/stream.js +13 -4
- package/backend/dist/cjs/users.d.ts +1 -1
- package/backend/dist/cjs/users.js +87 -72
- package/backend/dist/cjs/utils.d.ts +17 -9
- package/backend/dist/cjs/utils.js +22 -64
- package/backend/dist/cjs/view.d.ts +2 -2
- package/backend/dist/cjs/view.js +38 -40
- package/backend/dist/cjs/volt.d.ts +3 -2
- package/backend/dist/cjs/volt.js +2 -2
- package/backend/dist/css/volt.css +5 -0
- package/backend/dist/esm/database.d.ts +41 -68
- package/backend/dist/esm/database.js +127 -76
- package/backend/dist/esm/endpoint.d.ts +23 -9
- package/backend/dist/esm/endpoint.js +99 -22
- package/backend/dist/esm/frontend.d.ts +0 -2
- package/backend/dist/esm/frontend.js +9 -9
- package/backend/dist/esm/image_endpoint.d.ts +3 -1
- package/backend/dist/esm/image_endpoint.js +2 -1
- package/backend/dist/esm/payments/paddle.js +11 -3
- package/backend/dist/esm/plugins/css.d.ts +6 -5
- package/backend/dist/esm/plugins/css.js +32 -6
- package/backend/dist/esm/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/esm/plugins/ts/compiler.js +26 -2
- package/backend/dist/esm/plugins/ts/preprocessing.js +5 -3
- package/backend/dist/esm/server.d.ts +7 -13
- package/backend/dist/esm/server.js +182 -301
- package/backend/dist/esm/status.d.ts +1 -0
- package/backend/dist/esm/status.js +1 -0
- package/backend/dist/esm/stream.d.ts +5 -3
- package/backend/dist/esm/stream.js +13 -4
- package/backend/dist/esm/users.d.ts +1 -1
- package/backend/dist/esm/users.js +87 -72
- package/backend/dist/esm/utils.d.ts +17 -9
- package/backend/dist/esm/utils.js +21 -62
- package/backend/dist/esm/view.d.ts +2 -2
- package/backend/dist/esm/view.js +38 -40
- package/backend/dist/esm/volt.d.ts +3 -2
- package/backend/dist/esm/volt.js +2 -1
- package/backend/dist/esm-dev/blacklist.js +1 -1
- package/backend/dist/esm-dev/cli.js +2 -2
- package/backend/dist/esm-dev/database.d.ts +41 -68
- package/backend/dist/esm-dev/database.js +128 -77
- package/backend/dist/esm-dev/endpoint.d.ts +23 -9
- package/backend/dist/esm-dev/endpoint.js +100 -23
- package/backend/dist/esm-dev/file_watcher.js +1 -1
- package/backend/dist/esm-dev/frontend.d.ts +0 -2
- package/backend/dist/esm-dev/frontend.js +9 -9
- package/backend/dist/esm-dev/image_endpoint.d.ts +3 -1
- package/backend/dist/esm-dev/image_endpoint.js +2 -1
- package/backend/dist/esm-dev/logger.js +1 -1
- package/backend/dist/esm-dev/payments/paddle.js +12 -4
- package/backend/dist/esm-dev/plugins/css.d.ts +6 -5
- package/backend/dist/esm-dev/plugins/css.js +33 -7
- package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +6 -1
- package/backend/dist/esm-dev/plugins/ts/compiler.js +27 -3
- package/backend/dist/esm-dev/plugins/ts/preprocessing.js +7 -5
- package/backend/dist/esm-dev/rate_limit.js +1 -1
- package/backend/dist/esm-dev/server.d.ts +7 -13
- package/backend/dist/esm-dev/server.js +184 -303
- package/backend/dist/esm-dev/status.d.ts +1 -0
- package/backend/dist/esm-dev/status.js +1 -0
- package/backend/dist/esm-dev/stream.d.ts +5 -3
- package/backend/dist/esm-dev/stream.js +13 -4
- package/backend/dist/esm-dev/users.d.ts +1 -1
- package/backend/dist/esm-dev/users.js +88 -73
- package/backend/dist/esm-dev/utils.d.ts +17 -9
- package/backend/dist/esm-dev/utils.js +22 -63
- package/backend/dist/esm-dev/view.d.ts +2 -2
- package/backend/dist/esm-dev/view.js +39 -41
- package/backend/dist/esm-dev/volt.d.ts +3 -2
- package/backend/dist/esm-dev/volt.js +2 -1
- package/backend/src/database.ts +163 -152
- package/backend/src/endpoint.ts +123 -31
- package/backend/src/frontend.ts +9 -8
- package/backend/src/image_endpoint.ts +4 -0
- package/backend/src/payments/paddle.ts +11 -3
- package/backend/src/plugins/css.ts +36 -8
- package/backend/src/plugins/ts/compiler.ts +37 -1
- package/backend/src/plugins/ts/preprocessing.ts +5 -3
- package/backend/src/server.ts +167 -306
- package/backend/src/status.ts +1 -0
- package/backend/src/stream.ts +28 -8
- package/backend/src/users.ts +87 -72
- package/backend/src/utils.ts +58 -25
- package/backend/src/view.ts +30 -28
- package/backend/src/{volt.js → volt.ts} +2 -1
- package/backend/tsconfig.cjs.json +3 -3
- package/backend/tsconfig.esm.json +3 -3
- package/frontend/dist/elements/base.d.ts +397 -415
- package/frontend/dist/elements/base.js +565 -328
- package/frontend/dist/elements/module.d.ts +26 -12
- package/frontend/dist/elements/module.js +69 -32
- package/frontend/dist/elements/register_element.d.ts +3 -0
- package/frontend/dist/elements/register_element.js +22 -0
- package/frontend/dist/modules/auth.d.ts +1 -0
- package/frontend/dist/modules/auth.js +6 -5
- package/frontend/dist/modules/color.d.ts +159 -0
- package/frontend/dist/modules/color.js +315 -0
- package/frontend/dist/modules/colors.d.ts +1 -26
- package/frontend/dist/modules/colors.js +417 -338
- package/frontend/dist/modules/cookies.d.ts +1 -0
- package/frontend/dist/modules/cookies.js +1 -0
- package/frontend/dist/modules/events.d.ts +1 -0
- package/frontend/dist/modules/events.js +1 -0
- package/frontend/dist/modules/google.d.ts +1 -0
- package/frontend/dist/modules/google.js +1 -0
- package/frontend/dist/modules/meta.d.ts +1 -0
- package/frontend/dist/modules/meta.js +1 -0
- package/frontend/dist/modules/mutex.d.ts +1 -2
- package/frontend/dist/modules/mutex.js +3 -4
- package/frontend/dist/modules/paddle.d.ts +1 -0
- package/frontend/dist/modules/paddle.js +14 -13
- package/frontend/dist/modules/scheme.d.ts +1 -0
- package/frontend/dist/modules/scheme.js +4 -2
- package/frontend/dist/modules/statics.d.ts +1 -0
- package/frontend/dist/modules/statics.js +1 -0
- package/frontend/dist/modules/support.d.ts +1 -0
- package/frontend/dist/modules/support.js +3 -2
- package/frontend/dist/modules/theme.d.ts +56 -0
- package/frontend/dist/{ui → modules}/theme.js +186 -75
- package/frontend/dist/modules/themes.d.ts +1 -1
- package/frontend/dist/modules/themes.js +1 -0
- package/frontend/dist/modules/user.d.ts +1 -0
- package/frontend/dist/modules/user.js +11 -10
- package/frontend/dist/modules/utils.d.ts +23 -2
- package/frontend/dist/modules/utils.js +93 -1
- package/frontend/dist/types/gradient.js +4 -0
- package/frontend/dist/ui/border_button.d.ts +0 -25
- package/frontend/dist/ui/border_button.js +50 -51
- package/frontend/dist/ui/button.d.ts +0 -21
- package/frontend/dist/ui/button.js +41 -46
- package/frontend/dist/ui/canvas.js +15 -15
- package/frontend/dist/ui/checkbox.d.ts +3 -17
- package/frontend/dist/ui/checkbox.js +36 -30
- package/frontend/dist/ui/code.d.ts +15 -82
- package/frontend/dist/ui/code.js +150 -125
- package/frontend/dist/ui/color.d.ts +0 -1
- package/frontend/dist/ui/color.js +1 -1
- package/frontend/dist/ui/context_menu.d.ts +4 -2
- package/frontend/dist/ui/context_menu.js +16 -17
- package/frontend/dist/ui/css.js +2 -0
- package/frontend/dist/ui/divider.d.ts +0 -7
- package/frontend/dist/ui/divider.js +21 -25
- package/frontend/dist/ui/dropdown.d.ts +13 -7
- package/frontend/dist/ui/dropdown.js +65 -30
- package/frontend/dist/ui/for_each.d.ts +0 -5
- package/frontend/dist/ui/for_each.js +17 -22
- package/frontend/dist/ui/form.d.ts +17 -12
- package/frontend/dist/ui/form.js +21 -18
- package/frontend/dist/ui/frame_modes.d.ts +9 -12
- package/frontend/dist/ui/frame_modes.js +8 -10
- package/frontend/dist/ui/google_map.d.ts +0 -11
- package/frontend/dist/ui/google_map.js +23 -28
- package/frontend/dist/ui/gradient.d.ts +0 -5
- package/frontend/dist/ui/gradient.js +17 -22
- package/frontend/dist/ui/image.d.ts +27 -58
- package/frontend/dist/ui/image.js +99 -93
- package/frontend/dist/ui/input.d.ts +20 -97
- package/frontend/dist/ui/input.js +192 -170
- package/frontend/dist/ui/link.d.ts +0 -18
- package/frontend/dist/ui/link.js +42 -48
- package/frontend/dist/ui/list.js +36 -37
- package/frontend/dist/ui/loader_button.d.ts +4 -19
- package/frontend/dist/ui/loader_button.js +35 -37
- package/frontend/dist/ui/loaders.d.ts +0 -8
- package/frontend/dist/ui/loaders.js +20 -25
- package/frontend/dist/ui/popup.d.ts +11 -8
- package/frontend/dist/ui/popup.js +183 -24
- package/frontend/dist/ui/pseudo.d.ts +3 -3
- package/frontend/dist/ui/pseudo.js +14 -17
- package/frontend/dist/ui/scroller.d.ts +10 -48
- package/frontend/dist/ui/scroller.js +306 -300
- package/frontend/dist/ui/slider.d.ts +9 -3
- package/frontend/dist/ui/slider.js +31 -17
- package/frontend/dist/ui/spacer.d.ts +0 -9
- package/frontend/dist/ui/spacer.js +21 -26
- package/frontend/dist/ui/span.js +13 -15
- package/frontend/dist/ui/stack.d.ts +14 -75
- package/frontend/dist/ui/stack.js +166 -169
- package/frontend/dist/ui/steps.d.ts +10 -23
- package/frontend/dist/ui/steps.js +47 -34
- package/frontend/dist/ui/style.d.ts +4 -3
- package/frontend/dist/ui/style.js +13 -18
- package/frontend/dist/ui/switch.d.ts +10 -4
- package/frontend/dist/ui/switch.js +24 -16
- package/frontend/dist/ui/table.d.ts +0 -23
- package/frontend/dist/ui/table.js +113 -119
- package/frontend/dist/ui/tabs.d.ts +3 -19
- package/frontend/dist/ui/tabs.js +35 -29
- package/frontend/dist/ui/text.d.ts +0 -8
- package/frontend/dist/ui/text.js +20 -25
- package/frontend/dist/ui/title.d.ts +0 -15
- package/frontend/dist/ui/title.js +39 -45
- package/frontend/dist/ui/ui.d.ts +0 -2
- package/frontend/dist/ui/ui.js +0 -2
- package/frontend/dist/ui/view.d.ts +3 -17
- package/frontend/dist/ui/view.js +27 -32
- package/frontend/dist/volt.d.ts +2 -1
- package/frontend/dist/volt.js +3 -1
- package/frontend/examples/dashboard/dashboard.ts +774 -0
- package/frontend/examples/theme/theme.ts +58 -0
- package/frontend/src/css/volt.css +5 -0
- package/frontend/src/elements/base.ts +767 -545
- package/frontend/src/elements/module.ts +90 -29
- package/frontend/src/elements/register_element.ts +24 -0
- package/frontend/src/modules/auth.ts +7 -6
- package/frontend/src/modules/color.ts +348 -0
- package/frontend/src/modules/colors.ts +468 -449
- package/frontend/src/modules/cookies.ts +1 -0
- package/frontend/src/modules/events.ts +1 -0
- package/frontend/src/modules/google.ts +1 -0
- package/frontend/src/modules/meta.ts +2 -1
- package/frontend/src/modules/mutex.ts +2 -4
- package/frontend/src/modules/paddle.ts +21 -20
- package/frontend/src/modules/scheme.ts +4 -3
- package/frontend/src/modules/statics.ts +2 -1
- package/frontend/src/modules/support.ts +3 -2
- package/frontend/src/modules/theme.ts +413 -0
- package/frontend/src/modules/themes.ts +2 -1
- package/frontend/src/modules/user.ts +12 -11
- package/frontend/src/modules/utils.ts +125 -2
- package/frontend/src/ui/border_button.ts +41 -37
- package/frontend/src/ui/button.ts +33 -32
- package/frontend/src/ui/canvas.ts +5 -2
- package/frontend/src/ui/checkbox.ts +21 -22
- package/frontend/src/ui/code.ts +92 -86
- package/frontend/src/ui/context_menu.ts +7 -5
- package/frontend/src/ui/css.ts +1 -1
- package/frontend/src/ui/divider.ts +15 -10
- package/frontend/src/ui/dropdown.ts +38 -21
- package/frontend/src/ui/for_each.ts +9 -8
- package/frontend/src/ui/form.ts +26 -21
- package/frontend/src/ui/frame_modes.ts +13 -17
- package/frontend/src/ui/google_map.ts +15 -13
- package/frontend/src/ui/gradient.ts +9 -8
- package/frontend/src/ui/image.ts +108 -86
- package/frontend/src/ui/input.ts +145 -144
- package/frontend/src/ui/link.ts +25 -23
- package/frontend/src/ui/list.ts +12 -6
- package/frontend/src/ui/loader_button.ts +26 -25
- package/frontend/src/ui/loaders.ts +12 -11
- package/frontend/src/ui/popup.ts +168 -14
- package/frontend/src/ui/pseudo.ts +5 -3
- package/frontend/src/ui/scroller.ts +303 -294
- package/frontend/src/ui/slider.ts +15 -10
- package/frontend/src/ui/spacer.ts +14 -11
- package/frontend/src/ui/span.ts +6 -2
- package/frontend/src/ui/stack.ts +196 -183
- package/frontend/src/ui/steps.ts +38 -22
- package/frontend/src/ui/style.ts +7 -4
- package/frontend/src/ui/switch.ts +16 -11
- package/frontend/src/ui/table.ts +42 -34
- package/frontend/src/ui/tabs.ts +20 -19
- package/frontend/src/ui/text.ts +12 -11
- package/frontend/src/ui/title.ts +22 -20
- package/frontend/src/ui/ui.ts +0 -2
- package/frontend/src/ui/view.ts +20 -19
- package/frontend/src/volt.ts +3 -1
- package/frontend/{compile.js → tools/compile.old.js} +2 -2
- package/frontend/tools/embed_scripts.js +69 -0
- package/frontend/tsconfig.json +26 -0
- package/package.json +8 -8
- package/frontend/dist/ui/theme.d.ts +0 -25
- package/frontend/exports.json +0 -1340
- package/frontend/src/modules/date.js +0 -535
- package/frontend/src/ui/color.ts +0 -117
- package/frontend/src/ui/theme.ts +0 -279
- /package/backend/src/{vinc.dev.js → vinc.dev.ts} +0 -0
package/backend/src/status.ts
CHANGED
package/backend/src/stream.ts
CHANGED
|
@@ -748,6 +748,8 @@ export class Stream {
|
|
|
748
748
|
compress?: boolean
|
|
749
749
|
} = {}): this {
|
|
750
750
|
|
|
751
|
+
compress = false; // @todo @tmp
|
|
752
|
+
|
|
751
753
|
// Copy body.
|
|
752
754
|
if (data != null) {
|
|
753
755
|
body = data;
|
|
@@ -777,14 +779,14 @@ export class Stream {
|
|
|
777
779
|
body = JSON.stringify(body);
|
|
778
780
|
}
|
|
779
781
|
|
|
780
|
-
// Respond.
|
|
781
|
-
stream.respond(this.res_headers as any)
|
|
782
|
-
|
|
783
782
|
// Compress.
|
|
784
783
|
if (compress) {
|
|
785
784
|
body = zlib.gzipSync(body, {level: zlib.constants.Z_BEST_COMPRESSION});
|
|
786
785
|
}
|
|
787
786
|
|
|
787
|
+
// Respond.
|
|
788
|
+
stream.respond(this.res_headers as any)
|
|
789
|
+
|
|
788
790
|
// End.
|
|
789
791
|
if (body != null) {
|
|
790
792
|
stream.end(Buffer.from(body));
|
|
@@ -913,14 +915,32 @@ export class Stream {
|
|
|
913
915
|
* ...
|
|
914
916
|
* stream.error({data: "Some error occured"});
|
|
915
917
|
*/
|
|
916
|
-
error({
|
|
918
|
+
error({
|
|
919
|
+
message,
|
|
920
|
+
type = "APIError",
|
|
921
|
+
invalid_fields = {},
|
|
922
|
+
status = 500,
|
|
923
|
+
headers = {},
|
|
924
|
+
compress = false,
|
|
925
|
+
data = undefined,
|
|
926
|
+
}: {
|
|
927
|
+
message: string,
|
|
928
|
+
type?: string,
|
|
929
|
+
invalid_fields?: Record<string, string>,
|
|
917
930
|
status?: number,
|
|
918
931
|
headers?: Record<string, any>,
|
|
919
|
-
body?: any,
|
|
920
|
-
data?: any,
|
|
921
932
|
compress?: boolean
|
|
922
|
-
|
|
923
|
-
|
|
933
|
+
data?: any[] | Record<string, any>,
|
|
934
|
+
}): this {
|
|
935
|
+
return this.send({ status: status, headers: headers, compress: compress, body: {
|
|
936
|
+
error: {
|
|
937
|
+
type,
|
|
938
|
+
message,
|
|
939
|
+
status,
|
|
940
|
+
invalid_fields,
|
|
941
|
+
},
|
|
942
|
+
data,
|
|
943
|
+
}});
|
|
924
944
|
}
|
|
925
945
|
|
|
926
946
|
// Set headers.
|
package/backend/src/users.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { vhighlight } from "@vinc";
|
|
|
11
11
|
import * as utils from "./utils.js";
|
|
12
12
|
import * as Mail from "./plugins/mail.js";
|
|
13
13
|
import { Status } from "./status.js";
|
|
14
|
-
const {
|
|
14
|
+
const { APIError } = utils;
|
|
15
15
|
import { logger } from "./logger.js";
|
|
16
16
|
import { Stream, AuthStream } from "./stream.js"
|
|
17
17
|
import { Server, MailAttachment } from "./server.js"
|
|
@@ -319,16 +319,16 @@ export class Users {
|
|
|
319
319
|
// Initialization (private).
|
|
320
320
|
|
|
321
321
|
// Initialize.
|
|
322
|
-
_initialize(): void {
|
|
322
|
+
async _initialize(): Promise<void> {
|
|
323
323
|
|
|
324
324
|
// Database collections.
|
|
325
|
-
this._tokens_db = this.server.db.create_uid_collection("_tokens");
|
|
326
|
-
this._users_db = this.server.db.create_uid_collection("_users");
|
|
325
|
+
this._tokens_db = await this.server.db.create_uid_collection("_tokens");
|
|
326
|
+
this._users_db = await this.server.db.create_uid_collection("_users");
|
|
327
327
|
|
|
328
328
|
// Public database collections.
|
|
329
|
-
this.public = this.server.db.create_uid_collection("_users_public");
|
|
330
|
-
this.protected = this.server.db.create_uid_collection("_users_protected");
|
|
331
|
-
this.private = this.server.db.create_uid_collection("_users_private");
|
|
329
|
+
this.public = await this.server.db.create_uid_collection("_users_public");
|
|
330
|
+
this.protected = await this.server.db.create_uid_collection("_users_protected");
|
|
331
|
+
this.private = await this.server.db.create_uid_collection("_users_private");
|
|
332
332
|
|
|
333
333
|
// ---------------------------------------------------------
|
|
334
334
|
// Default auth endpoints.
|
|
@@ -391,12 +391,20 @@ export class Users {
|
|
|
391
391
|
username_err = err as Error;
|
|
392
392
|
}
|
|
393
393
|
if (email_err && username_err) {
|
|
394
|
-
return stream.error({
|
|
394
|
+
return stream.error({
|
|
395
|
+
status: Status.bad_request,
|
|
396
|
+
type: "InvalidParams",
|
|
397
|
+
message: email_err.message,
|
|
398
|
+
});
|
|
395
399
|
}
|
|
396
400
|
try {
|
|
397
401
|
password = stream.param("password");
|
|
398
402
|
} catch (err) {
|
|
399
|
-
return stream.error({
|
|
403
|
+
return stream.error({
|
|
404
|
+
status: Status.bad_request,
|
|
405
|
+
type: "InvalidParams",
|
|
406
|
+
message: (err as any).message,
|
|
407
|
+
});
|
|
400
408
|
}
|
|
401
409
|
|
|
402
410
|
// Get uid.
|
|
@@ -404,26 +412,24 @@ export class Users {
|
|
|
404
412
|
if ((uid = await this.get_uid_by_email(email)) == null) {
|
|
405
413
|
return stream.error({
|
|
406
414
|
status: Status.unauthorized,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
415
|
+
type: "Unauthorized",
|
|
416
|
+
message: "Unauthorized.",
|
|
417
|
+
invalid_fields: {
|
|
418
|
+
"email": "Invalid or unrecognized email",
|
|
419
|
+
"password": "Invalid or unrecognized password",
|
|
420
|
+
},
|
|
414
421
|
});
|
|
415
422
|
}
|
|
416
423
|
} else {
|
|
417
424
|
if ((uid = await this.get_uid(username as string)) == null) {
|
|
418
425
|
return stream.error({
|
|
419
426
|
status: Status.unauthorized,
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
427
|
+
type: "Unauthorized",
|
|
428
|
+
message: "Unauthorized.",
|
|
429
|
+
invalid_fields: {
|
|
430
|
+
"username": "Invalid or unrecognized username",
|
|
431
|
+
"password": "Invalid or unrecognized password",
|
|
432
|
+
},
|
|
427
433
|
});
|
|
428
434
|
}
|
|
429
435
|
}
|
|
@@ -539,23 +545,28 @@ export class Users {
|
|
|
539
545
|
if (error) {
|
|
540
546
|
return stream.error({
|
|
541
547
|
status: Status.bad_request,
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
548
|
+
type: "InvalidParams",
|
|
549
|
+
message: error,
|
|
550
|
+
invalid_fields: invalid_fields ?? undefined,
|
|
546
551
|
});
|
|
547
552
|
}
|
|
548
553
|
|
|
549
554
|
// Verify username and email.
|
|
550
555
|
if (await this.username_exists(params.username)) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
556
|
+
throw new APIError({
|
|
557
|
+
type: "UsernameAlreadyExists",
|
|
558
|
+
message: `Username "${params.username}" is already registered.`,
|
|
559
|
+
status: Status.bad_request,
|
|
560
|
+
invalid_fields: { "username": "Username is already registered" },
|
|
561
|
+
});
|
|
554
562
|
}
|
|
555
563
|
if (await this.email_exists(params.email)) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
564
|
+
throw new APIError({
|
|
565
|
+
type: "EmailAlreadyExists",
|
|
566
|
+
message: `Email "${params.email}" is already registered.`,
|
|
567
|
+
status: Status.bad_request,
|
|
568
|
+
invalid_fields: { "email": "Email is already registered" }
|
|
569
|
+
});
|
|
559
570
|
}
|
|
560
571
|
|
|
561
572
|
// Verify 2fa.
|
|
@@ -611,10 +622,9 @@ export class Users {
|
|
|
611
622
|
} catch (err) {
|
|
612
623
|
return stream.error({
|
|
613
624
|
status: Status.bad_request,
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}
|
|
625
|
+
type: "InvalidParams",
|
|
626
|
+
message: (err as Error).message,
|
|
627
|
+
invalid_fields: (err as any).invalid_fields || {},
|
|
618
628
|
});
|
|
619
629
|
}
|
|
620
630
|
|
|
@@ -646,7 +656,7 @@ export class Users {
|
|
|
646
656
|
|
|
647
657
|
// Check uid.
|
|
648
658
|
if (uid == null) {
|
|
649
|
-
return stream.error({ status: Status.forbidden,
|
|
659
|
+
return stream.error({ status: Status.forbidden, message: "Permission denied." });
|
|
650
660
|
}
|
|
651
661
|
|
|
652
662
|
// Verify.
|
|
@@ -654,12 +664,10 @@ export class Users {
|
|
|
654
664
|
if (err) {
|
|
655
665
|
return stream.error({
|
|
656
666
|
status: Status.forbidden,
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
},
|
|
662
|
-
}
|
|
667
|
+
message: "Permission denied.",
|
|
668
|
+
invalid_fields: {
|
|
669
|
+
"code": err,
|
|
670
|
+
},
|
|
663
671
|
});
|
|
664
672
|
}
|
|
665
673
|
|
|
@@ -690,17 +698,15 @@ export class Users {
|
|
|
690
698
|
if (error) {
|
|
691
699
|
return stream.error({
|
|
692
700
|
status: Status.bad_request,
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
invalid_fields,
|
|
696
|
-
}
|
|
701
|
+
message: error,
|
|
702
|
+
invalid_fields: invalid_fields ?? undefined,
|
|
697
703
|
});
|
|
698
704
|
}
|
|
699
705
|
|
|
700
706
|
// Get uid.
|
|
701
707
|
let uid;
|
|
702
708
|
if ((uid = await this.get_uid_by_email(params.email)) == null) {
|
|
703
|
-
return stream.error({ status: Status.forbidden,
|
|
709
|
+
return stream.error({ status: Status.forbidden, message: "Invalid email." });
|
|
704
710
|
}
|
|
705
711
|
|
|
706
712
|
// Verify 2fa.
|
|
@@ -708,12 +714,10 @@ export class Users {
|
|
|
708
714
|
if (err) {
|
|
709
715
|
return stream.error({
|
|
710
716
|
status: Status.forbidden,
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
},
|
|
716
|
-
}
|
|
717
|
+
message: "Invalid 2FA code.",
|
|
718
|
+
invalid_fields: {
|
|
719
|
+
"code": "Invalid code"
|
|
720
|
+
},
|
|
717
721
|
});
|
|
718
722
|
}
|
|
719
723
|
|
|
@@ -765,6 +769,7 @@ export class Users {
|
|
|
765
769
|
{
|
|
766
770
|
method: "POST",
|
|
767
771
|
endpoint: "/volt/user",
|
|
772
|
+
content_type: "application/json",
|
|
768
773
|
authenticated: true,
|
|
769
774
|
rate_limit: "global",
|
|
770
775
|
callback: async (stream: AuthStream) => {
|
|
@@ -778,6 +783,7 @@ export class Users {
|
|
|
778
783
|
{
|
|
779
784
|
method: "POST",
|
|
780
785
|
endpoint: "/volt/user/change_password",
|
|
786
|
+
content_type: "application/json",
|
|
781
787
|
authenticated: true,
|
|
782
788
|
rate_limit: "global",
|
|
783
789
|
params: {
|
|
@@ -790,12 +796,10 @@ export class Users {
|
|
|
790
796
|
if (await this.verify_password(stream.uid, params.current_password) !== true) {
|
|
791
797
|
return stream.error({
|
|
792
798
|
status: Status.unauthorized,
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
}
|
|
798
|
-
},
|
|
799
|
+
message: "Incorrect password.",
|
|
800
|
+
invalid_fields: {
|
|
801
|
+
current_password: "Incorrect password.",
|
|
802
|
+
}
|
|
799
803
|
});
|
|
800
804
|
}
|
|
801
805
|
|
|
@@ -804,10 +808,8 @@ export class Users {
|
|
|
804
808
|
if (error) {
|
|
805
809
|
return stream.error({
|
|
806
810
|
status: Status.bad_request,
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
invalid_fields,
|
|
810
|
-
}
|
|
811
|
+
message: error,
|
|
812
|
+
invalid_fields: invalid_fields ?? undefined,
|
|
811
813
|
});
|
|
812
814
|
}
|
|
813
815
|
|
|
@@ -826,6 +828,7 @@ export class Users {
|
|
|
826
828
|
{
|
|
827
829
|
method: "DELETE",
|
|
828
830
|
endpoint: "/volt/user",
|
|
831
|
+
content_type: "application/json",
|
|
829
832
|
authenticated: true,
|
|
830
833
|
rate_limit: "global",
|
|
831
834
|
callback: async (stream: AuthStream) => {
|
|
@@ -847,6 +850,7 @@ export class Users {
|
|
|
847
850
|
{
|
|
848
851
|
method: "POST",
|
|
849
852
|
endpoint: "/volt/user/api_key",
|
|
853
|
+
content_type: "application/json",
|
|
850
854
|
authenticated: true,
|
|
851
855
|
rate_limit: "global",
|
|
852
856
|
callback: async (stream: AuthStream) => {
|
|
@@ -863,6 +867,7 @@ export class Users {
|
|
|
863
867
|
{
|
|
864
868
|
method: "DELETE",
|
|
865
869
|
endpoint: "/volt/user/api_key",
|
|
870
|
+
content_type: "application/json",
|
|
866
871
|
authenticated: true,
|
|
867
872
|
rate_limit: "global",
|
|
868
873
|
callback: async (stream: AuthStream) => {
|
|
@@ -878,6 +883,7 @@ export class Users {
|
|
|
878
883
|
{
|
|
879
884
|
method: "GET",
|
|
880
885
|
endpoint: "/volt/user/data",
|
|
886
|
+
content_type: "application/json",
|
|
881
887
|
authenticated: true,
|
|
882
888
|
rate_limit: "global",
|
|
883
889
|
params: {
|
|
@@ -896,6 +902,7 @@ export class Users {
|
|
|
896
902
|
{
|
|
897
903
|
method: "POST",
|
|
898
904
|
endpoint: "/volt/user/data",
|
|
905
|
+
content_type: "application/json",
|
|
899
906
|
authenticated: true,
|
|
900
907
|
rate_limit: "global",
|
|
901
908
|
params: {
|
|
@@ -915,6 +922,7 @@ export class Users {
|
|
|
915
922
|
{
|
|
916
923
|
method: "DELETE",
|
|
917
924
|
endpoint: "/volt/user/data",
|
|
925
|
+
content_type: "application/json",
|
|
918
926
|
authenticated: true,
|
|
919
927
|
rate_limit: "global",
|
|
920
928
|
params: {
|
|
@@ -935,6 +943,7 @@ export class Users {
|
|
|
935
943
|
{
|
|
936
944
|
method: "GET",
|
|
937
945
|
endpoint: "/volt/user/data/protected",
|
|
946
|
+
content_type: "application/json",
|
|
938
947
|
authenticated: true,
|
|
939
948
|
rate_limit: "global",
|
|
940
949
|
params: {
|
|
@@ -995,7 +1004,7 @@ export class Users {
|
|
|
995
1004
|
first_name = stream.param("first_name");
|
|
996
1005
|
last_name = stream.param("last_name");
|
|
997
1006
|
} catch (err) {
|
|
998
|
-
return stream.error({ status: Status.bad_request,
|
|
1007
|
+
return stream.error({ status: Status.bad_request, message: (err as Error).message });
|
|
999
1008
|
}
|
|
1000
1009
|
} else {
|
|
1001
1010
|
user = await this.get(stream.uid);
|
|
@@ -1246,14 +1255,20 @@ export class Users {
|
|
|
1246
1255
|
// Check if username & email already exist.
|
|
1247
1256
|
if (_check_username_email) {
|
|
1248
1257
|
if (await this.username_exists(username)) {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1258
|
+
throw new APIError({
|
|
1259
|
+
type: "UsernameAlreadyExists",
|
|
1260
|
+
message: `Username "${username}" is already registered.`,
|
|
1261
|
+
status: Status.bad_request,
|
|
1262
|
+
invalid_fields: { "username": "Username is already registered" },
|
|
1263
|
+
});
|
|
1252
1264
|
}
|
|
1253
1265
|
if (await this.email_exists(email)) {
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1266
|
+
throw new APIError({
|
|
1267
|
+
type: "EmailAlreadyExists",
|
|
1268
|
+
message: `Email "${email}" is already registered.`,
|
|
1269
|
+
status: Status.bad_request,
|
|
1270
|
+
invalid_fields: { "email": "Email is already registered" }
|
|
1271
|
+
});
|
|
1257
1272
|
}
|
|
1258
1273
|
}
|
|
1259
1274
|
|
package/backend/src/utils.ts
CHANGED
|
@@ -8,10 +8,46 @@
|
|
|
8
8
|
|
|
9
9
|
import * as libcrypto from "crypto";
|
|
10
10
|
import { vlib } from "@vinc";
|
|
11
|
+
import { Status } from "./status.js";
|
|
12
|
+
import type { Stream } from "./stream.js";
|
|
11
13
|
|
|
12
14
|
// ---------------------------------------------------------
|
|
13
15
|
// Utils.
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* The API error class is used to throw an error that will be presented to the user. All other errors will result in an internal server error response without the error's message.
|
|
19
|
+
*/
|
|
20
|
+
export class APIError extends Error {
|
|
21
|
+
public type: string;
|
|
22
|
+
public status: number;
|
|
23
|
+
public data?: any[] | Record<string, any>;
|
|
24
|
+
public invalid_fields: Record<string, string>;
|
|
25
|
+
constructor({ type = "APIError", message, status, data, invalid_fields }: {
|
|
26
|
+
type?: string,
|
|
27
|
+
message: string,
|
|
28
|
+
status?: number,
|
|
29
|
+
data?: any,
|
|
30
|
+
invalid_fields?: Record<string, string>,
|
|
31
|
+
}) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "APIError";
|
|
34
|
+
this.type = type;
|
|
35
|
+
this.status = status ?? Status.internal_server_error;
|
|
36
|
+
this.data = data;
|
|
37
|
+
this.invalid_fields = invalid_fields ?? {};
|
|
38
|
+
}
|
|
39
|
+
serve(stream: Stream) {
|
|
40
|
+
stream.error({
|
|
41
|
+
status: this.status ?? Status.internal_server_error,
|
|
42
|
+
headers: {"Content-Type": "application/json"},
|
|
43
|
+
message: this.message,
|
|
44
|
+
type: this.type,
|
|
45
|
+
invalid_fields: this.invalid_fields,
|
|
46
|
+
});
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
/* @docs:
|
|
16
52
|
* @nav: Backend
|
|
17
53
|
@parent: Utils
|
|
@@ -35,21 +71,21 @@ import { vlib } from "@vinc";
|
|
|
35
71
|
@descr: The error body data.
|
|
36
72
|
@type: any
|
|
37
73
|
*/
|
|
38
|
-
export class FrontendError extends Error {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
74
|
+
// export class FrontendError extends Error {
|
|
75
|
+
// public name: string;
|
|
76
|
+
// public status?: number;
|
|
77
|
+
// public data?: any;
|
|
78
|
+
// public invalid_fields: Record<string, string> = {};
|
|
79
|
+
// constructor(message: string, status?: number, data?: any, invalid_fields?: Record<string, string>) {
|
|
80
|
+
// super(message);
|
|
81
|
+
// this.name = "FrontendError";
|
|
82
|
+
// this.status = status;
|
|
83
|
+
// this.data = data;
|
|
84
|
+
// if (invalid_fields !== undefined) {
|
|
85
|
+
// this.invalid_fields = invalid_fields;
|
|
86
|
+
// }
|
|
87
|
+
// }
|
|
88
|
+
// }
|
|
53
89
|
|
|
54
90
|
/* @docs:
|
|
55
91
|
* @nav: Backend
|
|
@@ -74,16 +110,15 @@ export class FrontendError extends Error {
|
|
|
74
110
|
@descr: The error body data.
|
|
75
111
|
@type: any
|
|
76
112
|
*/
|
|
77
|
-
export class APIError extends FrontendError {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
113
|
+
// export class APIError extends FrontendError {
|
|
114
|
+
// constructor(message: string, status?: number, data?: any, invalid_fields?: Record<string, string>) {
|
|
115
|
+
// super(message, status, data, invalid_fields);
|
|
116
|
+
// this.name = "APIError";
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
83
119
|
|
|
84
120
|
// Define interface with overloads
|
|
85
121
|
interface UtilsInt {
|
|
86
|
-
"FrontendError": typeof FrontendError; // Replace with actual type
|
|
87
122
|
"APIError": typeof APIError; // Replace with actual type
|
|
88
123
|
|
|
89
124
|
// Overload signatures in interface
|
|
@@ -100,9 +135,6 @@ interface UtilsInt {
|
|
|
100
135
|
// Implementation
|
|
101
136
|
export const Utils: UtilsInt = {
|
|
102
137
|
|
|
103
|
-
// An error that may be shown to the frontend user.
|
|
104
|
-
"FrontendError": FrontendError,
|
|
105
|
-
|
|
106
138
|
// An error that may be shown to the frontend user.
|
|
107
139
|
"APIError": APIError,
|
|
108
140
|
|
|
@@ -356,4 +388,5 @@ export const Utils: UtilsInt = {
|
|
|
356
388
|
},
|
|
357
389
|
|
|
358
390
|
}
|
|
391
|
+
export { Utils as utils }; // lowercase export for compatibility
|
|
359
392
|
export default Utils;
|
package/backend/src/view.ts
CHANGED
|
@@ -164,7 +164,7 @@ export class View {
|
|
|
164
164
|
is_js_ts_view: boolean;
|
|
165
165
|
html?: string | Buffer;
|
|
166
166
|
raw_html?: string | Buffer;
|
|
167
|
-
|
|
167
|
+
_bundle: any;
|
|
168
168
|
payments?: string | undefined;
|
|
169
169
|
// vhighlight?: string | undefined;
|
|
170
170
|
min_device_width?: number;
|
|
@@ -245,7 +245,7 @@ export class View {
|
|
|
245
245
|
|
|
246
246
|
// Attributes.
|
|
247
247
|
this.html = undefined;
|
|
248
|
-
this.
|
|
248
|
+
this._bundle = undefined;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
// Initialize.
|
|
@@ -256,21 +256,22 @@ export class View {
|
|
|
256
256
|
this._endpoint = endpoint;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
// Bundle the compiled typescript / javascript
|
|
260
|
-
async
|
|
259
|
+
// Bundle the compiled typescript / javascript dynamically on demand to optimize server startup for development purposes.
|
|
260
|
+
async _dynamic_bundle() {
|
|
261
|
+
|
|
261
262
|
// Server & endpoint.
|
|
262
263
|
if (this._server === undefined || this._endpoint === undefined) { throw Error("View has not been initialized with \"View._initialize()\" yet."); }
|
|
263
264
|
|
|
264
265
|
// Bundle.
|
|
265
|
-
const had_bundle = this.bundle !== undefined;
|
|
266
|
-
if (bundle != null) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
} else {
|
|
270
|
-
|
|
271
|
-
this.
|
|
272
|
-
entry_paths: [
|
|
273
|
-
minify: this._server.production,
|
|
266
|
+
// const had_bundle = this.bundle !== undefined;
|
|
267
|
+
// if (bundle != null) {
|
|
268
|
+
// // also accept already bundled for server.js in case multiple endpoint paths serve the same bundle.
|
|
269
|
+
// this.bundle = bundle;
|
|
270
|
+
// } else {
|
|
271
|
+
logger.log(2, log_source, `Bundling entry path "${this.source_path?.str()}".`)
|
|
272
|
+
this._bundle = await TSCompiler.bundle({
|
|
273
|
+
entry_paths: [this.source_path?.str() ?? ""],
|
|
274
|
+
minify: false,//this._server.production,
|
|
274
275
|
platform: "browser",
|
|
275
276
|
// format: "esm",
|
|
276
277
|
format: "iife",
|
|
@@ -278,29 +279,25 @@ export class View {
|
|
|
278
279
|
// target: "esnext",
|
|
279
280
|
// sourcemap: this._server.production ? false : "inline",
|
|
280
281
|
extract_inputs: true, // since bundle.inputs is used by server.js.
|
|
281
|
-
tree_shaking:
|
|
282
|
+
tree_shaking: false,
|
|
282
283
|
})
|
|
283
|
-
if (this.
|
|
284
|
+
if (this._bundle.errors.length > 0) {
|
|
284
285
|
logger.log(0, log_source, `Encountered an error while bundling "${this.source}".`)
|
|
285
|
-
this.
|
|
286
|
+
this._bundle.debug();
|
|
286
287
|
return;
|
|
287
288
|
}
|
|
288
|
-
}
|
|
289
|
+
// }
|
|
289
290
|
|
|
290
291
|
// Set options based on inputs.
|
|
291
|
-
this.payments = this.
|
|
292
|
+
this.payments = this._bundle.inputs.find((path: string) => path.endsWith("/modules/paddle.js"));
|
|
292
293
|
// this.vhighlight = this.bundle.inputs.find((path: string) => path.endsWith("/vhighlight.js"));
|
|
293
294
|
|
|
294
295
|
// Rebuild html.
|
|
295
296
|
await this._build_html();
|
|
296
|
-
|
|
297
|
-
logger.log(0, log_source, `Refreshing endpoint ${this._endpoint.method}:${this._endpoint.endpoint}.`)
|
|
298
|
-
} else {
|
|
299
|
-
logger.log(1, log_source, `Refreshing endpoint ${this._endpoint.method}:${this._endpoint.endpoint}.`)
|
|
300
|
-
}
|
|
297
|
+
logger.log(0, log_source, `Bundling javascript endpoint ${this._endpoint.method}:${this._endpoint.endpoint}.`)
|
|
301
298
|
|
|
302
299
|
// Response.
|
|
303
|
-
return this.bundle;
|
|
300
|
+
// return this.bundle;
|
|
304
301
|
}
|
|
305
302
|
|
|
306
303
|
// Build html.
|
|
@@ -308,9 +305,14 @@ export class View {
|
|
|
308
305
|
// Server & endpoint.
|
|
309
306
|
if (this._server === undefined || this._endpoint === undefined) { throw Error("View has not been initialized with \"View._initialize()\" yet."); }
|
|
310
307
|
|
|
308
|
+
// Bundle js files automatically.
|
|
309
|
+
if (this.is_js_ts_view && !this._bundle) {
|
|
310
|
+
await this._dynamic_bundle();
|
|
311
|
+
}
|
|
312
|
+
|
|
311
313
|
// Vars.
|
|
312
|
-
const line_break = this._server.production ? "" : "\n";
|
|
313
|
-
const has_bundle = this.
|
|
314
|
+
const line_break = this._server.production ? "\n" : "\n";
|
|
315
|
+
const has_bundle = this._bundle != null && typeof this._bundle === "object";
|
|
314
316
|
|
|
315
317
|
// Initialize html.
|
|
316
318
|
this.html = "";
|
|
@@ -590,8 +592,8 @@ export class View {
|
|
|
590
592
|
})
|
|
591
593
|
|
|
592
594
|
// Add direct source code.
|
|
593
|
-
if (has_bundle && typeof this.
|
|
594
|
-
this.html += `<script type='module'>${line_break}${this.
|
|
595
|
+
if (has_bundle && typeof this._bundle.code === "string") {
|
|
596
|
+
this.html += `<script type='module'>${line_break}${this._bundle.code}${line_break}</script>${line_break}`;
|
|
595
597
|
}
|
|
596
598
|
|
|
597
599
|
// Include the source.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// Exports.
|
|
8
8
|
|
|
9
9
|
// Create volt lib.
|
|
10
|
-
export {
|
|
10
|
+
export { APIError } from "./utils.js"
|
|
11
11
|
export * from "./status.js"
|
|
12
12
|
export * from "./meta.js"
|
|
13
13
|
export * from "./splash_screen.js"
|
|
@@ -22,4 +22,5 @@ export * from "./file_watcher.js"
|
|
|
22
22
|
export * as Mail from "./plugins/mail.js"
|
|
23
23
|
// export * as PDF from "./plugins/pdf.js"
|
|
24
24
|
export * as TypeScript from "./plugins/ts/compiler.js"
|
|
25
|
+
export * from "./plugins/css.js"
|
|
25
26
|
export * from "./frontend.js"
|