odac 0.9.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 (213) hide show
  1. package/.editorconfig +21 -0
  2. package/.github/workflows/auto-pr-description.yml +49 -0
  3. package/.github/workflows/release.yml +32 -0
  4. package/.github/workflows/test-coverage.yml +58 -0
  5. package/.husky/pre-commit +2 -0
  6. package/.kiro/steering/code-style.md +56 -0
  7. package/.kiro/steering/product.md +20 -0
  8. package/.kiro/steering/structure.md +77 -0
  9. package/.kiro/steering/tech.md +87 -0
  10. package/.prettierrc +10 -0
  11. package/.releaserc.js +134 -0
  12. package/AGENTS.md +84 -0
  13. package/CHANGELOG.md +181 -0
  14. package/CODE_OF_CONDUCT.md +83 -0
  15. package/CONTRIBUTING.md +63 -0
  16. package/LICENSE +661 -0
  17. package/README.md +57 -0
  18. package/SECURITY.md +26 -0
  19. package/bin/candy +10 -0
  20. package/bin/candypack +10 -0
  21. package/cli/index.js +3 -0
  22. package/cli/src/Cli.js +348 -0
  23. package/cli/src/Connector.js +93 -0
  24. package/cli/src/Monitor.js +416 -0
  25. package/core/Candy.js +87 -0
  26. package/core/Commands.js +239 -0
  27. package/core/Config.js +1094 -0
  28. package/core/Lang.js +52 -0
  29. package/core/Log.js +43 -0
  30. package/core/Process.js +26 -0
  31. package/docs/backend/01-overview/01-whats-in-the-candy-box.md +9 -0
  32. package/docs/backend/01-overview/02-super-handy-helper-functions.md +9 -0
  33. package/docs/backend/01-overview/03-development-server.md +79 -0
  34. package/docs/backend/02-structure/01-typical-project-layout.md +39 -0
  35. package/docs/backend/03-config/00-configuration-overview.md +214 -0
  36. package/docs/backend/03-config/01-database-connection.md +60 -0
  37. package/docs/backend/03-config/02-static-route-mapping-optional.md +20 -0
  38. package/docs/backend/03-config/03-request-timeout.md +11 -0
  39. package/docs/backend/03-config/04-environment-variables.md +227 -0
  40. package/docs/backend/03-config/05-early-hints.md +352 -0
  41. package/docs/backend/04-routing/01-basic-page-routes.md +28 -0
  42. package/docs/backend/04-routing/02-controller-less-view-routes.md +43 -0
  43. package/docs/backend/04-routing/03-api-and-data-routes.md +20 -0
  44. package/docs/backend/04-routing/04-authentication-aware-routes.md +48 -0
  45. package/docs/backend/04-routing/05-advanced-routing.md +14 -0
  46. package/docs/backend/04-routing/06-error-pages.md +101 -0
  47. package/docs/backend/04-routing/07-cron-jobs.md +149 -0
  48. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +17 -0
  49. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +20 -0
  50. package/docs/backend/05-controllers/03-controller-classes.md +93 -0
  51. package/docs/backend/05-forms/01-custom-forms.md +395 -0
  52. package/docs/backend/05-forms/02-automatic-database-insert.md +297 -0
  53. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +96 -0
  54. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +40 -0
  55. package/docs/backend/07-views/01-the-view-directory.md +73 -0
  56. package/docs/backend/07-views/02-rendering-a-view.md +179 -0
  57. package/docs/backend/07-views/03-template-syntax.md +181 -0
  58. package/docs/backend/07-views/03-variables.md +328 -0
  59. package/docs/backend/07-views/04-request-data.md +231 -0
  60. package/docs/backend/07-views/05-conditionals.md +290 -0
  61. package/docs/backend/07-views/06-loops.md +353 -0
  62. package/docs/backend/07-views/07-translations.md +358 -0
  63. package/docs/backend/07-views/08-backend-javascript.md +398 -0
  64. package/docs/backend/07-views/09-comments.md +297 -0
  65. package/docs/backend/08-database/01-database-connection.md +99 -0
  66. package/docs/backend/08-database/02-using-mysql.md +322 -0
  67. package/docs/backend/09-validation/01-the-validator-service.md +424 -0
  68. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +53 -0
  69. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +55 -0
  70. package/docs/backend/10-authentication/03-register.md +134 -0
  71. package/docs/backend/10-authentication/04-candy-register-forms.md +676 -0
  72. package/docs/backend/10-authentication/05-session-management.md +159 -0
  73. package/docs/backend/10-authentication/06-candy-login-forms.md +596 -0
  74. package/docs/backend/11-mail/01-the-mail-service.md +42 -0
  75. package/docs/backend/12-streaming/01-streaming-overview.md +300 -0
  76. package/docs/backend/13-utilities/01-candy-var.md +504 -0
  77. package/docs/frontend/01-overview/01-introduction.md +146 -0
  78. package/docs/frontend/02-ajax-navigation/01-quick-start.md +608 -0
  79. package/docs/frontend/02-ajax-navigation/02-configuration.md +370 -0
  80. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +519 -0
  81. package/docs/frontend/03-forms/01-form-handling.md +420 -0
  82. package/docs/frontend/04-api-requests/01-get-post.md +443 -0
  83. package/docs/frontend/05-streaming/01-client-streaming.md +163 -0
  84. package/docs/index.json +452 -0
  85. package/docs/server/01-installation/01-quick-install.md +19 -0
  86. package/docs/server/01-installation/02-manual-installation-via-npm.md +9 -0
  87. package/docs/server/02-get-started/01-core-concepts.md +7 -0
  88. package/docs/server/02-get-started/02-basic-commands.md +57 -0
  89. package/docs/server/02-get-started/03-cli-reference.md +276 -0
  90. package/docs/server/02-get-started/04-cli-quick-reference.md +102 -0
  91. package/docs/server/03-service/01-start-a-new-service.md +57 -0
  92. package/docs/server/03-service/02-delete-a-service.md +48 -0
  93. package/docs/server/04-web/01-create-a-website.md +36 -0
  94. package/docs/server/04-web/02-list-websites.md +9 -0
  95. package/docs/server/04-web/03-delete-a-website.md +29 -0
  96. package/docs/server/05-subdomain/01-create-a-subdomain.md +32 -0
  97. package/docs/server/05-subdomain/02-list-subdomains.md +33 -0
  98. package/docs/server/05-subdomain/03-delete-a-subdomain.md +41 -0
  99. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +34 -0
  100. package/docs/server/07-mail/01-create-a-mail-account.md +23 -0
  101. package/docs/server/07-mail/02-delete-a-mail-account.md +20 -0
  102. package/docs/server/07-mail/03-list-mail-accounts.md +20 -0
  103. package/docs/server/07-mail/04-change-account-password.md +23 -0
  104. package/eslint.config.mjs +120 -0
  105. package/framework/index.js +4 -0
  106. package/framework/src/Auth.js +309 -0
  107. package/framework/src/Candy.js +81 -0
  108. package/framework/src/Config.js +79 -0
  109. package/framework/src/Env.js +60 -0
  110. package/framework/src/Lang.js +57 -0
  111. package/framework/src/Mail.js +83 -0
  112. package/framework/src/Mysql.js +575 -0
  113. package/framework/src/Request.js +301 -0
  114. package/framework/src/Route/Cron.js +128 -0
  115. package/framework/src/Route/Internal.js +439 -0
  116. package/framework/src/Route.js +455 -0
  117. package/framework/src/Server.js +15 -0
  118. package/framework/src/Stream.js +163 -0
  119. package/framework/src/Token.js +37 -0
  120. package/framework/src/Validator.js +271 -0
  121. package/framework/src/Var.js +211 -0
  122. package/framework/src/View/EarlyHints.js +190 -0
  123. package/framework/src/View/Form.js +600 -0
  124. package/framework/src/View.js +513 -0
  125. package/framework/web/candy.js +838 -0
  126. package/jest.config.js +22 -0
  127. package/locale/de-DE.json +80 -0
  128. package/locale/en-US.json +79 -0
  129. package/locale/es-ES.json +80 -0
  130. package/locale/fr-FR.json +80 -0
  131. package/locale/pt-BR.json +80 -0
  132. package/locale/ru-RU.json +80 -0
  133. package/locale/tr-TR.json +85 -0
  134. package/locale/zh-CN.json +80 -0
  135. package/package.json +86 -0
  136. package/server/index.js +5 -0
  137. package/server/src/Api.js +88 -0
  138. package/server/src/DNS.js +940 -0
  139. package/server/src/Hub.js +535 -0
  140. package/server/src/Mail.js +571 -0
  141. package/server/src/SSL.js +180 -0
  142. package/server/src/Server.js +27 -0
  143. package/server/src/Service.js +248 -0
  144. package/server/src/Subdomain.js +64 -0
  145. package/server/src/Web/Firewall.js +170 -0
  146. package/server/src/Web/Proxy.js +134 -0
  147. package/server/src/Web.js +451 -0
  148. package/server/src/mail/imap.js +1091 -0
  149. package/server/src/mail/server.js +32 -0
  150. package/server/src/mail/smtp.js +786 -0
  151. package/test/cli/Cli.test.js +36 -0
  152. package/test/core/Candy.test.js +234 -0
  153. package/test/core/Commands.test.js +538 -0
  154. package/test/core/Config.test.js +1435 -0
  155. package/test/core/Lang.test.js +250 -0
  156. package/test/core/Process.test.js +156 -0
  157. package/test/framework/Route.test.js +239 -0
  158. package/test/framework/View/EarlyHints.test.js +282 -0
  159. package/test/scripts/check-coverage.js +132 -0
  160. package/test/server/Api.test.js +647 -0
  161. package/test/server/Client.test.js +338 -0
  162. package/test/server/DNS.test.js +2050 -0
  163. package/test/server/DNS.test.js.bak +2084 -0
  164. package/test/server/Log.test.js +73 -0
  165. package/test/server/Mail.account.test_.js +460 -0
  166. package/test/server/Mail.init.test_.js +411 -0
  167. package/test/server/Mail.test_.js +1340 -0
  168. package/test/server/SSL.test_.js +1491 -0
  169. package/test/server/Server.test.js +765 -0
  170. package/test/server/Service.test_.js +1127 -0
  171. package/test/server/Subdomain.test.js +440 -0
  172. package/test/server/Web/Firewall.test.js +175 -0
  173. package/test/server/Web.test_.js +1562 -0
  174. package/test/server/__mocks__/acme-client.js +17 -0
  175. package/test/server/__mocks__/bcrypt.js +50 -0
  176. package/test/server/__mocks__/child_process.js +389 -0
  177. package/test/server/__mocks__/crypto.js +432 -0
  178. package/test/server/__mocks__/fs.js +450 -0
  179. package/test/server/__mocks__/globalCandy.js +227 -0
  180. package/test/server/__mocks__/http-proxy.js +105 -0
  181. package/test/server/__mocks__/http.js +575 -0
  182. package/test/server/__mocks__/https.js +272 -0
  183. package/test/server/__mocks__/index.js +249 -0
  184. package/test/server/__mocks__/mail/server.js +100 -0
  185. package/test/server/__mocks__/mail/smtp.js +31 -0
  186. package/test/server/__mocks__/mailparser.js +81 -0
  187. package/test/server/__mocks__/net.js +369 -0
  188. package/test/server/__mocks__/node-forge.js +328 -0
  189. package/test/server/__mocks__/os.js +320 -0
  190. package/test/server/__mocks__/path.js +291 -0
  191. package/test/server/__mocks__/selfsigned.js +8 -0
  192. package/test/server/__mocks__/server/src/mail/server.js +100 -0
  193. package/test/server/__mocks__/server/src/mail/smtp.js +31 -0
  194. package/test/server/__mocks__/smtp-server.js +106 -0
  195. package/test/server/__mocks__/sqlite3.js +394 -0
  196. package/test/server/__mocks__/testFactories.js +299 -0
  197. package/test/server/__mocks__/testHelpers.js +363 -0
  198. package/test/server/__mocks__/tls.js +229 -0
  199. package/watchdog/index.js +3 -0
  200. package/watchdog/src/Watchdog.js +156 -0
  201. package/web/config.json +5 -0
  202. package/web/controller/page/about.js +27 -0
  203. package/web/controller/page/index.js +34 -0
  204. package/web/package.json +18 -0
  205. package/web/public/assets/css/style.css +1835 -0
  206. package/web/public/assets/js/app.js +96 -0
  207. package/web/route/www.js +19 -0
  208. package/web/skeleton/main.html +22 -0
  209. package/web/view/content/about.html +65 -0
  210. package/web/view/content/home.html +205 -0
  211. package/web/view/footer/main.html +11 -0
  212. package/web/view/head/main.html +5 -0
  213. package/web/view/header/main.html +14 -0
@@ -0,0 +1,239 @@
1
+ require('./Candy.js')
2
+
3
+ const path = require('path')
4
+
5
+ module.exports = {
6
+ auth: {
7
+ args: ['key', '-k', '--key'],
8
+ description: 'Define your server to your CandyPack account',
9
+ action: async args => {
10
+ const cli = Candy.cli('Cli')
11
+ let key = cli.parseArg(args, ['-k', '--key']) || args[0]
12
+ if (!key) key = await cli.question(__('Enter your authentication key: '))
13
+
14
+ await Candy.cli('Connector').call({
15
+ action: 'auth',
16
+ data: [key]
17
+ })
18
+ }
19
+ },
20
+ debug: {
21
+ description: 'Debug CandyPack Server',
22
+ action: async () => Candy.cli('Monitor').debug()
23
+ },
24
+ help: {
25
+ description: 'List all available commands',
26
+ action: async () => Candy.cli('Cli').help()
27
+ },
28
+ monit: {
29
+ description: 'Monitor Website or Service',
30
+ action: async () => Candy.cli('Monitor').monit()
31
+ },
32
+ restart: {
33
+ description: 'Restart CandyPack Server',
34
+ action: async () => Candy.cli('Cli').boot()
35
+ },
36
+ run: {
37
+ args: ['file'],
38
+ description: 'Add a new Service',
39
+ action: async args => {
40
+ let service = args[0]
41
+ if (!service.startsWith('/') && !/^[a-zA-Z]:\\|^\\\\/.test(service)) {
42
+ service = path.resolve() + '/' + service
43
+ }
44
+ await Candy.cli('Connector').call({action: 'service.start', data: [service]})
45
+ }
46
+ },
47
+
48
+ mail: {
49
+ title: 'MAIL',
50
+ sub: {
51
+ create: {
52
+ description: 'Create a new mail account',
53
+ args: ['-e', '--email', '-p', '--password'],
54
+ action: async args => {
55
+ const cli = Candy.cli('Cli')
56
+ let email = cli.parseArg(args, ['-e', '--email'])
57
+ let password = cli.parseArg(args, ['-p', '--password'])
58
+
59
+ if (!email) email = await cli.question(__('Enter the e-mail address: '))
60
+ if (!password) password = await cli.question(__('Enter the password: '))
61
+
62
+ let confirmPassword = password
63
+ if (!cli.parseArg(args, ['-p', '--password'])) {
64
+ confirmPassword = await cli.question(__('Re-enter the password: '))
65
+ }
66
+
67
+ await Candy.cli('Connector').call({
68
+ action: 'mail.create',
69
+ data: [email, password, confirmPassword]
70
+ })
71
+ }
72
+ },
73
+ delete: {
74
+ description: 'Delete a mail account',
75
+ args: ['-e', '--email'],
76
+ action: async args => {
77
+ const cli = Candy.cli('Cli')
78
+ let email = cli.parseArg(args, ['-e', '--email'])
79
+ if (!email) email = await cli.question(__('Enter the e-mail address: '))
80
+
81
+ await Candy.cli('Connector').call({
82
+ action: 'mail.delete',
83
+ data: [email]
84
+ })
85
+ }
86
+ },
87
+ list: {
88
+ description: 'List all domain mail accounts',
89
+ args: ['-d', '--domain'],
90
+ action: async args => {
91
+ const cli = Candy.cli('Cli')
92
+ let domain = cli.parseArg(args, ['-d', '--domain'])
93
+ if (!domain) domain = await cli.question(__('Enter the domain name: '))
94
+
95
+ await Candy.cli('Connector').call({action: 'mail.list', data: [domain]})
96
+ }
97
+ },
98
+ password: {
99
+ description: 'Change mail account password',
100
+ args: ['-e', '--email', '-p', '--password'],
101
+ action: async args => {
102
+ const cli = Candy.cli('Cli')
103
+ let email = cli.parseArg(args, ['-e', '--email'])
104
+ let password = cli.parseArg(args, ['-p', '--password'])
105
+
106
+ if (!email) email = await cli.question(__('Enter the e-mail address: '))
107
+ if (!password) password = await cli.question(__('Enter the new password: '))
108
+
109
+ let confirmPassword = password
110
+ if (!cli.parseArg(args, ['-p', '--password'])) {
111
+ confirmPassword = await cli.question(__('Re-enter the new password: '))
112
+ }
113
+
114
+ await Candy.cli('Connector').call({
115
+ action: 'mail.password',
116
+ data: [email, password, confirmPassword]
117
+ })
118
+ }
119
+ }
120
+ }
121
+ },
122
+ ssl: {
123
+ title: 'SSL',
124
+ sub: {
125
+ renew: {
126
+ description: 'Renew SSL certificate for a domain',
127
+ args: ['-d', '--domain'],
128
+ action: async args => {
129
+ const cli = Candy.cli('Cli')
130
+ let domain = cli.parseArg(args, ['-d', '--domain'])
131
+ if (!domain) domain = await cli.question(__('Enter the domain name: '))
132
+
133
+ await Candy.cli('Connector').call({action: 'ssl.renew', data: [domain]})
134
+ }
135
+ }
136
+ }
137
+ },
138
+ service: {
139
+ title: 'SERVICE',
140
+ sub: {
141
+ delete: {
142
+ description: 'Delete a Service',
143
+ args: ['-i', '--id'],
144
+ action: async args => {
145
+ const cli = Candy.cli('Cli')
146
+ let service = cli.parseArg(args, ['-i', '--id'])
147
+ if (!service) service = await cli.question(__('Enter the Service ID or Name: '))
148
+ await Candy.cli('Connector').call({action: 'service.delete', data: [service]})
149
+ }
150
+ }
151
+ }
152
+ },
153
+ subdomain: {
154
+ title: 'SUBDOMAIN',
155
+ sub: {
156
+ create: {
157
+ description: 'Create a new subdomain',
158
+ args: ['-s', '--subdomain'],
159
+ action: async args => {
160
+ const cli = Candy.cli('Cli')
161
+ let subdomain = cli.parseArg(args, ['-s', '--subdomain'])
162
+ if (!subdomain) subdomain = await cli.question(__('Enter the subdomain name (subdomain.example.com): '))
163
+
164
+ await Candy.cli('Connector').call({
165
+ action: 'subdomain.create',
166
+ data: [subdomain]
167
+ })
168
+ }
169
+ },
170
+ delete: {
171
+ description: 'Delete a subdomain',
172
+ args: ['-s', '--subdomain'],
173
+ action: async args => {
174
+ const cli = Candy.cli('Cli')
175
+ let subdomain = cli.parseArg(args, ['-s', '--subdomain'])
176
+ if (!subdomain) subdomain = await cli.question(__('Enter the subdomain name (subdomain.example.com): '))
177
+
178
+ await Candy.cli('Connector').call({
179
+ action: 'subdomain.delete',
180
+ data: [subdomain]
181
+ })
182
+ }
183
+ },
184
+ list: {
185
+ description: 'List all domain subdomains',
186
+ args: ['-d', '--domain'],
187
+ action: async args => {
188
+ const cli = Candy.cli('Cli')
189
+ let domain = cli.parseArg(args, ['-d', '--domain'])
190
+ if (!domain) domain = await cli.question(__('Enter the domain name: '))
191
+
192
+ await Candy.cli('Connector').call({
193
+ action: 'subdomain.list',
194
+ data: [domain]
195
+ })
196
+ }
197
+ }
198
+ }
199
+ },
200
+ web: {
201
+ title: 'WEBSITE',
202
+ sub: {
203
+ create: {
204
+ description: 'Create a new website',
205
+ args: ['-d', '--domain'],
206
+ action: async args => {
207
+ const cli = Candy.cli('Cli')
208
+ let domain = cli.parseArg(args, ['-d', '--domain'])
209
+ if (!domain) {
210
+ domain = await cli.question(__('Enter the domain name: '))
211
+ }
212
+ await Candy.cli('Connector').call({
213
+ action: 'web.create',
214
+ data: [domain]
215
+ })
216
+ }
217
+ },
218
+ delete: {
219
+ description: 'Delete a website',
220
+ args: ['-d', '--domain'],
221
+ action: async args => {
222
+ const cli = Candy.cli('Cli')
223
+ let domain = cli.parseArg(args, ['-d', '--domain'])
224
+ if (!domain) {
225
+ domain = await cli.question(__('Enter the domain name: '))
226
+ }
227
+ await Candy.cli('Connector').call({
228
+ action: 'web.delete',
229
+ data: [domain]
230
+ })
231
+ }
232
+ },
233
+ list: {
234
+ description: 'List all websites',
235
+ action: async () => await Candy.cli('Connector').call({action: 'web.list'})
236
+ }
237
+ }
238
+ }
239
+ }