@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.
Files changed (287) hide show
  1. package/backend/dist/cjs/database.d.ts +41 -68
  2. package/backend/dist/cjs/database.js +127 -76
  3. package/backend/dist/cjs/endpoint.d.ts +23 -9
  4. package/backend/dist/cjs/endpoint.js +98 -21
  5. package/backend/dist/cjs/frontend.d.ts +0 -2
  6. package/backend/dist/cjs/frontend.js +9 -9
  7. package/backend/dist/cjs/image_endpoint.d.ts +3 -1
  8. package/backend/dist/cjs/image_endpoint.js +2 -1
  9. package/backend/dist/cjs/payments/paddle.js +10 -2
  10. package/backend/dist/cjs/plugins/css.d.ts +6 -5
  11. package/backend/dist/cjs/plugins/css.js +32 -7
  12. package/backend/dist/cjs/plugins/ts/compiler.d.ts +6 -1
  13. package/backend/dist/cjs/plugins/ts/compiler.js +26 -2
  14. package/backend/dist/cjs/plugins/ts/preprocessing.js +5 -3
  15. package/backend/dist/cjs/server.d.ts +7 -13
  16. package/backend/dist/cjs/server.js +184 -303
  17. package/backend/dist/cjs/status.d.ts +1 -0
  18. package/backend/dist/cjs/status.js +2 -1
  19. package/backend/dist/cjs/stream.d.ts +5 -3
  20. package/backend/dist/cjs/stream.js +13 -4
  21. package/backend/dist/cjs/users.d.ts +1 -1
  22. package/backend/dist/cjs/users.js +87 -72
  23. package/backend/dist/cjs/utils.d.ts +17 -9
  24. package/backend/dist/cjs/utils.js +22 -64
  25. package/backend/dist/cjs/view.d.ts +2 -2
  26. package/backend/dist/cjs/view.js +38 -40
  27. package/backend/dist/cjs/volt.d.ts +3 -2
  28. package/backend/dist/cjs/volt.js +2 -2
  29. package/backend/dist/css/volt.css +5 -0
  30. package/backend/dist/esm/database.d.ts +41 -68
  31. package/backend/dist/esm/database.js +127 -76
  32. package/backend/dist/esm/endpoint.d.ts +23 -9
  33. package/backend/dist/esm/endpoint.js +99 -22
  34. package/backend/dist/esm/frontend.d.ts +0 -2
  35. package/backend/dist/esm/frontend.js +9 -9
  36. package/backend/dist/esm/image_endpoint.d.ts +3 -1
  37. package/backend/dist/esm/image_endpoint.js +2 -1
  38. package/backend/dist/esm/payments/paddle.js +11 -3
  39. package/backend/dist/esm/plugins/css.d.ts +6 -5
  40. package/backend/dist/esm/plugins/css.js +32 -6
  41. package/backend/dist/esm/plugins/ts/compiler.d.ts +6 -1
  42. package/backend/dist/esm/plugins/ts/compiler.js +26 -2
  43. package/backend/dist/esm/plugins/ts/preprocessing.js +5 -3
  44. package/backend/dist/esm/server.d.ts +7 -13
  45. package/backend/dist/esm/server.js +182 -301
  46. package/backend/dist/esm/status.d.ts +1 -0
  47. package/backend/dist/esm/status.js +1 -0
  48. package/backend/dist/esm/stream.d.ts +5 -3
  49. package/backend/dist/esm/stream.js +13 -4
  50. package/backend/dist/esm/users.d.ts +1 -1
  51. package/backend/dist/esm/users.js +87 -72
  52. package/backend/dist/esm/utils.d.ts +17 -9
  53. package/backend/dist/esm/utils.js +21 -62
  54. package/backend/dist/esm/view.d.ts +2 -2
  55. package/backend/dist/esm/view.js +38 -40
  56. package/backend/dist/esm/volt.d.ts +3 -2
  57. package/backend/dist/esm/volt.js +2 -1
  58. package/backend/dist/esm-dev/blacklist.js +1 -1
  59. package/backend/dist/esm-dev/cli.js +2 -2
  60. package/backend/dist/esm-dev/database.d.ts +41 -68
  61. package/backend/dist/esm-dev/database.js +128 -77
  62. package/backend/dist/esm-dev/endpoint.d.ts +23 -9
  63. package/backend/dist/esm-dev/endpoint.js +100 -23
  64. package/backend/dist/esm-dev/file_watcher.js +1 -1
  65. package/backend/dist/esm-dev/frontend.d.ts +0 -2
  66. package/backend/dist/esm-dev/frontend.js +9 -9
  67. package/backend/dist/esm-dev/image_endpoint.d.ts +3 -1
  68. package/backend/dist/esm-dev/image_endpoint.js +2 -1
  69. package/backend/dist/esm-dev/logger.js +1 -1
  70. package/backend/dist/esm-dev/payments/paddle.js +12 -4
  71. package/backend/dist/esm-dev/plugins/css.d.ts +6 -5
  72. package/backend/dist/esm-dev/plugins/css.js +33 -7
  73. package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +6 -1
  74. package/backend/dist/esm-dev/plugins/ts/compiler.js +27 -3
  75. package/backend/dist/esm-dev/plugins/ts/preprocessing.js +7 -5
  76. package/backend/dist/esm-dev/rate_limit.js +1 -1
  77. package/backend/dist/esm-dev/server.d.ts +7 -13
  78. package/backend/dist/esm-dev/server.js +184 -303
  79. package/backend/dist/esm-dev/status.d.ts +1 -0
  80. package/backend/dist/esm-dev/status.js +1 -0
  81. package/backend/dist/esm-dev/stream.d.ts +5 -3
  82. package/backend/dist/esm-dev/stream.js +13 -4
  83. package/backend/dist/esm-dev/users.d.ts +1 -1
  84. package/backend/dist/esm-dev/users.js +88 -73
  85. package/backend/dist/esm-dev/utils.d.ts +17 -9
  86. package/backend/dist/esm-dev/utils.js +22 -63
  87. package/backend/dist/esm-dev/view.d.ts +2 -2
  88. package/backend/dist/esm-dev/view.js +39 -41
  89. package/backend/dist/esm-dev/volt.d.ts +3 -2
  90. package/backend/dist/esm-dev/volt.js +2 -1
  91. package/backend/src/database.ts +163 -152
  92. package/backend/src/endpoint.ts +123 -31
  93. package/backend/src/frontend.ts +9 -8
  94. package/backend/src/image_endpoint.ts +4 -0
  95. package/backend/src/payments/paddle.ts +11 -3
  96. package/backend/src/plugins/css.ts +36 -8
  97. package/backend/src/plugins/ts/compiler.ts +37 -1
  98. package/backend/src/plugins/ts/preprocessing.ts +5 -3
  99. package/backend/src/server.ts +167 -306
  100. package/backend/src/status.ts +1 -0
  101. package/backend/src/stream.ts +28 -8
  102. package/backend/src/users.ts +87 -72
  103. package/backend/src/utils.ts +58 -25
  104. package/backend/src/view.ts +30 -28
  105. package/backend/src/{volt.js → volt.ts} +2 -1
  106. package/backend/tsconfig.cjs.json +3 -3
  107. package/backend/tsconfig.esm.json +3 -3
  108. package/frontend/dist/elements/base.d.ts +397 -415
  109. package/frontend/dist/elements/base.js +565 -328
  110. package/frontend/dist/elements/module.d.ts +26 -12
  111. package/frontend/dist/elements/module.js +69 -32
  112. package/frontend/dist/elements/register_element.d.ts +3 -0
  113. package/frontend/dist/elements/register_element.js +22 -0
  114. package/frontend/dist/modules/auth.d.ts +1 -0
  115. package/frontend/dist/modules/auth.js +6 -5
  116. package/frontend/dist/modules/color.d.ts +159 -0
  117. package/frontend/dist/modules/color.js +315 -0
  118. package/frontend/dist/modules/colors.d.ts +1 -26
  119. package/frontend/dist/modules/colors.js +417 -338
  120. package/frontend/dist/modules/cookies.d.ts +1 -0
  121. package/frontend/dist/modules/cookies.js +1 -0
  122. package/frontend/dist/modules/events.d.ts +1 -0
  123. package/frontend/dist/modules/events.js +1 -0
  124. package/frontend/dist/modules/google.d.ts +1 -0
  125. package/frontend/dist/modules/google.js +1 -0
  126. package/frontend/dist/modules/meta.d.ts +1 -0
  127. package/frontend/dist/modules/meta.js +1 -0
  128. package/frontend/dist/modules/mutex.d.ts +1 -2
  129. package/frontend/dist/modules/mutex.js +3 -4
  130. package/frontend/dist/modules/paddle.d.ts +1 -0
  131. package/frontend/dist/modules/paddle.js +14 -13
  132. package/frontend/dist/modules/scheme.d.ts +1 -0
  133. package/frontend/dist/modules/scheme.js +4 -2
  134. package/frontend/dist/modules/statics.d.ts +1 -0
  135. package/frontend/dist/modules/statics.js +1 -0
  136. package/frontend/dist/modules/support.d.ts +1 -0
  137. package/frontend/dist/modules/support.js +3 -2
  138. package/frontend/dist/modules/theme.d.ts +56 -0
  139. package/frontend/dist/{ui → modules}/theme.js +186 -75
  140. package/frontend/dist/modules/themes.d.ts +1 -1
  141. package/frontend/dist/modules/themes.js +1 -0
  142. package/frontend/dist/modules/user.d.ts +1 -0
  143. package/frontend/dist/modules/user.js +11 -10
  144. package/frontend/dist/modules/utils.d.ts +23 -2
  145. package/frontend/dist/modules/utils.js +93 -1
  146. package/frontend/dist/types/gradient.js +4 -0
  147. package/frontend/dist/ui/border_button.d.ts +0 -25
  148. package/frontend/dist/ui/border_button.js +50 -51
  149. package/frontend/dist/ui/button.d.ts +0 -21
  150. package/frontend/dist/ui/button.js +41 -46
  151. package/frontend/dist/ui/canvas.js +15 -15
  152. package/frontend/dist/ui/checkbox.d.ts +3 -17
  153. package/frontend/dist/ui/checkbox.js +36 -30
  154. package/frontend/dist/ui/code.d.ts +15 -82
  155. package/frontend/dist/ui/code.js +150 -125
  156. package/frontend/dist/ui/color.d.ts +0 -1
  157. package/frontend/dist/ui/color.js +1 -1
  158. package/frontend/dist/ui/context_menu.d.ts +4 -2
  159. package/frontend/dist/ui/context_menu.js +16 -17
  160. package/frontend/dist/ui/css.js +2 -0
  161. package/frontend/dist/ui/divider.d.ts +0 -7
  162. package/frontend/dist/ui/divider.js +21 -25
  163. package/frontend/dist/ui/dropdown.d.ts +13 -7
  164. package/frontend/dist/ui/dropdown.js +65 -30
  165. package/frontend/dist/ui/for_each.d.ts +0 -5
  166. package/frontend/dist/ui/for_each.js +17 -22
  167. package/frontend/dist/ui/form.d.ts +17 -12
  168. package/frontend/dist/ui/form.js +21 -18
  169. package/frontend/dist/ui/frame_modes.d.ts +9 -12
  170. package/frontend/dist/ui/frame_modes.js +8 -10
  171. package/frontend/dist/ui/google_map.d.ts +0 -11
  172. package/frontend/dist/ui/google_map.js +23 -28
  173. package/frontend/dist/ui/gradient.d.ts +0 -5
  174. package/frontend/dist/ui/gradient.js +17 -22
  175. package/frontend/dist/ui/image.d.ts +27 -58
  176. package/frontend/dist/ui/image.js +99 -93
  177. package/frontend/dist/ui/input.d.ts +20 -97
  178. package/frontend/dist/ui/input.js +192 -170
  179. package/frontend/dist/ui/link.d.ts +0 -18
  180. package/frontend/dist/ui/link.js +42 -48
  181. package/frontend/dist/ui/list.js +36 -37
  182. package/frontend/dist/ui/loader_button.d.ts +4 -19
  183. package/frontend/dist/ui/loader_button.js +35 -37
  184. package/frontend/dist/ui/loaders.d.ts +0 -8
  185. package/frontend/dist/ui/loaders.js +20 -25
  186. package/frontend/dist/ui/popup.d.ts +11 -8
  187. package/frontend/dist/ui/popup.js +183 -24
  188. package/frontend/dist/ui/pseudo.d.ts +3 -3
  189. package/frontend/dist/ui/pseudo.js +14 -17
  190. package/frontend/dist/ui/scroller.d.ts +10 -48
  191. package/frontend/dist/ui/scroller.js +306 -300
  192. package/frontend/dist/ui/slider.d.ts +9 -3
  193. package/frontend/dist/ui/slider.js +31 -17
  194. package/frontend/dist/ui/spacer.d.ts +0 -9
  195. package/frontend/dist/ui/spacer.js +21 -26
  196. package/frontend/dist/ui/span.js +13 -15
  197. package/frontend/dist/ui/stack.d.ts +14 -75
  198. package/frontend/dist/ui/stack.js +166 -169
  199. package/frontend/dist/ui/steps.d.ts +10 -23
  200. package/frontend/dist/ui/steps.js +47 -34
  201. package/frontend/dist/ui/style.d.ts +4 -3
  202. package/frontend/dist/ui/style.js +13 -18
  203. package/frontend/dist/ui/switch.d.ts +10 -4
  204. package/frontend/dist/ui/switch.js +24 -16
  205. package/frontend/dist/ui/table.d.ts +0 -23
  206. package/frontend/dist/ui/table.js +113 -119
  207. package/frontend/dist/ui/tabs.d.ts +3 -19
  208. package/frontend/dist/ui/tabs.js +35 -29
  209. package/frontend/dist/ui/text.d.ts +0 -8
  210. package/frontend/dist/ui/text.js +20 -25
  211. package/frontend/dist/ui/title.d.ts +0 -15
  212. package/frontend/dist/ui/title.js +39 -45
  213. package/frontend/dist/ui/ui.d.ts +0 -2
  214. package/frontend/dist/ui/ui.js +0 -2
  215. package/frontend/dist/ui/view.d.ts +3 -17
  216. package/frontend/dist/ui/view.js +27 -32
  217. package/frontend/dist/volt.d.ts +2 -1
  218. package/frontend/dist/volt.js +3 -1
  219. package/frontend/examples/dashboard/dashboard.ts +774 -0
  220. package/frontend/examples/theme/theme.ts +58 -0
  221. package/frontend/src/css/volt.css +5 -0
  222. package/frontend/src/elements/base.ts +767 -545
  223. package/frontend/src/elements/module.ts +90 -29
  224. package/frontend/src/elements/register_element.ts +24 -0
  225. package/frontend/src/modules/auth.ts +7 -6
  226. package/frontend/src/modules/color.ts +348 -0
  227. package/frontend/src/modules/colors.ts +468 -449
  228. package/frontend/src/modules/cookies.ts +1 -0
  229. package/frontend/src/modules/events.ts +1 -0
  230. package/frontend/src/modules/google.ts +1 -0
  231. package/frontend/src/modules/meta.ts +2 -1
  232. package/frontend/src/modules/mutex.ts +2 -4
  233. package/frontend/src/modules/paddle.ts +21 -20
  234. package/frontend/src/modules/scheme.ts +4 -3
  235. package/frontend/src/modules/statics.ts +2 -1
  236. package/frontend/src/modules/support.ts +3 -2
  237. package/frontend/src/modules/theme.ts +413 -0
  238. package/frontend/src/modules/themes.ts +2 -1
  239. package/frontend/src/modules/user.ts +12 -11
  240. package/frontend/src/modules/utils.ts +125 -2
  241. package/frontend/src/ui/border_button.ts +41 -37
  242. package/frontend/src/ui/button.ts +33 -32
  243. package/frontend/src/ui/canvas.ts +5 -2
  244. package/frontend/src/ui/checkbox.ts +21 -22
  245. package/frontend/src/ui/code.ts +92 -86
  246. package/frontend/src/ui/context_menu.ts +7 -5
  247. package/frontend/src/ui/css.ts +1 -1
  248. package/frontend/src/ui/divider.ts +15 -10
  249. package/frontend/src/ui/dropdown.ts +38 -21
  250. package/frontend/src/ui/for_each.ts +9 -8
  251. package/frontend/src/ui/form.ts +26 -21
  252. package/frontend/src/ui/frame_modes.ts +13 -17
  253. package/frontend/src/ui/google_map.ts +15 -13
  254. package/frontend/src/ui/gradient.ts +9 -8
  255. package/frontend/src/ui/image.ts +108 -86
  256. package/frontend/src/ui/input.ts +145 -144
  257. package/frontend/src/ui/link.ts +25 -23
  258. package/frontend/src/ui/list.ts +12 -6
  259. package/frontend/src/ui/loader_button.ts +26 -25
  260. package/frontend/src/ui/loaders.ts +12 -11
  261. package/frontend/src/ui/popup.ts +168 -14
  262. package/frontend/src/ui/pseudo.ts +5 -3
  263. package/frontend/src/ui/scroller.ts +303 -294
  264. package/frontend/src/ui/slider.ts +15 -10
  265. package/frontend/src/ui/spacer.ts +14 -11
  266. package/frontend/src/ui/span.ts +6 -2
  267. package/frontend/src/ui/stack.ts +196 -183
  268. package/frontend/src/ui/steps.ts +38 -22
  269. package/frontend/src/ui/style.ts +7 -4
  270. package/frontend/src/ui/switch.ts +16 -11
  271. package/frontend/src/ui/table.ts +42 -34
  272. package/frontend/src/ui/tabs.ts +20 -19
  273. package/frontend/src/ui/text.ts +12 -11
  274. package/frontend/src/ui/title.ts +22 -20
  275. package/frontend/src/ui/ui.ts +0 -2
  276. package/frontend/src/ui/view.ts +20 -19
  277. package/frontend/src/volt.ts +3 -1
  278. package/frontend/{compile.js → tools/compile.old.js} +2 -2
  279. package/frontend/tools/embed_scripts.js +69 -0
  280. package/frontend/tsconfig.json +26 -0
  281. package/package.json +8 -8
  282. package/frontend/dist/ui/theme.d.ts +0 -25
  283. package/frontend/exports.json +0 -1340
  284. package/frontend/src/modules/date.js +0 -535
  285. package/frontend/src/ui/color.ts +0 -117
  286. package/frontend/src/ui/theme.ts +0 -279
  287. /package/backend/src/{vinc.dev.js → vinc.dev.ts} +0 -0
@@ -196,4 +196,5 @@ export const Status = {
196
196
  }
197
197
  }
198
198
  };
199
+ export { Status as status }; // lowercase export for compatibility
199
200
  export default Status;
@@ -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({status = 500, headers = {}, body = null, data = null, compress = false}: {
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
- } = {}): this {
923
- return this.send({status: status, headers: headers, body: body ?? data, compress: compress});
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.
@@ -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 { FrontendError } = utils;
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({ status: Status.bad_request, data: { error: email_err.message } });
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({ status: Status.bad_request, data: { error: (err as Error).message } });
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
- data: {
408
- error: "Unauthorized.",
409
- invalid_fields: {
410
- "email": "Invalid or unrecognized email",
411
- "password": "Invalid or unrecognized password",
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
- data: {
421
- error: "Unauthorized.",
422
- invalid_fields: {
423
- "username": "Invalid or unrecognized username",
424
- "password": "Invalid or unrecognized password",
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
- data: {
543
- error,
544
- invalid_fields,
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
- const e = new FrontendError(`Username "${params.username}" is already registered.`);
552
- e.invalid_fields = { "username": "Username is already registered" };
553
- throw e;
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
- const e = new FrontendError(`Email "${params.email}" is already registered.`);
557
- e.invalid_fields = { "email": "Email is already registered" };
558
- throw e;
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
- data: {
615
- error: (err as Error).message,
616
- invalid_fields: (err as any).invalid_fields || {},
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, data: { error: "Permission denied." } });
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
- data: {
658
- error: "Permission denied.",
659
- invalid_fields: {
660
- "code": err,
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
- data: {
694
- error: error,
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, data: { error: "Invalid email." } });
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
- data: {
712
- error: "Invalid 2FA code.",
713
- invalid_fields: {
714
- "code": "Invalid code"
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
- data: {
794
- error: "Incorrect password.",
795
- invalid_fields: {
796
- current_password: "Incorrect password.",
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
- data: {
808
- error: error,
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, data: { error: (err as Error).message } });
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
- const e = new FrontendError(`Username "${username}" is already registered.`);
1250
- e.invalid_fields = {"username": "Username is already registered"};
1251
- throw e;
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
- const e = new FrontendError(`Email "${email}" is already registered.`);
1255
- e.invalid_fields = {"email": "Email is already registered"};
1256
- throw e;
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
 
@@ -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
- public name: string;
40
- public status?: number;
41
- public data?: any;
42
- public invalid_fields: Record<string, string> = {};
43
- constructor(message: string, status?: number, data?: any, invalid_fields?: Record<string, string>) {
44
- super(message);
45
- this.name = "FrontendError";
46
- this.status = status;
47
- this.data = data;
48
- if (invalid_fields !== undefined) {
49
- this;invalid_fields = invalid_fields;
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
- constructor(message: string, status?: number, data?: any, invalid_fields?: Record<string, string>) {
79
- super(message, status, data, invalid_fields);
80
- this.name = "APIError";
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;
@@ -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
- bundle: any;
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.bundle = undefined;
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 view.
260
- async _bundle_ts(dist_path: string, bundle: any = null): Promise<any> {
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
- // also accept already bundled for server.js in case multiple endpoint paths serve the same bundle.
268
- this.bundle = bundle;
269
- } else {
270
- logger.log(2, log_source, `Bundling entry path "${dist_path}".`)
271
- this.bundle = await TSCompiler.bundle({
272
- entry_paths: [dist_path],
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: true,
282
+ tree_shaking: false,
282
283
  })
283
- if (this.bundle.errors.length > 0) {
284
+ if (this._bundle.errors.length > 0) {
284
285
  logger.log(0, log_source, `Encountered an error while bundling "${this.source}".`)
285
- this.bundle.debug();
286
+ this._bundle.debug();
286
287
  return;
287
288
  }
288
- }
289
+ // }
289
290
 
290
291
  // Set options based on inputs.
291
- this.payments = this.bundle.inputs.find((path: string) => path.endsWith("/modules/paddle.js"));
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
- if (had_bundle) {
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.bundle != null && typeof this.bundle === "object";
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.bundle.code === "string") {
594
- this.html += `<script type='module'>${line_break}${this.bundle.code}${line_break}</script>${line_break}`;
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 { FrontendError, APIError } from "./utils.js"
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"