nibula 1.2.2 → 1.2.4
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 +0 -5
- package/CHANGELOG.md +21 -9
- package/README.md +1 -1
- package/bin/create.js +1 -2
- package/bin/nibula.js +2 -5
- package/nginx.conf +75 -75
- package/package.json +74 -74
- 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/favicon.svg +54 -54
- package/src/frontend/assets/brand/logo.svg +54 -54
- package/src/frontend/data/site.json +48 -48
- package/src/frontend/web.config +55 -55
- package/tools/assistant.js +122 -151
- package/tools/buildJs.js +39 -37
- package/tools/cleanOutput.js +23 -25
- package/tools/cli/prompt.js +40 -0
- package/tools/cli/ui.js +74 -0
- package/tools/config/messages.json +76 -0
- package/tools/config/settings.json +135 -0
- package/tools/lib/colors.js +17 -0
- package/tools/lib/files.js +65 -0
- package/tools/lib/logger.js +22 -0
- package/tools/lib/outputPath.js +141 -0
- package/tools/lib/pageActions.js +138 -0
- package/tools/lib/pageArtifacts.js +46 -0
- package/tools/lib/pageComponents.js +88 -0
- package/tools/lib/paths.js +61 -0
- package/tools/lib/project.js +54 -0
- package/tools/lib/siteData.js +93 -0
- package/tools/lib/text.js +47 -0
- package/tools/lib/validation.js +39 -0
- package/tools/res/templates/template.js +3 -1
- package/tools/res/templates/template.ts +3 -1
- package/tools/modules/constants.js +0 -66
- package/tools/modules/pageComponents.js +0 -77
- package/tools/modules/updateData.js +0 -90
- package/tools/modules/updateOutputPath.js +0 -112
- package/tools/modules/updatePage.js +0 -162
- package/tools/modules/utils.js +0 -27
- package/tools/modules/validation.js +0 -30
package/tools/assistant.js
CHANGED
|
@@ -1,152 +1,123 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const {
|
|
4
|
-
const {
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
const
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
console.log(`\n${color.dim}The project may be incomplete or created with a different Nibula version.${color.reset}`);
|
|
125
|
-
rl.close();
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
while (true) {
|
|
130
|
-
renderMenu();
|
|
131
|
-
|
|
132
|
-
const choice = await ask(`${color.cyan}❯${color.reset} Choose an option: `);
|
|
133
|
-
if (choice === null) break;
|
|
134
|
-
|
|
135
|
-
const action = MENU_ACTIONS[choice];
|
|
136
|
-
if (!action) {
|
|
137
|
-
console.log(`\n${color.red}✖ Invalid option.${color.reset}`);
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
await action();
|
|
143
|
-
} catch (err) {
|
|
144
|
-
console.log(`\n${color.red}✖ Unexpected error: ${err.message}${color.reset}`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
rl.close();
|
|
149
|
-
process.exit(0);
|
|
150
|
-
}
|
|
151
|
-
|
|
1
|
+
const settings = require('./config/settings.json');
|
|
2
|
+
const { message } = require('./lib/logger');
|
|
3
|
+
const { toKebabCase } = require('./lib/text');
|
|
4
|
+
const { validatePageName, validateOutputPath, checkRequiredFiles } = require('./lib/validation');
|
|
5
|
+
const { addPage, removePage, renamePage } = require('./lib/pageActions');
|
|
6
|
+
const { pageExists } = require('./lib/pageArtifacts');
|
|
7
|
+
const { updateOutputPath, getCurrentOutputPath } = require('./lib/outputPath');
|
|
8
|
+
const { ask, confirm, close } = require('./cli/prompt');
|
|
9
|
+
const ui = require('./cli/ui');
|
|
10
|
+
|
|
11
|
+
const NEW_LINE = '\n';
|
|
12
|
+
const NO_PREFIX = '';
|
|
13
|
+
|
|
14
|
+
async function askPageName(prompt) {
|
|
15
|
+
const raw = await ask(prompt);
|
|
16
|
+
if (raw === null) return null;
|
|
17
|
+
|
|
18
|
+
const name = toKebabCase(raw);
|
|
19
|
+
const error = validatePageName(name);
|
|
20
|
+
if (error) {
|
|
21
|
+
ui.error(error);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return name;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function handleCreate() {
|
|
28
|
+
const name = await askPageName(ui.promptLine(message('cli.createPrompt')));
|
|
29
|
+
if (name) addPage(name);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function handleRemove() {
|
|
33
|
+
const name = await askPageName(ui.promptLine(message('cli.removePrompt')));
|
|
34
|
+
if (!name) return;
|
|
35
|
+
|
|
36
|
+
if (!pageExists(name)) {
|
|
37
|
+
ui.warning(message('cli.pageNotFound', { name }));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const confirmed = await confirm(message('cli.confirmRemove', { name }));
|
|
42
|
+
if (!confirmed) {
|
|
43
|
+
ui.notice(message('cli.cancelled'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
removePage(name);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function handleRename() {
|
|
50
|
+
const oldName = await askPageName(ui.promptLine(message('cli.renameFromPrompt')));
|
|
51
|
+
if (!oldName) return;
|
|
52
|
+
|
|
53
|
+
const newName = await askPageName(ui.promptLine(message('cli.renameToPrompt'), NO_PREFIX));
|
|
54
|
+
if (!newName) return;
|
|
55
|
+
|
|
56
|
+
if (oldName === newName) {
|
|
57
|
+
ui.warning(message('cli.sameName'));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
renamePage(oldName, newName);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function handleOutputPath() {
|
|
64
|
+
const current = getCurrentOutputPath();
|
|
65
|
+
const prefix = current
|
|
66
|
+
? ui.noticePrefix(message('cli.currentOutputPath', { path: current }))
|
|
67
|
+
: NEW_LINE;
|
|
68
|
+
|
|
69
|
+
const input = await ask(ui.promptLine(message('cli.outputPathPrompt'), prefix));
|
|
70
|
+
if (input === null) return;
|
|
71
|
+
|
|
72
|
+
const error = validateOutputPath(input);
|
|
73
|
+
if (error) {
|
|
74
|
+
ui.error(error);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
updateOutputPath(input);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const ACTIONS = {
|
|
81
|
+
createPage: handleCreate,
|
|
82
|
+
removePage: handleRemove,
|
|
83
|
+
renamePage: handleRename,
|
|
84
|
+
outputPath: handleOutputPath,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function findAction(choice) {
|
|
88
|
+
const item = settings.cli.menu.find((entry) => entry.key === choice);
|
|
89
|
+
return item ? ACTIONS[item.action] : null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function main() {
|
|
93
|
+
const missing = checkRequiredFiles();
|
|
94
|
+
if (missing.length > 0) {
|
|
95
|
+
ui.renderMissingFiles(missing);
|
|
96
|
+
close();
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
while (true) {
|
|
101
|
+
ui.renderMenu();
|
|
102
|
+
|
|
103
|
+
const choice = await ask(ui.promptLine(message('cli.menuPrompt'), NO_PREFIX));
|
|
104
|
+
if (choice === null) break;
|
|
105
|
+
|
|
106
|
+
const action = findAction(choice);
|
|
107
|
+
if (!action) {
|
|
108
|
+
ui.error(message('cli.invalidOption'));
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
await action();
|
|
114
|
+
} catch (error) {
|
|
115
|
+
ui.error(message('cli.unexpectedError', { error: error.message }));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
close();
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
|
|
152
123
|
main();
|
package/tools/buildJs.js
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
esbuild.
|
|
37
|
-
}
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const esbuild = require('esbuild');
|
|
3
|
+
const glob = require('glob');
|
|
4
|
+
const settings = require('./config/settings.json');
|
|
5
|
+
const { PATHS } = require('./lib/paths');
|
|
6
|
+
const { readPackageJson, allScriptEntries } = require('./lib/project');
|
|
7
|
+
|
|
8
|
+
const WATCH_FLAG = '--watch';
|
|
9
|
+
const PATH_SEPARATOR = '/';
|
|
10
|
+
|
|
11
|
+
function toPosix(target) {
|
|
12
|
+
return target.split(path.sep).join(PATH_SEPARATOR);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function collectEntryPoints() {
|
|
16
|
+
return allScriptEntries().flatMap((entries) => glob.sync(toPosix(path.join(PATHS.root, entries))));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const packageJson = readPackageJson();
|
|
20
|
+
const outputDirectory = packageJson[settings.packageJson.outputKey] || settings.project.defaultOutputDirectory;
|
|
21
|
+
const watch = process.argv.includes(WATCH_FLAG);
|
|
22
|
+
const entryPoints = collectEntryPoints();
|
|
23
|
+
|
|
24
|
+
if (entryPoints.length === 0) {
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const options = {
|
|
29
|
+
entryPoints,
|
|
30
|
+
bundle: true,
|
|
31
|
+
outdir: path.join(PATHS.root, outputDirectory, ...settings.build.scriptOutput.split(PATH_SEPARATOR)),
|
|
32
|
+
minify: !watch,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (watch) {
|
|
36
|
+
esbuild.context(options).then((context) => context.watch()).catch(() => process.exit(1));
|
|
37
|
+
} else {
|
|
38
|
+
esbuild.build(options).catch(() => process.exit(1));
|
|
39
|
+
}
|
package/tools/cleanOutput.js
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const {
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
console.log(`(i) nothing to clean → ${outputDir}`);
|
|
25
|
-
}
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const settings = require('./config/settings.json');
|
|
3
|
+
const { PATHS } = require('./lib/paths');
|
|
4
|
+
const { readPackageJson } = require('./lib/project');
|
|
5
|
+
const { removeDirectory } = require('./lib/files');
|
|
6
|
+
const { log } = require('./lib/logger');
|
|
7
|
+
|
|
8
|
+
const OUTPUT_KEY = settings.packageJson.outputKey;
|
|
9
|
+
|
|
10
|
+
const packageJson = readPackageJson();
|
|
11
|
+
|
|
12
|
+
if (!packageJson[OUTPUT_KEY]) {
|
|
13
|
+
log('output.missingConfiguration', { key: OUTPUT_KEY, file: settings.paths.packageJson });
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const outputDirectory = path.resolve(PATHS.root, packageJson[OUTPUT_KEY]);
|
|
18
|
+
|
|
19
|
+
if (removeDirectory(outputDirectory)) {
|
|
20
|
+
log('output.cleaned', { path: outputDirectory });
|
|
21
|
+
} else {
|
|
22
|
+
log('output.nothingToClean', { path: outputDirectory });
|
|
23
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
const settings = require('../config/settings.json');
|
|
3
|
+
const { color } = require('../lib/colors');
|
|
4
|
+
|
|
5
|
+
const CONTROL_CHARACTERS_PATTERN = /[\x00-\x1F\x7F]/g;
|
|
6
|
+
const AFFIRMATIVE_PATTERN = /^y(es)?$/i;
|
|
7
|
+
const CONFIRM_HINT = settings.cli.confirmHint;
|
|
8
|
+
const EMPTY = '';
|
|
9
|
+
|
|
10
|
+
const readlineInterface = readline.createInterface({
|
|
11
|
+
input: process.stdin,
|
|
12
|
+
output: process.stdout,
|
|
13
|
+
terminal: true,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function sanitizeInput(value) {
|
|
17
|
+
return (value ?? EMPTY).replace(CONTROL_CHARACTERS_PATTERN, EMPTY).trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ask(prompt) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const onClose = () => resolve(null);
|
|
23
|
+
readlineInterface.once('close', onClose);
|
|
24
|
+
readlineInterface.question(prompt, (answer) => {
|
|
25
|
+
readlineInterface.off('close', onClose);
|
|
26
|
+
resolve(sanitizeInput(answer));
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function confirm(prompt) {
|
|
32
|
+
const answer = await ask(`${prompt} ${color.dim}${CONFIRM_HINT}${color.reset} `);
|
|
33
|
+
return AFFIRMATIVE_PATTERN.test((answer ?? EMPTY).trim());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function close() {
|
|
37
|
+
readlineInterface.close();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { ask, confirm, close };
|
package/tools/cli/ui.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const settings = require('../config/settings.json');
|
|
2
|
+
const { color } = require('../lib/colors');
|
|
3
|
+
const { message } = require('../lib/logger');
|
|
4
|
+
|
|
5
|
+
const SYMBOLS = settings.cli.symbols;
|
|
6
|
+
const COLORS = settings.cli.colors;
|
|
7
|
+
const MENU = settings.cli.menu;
|
|
8
|
+
const BOX_WIDTH = settings.cli.boxWidth;
|
|
9
|
+
const BOX_TITLE = settings.cli.title;
|
|
10
|
+
const BOX_TOP_LEFT = '\u256d';
|
|
11
|
+
const BOX_TOP_RIGHT = '\u256e';
|
|
12
|
+
const BOX_BOTTOM_LEFT = '\u2570';
|
|
13
|
+
const BOX_BOTTOM_RIGHT = '\u256f';
|
|
14
|
+
const BOX_HORIZONTAL = '\u2500';
|
|
15
|
+
const BOX_VERTICAL = '\u2502';
|
|
16
|
+
const NEW_LINE = '\n';
|
|
17
|
+
const SPACE = ' ';
|
|
18
|
+
|
|
19
|
+
function line(colorName, text) {
|
|
20
|
+
return `${color[colorName]}${text}${color.reset}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function promptLine(text, prefix = NEW_LINE) {
|
|
24
|
+
return `${prefix}${line(COLORS.prompt, SYMBOLS.prompt)} ${text}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function error(text) {
|
|
28
|
+
console.log(`${NEW_LINE}${line(COLORS.error, `${SYMBOLS.error} ${text}`)}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function warning(text) {
|
|
32
|
+
console.log(`${NEW_LINE}${line(COLORS.warning, `${SYMBOLS.warning} ${text}`)}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function notice(text) {
|
|
36
|
+
console.log(`${NEW_LINE}${line(COLORS.notice, text)}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function noticePrefix(text) {
|
|
40
|
+
return `${NEW_LINE}${line(COLORS.notice, text)}${NEW_LINE}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function centeredTitle() {
|
|
44
|
+
const padding = BOX_WIDTH - BOX_TITLE.length;
|
|
45
|
+
const left = SPACE.repeat(Math.ceil(padding / 2));
|
|
46
|
+
const right = SPACE.repeat(Math.floor(padding / 2));
|
|
47
|
+
return `${left}${BOX_TITLE}${right}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function renderMenu() {
|
|
51
|
+
const border = BOX_HORIZONTAL.repeat(BOX_WIDTH);
|
|
52
|
+
|
|
53
|
+
console.log(`${NEW_LINE}${color[COLORS.box]}${color.bold}${BOX_TOP_LEFT}${border}${BOX_TOP_RIGHT}`);
|
|
54
|
+
console.log(`${BOX_VERTICAL}${centeredTitle()}${BOX_VERTICAL}`);
|
|
55
|
+
console.log(`${BOX_BOTTOM_LEFT}${border}${BOX_BOTTOM_RIGHT}${color.reset}${NEW_LINE}`);
|
|
56
|
+
|
|
57
|
+
for (const item of MENU) {
|
|
58
|
+
console.log(` ${line(COLORS.menuKey, `${item.key}.`)} ${item.label}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log(`${NEW_LINE}${line(COLORS.notice, message('cli.exitHint'))}${NEW_LINE}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function renderMissingFiles(items) {
|
|
65
|
+
console.log(`${NEW_LINE}${line(COLORS.error, `${SYMBOLS.error} ${message('cli.missingFiles')}`)}`);
|
|
66
|
+
|
|
67
|
+
for (const item of items) {
|
|
68
|
+
console.log(` ${line(COLORS.error, SYMBOLS.bullet)} ${item.label}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`${NEW_LINE}${line(COLORS.notice, message('cli.incompleteProject'))}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { promptLine, noticePrefix, error, warning, notice, renderMenu, renderMissingFiles };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": {
|
|
3
|
+
"notInside": "Not inside a Nibula project."
|
|
4
|
+
},
|
|
5
|
+
"validation": {
|
|
6
|
+
"invalidName": "Invalid name.",
|
|
7
|
+
"invalidNameCharacters": "Page name can only contain lowercase letters, numbers, and hyphens.",
|
|
8
|
+
"nameStartsWithNumber": "Page name cannot start with a number.",
|
|
9
|
+
"protectedName": "\"{name}\" is a protected page name.",
|
|
10
|
+
"invalidPath": "Invalid path.",
|
|
11
|
+
"invalidPathCharacters": "Path contains invalid characters.",
|
|
12
|
+
"templatesLabel": "CLI page templates"
|
|
13
|
+
},
|
|
14
|
+
"page": {
|
|
15
|
+
"alreadyExists": "[skip] page \"{name}\" already exists",
|
|
16
|
+
"doesNotExist": "[skip] page \"{name}\" does not exist",
|
|
17
|
+
"targetExists": "[skip] target page \"{name}\" already exists",
|
|
18
|
+
"templateMissing": "[skip] template not found: {path}",
|
|
19
|
+
"fileMissing": "[skip] not found: {path}",
|
|
20
|
+
"fileCreated": "[created] {path}",
|
|
21
|
+
"fileRenamed": "[renamed] {source} \u2192 {destination}",
|
|
22
|
+
"fileDeleted": "[deleted] {path}",
|
|
23
|
+
"createFailed": "[error] could not create page files: {error}",
|
|
24
|
+
"renameFailed": "[error] could not rename page files: {error}",
|
|
25
|
+
"deleteFailed": "[error] {path}: {error}"
|
|
26
|
+
},
|
|
27
|
+
"components": {
|
|
28
|
+
"fileMissing": "[skip] not found: {path}",
|
|
29
|
+
"anchorMissing": "[skip] no {anchor} anchor in {file}",
|
|
30
|
+
"blockAdded": "[updated] page block added for \"{name}\"",
|
|
31
|
+
"blockMissing": "[skip] page block for \"{name}\" not found",
|
|
32
|
+
"blockRemoved": "[cleaned] page block removed for \"{name}\"",
|
|
33
|
+
"blockRenamed": "[renamed] page block \"{source}\" \u2192 \"{destination}\""
|
|
34
|
+
},
|
|
35
|
+
"siteData": {
|
|
36
|
+
"fileMissing": "[skip] not found: {path}",
|
|
37
|
+
"parseFailed": "[error] cannot parse {file}: {error}",
|
|
38
|
+
"recordExists": "[skip] record \"{name}\" already exists",
|
|
39
|
+
"recordMissing": "[skip] record \"{name}\" not found",
|
|
40
|
+
"recordAdded": "[updated] record \"{name}\" added",
|
|
41
|
+
"recordRemoved": "[cleaned] record \"{name}\" removed",
|
|
42
|
+
"recordRenamed": "[updated] record \"{source}\" renamed to \"{destination}\""
|
|
43
|
+
},
|
|
44
|
+
"output": {
|
|
45
|
+
"emptyPath": "[skip] empty output path",
|
|
46
|
+
"readFailed": "[error] cannot read {file}: {error}",
|
|
47
|
+
"updateFailed": "[error] could not update output path: {error}",
|
|
48
|
+
"updating": "\nupdating output path \u2192 \"{path}\"",
|
|
49
|
+
"variableMissing": "[skip] {variable} not found in {file}",
|
|
50
|
+
"keyMissing": "[skip] {key} not found in {file}",
|
|
51
|
+
"fileUpdated": "[updated] {file} \u2192 {path}",
|
|
52
|
+
"directoryDeleted": "[deleted] {path}",
|
|
53
|
+
"refuseDelete": "[skip] refusing to delete \"{path}\" (outside project)",
|
|
54
|
+
"missingConfiguration": "(!) {key} not found in {file}",
|
|
55
|
+
"cleaned": "(\u2713) cleaned \u2192 {path}",
|
|
56
|
+
"nothingToClean": "(i) nothing to clean \u2192 {path}"
|
|
57
|
+
},
|
|
58
|
+
"cli": {
|
|
59
|
+
"createPrompt": "Name of the new page: ",
|
|
60
|
+
"removePrompt": "Name of the page to remove: ",
|
|
61
|
+
"renameFromPrompt": "Page to rename: ",
|
|
62
|
+
"renameToPrompt": "New name: ",
|
|
63
|
+
"outputPathPrompt": "New output path: ",
|
|
64
|
+
"menuPrompt": "Choose an option: ",
|
|
65
|
+
"currentOutputPath": "Current path: \"{path}\"",
|
|
66
|
+
"confirmRemove": "This permanently deletes all files for \"{name}\".",
|
|
67
|
+
"cancelled": "Cancelled.",
|
|
68
|
+
"pageNotFound": "Page \"{name}\" does not exist.",
|
|
69
|
+
"sameName": "Old and new name are the same.",
|
|
70
|
+
"invalidOption": "Invalid option.",
|
|
71
|
+
"unexpectedError": "Unexpected error: {error}",
|
|
72
|
+
"missingFiles": "This project is missing required files:",
|
|
73
|
+
"incompleteProject": "The project may be incomplete or created with a different Nibula version.",
|
|
74
|
+
"exitHint": "CTRL + C to exit"
|
|
75
|
+
}
|
|
76
|
+
}
|