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
@@ -1,80 +1,80 @@
1
- {
2
- "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."
6
- },
7
- "validation": {
8
- "invalidName": "Invalid name.",
9
- "invalidNameCharacters": "Page name can only contain lowercase letters, numbers, and hyphens.",
10
- "nameStartsWithNumber": "Page name cannot start with a number.",
11
- "protectedName": "\"{name}\" is a protected page name.",
12
- "invalidPath": "Invalid path.",
13
- "invalidPathCharacters": "Path contains invalid characters.",
14
- "templatesLabel": "CLI page templates"
15
- },
16
- "page": {
17
- "alreadyExists": "[skip] page \"{name}\" already exists",
18
- "doesNotExist": "[skip] page \"{name}\" does not exist",
19
- "targetExists": "[skip] target page \"{name}\" already exists",
20
- "templateMissing": "[skip] template not found: {path}",
21
- "fileMissing": "[skip] not found: {path}",
22
- "fileCreated": "[created] {path}",
23
- "fileRenamed": "[renamed] {source} \u2192 {destination}",
24
- "fileDeleted": "[deleted] {path}",
25
- "createFailed": "[error] could not create page files: {error}",
26
- "renameFailed": "[error] could not rename page files: {error}",
27
- "deleteFailed": "[error] {path}: {error}"
28
- },
29
- "components": {
30
- "fileMissing": "[skip] not found: {path}",
31
- "anchorMissing": "[skip] no {anchor} anchor in {file}",
32
- "blockAdded": "[updated] page block added for \"{name}\"",
33
- "blockMissing": "[skip] page block for \"{name}\" not found",
34
- "blockRemoved": "[cleaned] page block removed for \"{name}\"",
35
- "blockRenamed": "[renamed] page block \"{source}\" \u2192 \"{destination}\""
36
- },
37
- "pagesData": {
38
- "fileMissing": "[skip] not found: {path}",
39
- "invalidStructure": "[error] {file} must contain an object of pages",
40
- "parseFailed": "[error] cannot parse {file}: {error}",
41
- "recordExists": "[skip] record \"{name}\" already exists",
42
- "recordMissing": "[skip] record \"{name}\" not found",
43
- "recordAdded": "[updated] record \"{name}\" added",
44
- "recordRemoved": "[cleaned] record \"{name}\" removed",
45
- "recordRenamed": "[updated] record \"{source}\" renamed to \"{destination}\""
46
- },
47
- "output": {
48
- "emptyPath": "[skip] empty output path",
49
- "readFailed": "[error] cannot read {file}: {error}",
50
- "updateFailed": "[error] could not update output path: {error}",
51
- "updating": "\nupdating output path \u2192 \"{path}\"",
52
- "variableMissing": "[skip] {variable} not found in {file}",
53
- "keyMissing": "[skip] {key} not found in {file}",
54
- "fileUpdated": "[updated] {file} \u2192 {path}",
55
- "directoryDeleted": "[deleted] {path}",
56
- "refuseDelete": "[skip] refusing to delete \"{path}\" (outside project)",
57
- "missingConfiguration": "(!) {key} not found in {file}",
58
- "cleaned": "(\u2713) cleaned \u2192 {path}",
59
- "nothingToClean": "(i) nothing to clean \u2192 {path}"
60
- },
61
- "cli": {
62
- "usingLocalVersion": "Nibula cli local version ({local})",
63
- "createPrompt": "Name of the new page: ",
64
- "removePrompt": "Name of the page to remove: ",
65
- "renameFromPrompt": "Page to rename: ",
66
- "renameToPrompt": "New name: ",
67
- "outputPathPrompt": "New output path: ",
68
- "menuPrompt": "Choose an option: ",
69
- "currentOutputPath": "Current path: \"{path}\"",
70
- "confirmRemove": "This permanently deletes all files for \"{name}\".",
71
- "cancelled": "Cancelled.",
72
- "pageNotFound": "Page \"{name}\" does not exist.",
73
- "sameName": "Old and new name are the same.",
74
- "invalidOption": "Invalid option.",
75
- "unexpectedError": "Unexpected error: {error}",
76
- "missingFiles": "This project is missing required files:",
77
- "incompleteProject": "The project may be incomplete or created with a different Nibula version.",
78
- "exitHint": "CTRL + C to exit"
79
- }
80
- }
1
+ {
2
+ "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."
6
+ },
7
+ "validation": {
8
+ "invalidName": "Invalid name.",
9
+ "invalidNameCharacters": "Page name can only contain lowercase letters, numbers, and hyphens.",
10
+ "nameStartsWithNumber": "Page name cannot start with a number.",
11
+ "protectedName": "\"{name}\" is a protected page name.",
12
+ "invalidPath": "Invalid path.",
13
+ "invalidPathCharacters": "Path contains invalid characters.",
14
+ "templatesLabel": "CLI page templates"
15
+ },
16
+ "page": {
17
+ "alreadyExists": "[skip] page \"{name}\" already exists",
18
+ "doesNotExist": "[skip] page \"{name}\" does not exist",
19
+ "targetExists": "[skip] target page \"{name}\" already exists",
20
+ "templateMissing": "[skip] template not found: {path}",
21
+ "fileMissing": "[skip] not found: {path}",
22
+ "fileCreated": "[created] {path}",
23
+ "fileRenamed": "[renamed] {source} \u2192 {destination}",
24
+ "fileDeleted": "[deleted] {path}",
25
+ "createFailed": "[error] could not create page files: {error}",
26
+ "renameFailed": "[error] could not rename page files: {error}",
27
+ "deleteFailed": "[error] {path}: {error}"
28
+ },
29
+ "components": {
30
+ "fileMissing": "[skip] not found: {path}",
31
+ "anchorMissing": "[skip] no {anchor} anchor in {file}",
32
+ "blockAdded": "[updated] page block added for \"{name}\"",
33
+ "blockMissing": "[skip] page block for \"{name}\" not found",
34
+ "blockRemoved": "[cleaned] page block removed for \"{name}\"",
35
+ "blockRenamed": "[renamed] page block \"{source}\" \u2192 \"{destination}\""
36
+ },
37
+ "pagesData": {
38
+ "fileMissing": "[skip] not found: {path}",
39
+ "invalidStructure": "[error] {file} must contain an object of pages",
40
+ "parseFailed": "[error] cannot parse {file}: {error}",
41
+ "recordExists": "[skip] record \"{name}\" already exists",
42
+ "recordMissing": "[skip] record \"{name}\" not found",
43
+ "recordAdded": "[updated] record \"{name}\" added",
44
+ "recordRemoved": "[cleaned] record \"{name}\" removed",
45
+ "recordRenamed": "[updated] record \"{source}\" renamed to \"{destination}\""
46
+ },
47
+ "output": {
48
+ "emptyPath": "[skip] empty output path",
49
+ "readFailed": "[error] cannot read {file}: {error}",
50
+ "updateFailed": "[error] could not update output path: {error}",
51
+ "updating": "\nupdating output path \u2192 \"{path}\"",
52
+ "variableMissing": "[skip] {variable} not found in {file}",
53
+ "keyMissing": "[skip] {key} not found in {file}",
54
+ "fileUpdated": "[updated] {file} \u2192 {path}",
55
+ "directoryDeleted": "[deleted] {path}",
56
+ "refuseDelete": "[skip] refusing to delete \"{path}\" (outside project)",
57
+ "missingConfiguration": "(!) {key} not found in {file}",
58
+ "cleaned": "(\u2713) cleaned \u2192 {path}",
59
+ "nothingToClean": "(i) nothing to clean \u2192 {path}"
60
+ },
61
+ "cli": {
62
+ "usingLocalVersion": "Nibula cli local version ({local})",
63
+ "createPrompt": "Name of the new page: ",
64
+ "removePrompt": "Name of the page to remove: ",
65
+ "renameFromPrompt": "Page to rename: ",
66
+ "renameToPrompt": "New name: ",
67
+ "outputPathPrompt": "New output path: ",
68
+ "menuPrompt": "Choose an option: ",
69
+ "currentOutputPath": "Current path: \"{path}\"",
70
+ "confirmRemove": "This permanently deletes all files for \"{name}\".",
71
+ "cancelled": "Cancelled.",
72
+ "pageNotFound": "Page \"{name}\" does not exist.",
73
+ "sameName": "Old and new name are the same.",
74
+ "invalidOption": "Invalid option.",
75
+ "unexpectedError": "Unexpected error: {error}",
76
+ "missingFiles": "This project is missing required files:",
77
+ "incompleteProject": "The project may be incomplete or created with a different Nibula version.",
78
+ "exitHint": "CTRL + C to exit"
79
+ }
80
+ }
@@ -1,131 +1,131 @@
1
- {
2
- "project": {
3
- "marker": ".eleventy.js",
4
- "defaultOutputDirectory": "out",
5
- "currentDirectory": ".",
6
- "outputSuffix": "-out"
7
- },
8
- "paths": {
9
- "eleventyConfig": ".eleventy.js",
10
- "packageJson": "package.json",
11
- "typescriptConfig": "tsconfig.json",
12
- "routes": "src/frontend/routes",
13
- "stylePages": "src/frontend/scss/pages",
14
- "pagesData": "src/frontend/data/pages.json",
15
- "siteData": "src/frontend/data/site.json",
16
- "pageComponents": "src/frontend/layouts/page-components.njk",
17
- "templates": "tools/res/templates"
18
- },
19
- "languages": {
20
- "javascript": {
21
- "pages": "src/frontend/js/pages",
22
- "extension": "js",
23
- "template": "template.js"
24
- },
25
- "typescript": {
26
- "pages": "src/frontend/ts/pages",
27
- "extension": "ts",
28
- "template": "template.ts"
29
- }
30
- },
31
- "packageJson": {
32
- "outputKey": "outputDir",
33
- "scriptsKey": "scripts"
34
- },
35
- "eleventy": {
36
- "outputVariable": "OUTPUT_DIR"
37
- },
38
- "typescript": {
39
- "outputKey": "outDir",
40
- "outputSubdirectory": "ts"
41
- },
42
- "build": {
43
- "scriptOutput": "js/pages"
44
- },
45
- "outputScripts": [
46
- {
47
- "name": "build:css",
48
- "marker": "/css",
49
- "template": "sass src/frontend/scss:{output}/css --no-source-map --style=compressed --quiet --load-path=node_modules"
50
- },
51
- {
52
- "name": "serve:css",
53
- "marker": "/css",
54
- "template": "sass --watch src/frontend/scss:{output}/css --no-source-map --quiet --load-path=node_modules"
55
- },
56
- {
57
- "name": "build:js",
58
- "marker": "/js/pages",
59
- "template": "esbuild \"{entries}\" --bundle --outdir={output}/js/pages --minify"
60
- },
61
- {
62
- "name": "serve:js",
63
- "marker": "/js/pages",
64
- "template": "esbuild \"{entries}\" --bundle --outdir={output}/js/pages --watch"
65
- }
66
- ],
67
- "page": {
68
- "protected": ["homepage", "404"],
69
- "styleExtension": "scss",
70
- "routeExtension": "njk",
71
- "styleTemplate": "template.scss",
72
- "routeTemplate": "template.njk",
73
- "outputFiles": [
74
- "js/pages/{camelName}.js",
75
- "css/pages/{camelName}.css",
76
- "{pageName}.html",
77
- "pages/{pageName}.html"
78
- ],
79
- "outputDirectories": [
80
- "{pageName}",
81
- "pages/{pageName}"
82
- ],
83
- "defaultData": {
84
- "seo": {
85
- "title": "{title}",
86
- "description": "description",
87
- "keywords": "",
88
- "noindex": false,
89
- "canonical": ""
90
- },
91
- "cdn": {
92
- "css": [],
93
- "js": []
94
- }
95
- }
96
- },
97
- "pageComponents": {
98
- "anchor": "{% else %}",
99
- "condition": "{% elif title == \"{camelName}\" %}",
100
- "include": "{% include \"component-name.njk\" ignore missing %}"
101
- },
102
- "frontMatter": {
103
- "title": "title: \"{camelName}\"",
104
- "permalink": "permalink: \"/{pageName}/\""
105
- },
106
- "cli": {
107
- "title": "Nibula CLI",
108
- "boxWidth": 17,
109
- "confirmHint": "[y/N]",
110
- "symbols": {
111
- "prompt": "\u276f",
112
- "error": "\u2716",
113
- "warning": "\u26a0",
114
- "bullet": "-"
115
- },
116
- "colors": {
117
- "box": "cyan",
118
- "menuKey": "dim",
119
- "prompt": "cyan",
120
- "error": "red",
121
- "warning": "yellow",
122
- "notice": "dim"
123
- },
124
- "menu": [
125
- { "key": "1", "action": "createPage", "label": "Create page" },
126
- { "key": "2", "action": "removePage", "label": "Remove page" },
127
- { "key": "3", "action": "renamePage", "label": "Rename page" },
128
- { "key": "4", "action": "outputPath", "label": "Configure output path" }
129
- ]
130
- }
1
+ {
2
+ "project": {
3
+ "marker": ".eleventy.js",
4
+ "defaultOutputDirectory": "out",
5
+ "currentDirectory": ".",
6
+ "outputSuffix": "-out"
7
+ },
8
+ "paths": {
9
+ "eleventyConfig": ".eleventy.js",
10
+ "packageJson": "package.json",
11
+ "typescriptConfig": "tsconfig.json",
12
+ "routes": "src/frontend/routes",
13
+ "stylePages": "src/frontend/scss/pages",
14
+ "pagesData": "src/frontend/data/pages.json",
15
+ "siteData": "src/frontend/data/site.json",
16
+ "pageComponents": "src/frontend/layouts/page-components.njk",
17
+ "templates": "tools/res/templates"
18
+ },
19
+ "languages": {
20
+ "javascript": {
21
+ "pages": "src/frontend/js/pages",
22
+ "extension": "js",
23
+ "template": "template.js"
24
+ },
25
+ "typescript": {
26
+ "pages": "src/frontend/ts/pages",
27
+ "extension": "ts",
28
+ "template": "template.ts"
29
+ }
30
+ },
31
+ "packageJson": {
32
+ "outputKey": "outputDir",
33
+ "scriptsKey": "scripts"
34
+ },
35
+ "eleventy": {
36
+ "outputVariable": "OUTPUT_DIR"
37
+ },
38
+ "typescript": {
39
+ "outputKey": "outDir",
40
+ "outputSubdirectory": "ts"
41
+ },
42
+ "build": {
43
+ "scriptOutput": "js/pages"
44
+ },
45
+ "outputScripts": [
46
+ {
47
+ "name": "build:css",
48
+ "marker": "/css",
49
+ "template": "sass src/frontend/scss:{output}/css --no-source-map --style=compressed --quiet --load-path=node_modules"
50
+ },
51
+ {
52
+ "name": "serve:css",
53
+ "marker": "/css",
54
+ "template": "sass --watch src/frontend/scss:{output}/css --no-source-map --quiet --load-path=node_modules"
55
+ },
56
+ {
57
+ "name": "build:js",
58
+ "marker": "/js/pages",
59
+ "template": "esbuild \"{entries}\" --bundle --outdir={output}/js/pages --minify"
60
+ },
61
+ {
62
+ "name": "serve:js",
63
+ "marker": "/js/pages",
64
+ "template": "esbuild \"{entries}\" --bundle --outdir={output}/js/pages --watch"
65
+ }
66
+ ],
67
+ "page": {
68
+ "protected": ["homepage", "404"],
69
+ "styleExtension": "scss",
70
+ "routeExtension": "njk",
71
+ "styleTemplate": "template.scss",
72
+ "routeTemplate": "template.njk",
73
+ "outputFiles": [
74
+ "js/pages/{camelName}.js",
75
+ "css/pages/{camelName}.css",
76
+ "{pageName}.html",
77
+ "pages/{pageName}.html"
78
+ ],
79
+ "outputDirectories": [
80
+ "{pageName}",
81
+ "pages/{pageName}"
82
+ ],
83
+ "defaultData": {
84
+ "seo": {
85
+ "title": "{title}",
86
+ "description": "description",
87
+ "keywords": "",
88
+ "noindex": false,
89
+ "canonical": ""
90
+ },
91
+ "cdn": {
92
+ "css": [],
93
+ "js": []
94
+ }
95
+ }
96
+ },
97
+ "pageComponents": {
98
+ "anchor": "{% else %}",
99
+ "condition": "{% elif title == \"{camelName}\" %}",
100
+ "include": "{% include \"component-name.njk\" ignore missing %}"
101
+ },
102
+ "frontMatter": {
103
+ "title": "title: \"{camelName}\"",
104
+ "permalink": "permalink: \"/{pageName}/\""
105
+ },
106
+ "cli": {
107
+ "title": "Nibula CLI",
108
+ "boxWidth": 17,
109
+ "confirmHint": "[y/N]",
110
+ "symbols": {
111
+ "prompt": "\u276f",
112
+ "error": "\u2716",
113
+ "warning": "\u26a0",
114
+ "bullet": "-"
115
+ },
116
+ "colors": {
117
+ "box": "cyan",
118
+ "menuKey": "dim",
119
+ "prompt": "cyan",
120
+ "error": "red",
121
+ "warning": "yellow",
122
+ "notice": "dim"
123
+ },
124
+ "menu": [
125
+ { "key": "1", "action": "createPage", "label": "Create page" },
126
+ { "key": "2", "action": "removePage", "label": "Remove page" },
127
+ { "key": "3", "action": "renamePage", "label": "Rename page" },
128
+ { "key": "4", "action": "outputPath", "label": "Configure output path" }
129
+ ]
130
+ }
131
131
  }
@@ -1,17 +1,17 @@
1
- const color = Object.freeze({
2
- reset: '\x1b[0m',
3
- bold: '\x1b[1m',
4
- dim: '\x1b[2m',
5
- red: '\x1b[31m',
6
- green: '\x1b[32m',
7
- yellow: '\x1b[33m',
8
- blue: '\x1b[34m',
9
- magenta: '\x1b[35m',
10
- cyan: '\x1b[36m',
11
- });
12
-
13
- function paint(name, text) {
14
- return `${color[name] ?? ''}${text}${color.reset}`;
15
- }
16
-
17
- module.exports = { color, paint };
1
+ const color = Object.freeze({
2
+ reset: '\x1b[0m',
3
+ bold: '\x1b[1m',
4
+ dim: '\x1b[2m',
5
+ red: '\x1b[31m',
6
+ green: '\x1b[32m',
7
+ yellow: '\x1b[33m',
8
+ blue: '\x1b[34m',
9
+ magenta: '\x1b[35m',
10
+ cyan: '\x1b[36m',
11
+ });
12
+
13
+ function paint(name, text) {
14
+ return `${color[name] ?? ''}${text}${color.reset}`;
15
+ }
16
+
17
+ module.exports = { color, paint };
@@ -1,76 +1,76 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const ENCODING = 'utf8';
5
- const INDENTATION = 2;
6
- const NEW_LINE = '\n';
7
-
8
- function exists(target) {
9
- return fs.existsSync(target);
10
- }
11
-
12
- function ensureDirectory(target) {
13
- fs.mkdirSync(path.dirname(target), { recursive: true });
14
- }
15
-
16
- function readText(target) {
17
- return fs.readFileSync(target, ENCODING);
18
- }
19
-
20
- function writeText(target, content) {
21
- ensureDirectory(target);
22
- fs.writeFileSync(target, content);
23
- }
24
-
25
- function readJson(target) {
26
- return JSON.parse(readText(target));
27
- }
28
-
29
- function writeJson(target, data) {
30
- writeText(target, `${JSON.stringify(data, null, INDENTATION)}${NEW_LINE}`);
31
- }
32
-
33
- function copyFile(source, destination) {
34
- ensureDirectory(destination);
35
- fs.copyFileSync(source, destination);
36
- }
37
-
38
- function moveFile(source, destination) {
39
- ensureDirectory(destination);
40
- fs.renameSync(source, destination);
41
- }
42
-
43
- function removeFile(target) {
44
- if (!exists(target)) return false;
45
- fs.unlinkSync(target);
46
- return true;
47
- }
48
-
49
- function removeDirectory(target) {
50
- if (!exists(target)) return false;
51
- fs.rmSync(target, { recursive: true, force: true });
52
- return true;
53
- }
54
-
55
- function removeDirectoryIfEmpty(target) {
56
- try {
57
- if (fs.readdirSync(target).length > 0) return false;
58
- fs.rmdirSync(target);
59
- return true;
60
- } catch (error) {
61
- return false;
62
- }
63
- }
64
-
65
- module.exports = {
66
- exists,
67
- readText,
68
- writeText,
69
- readJson,
70
- writeJson,
71
- copyFile,
72
- moveFile,
73
- removeFile,
74
- removeDirectory,
75
- removeDirectoryIfEmpty,
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const ENCODING = 'utf8';
5
+ const INDENTATION = 2;
6
+ const NEW_LINE = '\n';
7
+
8
+ function exists(target) {
9
+ return fs.existsSync(target);
10
+ }
11
+
12
+ function ensureDirectory(target) {
13
+ fs.mkdirSync(path.dirname(target), { recursive: true });
14
+ }
15
+
16
+ function readText(target) {
17
+ return fs.readFileSync(target, ENCODING);
18
+ }
19
+
20
+ function writeText(target, content) {
21
+ ensureDirectory(target);
22
+ fs.writeFileSync(target, content);
23
+ }
24
+
25
+ function readJson(target) {
26
+ return JSON.parse(readText(target));
27
+ }
28
+
29
+ function writeJson(target, data) {
30
+ writeText(target, `${JSON.stringify(data, null, INDENTATION)}${NEW_LINE}`);
31
+ }
32
+
33
+ function copyFile(source, destination) {
34
+ ensureDirectory(destination);
35
+ fs.copyFileSync(source, destination);
36
+ }
37
+
38
+ function moveFile(source, destination) {
39
+ ensureDirectory(destination);
40
+ fs.renameSync(source, destination);
41
+ }
42
+
43
+ function removeFile(target) {
44
+ if (!exists(target)) return false;
45
+ fs.unlinkSync(target);
46
+ return true;
47
+ }
48
+
49
+ function removeDirectory(target) {
50
+ if (!exists(target)) return false;
51
+ fs.rmSync(target, { recursive: true, force: true });
52
+ return true;
53
+ }
54
+
55
+ function removeDirectoryIfEmpty(target) {
56
+ try {
57
+ if (fs.readdirSync(target).length > 0) return false;
58
+ fs.rmdirSync(target);
59
+ return true;
60
+ } catch (error) {
61
+ return false;
62
+ }
63
+ }
64
+
65
+ module.exports = {
66
+ exists,
67
+ readText,
68
+ writeText,
69
+ readJson,
70
+ writeJson,
71
+ copyFile,
72
+ moveFile,
73
+ removeFile,
74
+ removeDirectory,
75
+ removeDirectoryIfEmpty,
76
76
  };
@@ -1,22 +1,22 @@
1
- const messages = require('../config/messages.json');
2
- const { formatText } = require('./text');
3
-
4
- const KEY_SEPARATOR = '.';
5
-
6
- function resolveTemplate(key) {
7
- return key.split(KEY_SEPARATOR).reduce(
8
- (current, part) => (current !== null && typeof current === 'object' ? current[part] : undefined),
9
- messages
10
- );
11
- }
12
-
13
- function message(key, values) {
14
- const template = resolveTemplate(key);
15
- return typeof template === 'string' ? formatText(template, values) : key;
16
- }
17
-
18
- function log(key, values) {
19
- console.log(message(key, values));
20
- }
21
-
22
- module.exports = { message, log };
1
+ const messages = require('../config/messages.json');
2
+ const { formatText } = require('./text');
3
+
4
+ const KEY_SEPARATOR = '.';
5
+
6
+ function resolveTemplate(key) {
7
+ return key.split(KEY_SEPARATOR).reduce(
8
+ (current, part) => (current !== null && typeof current === 'object' ? current[part] : undefined),
9
+ messages
10
+ );
11
+ }
12
+
13
+ function message(key, values) {
14
+ const template = resolveTemplate(key);
15
+ return typeof template === 'string' ? formatText(template, values) : key;
16
+ }
17
+
18
+ function log(key, values) {
19
+ console.log(message(key, values));
20
+ }
21
+
22
+ module.exports = { message, log };