nibula 1.6.0 → 1.6.2

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 (99) hide show
  1. package/.eleventy.js +82 -81
  2. package/CHANGELOG.md +395 -377
  3. package/LICENSE +169 -169
  4. package/NOTICE +4 -4
  5. package/README.md +110 -110
  6. package/bin/create.js +540 -505
  7. package/bin/delegate.js +58 -57
  8. package/bin/nibula.js +302 -302
  9. package/docs/Assistant CLI.md +65 -65
  10. package/docs/Backend.md +201 -201
  11. package/docs/Components.md +140 -140
  12. package/docs/Creating pages.md +69 -69
  13. package/docs/Deploy.md +210 -210
  14. package/docs/Head and SEO.md +139 -139
  15. package/docs/Javascript.md +126 -126
  16. package/docs/Styling with SCSS.md +141 -139
  17. package/nginx.conf +113 -113
  18. package/package.json +69 -69
  19. package/src/backend/.htaccess +6 -6
  20. package/src/backend/_core/composer.json +5 -5
  21. package/src/backend/_core/composer.lock +492 -492
  22. package/src/backend/_core/index.js +267 -267
  23. package/src/backend/_core/index.php +160 -160
  24. package/src/backend/_core/init.js +52 -52
  25. package/src/backend/_core/init.php +33 -33
  26. package/src/backend/_core/modules/RateLimiter.js +58 -58
  27. package/src/backend/_core/modules/RateLimiter.php +30 -30
  28. package/src/backend/_core/modules/Response.js +59 -59
  29. package/src/backend/_core/modules/Response.php +48 -48
  30. package/src/backend/api/protected/example-protected.js +23 -23
  31. package/src/backend/api/protected/example-protected.php +16 -16
  32. package/src/backend/api/public/example-public.js +24 -24
  33. package/src/backend/api/public/example-public.php +16 -16
  34. package/src/backend/database/Database.js +46 -46
  35. package/src/backend/database/Database.php +23 -23
  36. package/src/backend/example.config.js +37 -37
  37. package/src/backend/example.config.php +37 -37
  38. package/src/backend/package.json +17 -17
  39. package/src/backend/web.config +43 -43
  40. package/src/frontend/.htaccess +51 -51
  41. package/src/frontend/404.njk +17 -17
  42. package/src/frontend/assets/brand/favicon.svg +54 -54
  43. package/src/frontend/assets/brand/logo.svg +54 -54
  44. package/src/frontend/components/global/footer.njk +25 -25
  45. package/src/frontend/components/global/header.njk +6 -6
  46. package/src/frontend/components/welcome.njk +115 -115
  47. package/src/frontend/index.njk +8 -8
  48. package/src/frontend/js/global.js +10 -10
  49. package/src/frontend/js/modules/exampleModule.js +2 -2
  50. package/src/frontend/js/pages/404.js +8 -8
  51. package/src/frontend/js/pages/homepage.js +8 -8
  52. package/src/frontend/layouts/base.njk +135 -136
  53. package/src/frontend/layouts/page-components.njk +13 -13
  54. package/src/frontend/llms.njk +17 -17
  55. package/src/frontend/robots.njk +7 -7
  56. package/src/frontend/scss/_global.scss +46 -46
  57. package/src/frontend/scss/_root.scss +13 -13
  58. package/src/frontend/scss/modules/_animations.scss +24 -24
  59. package/src/frontend/scss/modules/_footer.scss +28 -28
  60. package/src/frontend/scss/modules/_header.scss +26 -26
  61. package/src/frontend/scss/modules/_mobile.scss +29 -29
  62. package/src/frontend/scss/modules/_typography.scss +18 -18
  63. package/src/frontend/scss/modules/frameworks/_bootstrap.scss +109 -109
  64. package/src/frontend/scss/modules/frameworks/_bulma.scss +108 -108
  65. package/src/frontend/scss/modules/frameworks/_foundation.scss +137 -137
  66. package/src/frontend/scss/modules/frameworks/_uikit.scss +109 -109
  67. package/src/frontend/scss/pages/404.scss +27 -27
  68. package/src/frontend/scss/pages/homepage.scss +22 -22
  69. package/src/frontend/sitemap.njk +17 -17
  70. package/src/frontend/ts/global.ts +11 -11
  71. package/src/frontend/ts/modules/exampleModule.ts +2 -2
  72. package/src/frontend/ts/pages/404.ts +8 -8
  73. package/src/frontend/ts/pages/homepage.ts +8 -8
  74. package/src/frontend/web.config +51 -51
  75. package/tools/assistant.js +122 -122
  76. package/tools/buildJs.js +39 -39
  77. package/tools/cleanOutput.js +23 -23
  78. package/tools/cli/prompt.js +40 -40
  79. package/tools/cli/ui.js +87 -87
  80. package/tools/config/messages.json +80 -80
  81. package/tools/config/settings.json +130 -130
  82. package/tools/lib/colors.js +17 -17
  83. package/tools/lib/files.js +75 -75
  84. package/tools/lib/logger.js +22 -22
  85. package/tools/lib/outputPath.js +141 -141
  86. package/tools/lib/pageActions.js +146 -146
  87. package/tools/lib/pageArtifacts.js +46 -46
  88. package/tools/lib/pageComponents.js +88 -88
  89. package/tools/lib/pagesData.js +87 -87
  90. package/tools/lib/paths.js +63 -63
  91. package/tools/lib/project.js +54 -54
  92. package/tools/lib/text.js +47 -47
  93. package/tools/lib/validation.js +40 -40
  94. package/tools/res/templates/template.js +7 -7
  95. package/tools/res/templates/template.njk +8 -8
  96. package/tools/res/templates/template.scss +22 -22
  97. package/tools/res/templates/template.ts +8 -8
  98. package/tsconfig.json +24 -24
  99. package/src/frontend/scss/pages/prova.scss +0 -23
package/tools/lib/text.js CHANGED
@@ -1,47 +1,47 @@
1
- const PLACEHOLDER_PATTERN = /\{(\w+)\}/g;
2
- const CAMEL_SEPARATOR_PATTERN = /[-_][a-z0-9]/g;
3
- const INVALID_KEBAB_PATTERN = /[^a-z0-9\s_-]/g;
4
- const KEBAB_SEPARATOR_PATTERN = /[\s_]+/g;
5
- const REPEATED_HYPHEN_PATTERN = /-+/g;
6
- const EDGE_HYPHEN_PATTERN = /^-+|-+$/g;
7
- const WORD_SEPARATOR = '-';
8
- const SPACE = ' ';
9
- const EMPTY = '';
10
-
11
- function formatText(template, values = {}) {
12
- return String(template).replace(PLACEHOLDER_PATTERN, (match, key) =>
13
- Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match
14
- );
15
- }
16
-
17
- function formatValue(value, values = {}) {
18
- if (typeof value === 'string') return formatText(value, values);
19
- if (Array.isArray(value)) return value.map((item) => formatValue(item, values));
20
- if (value !== null && typeof value === 'object') {
21
- return Object.fromEntries(
22
- Object.entries(value).map(([key, item]) => [key, formatValue(item, values)])
23
- );
24
- }
25
- return value;
26
- }
27
-
28
- function toCamelCase(value) {
29
- return value.toLowerCase().replace(CAMEL_SEPARATOR_PATTERN, (group) => group.slice(1).toUpperCase());
30
- }
31
-
32
- function toKebabCase(value) {
33
- return value.trim().toLowerCase()
34
- .replace(INVALID_KEBAB_PATTERN, EMPTY)
35
- .replace(KEBAB_SEPARATOR_PATTERN, WORD_SEPARATOR)
36
- .replace(REPEATED_HYPHEN_PATTERN, WORD_SEPARATOR)
37
- .replace(EDGE_HYPHEN_PATTERN, EMPTY);
38
- }
39
-
40
- function toTitleCase(value) {
41
- return value.split(WORD_SEPARATOR)
42
- .filter(Boolean)
43
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
44
- .join(SPACE);
45
- }
46
-
47
- module.exports = { formatText, formatValue, toCamelCase, toKebabCase, toTitleCase };
1
+ const PLACEHOLDER_PATTERN = /\{(\w+)\}/g;
2
+ const CAMEL_SEPARATOR_PATTERN = /[-_][a-z0-9]/g;
3
+ const INVALID_KEBAB_PATTERN = /[^a-z0-9\s_-]/g;
4
+ const KEBAB_SEPARATOR_PATTERN = /[\s_]+/g;
5
+ const REPEATED_HYPHEN_PATTERN = /-+/g;
6
+ const EDGE_HYPHEN_PATTERN = /^-+|-+$/g;
7
+ const WORD_SEPARATOR = '-';
8
+ const SPACE = ' ';
9
+ const EMPTY = '';
10
+
11
+ function formatText(template, values = {}) {
12
+ return String(template).replace(PLACEHOLDER_PATTERN, (match, key) =>
13
+ Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match
14
+ );
15
+ }
16
+
17
+ function formatValue(value, values = {}) {
18
+ if (typeof value === 'string') return formatText(value, values);
19
+ if (Array.isArray(value)) return value.map((item) => formatValue(item, values));
20
+ if (value !== null && typeof value === 'object') {
21
+ return Object.fromEntries(
22
+ Object.entries(value).map(([key, item]) => [key, formatValue(item, values)])
23
+ );
24
+ }
25
+ return value;
26
+ }
27
+
28
+ function toCamelCase(value) {
29
+ return value.toLowerCase().replace(CAMEL_SEPARATOR_PATTERN, (group) => group.slice(1).toUpperCase());
30
+ }
31
+
32
+ function toKebabCase(value) {
33
+ return value.trim().toLowerCase()
34
+ .replace(INVALID_KEBAB_PATTERN, EMPTY)
35
+ .replace(KEBAB_SEPARATOR_PATTERN, WORD_SEPARATOR)
36
+ .replace(REPEATED_HYPHEN_PATTERN, WORD_SEPARATOR)
37
+ .replace(EDGE_HYPHEN_PATTERN, EMPTY);
38
+ }
39
+
40
+ function toTitleCase(value) {
41
+ return value.split(WORD_SEPARATOR)
42
+ .filter(Boolean)
43
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
44
+ .join(SPACE);
45
+ }
46
+
47
+ module.exports = { formatText, formatValue, toCamelCase, toKebabCase, toTitleCase };
@@ -1,40 +1,40 @@
1
- const settings = require('../config/settings.json');
2
- const { PATHS } = require('./paths');
3
- const { exists } = require('./files');
4
- const { message } = require('./logger');
5
-
6
- const NAME_PATTERN = /^[a-z0-9-]+$/;
7
- const LEADING_DIGIT_PATTERN = /^\d/;
8
- const INVALID_PATH_PATTERN = /[<>|?*"']/;
9
-
10
- function requiredFiles() {
11
- return [
12
- { label: settings.paths.eleventyConfig, path: PATHS.eleventyConfig },
13
- { label: settings.paths.packageJson, path: PATHS.packageJson },
14
- { label: settings.paths.siteData, path: PATHS.siteData },
15
- { label: settings.paths.pagesData, path: PATHS.pagesData },
16
- { label: settings.paths.pageComponents, path: PATHS.pageComponents },
17
- { label: message('validation.templatesLabel'), path: PATHS.templates },
18
- ];
19
- }
20
-
21
- function validatePageName(name) {
22
- if (!name) return message('validation.invalidName');
23
- if (!NAME_PATTERN.test(name)) return message('validation.invalidNameCharacters');
24
- if (LEADING_DIGIT_PATTERN.test(name)) return message('validation.nameStartsWithNumber');
25
- if (settings.page.protected.includes(name)) return message('validation.protectedName', { name });
26
- return null;
27
- }
28
-
29
- function validateOutputPath(input) {
30
- const value = (input ?? '').trim();
31
- if (!value) return message('validation.invalidPath');
32
- if (INVALID_PATH_PATTERN.test(value)) return message('validation.invalidPathCharacters');
33
- return null;
34
- }
35
-
36
- function checkRequiredFiles() {
37
- return requiredFiles().filter((item) => !exists(item.path));
38
- }
39
-
40
- module.exports = { validatePageName, validateOutputPath, checkRequiredFiles };
1
+ const settings = require('../config/settings.json');
2
+ const { PATHS } = require('./paths');
3
+ const { exists } = require('./files');
4
+ const { message } = require('./logger');
5
+
6
+ const NAME_PATTERN = /^[a-z0-9-]+$/;
7
+ const LEADING_DIGIT_PATTERN = /^\d/;
8
+ const INVALID_PATH_PATTERN = /[<>|?*"']/;
9
+
10
+ function requiredFiles() {
11
+ return [
12
+ { label: settings.paths.eleventyConfig, path: PATHS.eleventyConfig },
13
+ { label: settings.paths.packageJson, path: PATHS.packageJson },
14
+ { label: settings.paths.siteData, path: PATHS.siteData },
15
+ { label: settings.paths.pagesData, path: PATHS.pagesData },
16
+ { label: settings.paths.pageComponents, path: PATHS.pageComponents },
17
+ { label: message('validation.templatesLabel'), path: PATHS.templates },
18
+ ];
19
+ }
20
+
21
+ function validatePageName(name) {
22
+ if (!name) return message('validation.invalidName');
23
+ if (!NAME_PATTERN.test(name)) return message('validation.invalidNameCharacters');
24
+ if (LEADING_DIGIT_PATTERN.test(name)) return message('validation.nameStartsWithNumber');
25
+ if (settings.page.protected.includes(name)) return message('validation.protectedName', { name });
26
+ return null;
27
+ }
28
+
29
+ function validateOutputPath(input) {
30
+ const value = (input ?? '').trim();
31
+ if (!value) return message('validation.invalidPath');
32
+ if (INVALID_PATH_PATTERN.test(value)) return message('validation.invalidPathCharacters');
33
+ return null;
34
+ }
35
+
36
+ function checkRequiredFiles() {
37
+ return requiredFiles().filter((item) => !exists(item.path));
38
+ }
39
+
40
+ module.exports = { validatePageName, validateOutputPath, checkRequiredFiles };
@@ -1,8 +1,8 @@
1
- import '../global.js';
2
- // import { initExampleModule } from '../modules/exampleModule';
3
-
4
- document.addEventListener("DOMContentLoaded", () => {
5
- // initExampleModule();
6
- });
7
-
1
+ import '../global.js';
2
+ // import { initExampleModule } from '../modules/exampleModule';
3
+
4
+ document.addEventListener("DOMContentLoaded", () => {
5
+ // initExampleModule();
6
+ });
7
+
8
8
  // 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 "../root" as root;
8
-
9
- // This global module contains the import framework, necessary modules for each page and any other common styles
10
- @import "../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-color;
1
+ //==========================
2
+ // CSS MODULES IMPORTS
3
+ //==========================
4
+
5
+ // Use @use with a namespace to avoid framework variable conflicts:
6
+ // Example: root.$primary
7
+ @use "../root" as root;
8
+
9
+ // This global module contains the import framework, necessary modules for each page and any other common styles
10
+ @import "../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-color;
23
23
  // }
@@ -1,9 +1,9 @@
1
- import '../global';
2
-
3
- // import { initExampleModule } from '../modules/exampleModule';
4
-
5
- document.addEventListener("DOMContentLoaded", (): void => {
6
- // initExampleModule();
7
- });
8
-
1
+ import '../global';
2
+
3
+ // import { initExampleModule } from '../modules/exampleModule';
4
+
5
+ document.addEventListener("DOMContentLoaded", (): void => {
6
+ // initExampleModule();
7
+ });
8
+
9
9
  // 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
  }
@@ -1,23 +0,0 @@
1
- //==========================
2
- // CSS MODULES IMPORTS
3
- //==========================
4
-
5
- // Use @use with a namespace to avoid framework variable conflicts:
6
- // Example: root.$primary
7
- @use "../root" as root;
8
-
9
- // This global module contains the import framework, necessary modules for each page and any other common styles
10
- @import "../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-color;
23
- // }