nibula 1.2.4 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/.eleventy.js +81 -81
  2. package/.eleventyignore +3 -3
  3. package/.github/workflows/publish.yml +37 -0
  4. package/CHANGELOG.md +179 -148
  5. package/LICENSE +169 -169
  6. package/NOTICE +4 -4
  7. package/README.md +120 -123
  8. package/bin/create.js +507 -507
  9. package/bin/nibula.js +317 -305
  10. package/docs/Assistant CLI.md +65 -65
  11. package/docs/Backend.md +295 -295
  12. package/docs/Components.md +84 -84
  13. package/docs/Creating pages.md +64 -64
  14. package/docs/Deploy.md +189 -189
  15. package/docs/Head and SEO.md +138 -138
  16. package/docs/Javascript.md +50 -50
  17. package/docs/Styling with SCSS.md +141 -141
  18. package/nginx.conf +75 -75
  19. package/package.json +1 -1
  20. package/src/backend/.htaccess +6 -6
  21. package/src/backend/_core/composer.json +5 -5
  22. package/src/backend/_core/composer.lock +492 -492
  23. package/src/backend/_core/index.js +267 -267
  24. package/src/backend/_core/index.php +147 -147
  25. package/src/backend/_core/init.js +52 -52
  26. package/src/backend/_core/init.php +33 -33
  27. package/src/backend/_core/modules/RateLimiter.js +58 -58
  28. package/src/backend/_core/modules/RateLimiter.php +30 -30
  29. package/src/backend/_core/modules/Response.js +59 -59
  30. package/src/backend/_core/modules/Response.php +48 -48
  31. package/src/backend/api/protected/example-protected.js +23 -23
  32. package/src/backend/api/protected/example-protected.php +16 -16
  33. package/src/backend/api/public/example-public.js +24 -24
  34. package/src/backend/api/public/example-public.php +16 -16
  35. package/src/backend/backend-node.service.example +30 -30
  36. package/src/backend/database/Database.js +46 -46
  37. package/src/backend/database/Database.php +23 -23
  38. package/src/backend/example.config.js +37 -37
  39. package/src/backend/example.config.php +27 -27
  40. package/src/backend/package.json +18 -18
  41. package/src/backend/web.config +16 -16
  42. package/src/frontend/.htaccess +51 -51
  43. package/src/frontend/404.njk +17 -17
  44. package/src/frontend/assets/brand/favicon.svg +54 -54
  45. package/src/frontend/assets/brand/logo.svg +54 -54
  46. package/src/frontend/components/global/footer.njk +25 -25
  47. package/src/frontend/components/global/header.njk +6 -6
  48. package/src/frontend/components/welcome.njk +114 -114
  49. package/src/frontend/data/site.json +48 -48
  50. package/src/frontend/index.njk +8 -8
  51. package/src/frontend/js/modules/exampleModule.js +2 -2
  52. package/src/frontend/js/pages/404.js +6 -6
  53. package/src/frontend/js/pages/homepage.js +6 -6
  54. package/src/frontend/layouts/base.njk +132 -132
  55. package/src/frontend/layouts/page-components.njk +13 -13
  56. package/src/frontend/llms.njk +17 -17
  57. package/src/frontend/robots.njk +7 -7
  58. package/src/frontend/scss/modules/_animations.scss +24 -24
  59. package/src/frontend/scss/modules/_footer.scss +27 -27
  60. package/src/frontend/scss/modules/_global.scss +47 -47
  61. package/src/frontend/scss/modules/_header.scss +27 -27
  62. package/src/frontend/scss/modules/_mobile.scss +29 -29
  63. package/src/frontend/scss/modules/_root.scss +34 -34
  64. package/src/frontend/scss/modules/_typography.scss +14 -14
  65. package/src/frontend/scss/modules/frameworks/_bootstrap.scss +109 -109
  66. package/src/frontend/scss/modules/frameworks/_bulma.scss +108 -108
  67. package/src/frontend/scss/modules/frameworks/_foundation.scss +138 -139
  68. package/src/frontend/scss/modules/frameworks/_uikit.scss +109 -109
  69. package/src/frontend/scss/pages/404.scss +27 -27
  70. package/src/frontend/scss/pages/homepage.scss +22 -22
  71. package/src/frontend/sitemap.njk +17 -17
  72. package/src/frontend/ts/modules/exampleModule.ts +2 -2
  73. package/src/frontend/ts/pages/404.ts +6 -6
  74. package/src/frontend/ts/pages/homepage.ts +6 -6
  75. package/src/frontend/web.config +55 -55
  76. package/tools/config/messages.json +3 -1
  77. package/tools/res/templates/template.js +6 -6
  78. package/tools/res/templates/template.njk +8 -8
  79. package/tools/res/templates/template.scss +22 -22
  80. package/tools/res/templates/template.ts +6 -6
  81. package/tsconfig.json +24 -24
@@ -1,18 +1,18 @@
1
- ---
2
- permalink: /sitemap.xml
3
- eleventyExcludeFromCollections: true
4
- ---
5
- <?xml version="1.0" encoding="utf-8"?>
6
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
7
- {% for page in collections.all %}
8
- {% set pageMeta = site.pages[page.data.title] %}
9
- {% if not page.data.draft and '/404' not in page.url and not (pageMeta and pageMeta.seo.noindex) %}
10
- <url>
11
- <loc>{{ site.url }}{{ page.url | lower }}</loc>
12
- <lastmod>{{ page.date.toISOString() }}</lastmod>
13
- <changefreq>weekly</changefreq>
14
- <priority>{{ '1.0' if page.url == '/' else '0.8' }}</priority>
15
- </url>
16
- {% endif %}
17
- {% endfor %}
1
+ ---
2
+ permalink: /sitemap.xml
3
+ eleventyExcludeFromCollections: true
4
+ ---
5
+ <?xml version="1.0" encoding="utf-8"?>
6
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
7
+ {% for page in collections.all %}
8
+ {% set pageMeta = site.pages[page.data.title] %}
9
+ {% if not page.data.draft and '/404' not in page.url and not (pageMeta and pageMeta.seo.noindex) %}
10
+ <url>
11
+ <loc>{{ site.url }}{{ page.url | lower }}</loc>
12
+ <lastmod>{{ page.date.toISOString() }}</lastmod>
13
+ <changefreq>weekly</changefreq>
14
+ <priority>{{ '1.0' if page.url == '/' else '0.8' }}</priority>
15
+ </url>
16
+ {% endif %}
17
+ {% endfor %}
18
18
  </urlset>
@@ -1,3 +1,3 @@
1
- export function initExampleModule(): void {
2
- // Module logic here
1
+ export function initExampleModule(): void {
2
+ // Module logic here
3
3
  }
@@ -1,7 +1,7 @@
1
- // import { initExampleModule } from '../modules/exampleModule';
2
-
3
- document.addEventListener("DOMContentLoaded", (): void => {
4
- // initExampleModule();
5
- });
6
-
1
+ // import { initExampleModule } from '../modules/exampleModule';
2
+
3
+ document.addEventListener("DOMContentLoaded", (): void => {
4
+ // initExampleModule();
5
+ });
6
+
7
7
  // Page logic here
@@ -1,7 +1,7 @@
1
- // import { initExampleModule } from '../modules/exampleModule';
2
-
3
- document.addEventListener("DOMContentLoaded", (): void => {
4
- // initExampleModule();
5
- });
6
-
1
+ // import { initExampleModule } from '../modules/exampleModule';
2
+
3
+ document.addEventListener("DOMContentLoaded", (): void => {
4
+ // initExampleModule();
5
+ });
6
+
7
7
  // Page logic here
@@ -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>
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "project": {
3
- "notInside": "Not inside a Nibula project."
3
+ "notInside": "Not inside a Nibula project.",
4
+ "alreadyInside": "You are already inside a Nibula project.",
5
+ "alreadyInsideHint": "Run \"nib new\" from outside a project."
4
6
  },
5
7
  "validation": {
6
8
  "invalidName": "Invalid name.",
@@ -1,7 +1,7 @@
1
- // import { initExampleModule } from '../modules/exampleModule.js';
2
-
3
- document.addEventListener("DOMContentLoaded", () => {
4
- // initExampleModule();
5
- });
6
-
1
+ // import { initExampleModule } from '../modules/exampleModule.js';
2
+
3
+ document.addEventListener("DOMContentLoaded", () => {
4
+ // initExampleModule();
5
+ });
6
+
7
7
  // Page logic here
@@ -1,9 +1,9 @@
1
- ---
2
- title: ""
3
- permalink: ""
4
- layout: page-components.njk
5
- ---
6
-
7
- <!-- !IMPORTANT -->
8
- <!-- DO NOT ADD ANYTHING HERE -->
1
+ ---
2
+ title: ""
3
+ permalink: ""
4
+ layout: page-components.njk
5
+ ---
6
+
7
+ <!-- !IMPORTANT -->
8
+ <!-- DO NOT ADD ANYTHING HERE -->
9
9
  <!-- You should create a new component.njk into src/frontend and include that in layouts/page-components.njk -->
@@ -1,23 +1,23 @@
1
- //==========================
2
- // CSS MODULES IMPORTS
3
- //==========================
4
-
5
- // Use @use with a namespace to avoid framework variable conflicts:
6
- // Example: root.$primary
7
- @use "../modules/root" as root;
8
-
9
- // This global module contains the import framework, necessary modules for each page and any other common styles
10
- @import "../modules/global";
11
-
12
- // Import any other module you need by import down here
13
- // @import "../modules/moduleName";
14
-
15
- //==========================
16
- // PAGE CUSTOM CSS RULES
17
- //==========================
18
-
19
- // Add any custom rule specific to this page below
20
- // These rules override the framework and module styles
21
- // body {
22
- // background-color: root.$primary;
1
+ //==========================
2
+ // CSS MODULES IMPORTS
3
+ //==========================
4
+
5
+ // Use @use with a namespace to avoid framework variable conflicts:
6
+ // Example: root.$primary
7
+ @use "../modules/root" as root;
8
+
9
+ // This global module contains the import framework, necessary modules for each page and any other common styles
10
+ @import "../modules/global";
11
+
12
+ // Import any other module you need by import down here
13
+ // @import "../modules/moduleName";
14
+
15
+ //==========================
16
+ // PAGE CUSTOM CSS RULES
17
+ //==========================
18
+
19
+ // Add any custom rule specific to this page below
20
+ // These rules override the framework and module styles
21
+ // body {
22
+ // background-color: root.$primary;
23
23
  // }
@@ -1,7 +1,7 @@
1
- // import { initExampleModule } from '../modules/exampleModule';
2
-
3
- document.addEventListener("DOMContentLoaded", (): void => {
4
- // initExampleModule();
5
- });
6
-
1
+ // import { initExampleModule } from '../modules/exampleModule';
2
+
3
+ document.addEventListener("DOMContentLoaded", (): void => {
4
+ // initExampleModule();
5
+ });
6
+
7
7
  // Page logic here
package/tsconfig.json CHANGED
@@ -1,25 +1,25 @@
1
- {
2
- // https://aka.ms/tsconfig
3
-
4
- // Add options by uncommenting or adding "<key>": <value> pairs inside compilerOptions
5
-
6
- "include": ["src/frontend/ts/**/*.ts"], // DO NOT CHANGE
7
-
8
- "compilerOptions": {
9
- "rootDir": "./src/frontend/ts", // DO NOT CHANGE
10
- "outDir": "./out/ts", // DO NOT CHANGE
11
- "module": "esnext",
12
- "target": "esnext",
13
- "types": [],
14
- "noUncheckedIndexedAccess": true,
15
- "exactOptionalPropertyTypes": true,
16
- "strict": true,
17
- "jsx": "react-jsx",
18
- "verbatimModuleSyntax": true,
19
- "isolatedModules": true,
20
- "noUncheckedSideEffectImports": true,
21
- "moduleDetection": "force",
22
- "skipLibCheck": true,
23
- "experimentalDecorators": true
24
- }
1
+ {
2
+ // https://aka.ms/tsconfig
3
+
4
+ // Add options by uncommenting or adding "<key>": <value> pairs inside compilerOptions
5
+
6
+ "include": ["src/frontend/ts/**/*.ts"], // DO NOT CHANGE
7
+
8
+ "compilerOptions": {
9
+ "rootDir": "./src/frontend/ts", // DO NOT CHANGE
10
+ "outDir": "./out/ts", // DO NOT CHANGE
11
+ "module": "esnext",
12
+ "target": "esnext",
13
+ "types": [],
14
+ "noUncheckedIndexedAccess": true,
15
+ "exactOptionalPropertyTypes": true,
16
+ "strict": true,
17
+ "jsx": "react-jsx",
18
+ "verbatimModuleSyntax": true,
19
+ "isolatedModules": true,
20
+ "noUncheckedSideEffectImports": true,
21
+ "moduleDetection": "force",
22
+ "skipLibCheck": true,
23
+ "experimentalDecorators": true
24
+ }
25
25
  }