nibula 1.1.2 → 1.2.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/.eleventy.js +1 -9
- package/CHANGELOG.md +31 -0
- package/README.md +6 -2
- package/bin/create.js +2 -3
- package/bin/nibula.js +4 -4
- package/docs/Assistant CLI.md +1 -1
- package/docs/Components.md +3 -14
- package/docs/Creating pages.md +5 -5
- package/docs/Head and SEO.md +36 -14
- package/docs/Javascript.md +1 -3
- package/docs/Styling with SCSS.md +9 -3
- package/nginx.conf +75 -75
- package/package.json +3 -3
- package/src/backend/_core/index.js +267 -267
- package/src/backend/_core/init.js +52 -52
- package/src/backend/_core/modules/RateLimiter.js +58 -58
- package/src/backend/_core/modules/Response.js +59 -59
- package/src/backend/api/protected/example-protected.js +23 -23
- package/src/backend/api/public/example-public.js +24 -24
- package/src/backend/backend-node.service.example +30 -30
- package/src/backend/database/Database.js +46 -46
- package/src/backend/example.config.js +37 -37
- package/src/backend/package.json +18 -18
- package/src/frontend/.htaccess +51 -51
- package/src/frontend/assets/brand/apple-touch-icon.png +0 -0
- package/src/frontend/assets/brand/favicon-32.png +0 -0
- package/src/frontend/assets/brand/favicon-48.png +0 -0
- package/src/frontend/assets/brand/favicon.svg +54 -54
- package/src/frontend/assets/brand/logo.svg +54 -54
- package/src/frontend/components/global/header.njk +1 -1
- package/src/frontend/components/welcome.njk +0 -1
- package/src/frontend/data/site.json +48 -54
- package/src/frontend/layouts/base.njk +6 -15
- package/src/frontend/scss/modules/_global.scss +4 -0
- package/src/frontend/web.config +55 -55
- package/{_tools → tools}/modules/constants.js +2 -2
- /package/{_tools → tools}/assistant.js +0 -0
- /package/{_tools → tools}/buildJs.js +0 -0
- /package/{_tools → tools}/cleanOutput.js +0 -0
- /package/{_tools → tools}/modules/pageComponents.js +0 -0
- /package/{_tools → tools}/modules/updateData.js +0 -0
- /package/{_tools → tools}/modules/updateOutputPath.js +0 -0
- /package/{_tools → tools}/modules/updatePage.js +0 -0
- /package/{_tools → tools}/modules/utils.js +0 -0
- /package/{_tools → tools}/modules/validation.js +0 -0
- /package/{_tools → tools}/res/templates/template.js +0 -0
- /package/{_tools → tools}/res/templates/template.njk +0 -0
- /package/{_tools → tools}/res/templates/template.scss +0 -0
- /package/{_tools → tools}/res/templates/template.ts +0 -0
package/src/frontend/.htaccess
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
Options -Indexes
|
|
2
|
-
ErrorDocument 404 /404.html
|
|
3
|
-
ErrorDocument 403 /404.html
|
|
4
|
-
|
|
5
|
-
<IfModule mod_rewrite.c>
|
|
6
|
-
RewriteEngine On
|
|
7
|
-
RewriteBase /
|
|
8
|
-
|
|
9
|
-
# Block sensitive files (web.config, dotfiles)
|
|
10
|
-
RewriteRule ^(web\.config|\..*)$ /404.html [L,NC]
|
|
11
|
-
</IfModule>
|
|
12
|
-
|
|
13
|
-
# === /api routing — covers BOTH backends ====================================
|
|
14
|
-
#
|
|
15
|
-
# Apache (unlike nginx) cannot health-check an upstream, so it cannot auto-fall
|
|
16
|
-
# back from Node to PHP. The behaviour is:
|
|
17
|
-
#
|
|
18
|
-
# - mod_proxy available -> /api is proxied to the Node backend (127.0.0.1:3000)
|
|
19
|
-
# - mod_proxy NOT present -> /api is rewritten to the PHP front controller
|
|
20
|
-
#
|
|
21
|
-
# Typical shared hosting (Aruba, cPanel) has no mod_proxy, so it uses PHP
|
|
22
|
-
# automatically. On a VPS running Node, mod_proxy sends /api to Node.
|
|
23
|
-
#
|
|
24
|
-
# If you are on a server that HAS mod_proxy but you want to use PHP, comment out
|
|
25
|
-
# the mod_proxy block below.
|
|
26
|
-
|
|
27
|
-
# --- Node backend (if mod_proxy is available) ---
|
|
28
|
-
<IfModule mod_proxy.c>
|
|
29
|
-
ProxyPreserveHost On
|
|
30
|
-
ProxyPass /api/ http://127.0.0.1:3000/api/ retry=0
|
|
31
|
-
ProxyPassReverse /api/ http://127.0.0.1:3000/api/
|
|
32
|
-
|
|
33
|
-
<IfModule mod_headers.c>
|
|
34
|
-
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
|
|
35
|
-
RequestHeader set X-Forwarded-Proto "https"
|
|
36
|
-
</IfModule>
|
|
37
|
-
</IfModule>
|
|
38
|
-
|
|
39
|
-
# --- PHP backend (fallback when mod_proxy is absent) ---
|
|
40
|
-
<IfModule mod_rewrite.c>
|
|
41
|
-
RewriteEngine On
|
|
42
|
-
RewriteBase /
|
|
43
|
-
RewriteRule ^api/(.*)$ backend/_core/index.php [QSA,L]
|
|
44
|
-
</IfModule>
|
|
45
|
-
|
|
46
|
-
# === Static files ===========================================================
|
|
47
|
-
<IfModule mod_rewrite.c>
|
|
48
|
-
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
|
49
|
-
RewriteCond %{REQUEST_FILENAME} -d
|
|
50
|
-
RewriteRule ^ - [L]
|
|
51
|
-
</IfModule>
|
|
1
|
+
Options -Indexes
|
|
2
|
+
ErrorDocument 404 /404.html
|
|
3
|
+
ErrorDocument 403 /404.html
|
|
4
|
+
|
|
5
|
+
<IfModule mod_rewrite.c>
|
|
6
|
+
RewriteEngine On
|
|
7
|
+
RewriteBase /
|
|
8
|
+
|
|
9
|
+
# Block sensitive files (web.config, dotfiles)
|
|
10
|
+
RewriteRule ^(web\.config|\..*)$ /404.html [L,NC]
|
|
11
|
+
</IfModule>
|
|
12
|
+
|
|
13
|
+
# === /api routing — covers BOTH backends ====================================
|
|
14
|
+
#
|
|
15
|
+
# Apache (unlike nginx) cannot health-check an upstream, so it cannot auto-fall
|
|
16
|
+
# back from Node to PHP. The behaviour is:
|
|
17
|
+
#
|
|
18
|
+
# - mod_proxy available -> /api is proxied to the Node backend (127.0.0.1:3000)
|
|
19
|
+
# - mod_proxy NOT present -> /api is rewritten to the PHP front controller
|
|
20
|
+
#
|
|
21
|
+
# Typical shared hosting (Aruba, cPanel) has no mod_proxy, so it uses PHP
|
|
22
|
+
# automatically. On a VPS running Node, mod_proxy sends /api to Node.
|
|
23
|
+
#
|
|
24
|
+
# If you are on a server that HAS mod_proxy but you want to use PHP, comment out
|
|
25
|
+
# the mod_proxy block below.
|
|
26
|
+
|
|
27
|
+
# --- Node backend (if mod_proxy is available) ---
|
|
28
|
+
<IfModule mod_proxy.c>
|
|
29
|
+
ProxyPreserveHost On
|
|
30
|
+
ProxyPass /api/ http://127.0.0.1:3000/api/ retry=0
|
|
31
|
+
ProxyPassReverse /api/ http://127.0.0.1:3000/api/
|
|
32
|
+
|
|
33
|
+
<IfModule mod_headers.c>
|
|
34
|
+
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
|
|
35
|
+
RequestHeader set X-Forwarded-Proto "https"
|
|
36
|
+
</IfModule>
|
|
37
|
+
</IfModule>
|
|
38
|
+
|
|
39
|
+
# --- PHP backend (fallback when mod_proxy is absent) ---
|
|
40
|
+
<IfModule mod_rewrite.c>
|
|
41
|
+
RewriteEngine On
|
|
42
|
+
RewriteBase /
|
|
43
|
+
RewriteRule ^api/(.*)$ backend/_core/index.php [QSA,L]
|
|
44
|
+
</IfModule>
|
|
45
|
+
|
|
46
|
+
# === Static files ===========================================================
|
|
47
|
+
<IfModule mod_rewrite.c>
|
|
48
|
+
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
|
49
|
+
RewriteCond %{REQUEST_FILENAME} -d
|
|
50
|
+
RewriteRule ^ - [L]
|
|
51
|
+
</IfModule>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
-
<stop offset="0" stop-color="#8b6fc4"/>
|
|
5
|
-
<stop offset="0.5" stop-color="#c9a06a"/>
|
|
6
|
-
<stop offset="1" stop-color="#f2c17a"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
|
|
9
|
-
<stop offset="0" stop-color="#6d4fa8"/>
|
|
10
|
-
<stop offset="0.45" stop-color="#a978b0"/>
|
|
11
|
-
<stop offset="0.75" stop-color="#e7a55f"/>
|
|
12
|
-
<stop offset="1" stop-color="#f7d08a"/>
|
|
13
|
-
</linearGradient>
|
|
14
|
-
<linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
|
|
15
|
-
<stop offset="0" stop-color="#f7d89a"/>
|
|
16
|
-
<stop offset="0.55" stop-color="#e0a95f"/>
|
|
17
|
-
<stop offset="1" stop-color="#b07d3e"/>
|
|
18
|
-
</linearGradient>
|
|
19
|
-
<linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
|
|
20
|
-
<stop offset="0" stop-color="#3a2c63"/>
|
|
21
|
-
<stop offset="1" stop-color="#2a2150"/>
|
|
22
|
-
</linearGradient>
|
|
23
|
-
</defs>
|
|
24
|
-
|
|
25
|
-
<path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
|
|
26
|
-
d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
|
|
27
|
-
<path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
|
|
28
|
-
d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
|
|
29
|
-
|
|
30
|
-
<!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
|
|
31
|
-
up right post, cut corner, down outer-right, close along the bottom -->
|
|
32
|
-
<path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
|
|
33
|
-
d="M148 362
|
|
34
|
-
L148 150
|
|
35
|
-
L206 150
|
|
36
|
-
L312 300
|
|
37
|
-
L312 150
|
|
38
|
-
L370 150
|
|
39
|
-
L370 205
|
|
40
|
-
L340 205
|
|
41
|
-
L340 362
|
|
42
|
-
L282 362
|
|
43
|
-
L206 255
|
|
44
|
-
L206 362
|
|
45
|
-
Z"/>
|
|
46
|
-
|
|
47
|
-
<g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
|
|
48
|
-
<path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
|
|
49
|
-
<path fill="none" stroke-width="5" d="M338 313 L386 313"/>
|
|
50
|
-
<path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
|
|
51
|
-
<path fill="none" stroke-width="5" d="M366 342 L402 384"/>
|
|
52
|
-
<circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
|
|
53
|
-
</g>
|
|
54
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#8b6fc4"/>
|
|
5
|
+
<stop offset="0.5" stop-color="#c9a06a"/>
|
|
6
|
+
<stop offset="1" stop-color="#f2c17a"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
|
|
9
|
+
<stop offset="0" stop-color="#6d4fa8"/>
|
|
10
|
+
<stop offset="0.45" stop-color="#a978b0"/>
|
|
11
|
+
<stop offset="0.75" stop-color="#e7a55f"/>
|
|
12
|
+
<stop offset="1" stop-color="#f7d08a"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
|
|
15
|
+
<stop offset="0" stop-color="#f7d89a"/>
|
|
16
|
+
<stop offset="0.55" stop-color="#e0a95f"/>
|
|
17
|
+
<stop offset="1" stop-color="#b07d3e"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
|
|
20
|
+
<stop offset="0" stop-color="#3a2c63"/>
|
|
21
|
+
<stop offset="1" stop-color="#2a2150"/>
|
|
22
|
+
</linearGradient>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
|
|
26
|
+
d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
|
|
27
|
+
<path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
|
|
28
|
+
d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
|
|
29
|
+
|
|
30
|
+
<!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
|
|
31
|
+
up right post, cut corner, down outer-right, close along the bottom -->
|
|
32
|
+
<path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
|
|
33
|
+
d="M148 362
|
|
34
|
+
L148 150
|
|
35
|
+
L206 150
|
|
36
|
+
L312 300
|
|
37
|
+
L312 150
|
|
38
|
+
L370 150
|
|
39
|
+
L370 205
|
|
40
|
+
L340 205
|
|
41
|
+
L340 362
|
|
42
|
+
L282 362
|
|
43
|
+
L206 255
|
|
44
|
+
L206 362
|
|
45
|
+
Z"/>
|
|
46
|
+
|
|
47
|
+
<g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
|
|
48
|
+
<path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
|
|
49
|
+
<path fill="none" stroke-width="5" d="M338 313 L386 313"/>
|
|
50
|
+
<path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
|
|
51
|
+
<path fill="none" stroke-width="5" d="M366 342 L402 384"/>
|
|
52
|
+
<circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
|
|
53
|
+
</g>
|
|
54
|
+
</svg>
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
-
<stop offset="0" stop-color="#8b6fc4"/>
|
|
5
|
-
<stop offset="0.5" stop-color="#c9a06a"/>
|
|
6
|
-
<stop offset="1" stop-color="#f2c17a"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
|
|
9
|
-
<stop offset="0" stop-color="#6d4fa8"/>
|
|
10
|
-
<stop offset="0.45" stop-color="#a978b0"/>
|
|
11
|
-
<stop offset="0.75" stop-color="#e7a55f"/>
|
|
12
|
-
<stop offset="1" stop-color="#f7d08a"/>
|
|
13
|
-
</linearGradient>
|
|
14
|
-
<linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
|
|
15
|
-
<stop offset="0" stop-color="#f7d89a"/>
|
|
16
|
-
<stop offset="0.55" stop-color="#e0a95f"/>
|
|
17
|
-
<stop offset="1" stop-color="#b07d3e"/>
|
|
18
|
-
</linearGradient>
|
|
19
|
-
<linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
|
|
20
|
-
<stop offset="0" stop-color="#3a2c63"/>
|
|
21
|
-
<stop offset="1" stop-color="#2a2150"/>
|
|
22
|
-
</linearGradient>
|
|
23
|
-
</defs>
|
|
24
|
-
|
|
25
|
-
<path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
|
|
26
|
-
d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
|
|
27
|
-
<path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
|
|
28
|
-
d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
|
|
29
|
-
|
|
30
|
-
<!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
|
|
31
|
-
up right post, cut corner, down outer-right, close along the bottom -->
|
|
32
|
-
<path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
|
|
33
|
-
d="M148 362
|
|
34
|
-
L148 150
|
|
35
|
-
L206 150
|
|
36
|
-
L312 300
|
|
37
|
-
L312 150
|
|
38
|
-
L370 150
|
|
39
|
-
L370 205
|
|
40
|
-
L340 205
|
|
41
|
-
L340 362
|
|
42
|
-
L282 362
|
|
43
|
-
L206 255
|
|
44
|
-
L206 362
|
|
45
|
-
Z"/>
|
|
46
|
-
|
|
47
|
-
<g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
|
|
48
|
-
<path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
|
|
49
|
-
<path fill="none" stroke-width="5" d="M338 313 L386 313"/>
|
|
50
|
-
<path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
|
|
51
|
-
<path fill="none" stroke-width="5" d="M366 342 L402 384"/>
|
|
52
|
-
<circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
|
|
53
|
-
</g>
|
|
54
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#8b6fc4"/>
|
|
5
|
+
<stop offset="0.5" stop-color="#c9a06a"/>
|
|
6
|
+
<stop offset="1" stop-color="#f2c17a"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
|
|
9
|
+
<stop offset="0" stop-color="#6d4fa8"/>
|
|
10
|
+
<stop offset="0.45" stop-color="#a978b0"/>
|
|
11
|
+
<stop offset="0.75" stop-color="#e7a55f"/>
|
|
12
|
+
<stop offset="1" stop-color="#f7d08a"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
|
|
15
|
+
<stop offset="0" stop-color="#f7d89a"/>
|
|
16
|
+
<stop offset="0.55" stop-color="#e0a95f"/>
|
|
17
|
+
<stop offset="1" stop-color="#b07d3e"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
|
|
20
|
+
<stop offset="0" stop-color="#3a2c63"/>
|
|
21
|
+
<stop offset="1" stop-color="#2a2150"/>
|
|
22
|
+
</linearGradient>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
|
|
26
|
+
d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
|
|
27
|
+
<path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
|
|
28
|
+
d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
|
|
29
|
+
|
|
30
|
+
<!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
|
|
31
|
+
up right post, cut corner, down outer-right, close along the bottom -->
|
|
32
|
+
<path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
|
|
33
|
+
d="M148 362
|
|
34
|
+
L148 150
|
|
35
|
+
L206 150
|
|
36
|
+
L312 300
|
|
37
|
+
L312 150
|
|
38
|
+
L370 150
|
|
39
|
+
L370 205
|
|
40
|
+
L340 205
|
|
41
|
+
L340 362
|
|
42
|
+
L282 362
|
|
43
|
+
L206 255
|
|
44
|
+
L206 362
|
|
45
|
+
Z"/>
|
|
46
|
+
|
|
47
|
+
<g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
|
|
48
|
+
<path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
|
|
49
|
+
<path fill="none" stroke-width="5" d="M338 313 L386 313"/>
|
|
50
|
+
<path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
|
|
51
|
+
<path fill="none" stroke-width="5" d="M366 342 L402 384"/>
|
|
52
|
+
<circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
|
|
53
|
+
</g>
|
|
54
|
+
</svg>
|
|
@@ -1,54 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"site_name": "Site name",
|
|
3
|
-
"title": "Site title",
|
|
4
|
-
"description": "Site description",
|
|
5
|
-
"keywords": "keyword1, keyword2, keyword3",
|
|
6
|
-
"domain": "yoursite.com",
|
|
7
|
-
"url": "https://yoursite.com",
|
|
8
|
-
"lang": "en",
|
|
9
|
-
"author": "Name and surname",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"css": [],
|
|
50
|
-
"js": []
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"site_name": "Site name",
|
|
3
|
+
"title": "Site title",
|
|
4
|
+
"description": "Site description",
|
|
5
|
+
"keywords": "keyword1, keyword2, keyword3",
|
|
6
|
+
"domain": "yoursite.com",
|
|
7
|
+
"url": "https://yoursite.com",
|
|
8
|
+
"lang": "en",
|
|
9
|
+
"author": "Name and surname",
|
|
10
|
+
"theme": "dark",
|
|
11
|
+
"legal": {
|
|
12
|
+
"privacy": "",
|
|
13
|
+
"cookie": "",
|
|
14
|
+
"cookieControls": "",
|
|
15
|
+
"terms": "",
|
|
16
|
+
"copyright": {
|
|
17
|
+
"year": "2026",
|
|
18
|
+
"text": "All rights reserved."
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"pages": {
|
|
22
|
+
"404": {
|
|
23
|
+
"seo": {
|
|
24
|
+
"title": "404 - Not found",
|
|
25
|
+
"keywords": "",
|
|
26
|
+
"noindex": true,
|
|
27
|
+
"canonical": ""
|
|
28
|
+
},
|
|
29
|
+
"cdn": {
|
|
30
|
+
"css": [],
|
|
31
|
+
"js": []
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"homepage": {
|
|
35
|
+
"seo": {
|
|
36
|
+
"title": "Homepage",
|
|
37
|
+
"description": "Description",
|
|
38
|
+
"keywords": "",
|
|
39
|
+
"noindex": false,
|
|
40
|
+
"canonical": ""
|
|
41
|
+
},
|
|
42
|
+
"cdn": {
|
|
43
|
+
"css": [],
|
|
44
|
+
"js": []
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<!-- This is the base of every page that you will create -->
|
|
2
2
|
|
|
3
3
|
<!DOCTYPE html>
|
|
4
|
-
<html lang="{{ site.lang or 'en' }}" data-bs-theme="{{ site.
|
|
4
|
+
<html lang="{{ site.lang or 'en' }}" data-bs-theme="{{ site.theme or 'light' }}">
|
|
5
5
|
|
|
6
6
|
<head>
|
|
7
7
|
<meta charset="UTF-8">
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
9
|
+
<meta name="color-scheme" content="{{ site.theme or 'light' }}">
|
|
9
10
|
|
|
10
11
|
{# Preconnect hints — establish early connections to external origins #}
|
|
11
12
|
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
|
@@ -26,8 +27,7 @@
|
|
|
26
27
|
<meta name="description" content="{{ pageData.seo.description or site.description }}">
|
|
27
28
|
<meta name="keywords" content="{{ pageData.seo.keywords or site.keywords }}">
|
|
28
29
|
<meta name="author" content="{{ site.author }}">
|
|
29
|
-
<meta name="theme-color" content="{{ site.theme_color
|
|
30
|
-
<meta name="theme-color" content="{{ site.theme_color.dark }}" media="(prefers-color-scheme: dark)">
|
|
30
|
+
<meta name="theme-color" content="{{ site.theme_color }}">
|
|
31
31
|
|
|
32
32
|
{% if pageData.seo.noindex %}
|
|
33
33
|
<meta name="robots" content="noindex, follow">
|
|
@@ -77,23 +77,14 @@
|
|
|
77
77
|
║ FAVICON ║
|
|
78
78
|
╚══════════════════╝#}
|
|
79
79
|
|
|
80
|
-
<link rel="icon" type="image/svg+xml" href="
|
|
81
|
-
|
|
82
|
-
<link rel="icon"
|
|
83
|
-
<link rel="apple-touch-icon" href="/assets/favicon.png">
|
|
84
|
-
#}
|
|
80
|
+
<link rel="icon" type="image/svg+xml" href="/assets/brand/favicon.svg">
|
|
81
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/assets/brand/favicon-32.png">
|
|
82
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/assets/brand/apple-touch-icon.png">
|
|
85
83
|
|
|
86
84
|
{#╔══════════════════╗
|
|
87
85
|
║ CSS ║
|
|
88
86
|
╚══════════════════╝#}
|
|
89
87
|
|
|
90
|
-
{# Markdown — theme-aware #}
|
|
91
|
-
{% if site.data_bs_theme == "dark" %}
|
|
92
|
-
<link rel="stylesheet" href="/css/github-markdown-dark.css">
|
|
93
|
-
{% else %}
|
|
94
|
-
<link rel="stylesheet" href="/css/github-markdown-light.css">
|
|
95
|
-
{% endif %}
|
|
96
|
-
|
|
97
88
|
{# Page CSS #}
|
|
98
89
|
<link rel="stylesheet" href="/css/pages/{{ title }}.css"/>
|
|
99
90
|
|
package/src/frontend/web.config
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!--
|
|
3
|
-
IIS config for a Nibula site — covers BOTH backends.
|
|
4
|
-
|
|
5
|
-
IIS (like Apache, unlike nginx) cannot health-check an upstream, so it cannot
|
|
6
|
-
auto-fall back from Node to PHP. URL Rewrite processes rules top-down and the
|
|
7
|
-
first match with stopProcessing="true" wins:
|
|
8
|
-
|
|
9
|
-
- "ApiToNode" wins if present -> /api is reverse-proxied to the Node backend
|
|
10
|
-
(requires the Application Request Routing + URL Rewrite modules, with proxy
|
|
11
|
-
enabled: ARR > Server Proxy Settings > Enable proxy).
|
|
12
|
-
- To use the PHP backend instead, remove or comment the "ApiToNode" rule;
|
|
13
|
-
"ApiToPhp" then rewrites /api to the PHP front controller.
|
|
14
|
-
|
|
15
|
-
On Windows shared hosting without ARR, keep only "ApiToPhp".
|
|
16
|
-
-->
|
|
17
|
-
<configuration>
|
|
18
|
-
<system.webServer>
|
|
19
|
-
<rewrite>
|
|
20
|
-
<rules>
|
|
21
|
-
|
|
22
|
-
<!-- Block sensitive files -->
|
|
23
|
-
<rule name="BlockSensitive" stopProcessing="true">
|
|
24
|
-
<match url="^(web\.config|\..*)$" ignoreCase="true" />
|
|
25
|
-
<action type="CustomResponse" statusCode="404" />
|
|
26
|
-
</rule>
|
|
27
|
-
|
|
28
|
-
<!-- Node backend (requires ARR). Remove this rule to use PHP. -->
|
|
29
|
-
<rule name="ApiToNode" stopProcessing="true">
|
|
30
|
-
<match url="^api/(.*)" ignoreCase="true" />
|
|
31
|
-
<action type="Rewrite" url="http://127.0.0.1:3000/api/{R:1}" appendQueryString="true" />
|
|
32
|
-
<serverVariables>
|
|
33
|
-
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
|
|
34
|
-
</serverVariables>
|
|
35
|
-
</rule>
|
|
36
|
-
|
|
37
|
-
<!-- PHP backend fallback: rewrite /api to the PHP front controller. -->
|
|
38
|
-
<rule name="ApiToPhp" stopProcessing="true">
|
|
39
|
-
<match url="^api/(.*)" ignoreCase="true" />
|
|
40
|
-
<action type="Rewrite" url="backend/_core/index.php" appendQueryString="true" />
|
|
41
|
-
</rule>
|
|
42
|
-
|
|
43
|
-
</rules>
|
|
44
|
-
</rewrite>
|
|
45
|
-
|
|
46
|
-
<directoryBrowse enabled="false" />
|
|
47
|
-
|
|
48
|
-
<httpErrors errorMode="Custom" existingResponse="Replace">
|
|
49
|
-
<remove statusCode="404" />
|
|
50
|
-
<remove statusCode="403" />
|
|
51
|
-
<error statusCode="404" path="/404.html" responseMode="ExecuteURL" />
|
|
52
|
-
<error statusCode="403" path="/404.html" responseMode="ExecuteURL" />
|
|
53
|
-
</httpErrors>
|
|
54
|
-
</system.webServer>
|
|
55
|
-
</configuration>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
IIS config for a Nibula site — covers BOTH backends.
|
|
4
|
+
|
|
5
|
+
IIS (like Apache, unlike nginx) cannot health-check an upstream, so it cannot
|
|
6
|
+
auto-fall back from Node to PHP. URL Rewrite processes rules top-down and the
|
|
7
|
+
first match with stopProcessing="true" wins:
|
|
8
|
+
|
|
9
|
+
- "ApiToNode" wins if present -> /api is reverse-proxied to the Node backend
|
|
10
|
+
(requires the Application Request Routing + URL Rewrite modules, with proxy
|
|
11
|
+
enabled: ARR > Server Proxy Settings > Enable proxy).
|
|
12
|
+
- To use the PHP backend instead, remove or comment the "ApiToNode" rule;
|
|
13
|
+
"ApiToPhp" then rewrites /api to the PHP front controller.
|
|
14
|
+
|
|
15
|
+
On Windows shared hosting without ARR, keep only "ApiToPhp".
|
|
16
|
+
-->
|
|
17
|
+
<configuration>
|
|
18
|
+
<system.webServer>
|
|
19
|
+
<rewrite>
|
|
20
|
+
<rules>
|
|
21
|
+
|
|
22
|
+
<!-- Block sensitive files -->
|
|
23
|
+
<rule name="BlockSensitive" stopProcessing="true">
|
|
24
|
+
<match url="^(web\.config|\..*)$" ignoreCase="true" />
|
|
25
|
+
<action type="CustomResponse" statusCode="404" />
|
|
26
|
+
</rule>
|
|
27
|
+
|
|
28
|
+
<!-- Node backend (requires ARR). Remove this rule to use PHP. -->
|
|
29
|
+
<rule name="ApiToNode" stopProcessing="true">
|
|
30
|
+
<match url="^api/(.*)" ignoreCase="true" />
|
|
31
|
+
<action type="Rewrite" url="http://127.0.0.1:3000/api/{R:1}" appendQueryString="true" />
|
|
32
|
+
<serverVariables>
|
|
33
|
+
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
|
|
34
|
+
</serverVariables>
|
|
35
|
+
</rule>
|
|
36
|
+
|
|
37
|
+
<!-- PHP backend fallback: rewrite /api to the PHP front controller. -->
|
|
38
|
+
<rule name="ApiToPhp" stopProcessing="true">
|
|
39
|
+
<match url="^api/(.*)" ignoreCase="true" />
|
|
40
|
+
<action type="Rewrite" url="backend/_core/index.php" appendQueryString="true" />
|
|
41
|
+
</rule>
|
|
42
|
+
|
|
43
|
+
</rules>
|
|
44
|
+
</rewrite>
|
|
45
|
+
|
|
46
|
+
<directoryBrowse enabled="false" />
|
|
47
|
+
|
|
48
|
+
<httpErrors errorMode="Custom" existingResponse="Replace">
|
|
49
|
+
<remove statusCode="404" />
|
|
50
|
+
<remove statusCode="403" />
|
|
51
|
+
<error statusCode="404" path="/404.html" responseMode="ExecuteURL" />
|
|
52
|
+
<error statusCode="403" path="/404.html" responseMode="ExecuteURL" />
|
|
53
|
+
</httpErrors>
|
|
54
|
+
</system.webServer>
|
|
55
|
+
</configuration>
|