odac 0.9.0 → 1.0.0

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 (208) hide show
  1. package/.github/workflows/auto-pr-description.yml +0 -2
  2. package/.github/workflows/codeql.yml +46 -0
  3. package/.github/workflows/release.yml +13 -6
  4. package/.github/workflows/test-coverage.yml +10 -9
  5. package/.releaserc.js +9 -6
  6. package/CHANGELOG.md +62 -150
  7. package/CODE_OF_CONDUCT.md +1 -1
  8. package/CONTRIBUTING.md +8 -8
  9. package/LICENSE +21 -661
  10. package/README.md +12 -12
  11. package/SECURITY.md +4 -4
  12. package/bin/odac.js +101 -0
  13. package/{framework/web/candy.js → client/odac.js} +310 -44
  14. package/docs/backend/01-overview/{01-whats-in-the-candy-box.md → 01-whats-in-the-odac-box.md} +4 -2
  15. package/docs/backend/01-overview/02-super-handy-helper-functions.md +29 -1
  16. package/docs/backend/01-overview/03-development-server.md +11 -11
  17. package/docs/backend/02-structure/01-typical-project-layout.md +4 -4
  18. package/docs/backend/03-config/00-configuration-overview.md +6 -6
  19. package/docs/backend/03-config/01-database-connection.md +1 -1
  20. package/docs/backend/03-config/02-static-route-mapping-optional.md +4 -4
  21. package/docs/backend/03-config/04-environment-variables.md +20 -20
  22. package/docs/backend/03-config/05-early-hints.md +4 -4
  23. package/docs/backend/04-routing/01-basic-page-routes.md +4 -4
  24. package/docs/backend/04-routing/02-controller-less-view-routes.md +5 -5
  25. package/docs/backend/04-routing/03-api-and-data-routes.md +3 -3
  26. package/docs/backend/04-routing/04-authentication-aware-routes.md +5 -5
  27. package/docs/backend/04-routing/05-advanced-routing.md +3 -3
  28. package/docs/backend/04-routing/06-error-pages.md +17 -17
  29. package/docs/backend/04-routing/07-cron-jobs.md +13 -13
  30. package/docs/backend/04-routing/08-middleware.md +214 -0
  31. package/docs/backend/04-routing/09-websocket-auth-middleware.md +292 -0
  32. package/docs/backend/04-routing/09-websocket-examples.md +381 -0
  33. package/docs/backend/04-routing/09-websocket-quick-reference.md +211 -0
  34. package/docs/backend/04-routing/09-websocket.md +298 -0
  35. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +3 -3
  36. package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +41 -0
  37. package/docs/backend/05-controllers/03-controller-classes.md +19 -19
  38. package/docs/backend/05-forms/01-custom-forms.md +114 -114
  39. package/docs/backend/05-forms/02-automatic-database-insert.md +82 -82
  40. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +26 -26
  41. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +10 -10
  42. package/docs/backend/07-views/01-the-view-directory.md +1 -1
  43. package/docs/backend/07-views/02-rendering-a-view.md +22 -22
  44. package/docs/backend/07-views/03-template-syntax.md +52 -52
  45. package/docs/backend/07-views/03-variables.md +84 -84
  46. package/docs/backend/07-views/04-request-data.md +57 -57
  47. package/docs/backend/07-views/05-conditionals.md +78 -78
  48. package/docs/backend/07-views/06-loops.md +114 -114
  49. package/docs/backend/07-views/07-translations.md +66 -66
  50. package/docs/backend/07-views/08-backend-javascript.md +103 -103
  51. package/docs/backend/07-views/09-comments.md +71 -71
  52. package/docs/backend/08-database/01-database-connection.md +8 -8
  53. package/docs/backend/08-database/02-using-mysql.md +49 -49
  54. package/docs/backend/09-validation/01-the-validator-service.md +38 -38
  55. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +15 -15
  56. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +10 -10
  57. package/docs/backend/10-authentication/03-register.md +12 -12
  58. package/docs/backend/10-authentication/{04-candy-register-forms.md → 04-odac-register-forms.md} +141 -141
  59. package/docs/backend/10-authentication/05-session-management.md +10 -10
  60. package/docs/backend/10-authentication/{06-candy-login-forms.md → 06-odac-login-forms.md} +125 -125
  61. package/docs/backend/11-mail/01-the-mail-service.md +5 -5
  62. package/docs/backend/12-streaming/01-streaming-overview.md +96 -54
  63. package/docs/backend/13-utilities/{01-candy-var.md → 01-odac-var.md} +109 -109
  64. package/docs/frontend/01-overview/01-introduction.md +30 -30
  65. package/docs/frontend/02-ajax-navigation/01-quick-start.md +45 -45
  66. package/docs/frontend/02-ajax-navigation/02-configuration.md +14 -14
  67. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +36 -36
  68. package/docs/frontend/03-forms/01-form-handling.md +32 -32
  69. package/docs/frontend/04-api-requests/01-get-post.md +33 -33
  70. package/docs/frontend/05-streaming/01-client-streaming.md +15 -15
  71. package/docs/frontend/06-websocket/00-overview.md +76 -0
  72. package/docs/frontend/06-websocket/01-websocket-client.md +139 -0
  73. package/docs/frontend/06-websocket/02-shared-websocket.md +149 -0
  74. package/docs/index.json +49 -11
  75. package/eslint.config.mjs +6 -6
  76. package/{framework/index.js → index.js} +1 -1
  77. package/package.json +14 -39
  78. package/{framework/src → src}/Auth.js +59 -59
  79. package/{framework/src → src}/Config.js +3 -3
  80. package/{framework/src → src}/Lang.js +7 -7
  81. package/{framework/src → src}/Mail.js +5 -5
  82. package/{framework/src → src}/Mysql.js +42 -42
  83. package/src/Odac.js +112 -0
  84. package/{framework/src → src}/Request.js +38 -36
  85. package/{framework/src → src}/Route/Internal.js +116 -116
  86. package/src/Route/Middleware.js +75 -0
  87. package/src/Route.js +621 -0
  88. package/src/Server.js +22 -0
  89. package/{framework/src → src}/Stream.js +11 -3
  90. package/{framework/src → src}/Validator.js +21 -21
  91. package/{framework/src → src}/Var.js +5 -5
  92. package/{framework/src → src}/View/EarlyHints.js +1 -1
  93. package/{framework/src → src}/View/Form.js +69 -69
  94. package/{framework/src → src}/View.js +78 -81
  95. package/src/WebSocket.js +403 -0
  96. package/template/config.json +5 -0
  97. package/{web → template}/controller/page/about.js +6 -6
  98. package/{web → template}/controller/page/index.js +9 -9
  99. package/{web → template}/package.json +4 -5
  100. package/{web → template}/public/assets/css/style.css +4 -4
  101. package/{web → template}/public/assets/js/app.js +6 -6
  102. package/{web → template}/route/www.js +6 -6
  103. package/{web → template}/skeleton/main.html +1 -1
  104. package/{web → template}/view/content/about.html +5 -5
  105. package/{web → template}/view/content/home.html +12 -12
  106. package/template/view/footer/main.html +11 -0
  107. package/{web → template}/view/head/main.html +1 -1
  108. package/{web → template}/view/header/main.html +2 -2
  109. package/test/core/Candy.test.js +58 -58
  110. package/test/core/Commands.test.js +7 -7
  111. package/test/core/Config.test.js +82 -85
  112. package/test/core/Lang.test.js +2 -2
  113. package/test/core/Process.test.js +6 -6
  114. package/test/framework/Route.test.js +56 -37
  115. package/test/framework/View/EarlyHints.test.js +2 -2
  116. package/test/framework/WebSocket.test.js +100 -0
  117. package/test/framework/middleware.test.js +85 -0
  118. package/test/server/Api.test.js +31 -31
  119. package/test/server/DNS.test.js +11 -11
  120. package/test/server/Hub.test.js +497 -0
  121. package/test/server/Mail.account.test_.js +3 -3
  122. package/test/server/Mail.init.test_.js +10 -10
  123. package/test/server/Mail.test_.js +20 -20
  124. package/test/server/SSL.test_.js +54 -54
  125. package/test/server/Server.test.js +39 -39
  126. package/test/server/Service.test_.js +7 -7
  127. package/test/server/Subdomain.test.js +7 -7
  128. package/test/server/Web/Firewall.test.js +87 -87
  129. package/test/server/Web/Proxy.test.js +397 -0
  130. package/test/server/{Web.test_.js → Web.test.js} +137 -205
  131. package/test/server/__mocks__/fs.js +2 -2
  132. package/test/server/__mocks__/{globalCandy.js → globalOdac.js} +5 -5
  133. package/test/server/__mocks__/index.js +6 -6
  134. package/test/server/__mocks__/testFactories.js +1 -1
  135. package/test/server/__mocks__/testHelpers.js +7 -7
  136. package/.husky/pre-commit +0 -2
  137. package/.kiro/steering/code-style.md +0 -56
  138. package/.kiro/steering/product.md +0 -20
  139. package/.kiro/steering/structure.md +0 -77
  140. package/.kiro/steering/tech.md +0 -87
  141. package/AGENTS.md +0 -84
  142. package/bin/candy +0 -10
  143. package/bin/candypack +0 -10
  144. package/cli/index.js +0 -3
  145. package/cli/src/Cli.js +0 -348
  146. package/cli/src/Connector.js +0 -93
  147. package/cli/src/Monitor.js +0 -416
  148. package/core/Candy.js +0 -87
  149. package/core/Commands.js +0 -239
  150. package/core/Config.js +0 -1094
  151. package/core/Lang.js +0 -52
  152. package/core/Log.js +0 -43
  153. package/core/Process.js +0 -26
  154. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +0 -20
  155. package/docs/server/01-installation/01-quick-install.md +0 -19
  156. package/docs/server/01-installation/02-manual-installation-via-npm.md +0 -9
  157. package/docs/server/02-get-started/01-core-concepts.md +0 -7
  158. package/docs/server/02-get-started/02-basic-commands.md +0 -57
  159. package/docs/server/02-get-started/03-cli-reference.md +0 -276
  160. package/docs/server/02-get-started/04-cli-quick-reference.md +0 -102
  161. package/docs/server/03-service/01-start-a-new-service.md +0 -57
  162. package/docs/server/03-service/02-delete-a-service.md +0 -48
  163. package/docs/server/04-web/01-create-a-website.md +0 -36
  164. package/docs/server/04-web/02-list-websites.md +0 -9
  165. package/docs/server/04-web/03-delete-a-website.md +0 -29
  166. package/docs/server/05-subdomain/01-create-a-subdomain.md +0 -32
  167. package/docs/server/05-subdomain/02-list-subdomains.md +0 -33
  168. package/docs/server/05-subdomain/03-delete-a-subdomain.md +0 -41
  169. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +0 -34
  170. package/docs/server/07-mail/01-create-a-mail-account.md +0 -23
  171. package/docs/server/07-mail/02-delete-a-mail-account.md +0 -20
  172. package/docs/server/07-mail/03-list-mail-accounts.md +0 -20
  173. package/docs/server/07-mail/04-change-account-password.md +0 -23
  174. package/framework/src/Candy.js +0 -81
  175. package/framework/src/Route.js +0 -455
  176. package/framework/src/Server.js +0 -15
  177. package/locale/de-DE.json +0 -80
  178. package/locale/en-US.json +0 -79
  179. package/locale/es-ES.json +0 -80
  180. package/locale/fr-FR.json +0 -80
  181. package/locale/pt-BR.json +0 -80
  182. package/locale/ru-RU.json +0 -80
  183. package/locale/tr-TR.json +0 -85
  184. package/locale/zh-CN.json +0 -80
  185. package/server/index.js +0 -5
  186. package/server/src/Api.js +0 -88
  187. package/server/src/DNS.js +0 -940
  188. package/server/src/Hub.js +0 -535
  189. package/server/src/Mail.js +0 -571
  190. package/server/src/SSL.js +0 -180
  191. package/server/src/Server.js +0 -27
  192. package/server/src/Service.js +0 -248
  193. package/server/src/Subdomain.js +0 -64
  194. package/server/src/Web/Firewall.js +0 -170
  195. package/server/src/Web/Proxy.js +0 -134
  196. package/server/src/Web.js +0 -451
  197. package/server/src/mail/imap.js +0 -1091
  198. package/server/src/mail/server.js +0 -32
  199. package/server/src/mail/smtp.js +0 -786
  200. package/test/server/Client.test.js +0 -338
  201. package/test/server/__mocks__/http-proxy.js +0 -105
  202. package/watchdog/index.js +0 -3
  203. package/watchdog/src/Watchdog.js +0 -156
  204. package/web/config.json +0 -5
  205. package/web/view/footer/main.html +0 -11
  206. /package/{framework/src → src}/Env.js +0 -0
  207. /package/{framework/src → src}/Route/Cron.js +0 -0
  208. /package/{framework/src → src}/Token.js +0 -0
@@ -1,455 +0,0 @@
1
- const fs = require('fs')
2
-
3
- const Cron = require('./Route/Cron.js')
4
- const Internal = require('./Route/Internal.js')
5
-
6
- var routes2 = {}
7
- const mime = {
8
- html: 'text/html',
9
- css: 'text/css',
10
- js: 'text/javascript',
11
- json: 'application/json',
12
- png: 'image/png',
13
- jpg: 'image/jpg',
14
- jpeg: 'image/jpeg',
15
- svg: 'image/svg+xml',
16
- ico: 'image/x-icon',
17
- mp3: 'audio/mpeg',
18
- mp4: 'video/mp4',
19
- webm: 'video/webm',
20
- woff: 'font/woff',
21
- woff2: 'font/woff2',
22
- ttf: 'font/ttf',
23
- otf: 'font/otf',
24
- eot: 'font/eot',
25
- pdf: 'application/pdf',
26
- zip: 'application/zip',
27
- tar: 'application/x-tar',
28
- gz: 'application/gzip',
29
- rar: 'application/x-rar-compressed',
30
- '7z': 'application/x-7z-compressed',
31
- txt: 'text/plain',
32
- log: 'text/plain',
33
- csv: 'text/csv',
34
- xml: 'text/xml',
35
- rss: 'application/rss+xml',
36
- atom: 'application/atom+xml',
37
- yaml: 'application/x-yaml',
38
- sh: 'application/x-sh',
39
- bat: 'application/x-bat',
40
- exe: 'application/x-exe',
41
- bin: 'application/x-binary',
42
- doc: 'application/msword',
43
- docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
44
- xls: 'application/vnd.ms-excel',
45
- xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
46
- ppt: 'application/vnd.ms-powerpoint',
47
- pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
48
- avi: 'video/x-msvideo',
49
- wmv: 'video/x-ms-wmv',
50
- flv: 'video/x-flv',
51
- webp: 'image/webp',
52
- gif: 'image/gif',
53
- bmp: 'image/bmp',
54
- tiff: 'image/tiff',
55
- tif: 'image/tiff',
56
- weba: 'audio/webm',
57
- wav: 'audio/wav',
58
- ogg: 'audio/ogg',
59
- flac: 'audio/flac',
60
- aac: 'audio/aac',
61
- midi: 'audio/midi'
62
- }
63
-
64
- class Route {
65
- loading = false
66
- routes = {}
67
- auth = {
68
- page: (path, authFile, file) => this.authPage(path, authFile, file),
69
- post: (path, authFile, file) => this.authPost(path, authFile, file),
70
- get: (path, authFile, file) => this.authGet(path, authFile, file)
71
- }
72
-
73
- async check(Candy) {
74
- let url = Candy.Request.url.split('?')[0]
75
- if (url.substr(-1) === '/') url = url.substr(0, url.length - 1)
76
-
77
- if (url.startsWith('/_candy/')) {
78
- Candy.Request.route = '_candy_internal'
79
- }
80
-
81
- if (['post', 'put', 'patch', 'delete'].includes(Candy.Request.method)) {
82
- const formToken = await Candy.request('_candy_form_token')
83
- if (formToken) {
84
- await Internal.processForm(Candy)
85
- }
86
- }
87
- if (
88
- Candy.Request.url === '/' &&
89
- Candy.Request.method === 'get' &&
90
- Candy.Request.header('X-Candy') === 'token' &&
91
- Candy.Request.header('Referer').startsWith((Candy.Request.ssl ? 'https://' : 'http://') + Candy.Request.host + '/') &&
92
- Candy.Request.header('X-Candy-Client') === Candy.Request.cookie('candy_client')
93
- ) {
94
- Candy.Request.header('Access-Control-Allow-Origin', (Candy.Request.ssl ? 'https://' : 'http://') + Candy.Request.host)
95
- Candy.Request.header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
96
- return {
97
- token: Candy.token()
98
- }
99
- }
100
-
101
- // Handle AJAX page load requests
102
- if (Candy.Request.method === 'get' && Candy.Request.header('X-Candy') === 'ajaxload') {
103
- let loadElements = Candy.Request.header('X-Candy-Load')
104
- if (loadElements) {
105
- Candy.Request.ajaxLoad = loadElements.split(',')
106
- }
107
- Candy.Request.isAjaxLoad = true
108
- Candy.Request.clientSkeleton = Candy.Request.header('X-Candy-Skeleton')
109
- }
110
- if (Candy.Config.route && Candy.Config.route[url]) {
111
- Candy.Config.route[url] = Candy.Config.route[url].replace('${candy}', `${__dir}/node_modules/candypack`)
112
- if (fs.existsSync(Candy.Config.route[url])) {
113
- let stat = fs.lstatSync(Candy.Config.route[url])
114
- if (stat.isFile()) {
115
- let type = 'text/html'
116
- if (Candy.Config.route[url].includes('.')) {
117
- let arr = Candy.Config.route[url].split('.')
118
- type = mime[arr[arr.length - 1]]
119
- }
120
- Candy.Request.header('Content-Type', type)
121
- Candy.Request.header('Cache-Control', 'public, max-age=31536000')
122
- Candy.Request.header('Content-Length', stat.size)
123
- return fs.readFileSync(Candy.Config.route[url])
124
- }
125
- }
126
- }
127
- for (let method of ['#' + Candy.Request.method, Candy.Request.method]) {
128
- let controller = this.#controller(Candy.Request.route, method, url)
129
- if (controller) {
130
- if (!method.startsWith('#') || (await Candy.Auth.check())) {
131
- Candy.Request.header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
132
- if (
133
- ['post', 'get'].includes(Candy.Request.method) &&
134
- controller.token &&
135
- (!(await Candy.request('_token')) || !Candy.token(await Candy.Request.request('_token')))
136
- )
137
- return Candy.Request.abort(401)
138
- if (typeof controller.cache === 'function') {
139
- if (controller.params) for (let key in controller.params) Candy.Request.data.url[key] = controller.params[key]
140
- return controller.cache(Candy)
141
- }
142
- }
143
- }
144
- }
145
- let authPageController = this.#controller(Candy.Request.route, '#page', url)
146
- if (authPageController && (await Candy.Auth.check())) {
147
- if (authPageController.params) for (let key in authPageController.params) Candy.Request.data.url[key] = authPageController.params[key]
148
- Candy.Request.page = authPageController.cache?.file || authPageController.file
149
- if (typeof authPageController.cache === 'function') {
150
- return authPageController.cache(Candy)
151
- }
152
- }
153
- let pageController = this.#controller(Candy.Request.route, 'page', url)
154
- if (pageController) {
155
- if (pageController.params) for (let key in pageController.params) Candy.Request.data.url[key] = pageController.params[key]
156
- Candy.Request.page = pageController.cache?.file || pageController.file
157
- if (typeof pageController.cache === 'function') {
158
- return pageController.cache(Candy)
159
- }
160
- }
161
- if (url && !url.includes('/../') && fs.existsSync(`${__dir}/public${url}`)) {
162
- let stat = fs.lstatSync(`${__dir}/public${url}`)
163
- if (stat.isFile()) {
164
- let type = 'text/html'
165
- if (url.includes('.')) {
166
- let arr = url.split('.')
167
- type = mime[arr[arr.length - 1]]
168
- }
169
- Candy.Request.header('Content-Type', type)
170
- Candy.Request.header('Cache-Control', 'public, max-age=31536000')
171
- Candy.Request.header('Content-Length', stat.size)
172
- return fs.readFileSync(`${__dir}/public${url}`)
173
- }
174
- }
175
- return Candy.Request.abort(404)
176
- }
177
-
178
- #controller(route, method, url) {
179
- if (!this.routes[route] || !this.routes[route][method]) return false
180
- if (this.routes[route][method][url]) return this.routes[route][method][url]
181
- let arr = url.split('/')
182
- for (let key in this.routes[route][method]) {
183
- if (!key.includes('{') || !key.includes('}')) continue
184
- let route_arr = key.split('/')
185
- if (route_arr.length !== arr.length) continue
186
- let params = {}
187
- let next = false
188
- for (let i = 0; i < route_arr.length; i++) {
189
- if (route_arr[i].includes('{') && route_arr[i].includes('}')) {
190
- params[route_arr[i].replace('{', '').replace('}', '')] = arr[i]
191
- arr[i] = route_arr[i]
192
- } else if (route_arr[i] !== arr[i]) {
193
- next = true
194
- break
195
- }
196
- }
197
- if (next) continue
198
- if (arr.join('/') === key)
199
- return {
200
- params: params,
201
- cache: this.routes[route][method][key].cache,
202
- token: this.routes[route][method][key].token
203
- }
204
- }
205
- return false
206
- }
207
-
208
- #init() {
209
- if (this.loading) return
210
- this.loading = true
211
- for (const file of fs.readdirSync(`${__dir}/controller/`)) {
212
- if (file.substr(-3) !== '.js') continue
213
- let name = file.replace('.js', '')
214
- if (!Candy.Route.class) Candy.Route.class = {}
215
- if (Candy.Route.class[name]) {
216
- if (Candy.Route.class[name].mtime >= fs.statSync(Candy.Route.class[name].path).mtimeMs + 1000) continue
217
- delete require.cache[require.resolve(Candy.Route.class[name].path)]
218
- }
219
- Candy.Route.class[name] = {
220
- path: `${__dir}/controller/${file}`,
221
- mtime: fs.statSync(`${__dir}/controller/${file}`).mtimeMs,
222
- module: require(`${__dir}/controller/${file}`)
223
- }
224
- }
225
- let dir = fs.readdirSync(`${__dir}/route/`)
226
- for (const file of dir) {
227
- if (file.substr(-3) !== '.js') continue
228
- let mtime = fs.statSync(`${__dir}/route/${file}`).mtimeMs
229
- Candy.Route.buff = file.replace('.js', '')
230
- if (!routes2[Candy.Route.buff] || routes2[Candy.Route.buff] < mtime - 1000) {
231
- delete require.cache[require.resolve(`${__dir}/route/${file}`)]
232
- routes2[Candy.Route.buff] = mtime
233
- require(`${__dir}/route/${file}`)
234
- }
235
- for (const type of ['page', '#page', 'post', '#post', 'get', '#get', 'error']) {
236
- if (!this.routes[Candy.Route.buff]) continue
237
- if (!this.routes[Candy.Route.buff][type]) continue
238
- for (const route in this.routes[Candy.Route.buff][type]) {
239
- if (routes2[Candy.Route.buff] > this.routes[Candy.Route.buff][type][route].loaded) {
240
- delete require.cache[require.resolve(this.routes[Candy.Route.buff][type][route].path)]
241
- delete this.routes[Candy.Route.buff][type][route]
242
- } else if (this.routes[Candy.Route.buff][type][route]) {
243
- if (typeof this.routes[Candy.Route.buff][type][route].type === 'function') continue
244
- if (this.routes[Candy.Route.buff][type][route].mtime < fs.statSync(this.routes[Candy.Route.buff][type][route].path).mtimeMs) {
245
- delete require.cache[require.resolve(this.routes[Candy.Route.buff][type][route].path)]
246
- this.routes[Candy.Route.buff][type][route].cache = require(this.routes[Candy.Route.buff][type][route].path)
247
- this.routes[Candy.Route.buff][type][route].mtime = fs.statSync(this.routes[Candy.Route.buff][type][route].path).mtimeMs
248
- }
249
- }
250
- }
251
- }
252
- delete Candy.Route.buff
253
- }
254
- Cron.init()
255
- this.loading = false
256
- }
257
-
258
- init() {
259
- this.#init()
260
- this.#registerInternalRoutes()
261
- setInterval(() => {
262
- this.#init()
263
- }, 5000)
264
- }
265
-
266
- #registerInternalRoutes() {
267
- if (!Candy.Route) Candy.Route = {}
268
- Candy.Route.buff = '_candy_internal'
269
-
270
- this.set(
271
- 'POST',
272
- '/_candy/register',
273
- async Candy => {
274
- const csrfToken = await Candy.request('_token')
275
- if (!csrfToken || !Candy.token(csrfToken)) {
276
- return Candy.Request.abort(401)
277
- }
278
- return await Internal.register(Candy)
279
- },
280
- {token: true}
281
- )
282
-
283
- this.set(
284
- 'POST',
285
- '/_candy/login',
286
- async Candy => {
287
- const csrfToken = await Candy.request('_token')
288
- if (!csrfToken || !Candy.token(csrfToken)) {
289
- return Candy.Request.abort(401)
290
- }
291
- return await Internal.login(Candy)
292
- },
293
- {token: true}
294
- )
295
-
296
- this.set(
297
- ['POST', 'GET', 'PUT', 'PATCH', 'DELETE'],
298
- '/_candy/form',
299
- async Candy => {
300
- const csrfToken = await Candy.request('_token')
301
- if (!csrfToken || !Candy.token(csrfToken)) {
302
- return Candy.Request.abort(401)
303
- }
304
- const result = await Internal.customForm(Candy)
305
- if (result !== null) return result
306
-
307
- return Candy.return({
308
- result: {
309
- success: false,
310
- message: 'No handler defined for this form'
311
- },
312
- errors: {_candy_form: 'Form action not configured'}
313
- })
314
- },
315
- {token: true}
316
- )
317
-
318
- delete Candy.Route.buff
319
- }
320
-
321
- async request(req, res) {
322
- let id = `${Date.now()}${Math.random().toString(36).substr(2, 9)}`
323
- let param = Candy.instance(id, req, res)
324
- if (!this.routes[param.Request.route]) return param.Request.end()
325
- try {
326
- let result = this.check(param)
327
- if (result instanceof Promise) result = await result
328
- const Stream = require('./Stream.js')
329
- if (result instanceof Stream) return
330
- if (param.Request.res.finished || param.Request.res.writableEnded) return
331
- if (result) param.Request.end(result)
332
- await param.View.print(param)
333
- param.Request.print(param)
334
- } catch (e) {
335
- console.error(e)
336
- param.Request.abort(500)
337
- return param.Request.end()
338
- }
339
- }
340
-
341
- set(type, url, file, options = {}) {
342
- if (Array.isArray(type)) {
343
- type = type.map(t => t.toLowerCase())
344
- for (const t of type) {
345
- this.set(t, url, file, options)
346
- }
347
- return
348
- }
349
-
350
- if (!options) options = {}
351
- if (typeof url !== 'string') url = String(url)
352
- if (url.length && url.substr(-1) === '/') url = url.substr(0, url.length - 1)
353
-
354
- type = type.toLowerCase()
355
-
356
- const isFunction = typeof file === 'function'
357
- let path = `${__dir}/route/${Candy.Route.buff}.js`
358
-
359
- if (!isFunction && file) {
360
- path = `${__dir}/controller/${type.replace('#', '')}/${file}.js`
361
- if (typeof file === 'string' && file.includes('.')) {
362
- let arr = file.split('.')
363
- path = `${__dir}/controller/${arr[0]}/${type.replace('#', '')}/${arr.slice(1).join('.')}.js`
364
- }
365
- }
366
-
367
- if (!this.routes[Candy.Route.buff]) this.routes[Candy.Route.buff] = {}
368
- if (!this.routes[Candy.Route.buff][type]) this.routes[Candy.Route.buff][type] = {}
369
-
370
- if (this.routes[Candy.Route.buff][type][url]) {
371
- this.routes[Candy.Route.buff][type][url].loaded = routes2[Candy.Route.buff]
372
- if (!isFunction && this.routes[Candy.Route.buff][type][url].mtime < fs.statSync(path).mtimeMs) {
373
- delete this.routes[Candy.Route.buff][type][url]
374
- delete require.cache[require.resolve(path)]
375
- } else return
376
- }
377
-
378
- if (isFunction || fs.existsSync(path)) {
379
- if (!this.routes[Candy.Route.buff][type][url]) this.routes[Candy.Route.buff][type][url] = {}
380
- this.routes[Candy.Route.buff][type][url].cache = isFunction ? file : require(path)
381
- this.routes[Candy.Route.buff][type][url].type = isFunction ? 'function' : 'controller'
382
- this.routes[Candy.Route.buff][type][url].file = file
383
- this.routes[Candy.Route.buff][type][url].mtime = isFunction ? Date.now() : fs.statSync(path).mtimeMs
384
- this.routes[Candy.Route.buff][type][url].path = path
385
- this.routes[Candy.Route.buff][type][url].loaded = routes2[Candy.Route.buff]
386
- this.routes[Candy.Route.buff][type][url].token = options.token ?? true
387
- }
388
- }
389
-
390
- page(path, file) {
391
- if (typeof file === 'object' && !Array.isArray(file)) {
392
- this.set('page', path, _candy => {
393
- _candy.View.set(file)
394
- return
395
- })
396
- return
397
- }
398
- if (file) this.set('page', path, file)
399
- }
400
-
401
- post(path, file, options) {
402
- this.set('post', path, file, options)
403
- }
404
-
405
- get(path, file, options) {
406
- this.set('get', path, file, options)
407
- }
408
-
409
- authPage(path, authFile, file) {
410
- if (typeof authFile === 'object' && !Array.isArray(authFile)) {
411
- this.set('#page', path, _candy => {
412
- _candy.View.set(authFile)
413
- return
414
- })
415
- if (typeof file === 'object' && !Array.isArray(file)) {
416
- this.set('page', path, _candy => {
417
- _candy.View.set(file)
418
- return
419
- })
420
- }
421
- return
422
- }
423
- if (authFile) this.set('#page', path, authFile)
424
- if (file) {
425
- if (typeof file === 'object' && !Array.isArray(file)) {
426
- this.set('page', path, _candy => {
427
- _candy.View.set(file)
428
- return
429
- })
430
- } else {
431
- this.set('page', path, file)
432
- }
433
- }
434
- }
435
-
436
- authPost(path, authFile, file) {
437
- if (authFile) this.set('#post', path, authFile)
438
- if (file) this.post(path, file)
439
- }
440
-
441
- authGet(path, authFile, file) {
442
- if (authFile) this.set('#get', path, authFile)
443
- if (file) this.get(path, file)
444
- }
445
-
446
- error(code, file) {
447
- this.set('error', code, file)
448
- }
449
-
450
- cron(controller) {
451
- return Cron.job(controller)
452
- }
453
- }
454
-
455
- module.exports = Route
@@ -1,15 +0,0 @@
1
- const http = require(`http`)
2
-
3
- module.exports = {
4
- init: function () {
5
- let args = process.argv.slice(2)
6
- if (args[0] == 'framework' && args[1] == 'run') args = args.slice(2)
7
- let port = parseInt(args[0] ?? '1071')
8
- console.log(`CandyPack Server running on \x1b]8;;http://127.0.0.1:${port}\x1b\\\x1b[4mhttp://127.0.0.1:${port}\x1b[0m\x1b]8;;\x1b\\.`)
9
- http
10
- .createServer((req, res) => {
11
- return Candy.Route.request(req, res)
12
- })
13
- .listen(port)
14
- }
15
- }
package/locale/de-DE.json DELETED
@@ -1,80 +0,0 @@
1
- {
2
- "Restart CandyPack Server": "CandyPack-Server neu starten",
3
- "Login to CandyPack Server": "Beim CandyPack-Server anmelden",
4
- "Status": "Status",
5
- "Starting CandyPack Server...": "CandyPack-Server wird gestartet...",
6
- "Uptime": "Betriebszeit",
7
- "Running": "Läuft",
8
- "Auth": "Authentifizierung",
9
- "Online": "Online",
10
- "%s Services": "%s Dienste",
11
- "Not logged in": "Nicht angemeldet",
12
- "Login on %s to manage all your server operations.": "Melden Sie sich bei %s an, um alle Ihre Server-Operationen zu verwalten.",
13
- "Start a CandyPack Service": "Einen CandyPack-Dienst starten",
14
- "Create a new Website": "Eine neue Website erstellen",
15
- "Delete a website": "Eine Website löschen",
16
- "List all CandyPack Services": "Alle CandyPack-Dienste auflisten",
17
- "List all CandyPack Websites": "Alle CandyPack-Websites auflisten",
18
- "Websites": "Websites",
19
- "Services": "Dienste",
20
- "Website %s doesn't have index.js file.": "Website %s hat keine index.js-Datei.",
21
- "Monitor Website or Service": "Website oder Dienst überwachen",
22
- "Offline": "Offline",
23
- "Restarting CandyPack Server...": "CandyPack-Server wird neu gestartet...",
24
- "Define your server to your CandyPack account": "Definieren Sie Ihren Server für Ihr CandyPack-Konto",
25
- "Insert Domain (example.com): ": "Domain eingeben (beispiel.com): ",
26
- "Commands:": "Befehle:",
27
- "Create a new Subdomain": "Eine neue Subdomain erstellen",
28
- "List all available commands": "Alle verfügbaren Befehle auflisten",
29
- "Website Management": "Website-Verwaltung",
30
- "Help": "Hilfe",
31
- "Add a new subdomain": "Eine neue Subdomain hinzufügen",
32
- "WEBSITE MANAGEMENT": "WEBSITE-VERWALTUNG",
33
- "HELP": "HILFE",
34
- "Debug CandyPack Server": "CandyPack-Server debuggen",
35
- "Add a new Service": "Einen neuen Dienst hinzufügen",
36
- "Domains": "Domänen",
37
- "Service %s added.": "Dienst %s hinzugefügt.",
38
- "Name": "Name",
39
- "Active": "Aktiv",
40
- "Errored": "Fehlerhaft",
41
- "Create a new mail account": "Ein neues E-Mail-Konto erstellen",
42
- "Delete a mail account": "Ein E-Mail-Konto löschen",
43
- "List all domain mail accounts": "Alle E-Mail-Konten einer Domain auflisten",
44
- "Change mail account password": "Passwort des E-Mail-Kontos ändern",
45
- "Renew SSL certificate for a domain": "SSL-Zertifikat für eine Domain erneuern",
46
- "List all domain subdomains": "Alle Subdomains einer Domain auflisten",
47
- "'%s' is not a valid command.": "'%s' ist kein gültiger Befehl.",
48
- "List all websites": "Alle Websites auflisten",
49
- "No websites found.": "Keine Websites gefunden.",
50
- "Service %s is not running.": "Dienst %s läuft nicht.",
51
- "Service %s not found.": "Dienst %s nicht gefunden.",
52
- "Enter the path to the website (%s): ": "Geben Sie den Pfad zur Website (%s) ein: ",
53
- "Website %s created.": "Website %s wurde erstellt.",
54
- "Websites:": "Websites:",
55
- "Website %s deleted.": "Website %s wurde gelöscht.",
56
- "Invalid domain.": "Ungültige Domain.",
57
- "Website %s1 created at %s2.": "Website %s1 wurde an %s2 erstellt.",
58
- "Enter the domain name: ": "Geben Sie den Domainnamen ein: ",
59
- "Modules": "Module",
60
- "Logs": "Protokolle",
61
- "Navigate": "Navigieren",
62
- "Select": "Auswählen",
63
- "Exit": "Beenden",
64
- "Website %s already exists.": "Website %s existiert bereits.",
65
- "Website %s not found.": "Website %s nicht gefunden.",
66
- "Create a new website": "Eine neue Website erstellen",
67
- "Setting up domain %s...": "Domain %s wird eingerichtet...",
68
- "Domain %s set.": "Domain %s wurde festgelegt.",
69
- "Setting up website files for %s...": "Website-Dateien für %s werden eingerichtet...",
70
- "Website files for %s set.": "Website-Dateien für %s wurden festgelegt.",
71
- "Setting up DNS records for %s...": "DNS-Einträge für %s werden eingerichtet...",
72
- "DNS records for %s set.": "DNS-Einträge für %s wurden festgelegt.",
73
- "Setting up SSL certificate for %s...": "SSL-Zertifikat für %s wird eingerichtet...",
74
- "SSL certificate for domain %s renewed successfully.": "SSL-Zertifikat für Domain %s wurde erfolgreich erneuert.",
75
- "Subdomain %s1 created successfully for domain %s2.": "Subdomain %s1 wurde erfolgreich für Domain %s2 erstellt.",
76
- "Invalid subdomain name.": "Ungültiger Subdomain-Name.",
77
- "Subdomain %s1 deleted successfully from domain %s2.": "Subdomain %s1 wurde erfolgreich von Domain %s2 gelöscht.",
78
- "%s is a domain.": "%s ist eine Domain.",
79
- "Enter the subdomain name (subdomain.example.com): ": "Geben Sie den Subdomain-Namen ein (subdomain.example.com): "
80
- }
package/locale/en-US.json DELETED
@@ -1,79 +0,0 @@
1
- {
2
- "Restart CandyPack Server": "Restart CandyPack Server",
3
- "Login to CandyPack Server": "Login to CandyPack Server",
4
- "Status": "Status",
5
- "Starting CandyPack Server...": "Starting CandyPack Server...",
6
- "Uptime": "Uptime",
7
- "Running": "Running",
8
- "Auth": "Auth",
9
- "Online": "Online",
10
- "%s Services": "%s Services",
11
- "Not logged in": "Not logged in",
12
- "Login on %s to manage all your server operations.": "Login on %s to manage all your server operations.",
13
- "Start a CandyPack Service": "Start a CandyPack Service",
14
- "Create a new Website": "Create a new Website",
15
- "Delete a website": "Delete a website",
16
- "List all CandyPack Services": "List all CandyPack Services",
17
- "List all CandyPack Websites": "List all CandyPack Websites",
18
- "Websites": "Websites",
19
- "Services": "Services",
20
- "Website %s doesn't have index.js file.": "Website %s doesn't have index.js file.",
21
- "Monitor Website or Service": "Monitor Website or Service",
22
- "Offline": "Offline",
23
- "Restarting CandyPack Server...": "Restarting CandyPack Server...",
24
- "Define your server to your CandyPack account": "Define your server to your CandyPack account",
25
- "Insert Domain (example.com): ": "Insert Domain (example.com): ",
26
- "Commands:": "Commands:",
27
- "Create a new Subdomain": "Create a new Subdomain",
28
- "List all available commands": "List all available commands",
29
- "Website Management": "Website Management",
30
- "Help": "Help",
31
- "Add a new subdomain": "Add a new subdomain",
32
- "WEBSITE MANAGEMENT": "WEBSITE MANAGEMENT",
33
- "HELP": "HELP",
34
- "Debug CandyPack Server": "Debug CandyPack Server",
35
- "Add a new Service": "Add a new Service",
36
- "Domains": "Domains",
37
- "Service %s added.": "Service %s added.",
38
- "Name": "Name",
39
- "Active": "Active",
40
- "Errored": "Errored",
41
- "Create a new mail account": "Create a new mail account",
42
- "Delete a mail account": "Delete a mail account",
43
- "List all domain mail accounts": "List all domain mail accounts",
44
- "Change mail account password": "Change mail account password",
45
- "Renew SSL certificate for a domain": "Renew SSL certificate for a domain",
46
- "List all domain subdomains": "List all domain subdomains",
47
- "'%s' is not a valid command.": "'%s' is not a valid command.",
48
- "List all websites": "List all websites",
49
- "No websites found.": "No websites found.",
50
- "Service %s is not running.": "Service %s is not running.",
51
- "Service %s not found.": "Service %s not found.",
52
- "Website %s created.": "Website %s created.",
53
- "Websites:": "Websites:",
54
- "Website %s deleted.": "Website %s deleted.",
55
- "Invalid domain.": "Invalid domain.",
56
- "Website %s1 created at %s2.": "Website %s1 created at %s2.",
57
- "Enter the domain name: ": "Enter the domain name: ",
58
- "Modules": "Modules",
59
- "Logs": "Logs",
60
- "Navigate": "Navigate",
61
- "Select": "Select",
62
- "Exit": "Exit",
63
- "Website %s already exists.": "Website %s already exists.",
64
- "Website %s not found.": "Website %s not found.",
65
- "Create a new website": "Create a new website",
66
- "Setting up domain %s...": "Setting up domain %s...",
67
- "Domain %s set.": "Domain %s set.",
68
- "Setting up website files for %s...": "Setting up website files for %s...",
69
- "Website files for %s set.": "Website files for %s set.",
70
- "Setting up DNS records for %s...": "Setting up DNS records for %s...",
71
- "DNS records for %s set.": "DNS records for %s set.",
72
- "Setting up SSL certificate for %s...": "Setting up SSL certificate for %s...",
73
- "SSL certificate for domain %s renewed successfully.": "SSL certificate for domain %s renewed successfully.",
74
- "Subdomain %s1 created successfully for domain %s2.": "Subdomain %s1 created successfully for domain %s2.",
75
- "Invalid subdomain name.": "Invalid subdomain name.",
76
- "Subdomain %s1 deleted successfully from domain %s2.": "Subdomain %s1 deleted successfully from domain %s2.",
77
- "%s is a domain.": "%s is a domain.",
78
- "Enter the subdomain name (subdomain.example.com): ": "Enter the subdomain name (subdomain.example.com): "
79
- }