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.
- package/.github/workflows/auto-pr-description.yml +0 -2
- package/.github/workflows/codeql.yml +46 -0
- package/.github/workflows/release.yml +13 -6
- package/.github/workflows/test-coverage.yml +10 -9
- package/.releaserc.js +9 -6
- package/CHANGELOG.md +62 -150
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTING.md +8 -8
- package/LICENSE +21 -661
- package/README.md +12 -12
- package/SECURITY.md +4 -4
- package/bin/odac.js +101 -0
- package/{framework/web/candy.js → client/odac.js} +310 -44
- package/docs/backend/01-overview/{01-whats-in-the-candy-box.md → 01-whats-in-the-odac-box.md} +4 -2
- package/docs/backend/01-overview/02-super-handy-helper-functions.md +29 -1
- package/docs/backend/01-overview/03-development-server.md +11 -11
- package/docs/backend/02-structure/01-typical-project-layout.md +4 -4
- package/docs/backend/03-config/00-configuration-overview.md +6 -6
- package/docs/backend/03-config/01-database-connection.md +1 -1
- package/docs/backend/03-config/02-static-route-mapping-optional.md +4 -4
- package/docs/backend/03-config/04-environment-variables.md +20 -20
- package/docs/backend/03-config/05-early-hints.md +4 -4
- package/docs/backend/04-routing/01-basic-page-routes.md +4 -4
- package/docs/backend/04-routing/02-controller-less-view-routes.md +5 -5
- package/docs/backend/04-routing/03-api-and-data-routes.md +3 -3
- package/docs/backend/04-routing/04-authentication-aware-routes.md +5 -5
- package/docs/backend/04-routing/05-advanced-routing.md +3 -3
- package/docs/backend/04-routing/06-error-pages.md +17 -17
- package/docs/backend/04-routing/07-cron-jobs.md +13 -13
- package/docs/backend/04-routing/08-middleware.md +214 -0
- package/docs/backend/04-routing/09-websocket-auth-middleware.md +292 -0
- package/docs/backend/04-routing/09-websocket-examples.md +381 -0
- package/docs/backend/04-routing/09-websocket-quick-reference.md +211 -0
- package/docs/backend/04-routing/09-websocket.md +298 -0
- package/docs/backend/05-controllers/01-how-to-build-a-controller.md +3 -3
- package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +41 -0
- package/docs/backend/05-controllers/03-controller-classes.md +19 -19
- package/docs/backend/05-forms/01-custom-forms.md +114 -114
- package/docs/backend/05-forms/02-automatic-database-insert.md +82 -82
- package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +26 -26
- package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +10 -10
- package/docs/backend/07-views/01-the-view-directory.md +1 -1
- package/docs/backend/07-views/02-rendering-a-view.md +22 -22
- package/docs/backend/07-views/03-template-syntax.md +52 -52
- package/docs/backend/07-views/03-variables.md +84 -84
- package/docs/backend/07-views/04-request-data.md +57 -57
- package/docs/backend/07-views/05-conditionals.md +78 -78
- package/docs/backend/07-views/06-loops.md +114 -114
- package/docs/backend/07-views/07-translations.md +66 -66
- package/docs/backend/07-views/08-backend-javascript.md +103 -103
- package/docs/backend/07-views/09-comments.md +71 -71
- package/docs/backend/08-database/01-database-connection.md +8 -8
- package/docs/backend/08-database/02-using-mysql.md +49 -49
- package/docs/backend/09-validation/01-the-validator-service.md +38 -38
- package/docs/backend/10-authentication/01-user-logins-with-authjs.md +15 -15
- package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +10 -10
- package/docs/backend/10-authentication/03-register.md +12 -12
- package/docs/backend/10-authentication/{04-candy-register-forms.md → 04-odac-register-forms.md} +141 -141
- package/docs/backend/10-authentication/05-session-management.md +10 -10
- package/docs/backend/10-authentication/{06-candy-login-forms.md → 06-odac-login-forms.md} +125 -125
- package/docs/backend/11-mail/01-the-mail-service.md +5 -5
- package/docs/backend/12-streaming/01-streaming-overview.md +96 -54
- package/docs/backend/13-utilities/{01-candy-var.md → 01-odac-var.md} +109 -109
- package/docs/frontend/01-overview/01-introduction.md +30 -30
- package/docs/frontend/02-ajax-navigation/01-quick-start.md +45 -45
- package/docs/frontend/02-ajax-navigation/02-configuration.md +14 -14
- package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +36 -36
- package/docs/frontend/03-forms/01-form-handling.md +32 -32
- package/docs/frontend/04-api-requests/01-get-post.md +33 -33
- package/docs/frontend/05-streaming/01-client-streaming.md +15 -15
- package/docs/frontend/06-websocket/00-overview.md +76 -0
- package/docs/frontend/06-websocket/01-websocket-client.md +139 -0
- package/docs/frontend/06-websocket/02-shared-websocket.md +149 -0
- package/docs/index.json +49 -11
- package/eslint.config.mjs +6 -6
- package/{framework/index.js → index.js} +1 -1
- package/package.json +14 -39
- package/{framework/src → src}/Auth.js +59 -59
- package/{framework/src → src}/Config.js +3 -3
- package/{framework/src → src}/Lang.js +7 -7
- package/{framework/src → src}/Mail.js +5 -5
- package/{framework/src → src}/Mysql.js +42 -42
- package/src/Odac.js +112 -0
- package/{framework/src → src}/Request.js +38 -36
- package/{framework/src → src}/Route/Internal.js +116 -116
- package/src/Route/Middleware.js +75 -0
- package/src/Route.js +621 -0
- package/src/Server.js +22 -0
- package/{framework/src → src}/Stream.js +11 -3
- package/{framework/src → src}/Validator.js +21 -21
- package/{framework/src → src}/Var.js +5 -5
- package/{framework/src → src}/View/EarlyHints.js +1 -1
- package/{framework/src → src}/View/Form.js +69 -69
- package/{framework/src → src}/View.js +78 -81
- package/src/WebSocket.js +403 -0
- package/template/config.json +5 -0
- package/{web → template}/controller/page/about.js +6 -6
- package/{web → template}/controller/page/index.js +9 -9
- package/{web → template}/package.json +4 -5
- package/{web → template}/public/assets/css/style.css +4 -4
- package/{web → template}/public/assets/js/app.js +6 -6
- package/{web → template}/route/www.js +6 -6
- package/{web → template}/skeleton/main.html +1 -1
- package/{web → template}/view/content/about.html +5 -5
- package/{web → template}/view/content/home.html +12 -12
- package/template/view/footer/main.html +11 -0
- package/{web → template}/view/head/main.html +1 -1
- package/{web → template}/view/header/main.html +2 -2
- package/test/core/Candy.test.js +58 -58
- package/test/core/Commands.test.js +7 -7
- package/test/core/Config.test.js +82 -85
- package/test/core/Lang.test.js +2 -2
- package/test/core/Process.test.js +6 -6
- package/test/framework/Route.test.js +56 -37
- package/test/framework/View/EarlyHints.test.js +2 -2
- package/test/framework/WebSocket.test.js +100 -0
- package/test/framework/middleware.test.js +85 -0
- package/test/server/Api.test.js +31 -31
- package/test/server/DNS.test.js +11 -11
- package/test/server/Hub.test.js +497 -0
- package/test/server/Mail.account.test_.js +3 -3
- package/test/server/Mail.init.test_.js +10 -10
- package/test/server/Mail.test_.js +20 -20
- package/test/server/SSL.test_.js +54 -54
- package/test/server/Server.test.js +39 -39
- package/test/server/Service.test_.js +7 -7
- package/test/server/Subdomain.test.js +7 -7
- package/test/server/Web/Firewall.test.js +87 -87
- package/test/server/Web/Proxy.test.js +397 -0
- package/test/server/{Web.test_.js → Web.test.js} +137 -205
- package/test/server/__mocks__/fs.js +2 -2
- package/test/server/__mocks__/{globalCandy.js → globalOdac.js} +5 -5
- package/test/server/__mocks__/index.js +6 -6
- package/test/server/__mocks__/testFactories.js +1 -1
- package/test/server/__mocks__/testHelpers.js +7 -7
- package/.husky/pre-commit +0 -2
- package/.kiro/steering/code-style.md +0 -56
- package/.kiro/steering/product.md +0 -20
- package/.kiro/steering/structure.md +0 -77
- package/.kiro/steering/tech.md +0 -87
- package/AGENTS.md +0 -84
- package/bin/candy +0 -10
- package/bin/candypack +0 -10
- package/cli/index.js +0 -3
- package/cli/src/Cli.js +0 -348
- package/cli/src/Connector.js +0 -93
- package/cli/src/Monitor.js +0 -416
- package/core/Candy.js +0 -87
- package/core/Commands.js +0 -239
- package/core/Config.js +0 -1094
- package/core/Lang.js +0 -52
- package/core/Log.js +0 -43
- package/core/Process.js +0 -26
- package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +0 -20
- package/docs/server/01-installation/01-quick-install.md +0 -19
- package/docs/server/01-installation/02-manual-installation-via-npm.md +0 -9
- package/docs/server/02-get-started/01-core-concepts.md +0 -7
- package/docs/server/02-get-started/02-basic-commands.md +0 -57
- package/docs/server/02-get-started/03-cli-reference.md +0 -276
- package/docs/server/02-get-started/04-cli-quick-reference.md +0 -102
- package/docs/server/03-service/01-start-a-new-service.md +0 -57
- package/docs/server/03-service/02-delete-a-service.md +0 -48
- package/docs/server/04-web/01-create-a-website.md +0 -36
- package/docs/server/04-web/02-list-websites.md +0 -9
- package/docs/server/04-web/03-delete-a-website.md +0 -29
- package/docs/server/05-subdomain/01-create-a-subdomain.md +0 -32
- package/docs/server/05-subdomain/02-list-subdomains.md +0 -33
- package/docs/server/05-subdomain/03-delete-a-subdomain.md +0 -41
- package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +0 -34
- package/docs/server/07-mail/01-create-a-mail-account.md +0 -23
- package/docs/server/07-mail/02-delete-a-mail-account.md +0 -20
- package/docs/server/07-mail/03-list-mail-accounts.md +0 -20
- package/docs/server/07-mail/04-change-account-password.md +0 -23
- package/framework/src/Candy.js +0 -81
- package/framework/src/Route.js +0 -455
- package/framework/src/Server.js +0 -15
- package/locale/de-DE.json +0 -80
- package/locale/en-US.json +0 -79
- package/locale/es-ES.json +0 -80
- package/locale/fr-FR.json +0 -80
- package/locale/pt-BR.json +0 -80
- package/locale/ru-RU.json +0 -80
- package/locale/tr-TR.json +0 -85
- package/locale/zh-CN.json +0 -80
- package/server/index.js +0 -5
- package/server/src/Api.js +0 -88
- package/server/src/DNS.js +0 -940
- package/server/src/Hub.js +0 -535
- package/server/src/Mail.js +0 -571
- package/server/src/SSL.js +0 -180
- package/server/src/Server.js +0 -27
- package/server/src/Service.js +0 -248
- package/server/src/Subdomain.js +0 -64
- package/server/src/Web/Firewall.js +0 -170
- package/server/src/Web/Proxy.js +0 -134
- package/server/src/Web.js +0 -451
- package/server/src/mail/imap.js +0 -1091
- package/server/src/mail/server.js +0 -32
- package/server/src/mail/smtp.js +0 -786
- package/test/server/Client.test.js +0 -338
- package/test/server/__mocks__/http-proxy.js +0 -105
- package/watchdog/index.js +0 -3
- package/watchdog/src/Watchdog.js +0 -156
- package/web/config.json +0 -5
- package/web/view/footer/main.html +0 -11
- /package/{framework/src → src}/Env.js +0 -0
- /package/{framework/src → src}/Route/Cron.js +0 -0
- /package/{framework/src → src}/Token.js +0 -0
package/framework/src/Route.js
DELETED
|
@@ -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
|
package/framework/src/Server.js
DELETED
|
@@ -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
|
-
}
|