create-berna-stencil 2.6.0 → 2.6.1
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/.gitignore +5 -4
- package/README.md +1 -6
- package/_tools/assistant.js +92 -88
- package/_tools/modules/constants.js +23 -0
- package/_tools/modules/pageComponents.js +77 -0
- package/_tools/modules/updateData.js +25 -44
- package/_tools/modules/updateOutputPath.js +59 -63
- package/_tools/modules/updatePage.js +131 -104
- package/_tools/modules/utils.js +16 -19
- package/_tools/modules/validation.js +20 -0
- package/bin/create.js +75 -13
- package/package.json +50 -65
- package/src/backend/_core/vendor/composer/autoload_static.php +10 -10
- package/src/backend/_core/vendor/composer/installed.json +6 -6
- package/src/backend/_core/vendor/composer/installed.php +2 -2
- package/src/backend/_core/vendor/graham-campbell/result-type/.gitattributes +9 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/CODE_OF_CONDUCT.md +132 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/CONTRIBUTING.md +31 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/FUNDING.yml +2 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/SECURITY.md +14 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/stale.yml +11 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/tests.yml +40 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/CHANGELOG.md +53 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/LICENSE +21 -21
- package/src/backend/_core/vendor/graham-campbell/result-type/README.md +42 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/composer.json +33 -33
- package/src/backend/_core/vendor/graham-campbell/result-type/phpunit.xml.dist +13 -0
- package/src/backend/_core/vendor/graham-campbell/result-type/src/Error.php +121 -121
- package/src/backend/_core/vendor/graham-campbell/result-type/src/Result.php +69 -69
- package/src/backend/_core/vendor/graham-campbell/result-type/src/Success.php +120 -120
- package/src/backend/_core/vendor/graham-campbell/result-type/tests/ResultTest.php +95 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.gitattributes +13 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/CODE_OF_CONDUCT.md +132 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/CONTRIBUTING.md +30 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/FUNDING.yml +2 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/SECURITY.md +14 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/static.yml +40 -0
- package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/tests.yml +40 -0
- package/src/backend/_core/vendor/phpoption/phpoption/LICENSE +200 -200
- package/src/backend/_core/vendor/phpoption/phpoption/Makefile +17 -0
- package/src/backend/_core/vendor/phpoption/phpoption/README.md +201 -0
- package/src/backend/_core/vendor/phpoption/phpoption/composer.json +50 -50
- package/src/backend/_core/vendor/phpoption/phpoption/phpstan-baseline.neon +44 -0
- package/src/backend/_core/vendor/phpoption/phpoption/phpstan.neon.dist +7 -0
- package/src/backend/_core/vendor/phpoption/phpoption/phpunit.xml.dist +13 -0
- package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +175 -175
- package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/None.php +136 -136
- package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Option.php +434 -434
- package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Some.php +169 -169
- package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/EnsureTest.php +72 -0
- package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/LazyOptionTest.php +357 -0
- package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/NoneTest.php +153 -0
- package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/OptionTest.php +166 -0
- package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/SomeTest.php +194 -0
- package/src/backend/_core/vendor/phpoption/phpoption/tests/bootstrap.php +8 -0
- package/src/backend/_core/vendor/phpoption/phpoption/vendor-bin/phpstan/composer.json +8 -0
- package/src/backend/_core/vendor/symfony/polyfill-ctype/Ctype.php +232 -232
- package/src/backend/_core/vendor/symfony/polyfill-ctype/LICENSE +19 -19
- package/src/backend/_core/vendor/symfony/polyfill-ctype/README.md +12 -12
- package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap.php +50 -50
- package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap80.php +46 -46
- package/src/backend/_core/vendor/symfony/polyfill-ctype/composer.json +38 -38
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/LICENSE +19 -19
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/Mbstring.php +1077 -1077
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/README.md +13 -13
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +119 -119
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -1397
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -5
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -1489
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap.php +171 -171
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap80.php +167 -167
- package/src/backend/_core/vendor/symfony/polyfill-mbstring/composer.json +39 -39
- package/src/backend/_core/vendor/symfony/polyfill-php80/LICENSE +19 -19
- package/src/backend/_core/vendor/symfony/polyfill-php80/Php80.php +115 -115
- package/src/backend/_core/vendor/symfony/polyfill-php80/PhpToken.php +106 -106
- package/src/backend/_core/vendor/symfony/polyfill-php80/README.md +25 -25
- package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +31 -31
- package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +16 -16
- package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +20 -20
- package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +16 -16
- package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +16 -16
- package/src/backend/_core/vendor/symfony/polyfill-php80/bootstrap.php +42 -42
- package/src/backend/_core/vendor/symfony/polyfill-php80/composer.json +37 -37
- package/src/backend/_core/vendor/vlucas/phpdotenv/.editorconfig +15 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.gitattributes +15 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CODE_OF_CONDUCT.md +132 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CONTRIBUTING.md +30 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/FUNDING.yml +2 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/SECURITY.md +14 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/static.yml +40 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/tests.yml +70 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/LICENSE +30 -30
- package/src/backend/_core/vendor/vlucas/phpdotenv/Makefile +17 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/README.md +370 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/UPGRADING.md +196 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/composer.json +60 -60
- package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan-baseline.neon +157 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan.neon.dist +7 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/phpunit.xml.dist +13 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Dotenv.php +267 -267
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +12 -12
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php +12 -12
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php +12 -12
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php +12 -12
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php +12 -12
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Loader.php +48 -48
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +20 -20
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +65 -65
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Entry.php +59 -59
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +299 -299
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +58 -58
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lines.php +127 -127
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Parser.php +53 -53
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +19 -19
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Value.php +88 -88
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +15 -15
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +89 -89
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +80 -80
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +88 -88
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +85 -85
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +110 -110
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +48 -48
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +64 -64
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +91 -91
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +17 -17
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +104 -104
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +88 -88
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +27 -27
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php +107 -107
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +272 -272
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +51 -51
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Paths.php +44 -44
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Reader.php +81 -81
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/FileStore.php +72 -72
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +141 -141
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +17 -17
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StringStore.php +37 -37
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Regex.php +112 -112
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Str.php +108 -108
- package/src/backend/_core/vendor/vlucas/phpdotenv/src/Validator.php +207 -207
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/DotenvTest.php +387 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Loader/LoaderTest.php +86 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/EntryParserTest.php +234 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LexerTest.php +40 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LinesTest.php +53 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/ParserTest.php +98 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ArrayAdapterTest.php +57 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/EnvConstAdapterTest.php +75 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/PutenvAdapterTest.php +52 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ServerConstAdapterTest.php +75 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/RepositoryTest.php +305 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Store/StoreTest.php +141 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/ValidatorTest.php +479 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/.env +5 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/assertions.env +18 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/booleans.env +33 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/commented.env +15 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/empty.env +1 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/example.env +1 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/exported.env +7 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/immutable.env +1 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/integers.env +17 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/large.env +2 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multibyte.env +3 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiline.env +14 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiple.env +4 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/mutable.env +1 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/nested.env +15 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/quoted.env +11 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/specialchars.env +8 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/unicodevarnames.env +2 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/utf8-with-bom-encoding.env +3 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/windows.env +1 -0
- package/src/backend/_core/vendor/vlucas/phpdotenv/vendor-bin/phpstan/composer.json +15 -0
- package/src/backend/{config.example.php → config.php} +4 -13
- package/src/frontend/data/site.json +44 -44
- package/_tools/buildJs.js +0 -28
- package/_tools/cleanOutput.js +0 -20
- package/_tools/modules/updateIncludes.js +0 -81
|
@@ -1,113 +1,109 @@
|
|
|
1
|
-
const fs
|
|
1
|
+
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const { PATHS } = require('./constants');
|
|
3
4
|
const { isTypeScriptProject } = require('./utils');
|
|
4
5
|
|
|
5
|
-
const ELEVENTY_CONFIG = path.resolve(__dirname, '../../.eleventy.js');
|
|
6
|
-
const PACKAGE_JSON = path.resolve(__dirname, '../../package.json');
|
|
7
|
-
const TSCONFIG = path.resolve(__dirname, '../../tsconfig.json');
|
|
8
|
-
|
|
9
6
|
const OUTPUT_DIR_REGEX = /const OUTPUT_DIR\s*=\s*['"`]([^'"`]*)['"`]/;
|
|
10
|
-
|
|
11
|
-
// --- Helpers ---
|
|
7
|
+
const TSCONFIG_OUTDIR_REGEX = /"outDir"\s*:\s*"[^"]*"/;
|
|
12
8
|
|
|
13
9
|
function parseOutputDir(content) {
|
|
14
10
|
const match = content.match(OUTPUT_DIR_REGEX);
|
|
15
11
|
return match ? match[1] : null;
|
|
16
12
|
}
|
|
17
13
|
|
|
18
|
-
// --- Updaters ---
|
|
19
|
-
|
|
20
14
|
function updateEleventyConfig(newPath) {
|
|
21
|
-
const content = fs.readFileSync(
|
|
22
|
-
|
|
23
|
-
const updated = content.replace(
|
|
24
|
-
OUTPUT_DIR_REGEX,
|
|
25
|
-
`const OUTPUT_DIR = "${newPath}"`
|
|
26
|
-
);
|
|
15
|
+
const content = fs.readFileSync(PATHS.eleventyConfig, 'utf8');
|
|
16
|
+
const updated = content.replace(OUTPUT_DIR_REGEX, `const OUTPUT_DIR = "${newPath}"`);
|
|
27
17
|
|
|
28
18
|
if (content === updated) {
|
|
29
|
-
console.log('
|
|
30
|
-
return
|
|
19
|
+
console.log('[skip] OUTPUT_DIR not found in .eleventy.js');
|
|
20
|
+
return;
|
|
31
21
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
console.log(`(✓) .eleventy.js updated → ${newPath}`);
|
|
35
|
-
return true;
|
|
22
|
+
fs.writeFileSync(PATHS.eleventyConfig, updated);
|
|
23
|
+
console.log(`[updated] .eleventy.js → ${newPath}`);
|
|
36
24
|
}
|
|
37
25
|
|
|
38
26
|
function updatePackageJson(newPath) {
|
|
39
|
-
const pkg = JSON.parse(fs.readFileSync(
|
|
27
|
+
const pkg = JSON.parse(fs.readFileSync(PATHS.packageJson, 'utf8'));
|
|
28
|
+
const scriptGlob = isTypeScriptProject()
|
|
29
|
+
? 'src/frontend/ts/pages/*.ts'
|
|
30
|
+
: 'src/frontend/js/pages/*.js';
|
|
40
31
|
|
|
41
32
|
pkg.outputDir = newPath;
|
|
42
|
-
|
|
43
|
-
const usesTs = isTypeScriptProject();
|
|
44
|
-
|
|
33
|
+
pkg.scripts = pkg.scripts || {};
|
|
45
34
|
pkg.scripts['build:css'] = `sass src/frontend/scss:${newPath}/css --no-source-map --style=compressed --quiet`;
|
|
46
35
|
pkg.scripts['serve:css'] = `sass --watch src/frontend/scss:${newPath}/css --no-source-map --quiet`;
|
|
36
|
+
pkg.scripts['build:js'] = `esbuild "${scriptGlob}" --bundle --outdir=${newPath}/js/pages --minify`;
|
|
37
|
+
pkg.scripts['serve:js'] = `esbuild "${scriptGlob}" --bundle --outdir=${newPath}/js/pages --watch`;
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
pkg.scripts['serve:js'] = `esbuild "src/frontend/ts/pages/*.ts" --bundle --outdir=${newPath}/js/pages --watch`;
|
|
51
|
-
} else {
|
|
52
|
-
pkg.scripts['build:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --minify`;
|
|
53
|
-
pkg.scripts['serve:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --watch`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fs.writeFileSync(PACKAGE_JSON, JSON.stringify(pkg, null, 2), 'utf-8');
|
|
57
|
-
console.log(`(✓) package.json updated → ${newPath}`);
|
|
58
|
-
return true;
|
|
39
|
+
fs.writeFileSync(PATHS.packageJson, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
40
|
+
console.log(`[updated] package.json → ${newPath}`);
|
|
59
41
|
}
|
|
60
42
|
|
|
61
|
-
const TSCONFIG_OUTDIR_REGEX = /"outDir"\s*:\s*"[^"]*"/;
|
|
62
|
-
|
|
63
43
|
function updateTsConfig(newPath) {
|
|
64
44
|
if (!isTypeScriptProject()) return;
|
|
65
45
|
|
|
66
|
-
const content = fs.readFileSync(
|
|
46
|
+
const content = fs.readFileSync(PATHS.tsconfig, 'utf8');
|
|
67
47
|
const updated = content.replace(TSCONFIG_OUTDIR_REGEX, `"outDir": "./${newPath}/ts"`);
|
|
68
48
|
|
|
69
49
|
if (content === updated) {
|
|
70
|
-
console.log('
|
|
50
|
+
console.log('[skip] outDir not found in tsconfig.json');
|
|
71
51
|
return;
|
|
72
52
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
console.log(`(✓) tsconfig.json updated → ${newPath}/ts`);
|
|
53
|
+
fs.writeFileSync(PATHS.tsconfig, updated);
|
|
54
|
+
console.log(`[updated] tsconfig.json → ${newPath}/ts`);
|
|
76
55
|
}
|
|
77
56
|
|
|
78
|
-
|
|
57
|
+
function deleteOldOutput(oldPath) {
|
|
58
|
+
if (!oldPath) return;
|
|
79
59
|
|
|
80
|
-
|
|
81
|
-
const
|
|
60
|
+
const oldAbsPath = path.resolve(PATHS.root, oldPath);
|
|
61
|
+
const insideProject = oldAbsPath.startsWith(PATHS.root + path.sep);
|
|
62
|
+
|
|
63
|
+
if (!insideProject || oldAbsPath === PATHS.root) {
|
|
64
|
+
console.log(`[skip] refusing to delete "${oldAbsPath}" (outside project)`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (fs.existsSync(oldAbsPath)) {
|
|
68
|
+
fs.rmSync(oldAbsPath, { recursive: true, force: true });
|
|
69
|
+
console.log(`[deleted] ${oldAbsPath}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function updateOutputPath(rawPath) {
|
|
74
|
+
const trimmed = (rawPath ?? '').trim().replace(/\\/g, '/');
|
|
75
|
+
if (!trimmed) {
|
|
76
|
+
console.log('[skip] empty output path');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
82
79
|
|
|
83
80
|
const normalizedPath = trimmed === '.'
|
|
84
81
|
? 'out'
|
|
85
82
|
: `${trimmed.replace(/\/$/, '')}/${path.basename(process.cwd())}-out`;
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
fs.rmSync(oldAbsPath, { recursive: true, force: true });
|
|
94
|
-
console.log(`(✓) folder deleted → ${oldAbsPath}`);
|
|
95
|
-
} else {
|
|
96
|
-
console.log(`(i) folder not found, nothing to delete → ${oldAbsPath}`);
|
|
97
|
-
}
|
|
84
|
+
let oldPath = null;
|
|
85
|
+
try {
|
|
86
|
+
oldPath = parseOutputDir(fs.readFileSync(PATHS.eleventyConfig, 'utf8'));
|
|
87
|
+
} catch (err) {
|
|
88
|
+
console.log(`[error] cannot read .eleventy.js: ${err.message}`);
|
|
89
|
+
return;
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
|
|
92
|
+
deleteOldOutput(oldPath);
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
94
|
+
console.log(`\nupdating output path → "${normalizedPath}"`);
|
|
95
|
+
try {
|
|
96
|
+
updatePackageJson(normalizedPath);
|
|
97
|
+
updateEleventyConfig(normalizedPath);
|
|
98
|
+
updateTsConfig(normalizedPath);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.log(`[error] could not update output path: ${err.message}`);
|
|
101
|
+
}
|
|
105
102
|
}
|
|
106
103
|
|
|
107
104
|
function getCurrentOutputPath() {
|
|
108
105
|
try {
|
|
109
|
-
|
|
110
|
-
return parseOutputDir(content);
|
|
106
|
+
return parseOutputDir(fs.readFileSync(PATHS.eleventyConfig, 'utf8'));
|
|
111
107
|
} catch {
|
|
112
108
|
return null;
|
|
113
109
|
}
|
|
@@ -1,135 +1,162 @@
|
|
|
1
|
-
const
|
|
1
|
+
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
+
const { PATHS } = require('./constants');
|
|
5
|
+
const { toCamelCase, isTypeScriptProject } = require('./utils');
|
|
4
6
|
const { addSiteData, removeSiteData, renameSiteData } = require('./updateData');
|
|
5
|
-
const {
|
|
7
|
+
const { addPageBlock, removePageBlock, renamePageBlock } = require('./pageComponents');
|
|
6
8
|
const { getCurrentOutputPath } = require('./updateOutputPath');
|
|
7
|
-
const { toCamelCase, isTypeScriptProject } = require('./utils');
|
|
8
|
-
|
|
9
|
-
const TEMPLATES_DIR = path.join(__dirname, '..', 'res', 'templates');
|
|
10
|
-
|
|
11
|
-
function getPageTargets(pageName) {
|
|
12
|
-
const camelName = toCamelCase(pageName);
|
|
13
|
-
const usesTs = isTypeScriptProject();
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
function getPageArtifacts(pageName) {
|
|
11
|
+
const camelName = toCamelCase(pageName);
|
|
12
|
+
const usesTs = isTypeScriptProject();
|
|
13
|
+
const scriptDir = usesTs ? PATHS.tsPages : PATHS.jsPages;
|
|
14
|
+
const scriptExt = usesTs ? 'ts' : 'js';
|
|
15
|
+
const outputRoot = path.join(PATHS.root, getCurrentOutputPath() || 'out');
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
camelName,
|
|
19
|
+
source: {
|
|
20
|
+
scss: path.join(PATHS.scssPages, `${camelName}.scss`),
|
|
21
|
+
script: path.join(scriptDir, `${camelName}.${scriptExt}`),
|
|
22
|
+
route: path.join(PATHS.routes, `${pageName}.njk`),
|
|
25
23
|
},
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
output: {
|
|
25
|
+
files: [
|
|
26
|
+
path.join(outputRoot, 'js', 'pages', `${camelName}.js`),
|
|
27
|
+
path.join(outputRoot, 'css', 'pages', `${camelName}.css`),
|
|
28
|
+
path.join(outputRoot, `${pageName}.html`),
|
|
29
|
+
path.join(outputRoot, 'pages', `${pageName}.html`),
|
|
30
|
+
],
|
|
31
|
+
folders: [
|
|
32
|
+
path.join(outputRoot, pageName),
|
|
33
|
+
path.join(outputRoot, 'pages', pageName),
|
|
34
|
+
],
|
|
30
35
|
},
|
|
31
|
-
|
|
36
|
+
};
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
getPageTargets(pageName).forEach(({ folder, templateFile, fileName }) => {
|
|
38
|
-
const destPath = path.join(folder, fileName);
|
|
39
|
-
fileSystem.mkdirSync(folder, { recursive: true });
|
|
40
|
-
|
|
41
|
-
if (fileSystem.existsSync(destPath)) return;
|
|
42
|
-
|
|
43
|
-
const srcPath = path.join(TEMPLATES_DIR, templateFile);
|
|
39
|
+
function pageExists(pageName) {
|
|
40
|
+
return fs.existsSync(path.join(PATHS.routes, `${pageName}.njk`));
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fileSystem.copyFileSync(srcPath, destPath);
|
|
52
|
-
}
|
|
43
|
+
function applyRouteFrontMatter(filePath, camelName, pageName) {
|
|
44
|
+
const content = fs.readFileSync(filePath, 'utf8')
|
|
45
|
+
.replace(/^title:.*$/m, `title: "${camelName}"`)
|
|
46
|
+
.replace(/^permalink:.*$/m, `permalink: "/${pageName}/"`);
|
|
47
|
+
fs.writeFileSync(filePath, content);
|
|
48
|
+
}
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
function addPage(pageName) {
|
|
51
|
+
if (pageExists(pageName)) {
|
|
52
|
+
console.log(`[skip] page "${pageName}" already exists`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { camelName, source } = getPageArtifacts(pageName);
|
|
57
|
+
const usesTs = isTypeScriptProject();
|
|
58
|
+
|
|
59
|
+
const creations = [
|
|
60
|
+
{ dest: source.scss, template: 'template.scss', isRoute: false },
|
|
61
|
+
{ dest: source.script, template: usesTs ? 'template.ts' : 'template.js', isRoute: false },
|
|
62
|
+
{ dest: source.route, template: 'template.njk', isRoute: true },
|
|
63
|
+
];
|
|
56
64
|
|
|
57
|
-
|
|
65
|
+
try {
|
|
66
|
+
creations.forEach(({ dest, template, isRoute }) => {
|
|
67
|
+
const templatePath = path.join(PATHS.templates, template);
|
|
68
|
+
if (!fs.existsSync(templatePath)) {
|
|
69
|
+
console.log(`[skip] template not found: ${templatePath}`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
74
|
+
fs.copyFileSync(templatePath, dest);
|
|
75
|
+
if (isRoute) applyRouteFrontMatter(dest, camelName, pageName);
|
|
76
|
+
|
|
77
|
+
console.log(`[created] ${dest}`);
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.log(`[error] could not create page files: ${err.message}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
addPageBlock(pageName);
|
|
58
85
|
addSiteData(pageName);
|
|
59
86
|
}
|
|
60
87
|
|
|
61
88
|
function renamePage(oldName, newName) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
89
|
+
if (!pageExists(oldName)) {
|
|
90
|
+
console.log(`[skip] page "${oldName}" does not exist`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (pageExists(newName)) {
|
|
94
|
+
console.log(`[skip] target page "${newName}" already exists`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const oldArtifacts = getPageArtifacts(oldName);
|
|
99
|
+
const newArtifacts = getPageArtifacts(newName);
|
|
100
|
+
|
|
101
|
+
const moves = [
|
|
102
|
+
{ src: oldArtifacts.source.scss, dest: newArtifacts.source.scss },
|
|
103
|
+
{ src: oldArtifacts.source.script, dest: newArtifacts.source.script },
|
|
104
|
+
{ src: oldArtifacts.source.route, dest: newArtifacts.source.route },
|
|
72
105
|
];
|
|
73
106
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
try {
|
|
108
|
+
moves.forEach(({ src, dest }) => {
|
|
109
|
+
if (!fs.existsSync(src)) {
|
|
110
|
+
console.log(`[skip] not found: ${src}`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
114
|
+
fs.renameSync(src, dest);
|
|
115
|
+
console.log(`[renamed] ${src} → ${dest}`);
|
|
116
|
+
|
|
117
|
+
if (dest.endsWith('.njk')) applyRouteFrontMatter(dest, newArtifacts.camelName, newName);
|
|
118
|
+
});
|
|
119
|
+
} catch (err) {
|
|
120
|
+
console.log(`[error] could not rename page files: ${err.message}`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
renamePageBlock(oldName, newName);
|
|
92
125
|
renameSiteData(oldName, newName);
|
|
93
126
|
}
|
|
94
127
|
|
|
95
128
|
function removePage(pageName) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const foldersToDelete = [
|
|
113
|
-
path.join(OUTPUT_DIR, pageName),
|
|
114
|
-
path.join(OUTPUT_DIR, 'pages', pageName),
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
filesToDelete.forEach(f => {
|
|
118
|
-
if (fileSystem.existsSync(f)) {
|
|
119
|
-
fileSystem.unlinkSync(f);
|
|
120
|
-
console.log(`[deleted file] ${f}`);
|
|
129
|
+
if (!pageExists(pageName)) {
|
|
130
|
+
console.log(`[skip] page "${pageName}" does not exist`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const { source, output } = getPageArtifacts(pageName);
|
|
134
|
+
const filesToDelete = [source.scss, source.script, source.route, ...output.files];
|
|
135
|
+
|
|
136
|
+
filesToDelete.forEach((file) => {
|
|
137
|
+
try {
|
|
138
|
+
if (fs.existsSync(file)) {
|
|
139
|
+
fs.unlinkSync(file);
|
|
140
|
+
console.log(`[deleted] ${file}`);
|
|
141
|
+
}
|
|
142
|
+
} catch (err) {
|
|
143
|
+
console.log(`[error] ${file}: ${err.message}`);
|
|
121
144
|
}
|
|
122
145
|
});
|
|
123
146
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
output.folders.forEach((folder) => {
|
|
148
|
+
try {
|
|
149
|
+
if (fs.existsSync(folder)) {
|
|
150
|
+
fs.rmSync(folder, { recursive: true, force: true });
|
|
151
|
+
console.log(`[deleted] ${folder}`);
|
|
152
|
+
}
|
|
153
|
+
} catch (err) {
|
|
154
|
+
console.log(`[error] ${folder}: ${err.message}`);
|
|
128
155
|
}
|
|
129
156
|
});
|
|
130
157
|
|
|
131
|
-
|
|
158
|
+
removePageBlock(pageName);
|
|
132
159
|
removeSiteData(pageName);
|
|
133
160
|
}
|
|
134
161
|
|
|
135
|
-
module.exports = { addPage, removePage, renamePage };
|
|
162
|
+
module.exports = { addPage, removePage, renamePage, pageExists };
|
package/_tools/modules/utils.js
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
|
-
const fs
|
|
2
|
-
const
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { PATHS } = require('./constants');
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
function toCamelCase(value) {
|
|
5
|
+
return value.toLowerCase().replace(/[-_][a-z0-9]/g, (group) => group.slice(1).toUpperCase());
|
|
6
|
+
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
8
|
+
function toKebabCase(value) {
|
|
9
|
+
return value.trim().toLowerCase()
|
|
10
|
+
.replace(/[^a-z0-9\s_-]/g, '')
|
|
11
|
+
.replace(/[\s_]+/g, '-')
|
|
12
|
+
.replace(/-+/g, '-')
|
|
13
|
+
.replace(/^-+|-+$/g, '');
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
// Converts a kebab-case page name to a human-readable title
|
|
18
|
-
// e.g. "about-us" → "About Us"
|
|
19
16
|
function toNiceTitle(pageName) {
|
|
20
|
-
return pageName
|
|
21
|
-
.
|
|
22
|
-
.map(
|
|
17
|
+
return pageName.split('-')
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
23
20
|
.join(' ');
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
function isTypeScriptProject() {
|
|
27
|
-
return fs.existsSync(
|
|
24
|
+
return fs.existsSync(PATHS.tsconfig);
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
module.exports = { toCamelCase, toNiceTitle, isTypeScriptProject };
|
|
27
|
+
module.exports = { toCamelCase, toKebabCase, toNiceTitle, isTypeScriptProject };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { MAX_PAGE_NAME_LENGTH, PROTECTED_PAGES } = require('./constants');
|
|
2
|
+
|
|
3
|
+
function validatePageName(name) {
|
|
4
|
+
if (!name) return 'Invalid name.';
|
|
5
|
+
if (name.length > MAX_PAGE_NAME_LENGTH) return `Name must be ${MAX_PAGE_NAME_LENGTH} characters or fewer.`;
|
|
6
|
+
if (!/^[a-z0-9-]+$/.test(name)) return 'Page name can only contain lowercase letters, numbers, and hyphens.';
|
|
7
|
+
if (/^\d/.test(name)) return 'Page name cannot start with a number.';
|
|
8
|
+
if (PROTECTED_PAGES.includes(name)) return `"${name}" is a protected page name.`;
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function validateOutputPath(input) {
|
|
13
|
+
const value = (input ?? '').trim();
|
|
14
|
+
if (!value) return 'Invalid path.';
|
|
15
|
+
if (value.includes('..')) return 'Path cannot contain "..".';
|
|
16
|
+
if (/[<>|?*"']/.test(value)) return 'Path contains invalid characters.';
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = { validatePageName, validateOutputPath };
|