@vandenberghinc/volt 1.1.4 → 1.1.6

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 (290) hide show
  1. package/backend/dist/cjs/database.d.ts +41 -68
  2. package/backend/dist/cjs/database.js +136 -78
  3. package/backend/dist/cjs/endpoint.d.ts +23 -9
  4. package/backend/dist/cjs/endpoint.js +98 -21
  5. package/backend/dist/cjs/file_watcher.js +2 -2
  6. package/backend/dist/cjs/frontend.d.ts +0 -2
  7. package/backend/dist/cjs/frontend.js +9 -9
  8. package/backend/dist/cjs/image_endpoint.d.ts +3 -1
  9. package/backend/dist/cjs/image_endpoint.js +2 -1
  10. package/backend/dist/cjs/payments/paddle.js +10 -2
  11. package/backend/dist/cjs/plugins/css.d.ts +6 -5
  12. package/backend/dist/cjs/plugins/css.js +32 -7
  13. package/backend/dist/cjs/plugins/ts/compiler.d.ts +6 -1
  14. package/backend/dist/cjs/plugins/ts/compiler.js +26 -2
  15. package/backend/dist/cjs/plugins/ts/preprocessing.js +5 -3
  16. package/backend/dist/cjs/server.d.ts +7 -13
  17. package/backend/dist/cjs/server.js +184 -303
  18. package/backend/dist/cjs/status.d.ts +1 -0
  19. package/backend/dist/cjs/status.js +2 -1
  20. package/backend/dist/cjs/stream.d.ts +5 -3
  21. package/backend/dist/cjs/stream.js +13 -4
  22. package/backend/dist/cjs/users.d.ts +1 -1
  23. package/backend/dist/cjs/users.js +87 -72
  24. package/backend/dist/cjs/utils.d.ts +17 -9
  25. package/backend/dist/cjs/utils.js +22 -64
  26. package/backend/dist/cjs/view.d.ts +2 -2
  27. package/backend/dist/cjs/view.js +38 -40
  28. package/backend/dist/cjs/volt.d.ts +3 -2
  29. package/backend/dist/cjs/volt.js +2 -2
  30. package/backend/dist/css/volt.css +5 -0
  31. package/backend/dist/esm/database.d.ts +41 -68
  32. package/backend/dist/esm/database.js +137 -79
  33. package/backend/dist/esm/endpoint.d.ts +23 -9
  34. package/backend/dist/esm/endpoint.js +99 -22
  35. package/backend/dist/esm/file_watcher.js +2 -2
  36. package/backend/dist/esm/frontend.d.ts +0 -2
  37. package/backend/dist/esm/frontend.js +9 -9
  38. package/backend/dist/esm/image_endpoint.d.ts +3 -1
  39. package/backend/dist/esm/image_endpoint.js +2 -1
  40. package/backend/dist/esm/payments/paddle.js +11 -3
  41. package/backend/dist/esm/plugins/css.d.ts +6 -5
  42. package/backend/dist/esm/plugins/css.js +32 -6
  43. package/backend/dist/esm/plugins/ts/compiler.d.ts +6 -1
  44. package/backend/dist/esm/plugins/ts/compiler.js +26 -2
  45. package/backend/dist/esm/plugins/ts/preprocessing.js +5 -3
  46. package/backend/dist/esm/server.d.ts +7 -13
  47. package/backend/dist/esm/server.js +182 -301
  48. package/backend/dist/esm/status.d.ts +1 -0
  49. package/backend/dist/esm/status.js +1 -0
  50. package/backend/dist/esm/stream.d.ts +5 -3
  51. package/backend/dist/esm/stream.js +13 -4
  52. package/backend/dist/esm/users.d.ts +1 -1
  53. package/backend/dist/esm/users.js +87 -72
  54. package/backend/dist/esm/utils.d.ts +17 -9
  55. package/backend/dist/esm/utils.js +21 -62
  56. package/backend/dist/esm/view.d.ts +2 -2
  57. package/backend/dist/esm/view.js +38 -40
  58. package/backend/dist/esm/volt.d.ts +3 -2
  59. package/backend/dist/esm/volt.js +2 -1
  60. package/backend/dist/esm-dev/blacklist.js +1 -1
  61. package/backend/dist/esm-dev/cli.js +2 -2
  62. package/backend/dist/esm-dev/database.d.ts +41 -68
  63. package/backend/dist/esm-dev/database.js +138 -80
  64. package/backend/dist/esm-dev/endpoint.d.ts +23 -9
  65. package/backend/dist/esm-dev/endpoint.js +100 -23
  66. package/backend/dist/esm-dev/file_watcher.js +3 -3
  67. package/backend/dist/esm-dev/frontend.d.ts +0 -2
  68. package/backend/dist/esm-dev/frontend.js +9 -9
  69. package/backend/dist/esm-dev/image_endpoint.d.ts +3 -1
  70. package/backend/dist/esm-dev/image_endpoint.js +2 -1
  71. package/backend/dist/esm-dev/logger.js +1 -1
  72. package/backend/dist/esm-dev/payments/paddle.js +12 -4
  73. package/backend/dist/esm-dev/plugins/css.d.ts +6 -5
  74. package/backend/dist/esm-dev/plugins/css.js +33 -7
  75. package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +6 -1
  76. package/backend/dist/esm-dev/plugins/ts/compiler.js +27 -3
  77. package/backend/dist/esm-dev/plugins/ts/preprocessing.js +7 -5
  78. package/backend/dist/esm-dev/rate_limit.js +1 -1
  79. package/backend/dist/esm-dev/server.d.ts +7 -13
  80. package/backend/dist/esm-dev/server.js +184 -303
  81. package/backend/dist/esm-dev/status.d.ts +1 -0
  82. package/backend/dist/esm-dev/status.js +1 -0
  83. package/backend/dist/esm-dev/stream.d.ts +5 -3
  84. package/backend/dist/esm-dev/stream.js +13 -4
  85. package/backend/dist/esm-dev/users.d.ts +1 -1
  86. package/backend/dist/esm-dev/users.js +88 -73
  87. package/backend/dist/esm-dev/utils.d.ts +17 -9
  88. package/backend/dist/esm-dev/utils.js +22 -63
  89. package/backend/dist/esm-dev/view.d.ts +2 -2
  90. package/backend/dist/esm-dev/view.js +39 -41
  91. package/backend/dist/esm-dev/volt.d.ts +3 -2
  92. package/backend/dist/esm-dev/volt.js +2 -1
  93. package/backend/src/database.ts +173 -155
  94. package/backend/src/endpoint.ts +123 -31
  95. package/backend/src/file_watcher.ts +2 -2
  96. package/backend/src/frontend.ts +9 -8
  97. package/backend/src/image_endpoint.ts +4 -0
  98. package/backend/src/payments/paddle.ts +11 -3
  99. package/backend/src/plugins/css.ts +36 -8
  100. package/backend/src/plugins/ts/compiler.ts +37 -1
  101. package/backend/src/plugins/ts/preprocessing.ts +5 -3
  102. package/backend/src/server.ts +167 -306
  103. package/backend/src/status.ts +1 -0
  104. package/backend/src/stream.ts +28 -8
  105. package/backend/src/users.ts +87 -72
  106. package/backend/src/utils.ts +58 -25
  107. package/backend/src/view.ts +30 -28
  108. package/backend/src/{volt.js → volt.ts} +2 -1
  109. package/backend/tsconfig.cjs.json +3 -3
  110. package/backend/tsconfig.esm.json +3 -3
  111. package/frontend/dist/elements/base.d.ts +414 -432
  112. package/frontend/dist/elements/base.js +566 -329
  113. package/frontend/dist/elements/module.d.ts +26 -12
  114. package/frontend/dist/elements/module.js +69 -32
  115. package/frontend/dist/elements/register_element.d.ts +3 -0
  116. package/frontend/dist/elements/register_element.js +22 -0
  117. package/frontend/dist/modules/auth.d.ts +1 -0
  118. package/frontend/dist/modules/auth.js +6 -5
  119. package/frontend/dist/modules/color.d.ts +159 -0
  120. package/frontend/dist/modules/color.js +315 -0
  121. package/frontend/dist/modules/colors.d.ts +1 -26
  122. package/frontend/dist/modules/colors.js +417 -340
  123. package/frontend/dist/modules/cookies.d.ts +1 -0
  124. package/frontend/dist/modules/cookies.js +1 -0
  125. package/frontend/dist/modules/events.d.ts +1 -0
  126. package/frontend/dist/modules/events.js +1 -0
  127. package/frontend/dist/modules/google.d.ts +1 -0
  128. package/frontend/dist/modules/google.js +1 -0
  129. package/frontend/dist/modules/meta.d.ts +1 -0
  130. package/frontend/dist/modules/meta.js +1 -0
  131. package/frontend/dist/modules/mutex.d.ts +1 -2
  132. package/frontend/dist/modules/mutex.js +3 -4
  133. package/frontend/dist/modules/paddle.d.ts +1 -0
  134. package/frontend/dist/modules/paddle.js +14 -13
  135. package/frontend/dist/modules/scheme.d.ts +1 -0
  136. package/frontend/dist/modules/scheme.js +5 -3
  137. package/frontend/dist/modules/statics.d.ts +1 -0
  138. package/frontend/dist/modules/statics.js +1 -0
  139. package/frontend/dist/modules/support.d.ts +1 -0
  140. package/frontend/dist/modules/support.js +3 -2
  141. package/frontend/dist/modules/theme.d.ts +56 -0
  142. package/frontend/dist/{ui → modules}/theme.js +186 -75
  143. package/frontend/dist/modules/themes.d.ts +1 -1
  144. package/frontend/dist/modules/themes.js +1 -0
  145. package/frontend/dist/modules/user.d.ts +1 -0
  146. package/frontend/dist/modules/user.js +11 -10
  147. package/frontend/dist/modules/utils.d.ts +23 -2
  148. package/frontend/dist/modules/utils.js +93 -1
  149. package/frontend/dist/types/gradient.js +4 -0
  150. package/frontend/dist/ui/border_button.d.ts +0 -25
  151. package/frontend/dist/ui/border_button.js +50 -51
  152. package/frontend/dist/ui/button.d.ts +0 -21
  153. package/frontend/dist/ui/button.js +41 -46
  154. package/frontend/dist/ui/canvas.js +15 -15
  155. package/frontend/dist/ui/checkbox.d.ts +3 -17
  156. package/frontend/dist/ui/checkbox.js +36 -30
  157. package/frontend/dist/ui/code.d.ts +15 -82
  158. package/frontend/dist/ui/code.js +150 -125
  159. package/frontend/dist/ui/color.d.ts +0 -1
  160. package/frontend/dist/ui/color.js +1 -1
  161. package/frontend/dist/ui/context_menu.d.ts +4 -2
  162. package/frontend/dist/ui/context_menu.js +16 -17
  163. package/frontend/dist/ui/css.js +2 -0
  164. package/frontend/dist/ui/divider.d.ts +0 -7
  165. package/frontend/dist/ui/divider.js +21 -25
  166. package/frontend/dist/ui/dropdown.d.ts +13 -7
  167. package/frontend/dist/ui/dropdown.js +65 -30
  168. package/frontend/dist/ui/for_each.d.ts +0 -5
  169. package/frontend/dist/ui/for_each.js +17 -22
  170. package/frontend/dist/ui/form.d.ts +17 -12
  171. package/frontend/dist/ui/form.js +21 -18
  172. package/frontend/dist/ui/frame_modes.d.ts +9 -12
  173. package/frontend/dist/ui/frame_modes.js +8 -10
  174. package/frontend/dist/ui/google_map.d.ts +0 -11
  175. package/frontend/dist/ui/google_map.js +23 -28
  176. package/frontend/dist/ui/gradient.d.ts +0 -5
  177. package/frontend/dist/ui/gradient.js +17 -22
  178. package/frontend/dist/ui/image.d.ts +27 -58
  179. package/frontend/dist/ui/image.js +99 -93
  180. package/frontend/dist/ui/input.d.ts +20 -97
  181. package/frontend/dist/ui/input.js +192 -170
  182. package/frontend/dist/ui/link.d.ts +0 -18
  183. package/frontend/dist/ui/link.js +42 -48
  184. package/frontend/dist/ui/list.js +36 -37
  185. package/frontend/dist/ui/loader_button.d.ts +4 -19
  186. package/frontend/dist/ui/loader_button.js +35 -37
  187. package/frontend/dist/ui/loaders.d.ts +0 -8
  188. package/frontend/dist/ui/loaders.js +20 -25
  189. package/frontend/dist/ui/popup.d.ts +11 -8
  190. package/frontend/dist/ui/popup.js +183 -24
  191. package/frontend/dist/ui/pseudo.d.ts +3 -3
  192. package/frontend/dist/ui/pseudo.js +14 -17
  193. package/frontend/dist/ui/scroller.d.ts +10 -48
  194. package/frontend/dist/ui/scroller.js +306 -300
  195. package/frontend/dist/ui/slider.d.ts +9 -3
  196. package/frontend/dist/ui/slider.js +31 -17
  197. package/frontend/dist/ui/spacer.d.ts +0 -9
  198. package/frontend/dist/ui/spacer.js +21 -26
  199. package/frontend/dist/ui/span.js +13 -15
  200. package/frontend/dist/ui/stack.d.ts +14 -75
  201. package/frontend/dist/ui/stack.js +166 -169
  202. package/frontend/dist/ui/steps.d.ts +10 -23
  203. package/frontend/dist/ui/steps.js +47 -34
  204. package/frontend/dist/ui/style.d.ts +4 -3
  205. package/frontend/dist/ui/style.js +13 -18
  206. package/frontend/dist/ui/switch.d.ts +10 -4
  207. package/frontend/dist/ui/switch.js +24 -16
  208. package/frontend/dist/ui/table.d.ts +0 -23
  209. package/frontend/dist/ui/table.js +113 -119
  210. package/frontend/dist/ui/tabs.d.ts +3 -19
  211. package/frontend/dist/ui/tabs.js +35 -29
  212. package/frontend/dist/ui/text.d.ts +0 -8
  213. package/frontend/dist/ui/text.js +20 -25
  214. package/frontend/dist/ui/title.d.ts +0 -15
  215. package/frontend/dist/ui/title.js +39 -45
  216. package/frontend/dist/ui/ui.d.ts +0 -2
  217. package/frontend/dist/ui/ui.js +0 -2
  218. package/frontend/dist/ui/view.d.ts +3 -17
  219. package/frontend/dist/ui/view.js +27 -32
  220. package/frontend/dist/volt.d.ts +2 -1
  221. package/frontend/dist/volt.js +3 -1
  222. package/frontend/examples/dashboard/dashboard.ts +774 -0
  223. package/frontend/examples/theme/theme.ts +58 -0
  224. package/frontend/src/css/volt.css +5 -0
  225. package/frontend/src/elements/base.ts +767 -545
  226. package/frontend/src/elements/module.ts +90 -29
  227. package/frontend/src/elements/register_element.ts +24 -0
  228. package/frontend/src/modules/auth.ts +7 -6
  229. package/frontend/src/modules/color.ts +348 -0
  230. package/frontend/src/modules/colors.ts +468 -449
  231. package/frontend/src/modules/cookies.ts +1 -0
  232. package/frontend/src/modules/events.ts +1 -0
  233. package/frontend/src/modules/google.ts +1 -0
  234. package/frontend/src/modules/meta.ts +2 -1
  235. package/frontend/src/modules/mutex.ts +2 -4
  236. package/frontend/src/modules/paddle.ts +21 -20
  237. package/frontend/src/modules/scheme.ts +5 -4
  238. package/frontend/src/modules/statics.ts +2 -1
  239. package/frontend/src/modules/support.ts +3 -2
  240. package/frontend/src/modules/theme.ts +413 -0
  241. package/frontend/src/modules/themes.ts +2 -1
  242. package/frontend/src/modules/user.ts +12 -11
  243. package/frontend/src/modules/utils.ts +125 -2
  244. package/frontend/src/ui/border_button.ts +41 -37
  245. package/frontend/src/ui/button.ts +33 -32
  246. package/frontend/src/ui/canvas.ts +5 -2
  247. package/frontend/src/ui/checkbox.ts +21 -22
  248. package/frontend/src/ui/code.ts +92 -86
  249. package/frontend/src/ui/context_menu.ts +7 -5
  250. package/frontend/src/ui/css.ts +1 -1
  251. package/frontend/src/ui/divider.ts +15 -10
  252. package/frontend/src/ui/dropdown.ts +38 -21
  253. package/frontend/src/ui/for_each.ts +9 -8
  254. package/frontend/src/ui/form.ts +26 -21
  255. package/frontend/src/ui/frame_modes.ts +13 -17
  256. package/frontend/src/ui/google_map.ts +15 -13
  257. package/frontend/src/ui/gradient.ts +9 -8
  258. package/frontend/src/ui/image.ts +108 -86
  259. package/frontend/src/ui/input.ts +145 -144
  260. package/frontend/src/ui/link.ts +25 -23
  261. package/frontend/src/ui/list.ts +12 -6
  262. package/frontend/src/ui/loader_button.ts +26 -25
  263. package/frontend/src/ui/loaders.ts +12 -11
  264. package/frontend/src/ui/popup.ts +168 -14
  265. package/frontend/src/ui/pseudo.ts +5 -3
  266. package/frontend/src/ui/scroller.ts +303 -294
  267. package/frontend/src/ui/slider.ts +15 -10
  268. package/frontend/src/ui/spacer.ts +14 -11
  269. package/frontend/src/ui/span.ts +6 -2
  270. package/frontend/src/ui/stack.ts +196 -183
  271. package/frontend/src/ui/steps.ts +38 -22
  272. package/frontend/src/ui/style.ts +7 -4
  273. package/frontend/src/ui/switch.ts +16 -11
  274. package/frontend/src/ui/table.ts +42 -34
  275. package/frontend/src/ui/tabs.ts +20 -19
  276. package/frontend/src/ui/text.ts +12 -11
  277. package/frontend/src/ui/title.ts +22 -20
  278. package/frontend/src/ui/ui.ts +0 -2
  279. package/frontend/src/ui/view.ts +20 -19
  280. package/frontend/src/volt.ts +3 -1
  281. package/frontend/{compile.js → tools/compile.old.js} +2 -2
  282. package/frontend/tools/embed_scripts.js +69 -0
  283. package/frontend/tsconfig.json +26 -0
  284. package/package.json +7 -6
  285. package/frontend/dist/ui/theme.d.ts +0 -25
  286. package/frontend/exports.json +0 -1340
  287. package/frontend/src/modules/date.js +0 -535
  288. package/frontend/src/ui/color.ts +0 -117
  289. package/frontend/src/ui/theme.ts +0 -279
  290. /package/backend/src/{vinc.dev.js → vinc.dev.ts} +0 -0
@@ -11,11 +11,12 @@ import zlib from 'zlib';
11
11
  import { View } from './view.js';
12
12
  import { vlib } from "@vinc";
13
13
  import { vhighlight } from "@vinc";
14
- import { Utils, FrontendError } from "./utils.js";
14
+ import { Utils, APIError } from "./utils.js";
15
15
  import { Status } from "./status.js";
16
16
  import { logger, LogSource } from "./logger.js";
17
17
  import { RateLimits, RateLimitGroup } from "./rate_limit.js";
18
18
  import { Stream, AuthStream, Params } from "./stream.js";
19
+ import type { Server } from "./server.js";
19
20
 
20
21
  const log_source = new LogSource("Endpoint")
21
22
 
@@ -24,17 +25,17 @@ const log_source = new LogSource("Endpoint")
24
25
 
25
26
  type EndpointCallback = ((stream: Stream, params: Params) => any) | ((stream: AuthStream, params: Params) => any);
26
27
 
27
- export interface EndpointOptions {
28
+ interface BaseEndpointOptions {
28
29
  method?: string,
29
30
  endpoint: string | RegExp,
30
31
  authenticated?: boolean,
31
32
  rate_limit?: string | RateLimitGroup | RateLimitGroup[] | null,
32
33
  params?: Record<string, any> | null,
33
34
  callback?: EndpointCallback,
34
- view?: View | Record<string, any> | null,
35
+ // view?: View | Record<string, any> | null,
35
36
  data?: any,
36
- content_type?: string,
37
- compress?: boolean,
37
+ // content_type: string,
38
+ compress?: "auto" | boolean,
38
39
  cache?: boolean | number,
39
40
  ip_whitelist?: string[] | null,
40
41
  sitemap?: boolean | null,
@@ -43,6 +44,15 @@ export interface EndpointOptions {
43
44
  _path?: string | null,
44
45
  _is_static?: boolean,
45
46
  }
47
+ interface EndpointOptionsWithView extends Omit<BaseEndpointOptions, "content_type" | "view"> {
48
+ view: View | Record<string, any>;
49
+ content_type?: string; // optional when view is provided
50
+ }
51
+ interface EndpointOptionsWithoutView extends BaseEndpointOptions {
52
+ view?: null | undefined;
53
+ content_type: string; // required if no view is provided
54
+ }
55
+ export type EndpointOptions = EndpointOptionsWithView | EndpointOptionsWithoutView;
46
56
 
47
57
  /* @docs:
48
58
  * @nav: Backend
@@ -149,6 +159,58 @@ class Endpoint {
149
159
  // Static attributes.
150
160
  static rate_limits: Map<string, any> = new Map();
151
161
 
162
+ static compressed_content_types: string[] = [
163
+ // Image formats (often already compressed)
164
+ "image/jpeg",
165
+ "image/png",
166
+ "image/gif",
167
+ "image/webp",
168
+ "image/bmp",
169
+ "image/tiff",
170
+ "image/vnd.microsoft.icon", // ICO
171
+ // Audio formats (usually compressed)
172
+ "audio/mpeg", // MP3
173
+ "audio/mp3",
174
+ "audio/ogg",
175
+ "audio/wav",
176
+ "audio/x-wav",
177
+ "audio/flac",
178
+ "audio/aac",
179
+ "audio/midi",
180
+ // Video formats (typically compressed)
181
+ "video/mp4",
182
+ "video/mpeg",
183
+ "video/ogg",
184
+ "video/webm",
185
+ "video/x-msvideo", // AVI
186
+ "video/quicktime", // MOV
187
+ // Archive / Compressed file formats
188
+ "application/zip",
189
+ "application/x-7z-compressed",
190
+ "application/x-rar-compressed",
191
+ "application/x-tar",
192
+ "application/gzip",
193
+ "application/x-gzip",
194
+ "application/x-bzip",
195
+ "application/x-bzip2",
196
+ "application/x-xz",
197
+ // Documents that are usually compressed internally
198
+ "application/pdf",
199
+ "application/vnd.ms-powerpoint",
200
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
201
+ "application/vnd.ms-excel",
202
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
203
+ "application/msword",
204
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
205
+ // Font files
206
+ "font/woff",
207
+ "font/woff2",
208
+ "application/font-sfnt",
209
+ "application/vnd.ms-fontobject",
210
+ // Other binary data
211
+ "application/octet-stream",
212
+ ]
213
+
152
214
  // Instance attributes
153
215
  method: string;
154
216
  endpoint: string | RegExp;
@@ -156,7 +218,7 @@ class Endpoint {
156
218
  params: Record<string, any> | null;
157
219
  callback?: EndpointCallback = undefined;
158
220
  data: any;
159
- content_type: string;
221
+ content_type?: string;
160
222
  compress: boolean;
161
223
  cache: boolean | number;
162
224
  sitemap: boolean | null;
@@ -174,6 +236,9 @@ class Endpoint {
174
236
  content_length?: number;
175
237
  is_image_endpoint?: boolean;
176
238
 
239
+ _initialized = false;
240
+ _server: any;
241
+
177
242
  constructor({
178
243
  method = "GET",
179
244
  endpoint = "/",
@@ -183,8 +248,8 @@ class Endpoint {
183
248
  callback = undefined,
184
249
  view = null,
185
250
  data = null,
186
- content_type = "text/plain",
187
- compress = true,
251
+ content_type,// = "text/plain",
252
+ compress = "auto",
188
253
  cache = true,
189
254
  ip_whitelist = null,
190
255
  sitemap = null,
@@ -192,7 +257,8 @@ class Endpoint {
192
257
  _templates = {}, // only used in loading static files.
193
258
  _path = null,
194
259
  _is_static = false,
195
- }: EndpointOptions) {
260
+ _server,
261
+ }: EndpointOptions & { _server: Server }) {
196
262
  // Attributes.
197
263
  this.method = method;
198
264
  this.endpoint = endpoint;
@@ -203,7 +269,6 @@ class Endpoint {
203
269
  }
204
270
  this.data = data;
205
271
  this.content_type = content_type;
206
- this.compress = compress !== false;
207
272
  this.cache = cache;
208
273
  this.sitemap = sitemap;
209
274
  this.robots = robots;
@@ -227,6 +292,19 @@ class Endpoint {
227
292
  this.endpoint = Utils.clean_endpoint(this.endpoint as string);
228
293
  }
229
294
 
295
+ // Set compress.
296
+ if (compress === "auto" || typeof compress !== "boolean") {
297
+ compress = Endpoint.compressed_content_types.includes(this.content_type??"")
298
+ } else if (compress === true && this.content_type != null && Endpoint.compressed_content_types.includes(this.content_type)) {
299
+ logger.warn(1, log_source, `Overriding parameter "compress", disabling compression of endpoint ${this.endpoint}.`)
300
+ compress = false;
301
+ }
302
+ this.compress = compress;
303
+ this.compress = false;
304
+ if (this.compress) {
305
+ console.log(">>> compress", { endpoint: this.endpoint, content_type: this.content_type })
306
+ }
307
+
230
308
  // Argument `view` may also be passed as an object instead of class View.
231
309
  if (view == null) {
232
310
  this.view = null;
@@ -269,6 +347,14 @@ class Endpoint {
269
347
 
270
348
  // The endpoint parent for params verification.
271
349
  this._verify_params_parent = this.method + ":" + this.endpoint + ":";
350
+
351
+ // Initialize.
352
+ this._server = _server;
353
+
354
+ // Initialize html.
355
+ if (this.view != null) {
356
+ this.view._initialize(_server, this);
357
+ }
272
358
  }
273
359
 
274
360
  // Load data by path.
@@ -345,29 +431,34 @@ class Endpoint {
345
431
  }
346
432
 
347
433
  // Initialize.
348
- async _initialize(server: any): Promise<void> {
434
+ async _dynamic_initialize(): Promise < void> {
435
+ if (!this._server) {
436
+ throw new Error(`Endpoint "${this.method}:${this.endpoint}" is not initialized by the server yet.`);
437
+ }
349
438
  // Build html code of view.
350
439
  if (this.view != null) {
351
- this.view._initialize(server, this);
352
440
  await this.view._build_html();
353
441
  }
354
442
 
355
443
  // Compression enabled.
356
- if (server.production && this.callback == null && this.compress) {
444
+ if (this._server.production && this.callback == null && this.compress) {
357
445
  this._is_compressed = true;
358
446
  if (this.data != null) {
359
447
  this.raw_data = this.data;
360
448
  this.data = zlib.gzipSync(this.data, {level: zlib.constants.Z_BEST_COMPRESSION});
449
+ this.content_length = this.data.length;
361
450
  } else if (this.view != null) {
362
451
  this.view.raw_html = this.view.html;
363
452
  this.view.html = zlib.gzipSync(this.view.html as any, {level: zlib.constants.Z_BEST_COMPRESSION});
453
+ this.content_length = this.view.html.length;
364
454
  }
455
+ console.log(">>> Compressed - content_length:",this.content_length)
365
456
  }
366
457
 
367
458
  // Set cache headers.
368
- if (!server.production) {
369
- this.cache = false;
370
- }
459
+ // if (!this._server.production) {
460
+ this.cache = false as number | boolean; // @todo @tmp
461
+ // }
371
462
  if ((this.callback == null || this.is_image_endpoint) && (typeof this.cache === "number" || this.cache === true)) {
372
463
  if (this.cache === 1 || this.cache === true) {
373
464
  this.headers.push(["Cache-Control", "max-age=86400"]);
@@ -391,10 +482,18 @@ class Endpoint {
391
482
  if (this.content_type != null) {
392
483
  this.headers.push(["Content-Type", this.content_type]);
393
484
  }
485
+ if (this._is_compressed) {
486
+ console.log("Compressed headers:", this.headers)
487
+ }
488
+
489
+ this._initialized = true;
394
490
  }
395
491
 
396
492
  // Serve a client.
397
- async _serve(stream: any, status_code: number = 200): Promise<void> {
493
+ async _serve(stream: Stream, status_code: number = 200): Promise<void> {
494
+ if (!this._initialized) {
495
+ await this._dynamic_initialize();
496
+ }
398
497
  try {
399
498
  // Check IP whitelist.
400
499
  if (this.ip_whitelist && !this.ip_whitelist.includes(stream.ip)) {
@@ -433,29 +532,22 @@ class Endpoint {
433
532
  try {
434
533
  let promise;
435
534
  if (this.params != null) {
436
- promise = this.callback(stream, stream.params ?? {});
535
+ promise = this.callback(stream as any, stream.params ?? {});
437
536
  } else {
438
- promise = this.callback(stream, {});
537
+ promise = this.callback(stream as any, {});
439
538
  }
440
539
  if (promise instanceof Promise) {
441
540
  await promise;
442
541
  }
443
542
  } catch (err: any) {
444
- if (err instanceof FrontendError) {
445
- let data: Record<string, any> = {error: err.message != null ? err.message : "Internal Server Error"};
446
- if (err.data != null && typeof err.data === "object") {
447
- Object.assign(data, err.data);
448
- }
449
- stream.send({
450
- status: err.status != null ? err.status : Status.internal_server_error,
451
- headers: {"Content-Type": "application/json"},
452
- data,
453
- });
543
+ if (err instanceof APIError) {
544
+ err.serve(stream);
454
545
  } else {
455
- stream.send({
546
+ stream.error({
456
547
  status: Status.internal_server_error,
457
548
  headers: {"Content-Type": "application/json"},
458
- data: {error: "Internal Server Error"},
549
+ message: "Internal Server Error",
550
+ type: "InternalServerError",
459
551
  });
460
552
  }
461
553
  logger.error(log_source, `${this.method}:${this.endpoint}: `, err); // after sending the response since this edits the error.
@@ -193,7 +193,7 @@ class FileWatcher {
193
193
  // Check if the excluded paths exist for user mistakes, these happen often.
194
194
  this.excluded.forEach(path => {
195
195
  if (!new vlib.Path(path).exists()) {
196
- logger.warn(0, this.log_source, `Excluded file watcher path ${path} does not exist.`);
196
+ logger.warn(1, this.log_source, `Excluded file watcher path ${path} does not exist.`);
197
197
  }
198
198
  })
199
199
 
@@ -222,7 +222,7 @@ class FileWatcher {
222
222
  logger.log(2, this.log_source, "Add file watcher exclude", add)
223
223
  this.excluded.push(add)
224
224
  } catch (e) {
225
- logger.warn(0, this.log_source, `Excluded file watcher path ${path.toString()} does not exist.`);
225
+ logger.warn(1, this.log_source, `Excluded file watcher path ${path.toString()} does not exist.`);
226
226
  }
227
227
  }
228
228
 
@@ -15,14 +15,15 @@ export const web_exports = {
15
15
  export const Frontend = {
16
16
 
17
17
  // Load frontend globals.
18
- async load_globals(): Promise<string[]> {
19
- const data: { [key: string]: string[] } = await (new vlib.Path(`${__dirname}/../../../frontend/exports.json`).load());
20
- return Object.values(data).flat();
21
- },
22
- load_globals_sync(): string[] {
23
- const data: { [key: string]: string[] } = new vlib.Path(`${__dirname}/../../../frontend/exports.json`).load_sync();
24
- return Object.values(data).flat();
25
- },
18
+ // @deprecated
19
+ // async load_globals(): Promise<string[]> {
20
+ // const data: { [key: string]: string[] } = await (new vlib.Path(`${__dirname}/../../../frontend/exports.json`).load());
21
+ // return Object.values(data).flat();
22
+ // },
23
+ // load_globals_sync(): string[] {
24
+ // const data: { [key: string]: string[] } = new vlib.Path(`${__dirname}/../../../frontend/exports.json`).load_sync();
25
+ // return Object.values(data).flat();
26
+ // },
26
27
 
27
28
  // Path to css files.
28
29
  css: {
@@ -16,6 +16,7 @@ import { vlib } from "@vinc";
16
16
  import { Endpoint } from "./endpoint.js";
17
17
  import { logger, LogSource } from "./logger.js";
18
18
  import { RateLimitGroup } from "./rate_limit.js";
19
+ import type { Server } from "./server.js";
19
20
 
20
21
  const log_source = new LogSource("ImageEndpoint")
21
22
 
@@ -68,6 +69,7 @@ class ImageEndpoint extends Endpoint implements Endpoint {
68
69
  cache = true,
69
70
  _is_static = true,
70
71
  rate_limit = undefined,
72
+ _server,
71
73
  }: {
72
74
  endpoint: string,
73
75
  path: vlib.Path,
@@ -75,6 +77,7 @@ class ImageEndpoint extends Endpoint implements Endpoint {
75
77
  cache?: boolean | number,
76
78
  _is_static?: boolean,
77
79
  rate_limit?: string | RateLimitGroup,
80
+ _server: Server,
78
81
  }) {
79
82
  // Initialize base.
80
83
  super({
@@ -92,6 +95,7 @@ class ImageEndpoint extends Endpoint implements Endpoint {
92
95
  rate_limit,
93
96
  _path: path.str(),
94
97
  _is_static,
98
+ _server,
95
99
  })
96
100
 
97
101
  // Attributes.
@@ -12,7 +12,7 @@ import blobstream from 'blob-stream';
12
12
 
13
13
 
14
14
  import { vlib } from "@vinc";
15
- import { Utils, FrontendError } from "../utils.js";
15
+ import { Utils, APIError } from "../utils.js";
16
16
  import { logger } from "../logger.js";
17
17
  import { Status } from "../status.js";
18
18
 
@@ -732,7 +732,11 @@ export class Paddle {
732
732
 
733
733
  // Cancel.
734
734
  if (subscription.status !== "active") {
735
- throw new FrontendError(`This subscription does not contain any cancellable items, the subscription is likely already cancelled.`, Status.bad_request);
735
+ throw new APIError({
736
+ type: "NoActiveSubscriptionError",
737
+ message: `This subscription is already cancelled and will become inactive at the end of the billing period.`,
738
+ status: Status.bad_request,
739
+ });
736
740
  }
737
741
  await this._req("POST", `/subscriptions/${subscription.id}/cancel`, {
738
742
  effective_from: immediate ? "immediately" : null,
@@ -2318,7 +2322,11 @@ export class Paddle {
2318
2322
  }
2319
2323
  });
2320
2324
  if (_throw_no_cancelled_err && cancelled.length === 0) {
2321
- throw new FrontendError("No cancellable subscriptions found.", Status.bad_request);
2325
+ throw new APIError({
2326
+ type: "NoCancellableSubscriptions",
2327
+ message: "No cancellable subscriptions found.",
2328
+ status: Status.bad_request,
2329
+ });
2322
2330
  }
2323
2331
  }
2324
2332
 
@@ -8,12 +8,13 @@
8
8
 
9
9
  import CleanCSS from 'clean-css';
10
10
  import { vlib } from "@vinc";
11
+ import { log } from 'console';
11
12
 
12
13
  // ---------------------------------------------------------
13
14
  // CSS utils.
14
15
 
15
16
  // Implementation
16
- export class CSS {
17
+ export namespace CSS {
17
18
 
18
19
  /* @docs:
19
20
  @nav: Backend
@@ -28,7 +29,7 @@ export class CSS {
28
29
  @descr: The css data.
29
30
  @type: string
30
31
  */
31
- static minify(data: string): string {
32
+ export function minify(data: string): string {
32
33
  return new CleanCSS().minify(data).styles;
33
34
  }
34
35
 
@@ -48,20 +49,25 @@ export class CSS {
48
49
  @descr: The css data.
49
50
  @type: string
50
51
  */
51
- static async bundle({
52
- data = "",
52
+ export async function bundle({
53
+ data,
53
54
  paths = undefined,
54
55
  minify = false,
55
56
  output = undefined,
57
+ postprocess = undefined,
58
+ log_level = 0,
56
59
  }: {
57
60
  data: string;
58
61
  paths?: string[];
59
62
  minify?: boolean;
60
- output?: string;
63
+ output?: string | string[];
64
+ postprocess?: undefined | ((data: string) => string | Promise<string>);
65
+ log_level?: number;
61
66
  }): Promise<string> {
62
67
 
63
68
  // Load via paths.
64
69
  if (paths !== undefined) {
70
+ data = "";
65
71
  for (const path of paths) {
66
72
  (data as string) += await new vlib.Path(path).load();
67
73
  }
@@ -72,13 +78,35 @@ export class CSS {
72
78
  data = CSS.minify(data!);
73
79
  }
74
80
 
81
+ // Postprocess.
82
+ if (typeof postprocess === "function") {
83
+ const res = postprocess(data);
84
+ if (res instanceof Promise) {
85
+ data = await res;
86
+ } else {
87
+ data = res;
88
+ }
89
+ }
90
+
75
91
  // Save.
76
- if (output) {
92
+ if (typeof output === "string") {
77
93
  await new vlib.Path(output).save(data);
94
+ } else if (Array.isArray(output)) {
95
+ for (let i = 0; i < output.length; i++) {
96
+ await new vlib.Path(output[i]).save(data);
97
+ }
98
+ }
99
+
100
+ // Logs.
101
+ if (log_level >= 1) {
102
+ const first_path = typeof output === "string" ? output : (Array.isArray(output) ? output[0] : undefined);
103
+ if (first_path != null) {
104
+ const p = new vlib.Path(first_path);
105
+ vlib.Utils.print_marker(`Bundled ${p.name()} (${p.str()}) [${vlib.Utils.format_bytes(p.size)}].`);
106
+ }
78
107
  }
79
108
 
80
109
  // Return.
81
110
  return data as string;
82
111
  }
83
- }
84
- export default CSS;
112
+ }
@@ -781,7 +781,7 @@ export interface BundleOptions {
781
781
  include?: string[],
782
782
 
783
783
  // Output path.
784
- output?: string,
784
+ output?: string | string[],
785
785
 
786
786
  // @deprecated Additional entry paths.
787
787
  entry_paths?: string[],
@@ -820,6 +820,9 @@ export interface BundleOptions {
820
820
  */
821
821
  tree_shaking?: boolean;
822
822
 
823
+ /** External library names not to be included in the bundle */
824
+ externals?: string[];
825
+
823
826
  /**
824
827
  * Enable or disable debug console statements.
825
828
  */
@@ -841,6 +844,12 @@ export interface BundleOptions {
841
844
 
842
845
  // Any other esbuild.bundle options.
843
846
  opts?: any;
847
+
848
+ // Post process the bundled code.
849
+ postprocess?: undefined | ((data: string) => string | Promise<string>);
850
+
851
+ /** Log level (default is 0) */
852
+ log_level?: number;
844
853
  }
845
854
 
846
855
  /**
@@ -924,6 +933,7 @@ export async function bundle(options: BundleOptions): Promise<BundleResult> {
924
933
  let {
925
934
  entry_paths = [],
926
935
  include = [],
936
+ externals = [],
927
937
  output = undefined,
928
938
  platform = 'browser',
929
939
  format = 'iife',
@@ -936,6 +946,8 @@ export async function bundle(options: BundleOptions): Promise<BundleResult> {
936
946
  debug = false,
937
947
  bundler = "esbuild",
938
948
  opts = {},
949
+ postprocess = undefined,
950
+ log_level = 0,
939
951
  // bundler = "rollup",
940
952
  } = options;
941
953
  if (entry_paths.length > 0) {
@@ -967,6 +979,7 @@ export async function bundle(options: BundleOptions): Promise<BundleResult> {
967
979
  // minifyWhitespace: false,
968
980
  // minifySyntax: false,
969
981
  // minifyIdentifiers: false,
982
+ external: externals,
970
983
  ...opts,
971
984
  });
972
985
  if (result.errors.length > 0) {
@@ -1115,9 +1128,32 @@ export async function bundle(options: BundleOptions): Promise<BundleResult> {
1115
1128
  }
1116
1129
  }
1117
1130
 
1131
+ // Postprocess.
1132
+ if (bundled_code && typeof postprocess === "function") {
1133
+ const res = postprocess(bundled_code);
1134
+ if (res instanceof Promise) {
1135
+ bundled_code = await res;
1136
+ } else {
1137
+ bundled_code = res;
1138
+ }
1139
+ }
1140
+
1118
1141
  // Write to file.
1119
1142
  if (typeof output === "string") {
1120
1143
  await new vlib.Path(output).save(bundled_code ?? "");
1144
+ } else if (Array.isArray(output)) {
1145
+ for (let i = 0; i < output.length; i++) {
1146
+ await new vlib.Path(output[i]).save(bundled_code ?? "");
1147
+ }
1148
+ }
1149
+
1150
+ // Logs.
1151
+ if (log_level >= 1) {
1152
+ const first_path = typeof output === "string" ? output : (Array.isArray(output) ? output[0] : undefined);
1153
+ if (first_path != null) {
1154
+ const p = new vlib.Path(first_path);
1155
+ vlib.Utils.print_marker(`Bundled ${p.name()} (${p.str()}) [${vlib.Utils.format_bytes(p.size)}].`);
1156
+ }
1121
1157
  }
1122
1158
 
1123
1159
  return {
@@ -562,9 +562,11 @@ function detect_unused_imports(source_file: ts.SourceFile): string[] {
562
562
 
563
563
  // Load volt exports.
564
564
  if (volt_exports === undefined) {
565
- volt_exports = new vlib.Path(`${__dirname}/../../../../../frontend/exports.json`).load_sync({type: "object"}) as Record<string, string[]>;
566
- volt_exports["ui/ui.ts"] = ["VoltUI"];
567
- volt_exports["volt.ts"] = ["Volt"];
565
+ volt_exports = {};
566
+ // @deprecated.
567
+ // volt_exports = new vlib.Path(`${__dirname}/../../../../../frontend/exports.json`).load_sync({type: "object"}) as Record<string, string[]>;
568
+ // volt_exports["ui/ui.ts"] = ["VoltUI"];
569
+ // volt_exports["volt.ts"] = ["Volt"];
568
570
  }
569
571
 
570
572
  // Vars.