create-berna-stencil 2.0.15 → 2.2.0

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 (193) hide show
  1. package/.eleventy.js +5 -27
  2. package/README.md +1 -1
  3. package/_tools/buildJs.js +28 -0
  4. package/_tools/cleanOutput.js +9 -13
  5. package/_tools/modules/updateOutputPath.js +36 -14
  6. package/_tools/modules/updatePage.js +31 -11
  7. package/_tools/res/templates/template.js +3 -11
  8. package/_tools/res/templates/template.ts +13 -0
  9. package/bin/create.js +161 -111
  10. package/docs/Assistant CLI.md +2 -0
  11. package/docs/Creating pages.md +2 -0
  12. package/docs/Javascript.md +30 -37
  13. package/package.json +64 -63
  14. package/src/backend/_core/index.php +10 -1
  15. package/src/backend/_core/init.php +4 -3
  16. package/src/backend/_core/modules/RateLimiter.php +31 -0
  17. package/src/backend/_core/vendor/composer/autoload_static.php +10 -10
  18. package/src/backend/_core/vendor/composer/installed.json +6 -6
  19. package/src/backend/_core/vendor/composer/installed.php +2 -2
  20. package/src/backend/_core/vendor/graham-campbell/result-type/.gitattributes +9 -0
  21. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CODE_OF_CONDUCT.md +132 -0
  22. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CONTRIBUTING.md +31 -0
  23. package/src/backend/_core/vendor/graham-campbell/result-type/.github/FUNDING.yml +2 -0
  24. package/src/backend/_core/vendor/graham-campbell/result-type/.github/SECURITY.md +14 -0
  25. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/stale.yml +11 -0
  26. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/tests.yml +40 -0
  27. package/src/backend/_core/vendor/graham-campbell/result-type/CHANGELOG.md +53 -0
  28. package/src/backend/_core/vendor/graham-campbell/result-type/LICENSE +21 -21
  29. package/src/backend/_core/vendor/graham-campbell/result-type/README.md +42 -0
  30. package/src/backend/_core/vendor/graham-campbell/result-type/composer.json +33 -33
  31. package/src/backend/_core/vendor/graham-campbell/result-type/phpunit.xml.dist +13 -0
  32. package/src/backend/_core/vendor/graham-campbell/result-type/src/Error.php +121 -121
  33. package/src/backend/_core/vendor/graham-campbell/result-type/src/Result.php +69 -69
  34. package/src/backend/_core/vendor/graham-campbell/result-type/src/Success.php +120 -120
  35. package/src/backend/_core/vendor/graham-campbell/result-type/tests/ResultTest.php +95 -0
  36. package/src/backend/_core/vendor/phpoption/phpoption/.gitattributes +13 -0
  37. package/src/backend/_core/vendor/phpoption/phpoption/.github/CODE_OF_CONDUCT.md +132 -0
  38. package/src/backend/_core/vendor/phpoption/phpoption/.github/CONTRIBUTING.md +30 -0
  39. package/src/backend/_core/vendor/phpoption/phpoption/.github/FUNDING.yml +2 -0
  40. package/src/backend/_core/vendor/phpoption/phpoption/.github/SECURITY.md +14 -0
  41. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/static.yml +40 -0
  42. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/tests.yml +40 -0
  43. package/src/backend/_core/vendor/phpoption/phpoption/LICENSE +200 -200
  44. package/src/backend/_core/vendor/phpoption/phpoption/Makefile +17 -0
  45. package/src/backend/_core/vendor/phpoption/phpoption/README.md +201 -0
  46. package/src/backend/_core/vendor/phpoption/phpoption/composer.json +50 -50
  47. package/src/backend/_core/vendor/phpoption/phpoption/phpstan-baseline.neon +44 -0
  48. package/src/backend/_core/vendor/phpoption/phpoption/phpstan.neon.dist +7 -0
  49. package/src/backend/_core/vendor/phpoption/phpoption/phpunit.xml.dist +13 -0
  50. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +175 -175
  51. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/None.php +136 -136
  52. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Option.php +434 -434
  53. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Some.php +169 -169
  54. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/EnsureTest.php +72 -0
  55. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/LazyOptionTest.php +357 -0
  56. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/NoneTest.php +153 -0
  57. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/OptionTest.php +166 -0
  58. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/SomeTest.php +194 -0
  59. package/src/backend/_core/vendor/phpoption/phpoption/tests/bootstrap.php +8 -0
  60. package/src/backend/_core/vendor/phpoption/phpoption/vendor-bin/phpstan/composer.json +8 -0
  61. package/src/backend/_core/vendor/symfony/polyfill-ctype/Ctype.php +232 -232
  62. package/src/backend/_core/vendor/symfony/polyfill-ctype/LICENSE +19 -19
  63. package/src/backend/_core/vendor/symfony/polyfill-ctype/README.md +12 -12
  64. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap.php +50 -50
  65. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap80.php +46 -46
  66. package/src/backend/_core/vendor/symfony/polyfill-ctype/composer.json +38 -38
  67. package/src/backend/_core/vendor/symfony/polyfill-mbstring/LICENSE +19 -19
  68. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Mbstring.php +1077 -1077
  69. package/src/backend/_core/vendor/symfony/polyfill-mbstring/README.md +13 -13
  70. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +119 -119
  71. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -1397
  72. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -5
  73. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -1489
  74. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap.php +171 -171
  75. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap80.php +167 -167
  76. package/src/backend/_core/vendor/symfony/polyfill-mbstring/composer.json +39 -39
  77. package/src/backend/_core/vendor/symfony/polyfill-php80/LICENSE +19 -19
  78. package/src/backend/_core/vendor/symfony/polyfill-php80/Php80.php +115 -115
  79. package/src/backend/_core/vendor/symfony/polyfill-php80/PhpToken.php +106 -106
  80. package/src/backend/_core/vendor/symfony/polyfill-php80/README.md +25 -25
  81. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +31 -31
  82. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +16 -16
  83. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +20 -20
  84. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +16 -16
  85. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +16 -16
  86. package/src/backend/_core/vendor/symfony/polyfill-php80/bootstrap.php +42 -42
  87. package/src/backend/_core/vendor/symfony/polyfill-php80/composer.json +37 -37
  88. package/src/backend/_core/vendor/vlucas/phpdotenv/.editorconfig +15 -0
  89. package/src/backend/_core/vendor/vlucas/phpdotenv/.gitattributes +15 -0
  90. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CODE_OF_CONDUCT.md +132 -0
  91. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CONTRIBUTING.md +30 -0
  92. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/FUNDING.yml +2 -0
  93. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/SECURITY.md +14 -0
  94. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/static.yml +40 -0
  95. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/tests.yml +70 -0
  96. package/src/backend/_core/vendor/vlucas/phpdotenv/LICENSE +30 -30
  97. package/src/backend/_core/vendor/vlucas/phpdotenv/Makefile +17 -0
  98. package/src/backend/_core/vendor/vlucas/phpdotenv/README.md +370 -0
  99. package/src/backend/_core/vendor/vlucas/phpdotenv/UPGRADING.md +196 -0
  100. package/src/backend/_core/vendor/vlucas/phpdotenv/composer.json +60 -60
  101. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan-baseline.neon +157 -0
  102. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan.neon.dist +7 -0
  103. package/src/backend/_core/vendor/vlucas/phpdotenv/phpunit.xml.dist +13 -0
  104. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Dotenv.php +267 -267
  105. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +12 -12
  106. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php +12 -12
  107. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php +12 -12
  108. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php +12 -12
  109. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php +12 -12
  110. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Loader.php +48 -48
  111. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +20 -20
  112. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +65 -65
  113. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Entry.php +59 -59
  114. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +299 -299
  115. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +58 -58
  116. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lines.php +127 -127
  117. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Parser.php +53 -53
  118. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +19 -19
  119. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Value.php +88 -88
  120. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +15 -15
  121. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +89 -89
  122. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +80 -80
  123. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +88 -88
  124. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +85 -85
  125. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +110 -110
  126. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +48 -48
  127. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +64 -64
  128. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +91 -91
  129. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +17 -17
  130. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +104 -104
  131. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +88 -88
  132. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +27 -27
  133. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php +107 -107
  134. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +272 -272
  135. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +51 -51
  136. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Paths.php +44 -44
  137. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Reader.php +81 -81
  138. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/FileStore.php +72 -72
  139. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +141 -141
  140. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +17 -17
  141. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StringStore.php +37 -37
  142. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Regex.php +112 -112
  143. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Str.php +108 -108
  144. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Validator.php +207 -207
  145. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/DotenvTest.php +387 -0
  146. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Loader/LoaderTest.php +86 -0
  147. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/EntryParserTest.php +234 -0
  148. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LexerTest.php +40 -0
  149. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LinesTest.php +53 -0
  150. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/ParserTest.php +98 -0
  151. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ArrayAdapterTest.php +57 -0
  152. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/EnvConstAdapterTest.php +75 -0
  153. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/PutenvAdapterTest.php +52 -0
  154. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ServerConstAdapterTest.php +75 -0
  155. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/RepositoryTest.php +305 -0
  156. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Store/StoreTest.php +141 -0
  157. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/ValidatorTest.php +479 -0
  158. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/.env +5 -0
  159. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/assertions.env +18 -0
  160. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/booleans.env +33 -0
  161. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/commented.env +15 -0
  162. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/empty.env +1 -0
  163. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/example.env +1 -0
  164. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/exported.env +7 -0
  165. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/immutable.env +1 -0
  166. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/integers.env +17 -0
  167. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/large.env +2 -0
  168. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multibyte.env +3 -0
  169. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiline.env +14 -0
  170. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiple.env +4 -0
  171. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/mutable.env +1 -0
  172. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/nested.env +15 -0
  173. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/quoted.env +11 -0
  174. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/specialchars.env +8 -0
  175. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/unicodevarnames.env +2 -0
  176. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/utf8-with-bom-encoding.env +3 -0
  177. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/windows.env +1 -0
  178. package/src/backend/_core/vendor/vlucas/phpdotenv/vendor-bin/phpstan/composer.json +15 -0
  179. package/src/backend/api/protected/example-protected.php +1 -1
  180. package/src/backend/api/public/example-public.php +1 -1
  181. package/src/backend/config.php +19 -0
  182. package/src/backend/web.config +2 -5
  183. package/src/frontend/.htaccess +4 -1
  184. package/src/frontend/js/modules/exampleModule.js +7 -0
  185. package/src/frontend/js/pages/404.js +3 -11
  186. package/src/frontend/js/pages/homepage.js +3 -11
  187. package/src/frontend/ts/modules/exampleModule.ts +3 -0
  188. package/src/frontend/ts/pages/404.ts +13 -0
  189. package/src/frontend/ts/pages/homepage.ts +13 -0
  190. package/src/frontend/web.config +21 -30
  191. package/src/frontend/js/modules/forms/normalizePhoneNumber.js +0 -42
  192. package/src/frontend/js/modules/forms/textAreaAutoExpand.js +0 -38
  193. package/src/frontend/js/modules/notification.js +0 -39
package/.eleventy.js CHANGED
@@ -24,9 +24,6 @@ module.exports = function (eleventyConfig) {
24
24
  }
25
25
  }
26
26
 
27
- // =====================================================
28
- // SHORTCODE — Markdown file renderer
29
- // =====================================================
30
27
  const md = markdownIt({ html: true });
31
28
 
32
29
  eleventyConfig.addShortcode('mdFile', function(filePath) {
@@ -34,38 +31,21 @@ module.exports = function (eleventyConfig) {
34
31
  return md.render(content);
35
32
  });
36
33
 
37
- // =====================================================
38
- // SHORTCODE — Markdown css
39
- // =====================================================
40
34
  eleventyConfig.addPassthroughCopy({
41
35
  "node_modules/github-markdown-css/github-markdown-dark.css": "css/github-markdown-dark.css",
42
36
  "node_modules/github-markdown-css/github-markdown-light.css": "css/github-markdown-light.css",
43
37
  });
44
38
 
45
- // =====================================================
46
- // ESBUILD — Bundles and minifies JS files before build
47
- // =====================================================
48
- eleventyConfig.on("eleventy.before", async () => {
49
- const entryPoints = glob.sync("src/frontend/js/pages/*.js");
50
- await esbuild.build({
51
- entryPoints,
52
- bundle: true,
53
- outdir: `${OUTPUT_DIR}/js/pages`,
54
- minify: true,
55
- });
39
+ eleventyConfig.on("eleventy.before", () => {
56
40
  copyRecursiveSync("src/backend", `${OUTPUT_DIR}/backend`);
57
41
  });
58
42
 
59
- // =====================================================
60
- // PASSTHROUGH — Static files
61
- // =====================================================
62
43
  eleventyConfig.addPassthroughCopy("src/frontend/.htaccess");
63
44
  eleventyConfig.addPassthroughCopy("src/frontend/web.config");
64
45
  eleventyConfig.addPassthroughCopy("src/frontend/assets");
65
46
  eleventyConfig.addPassthroughCopy("src/frontend/robots.txt");
66
47
 
67
48
  eleventyConfig.addPassthroughCopy({
68
- // Bootstrap
69
49
  "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js": "js/bootstrap.bundle.min.js",
70
50
  "node_modules/bootstrap-icons/font/fonts": "css/fonts",
71
51
 
@@ -79,9 +59,6 @@ module.exports = function (eleventyConfig) {
79
59
  // Bulma — CSS only, no JS passthrough needed
80
60
  });
81
61
 
82
- // =====================================================
83
- // ELEVENTY IMAGE — Responsive images
84
- // =====================================================
85
62
  eleventyConfig.addShortcode("image", async function (src, alt) {
86
63
  let metadata = await Image(src, {
87
64
  widths: [320, 480, 720, 1280, 1920, 2048, 2560, 3840, 4096, 7680],
@@ -98,11 +75,12 @@ module.exports = function (eleventyConfig) {
98
75
  });
99
76
  });
100
77
 
101
- // =====================================================
102
- // WATCH & DIRECTORY CONFIG
103
- // =====================================================
104
78
  eleventyConfig.addWatchTarget("./src/frontend/scss");
105
79
 
80
+ eleventyConfig.setServerOptions({
81
+ watch: [`${OUTPUT_DIR}/js/**/*.js`]
82
+ });
83
+
106
84
  return {
107
85
  dir: {
108
86
  input: "src/frontend",
package/README.md CHANGED
@@ -12,7 +12,7 @@ Building a website from scratch involves a lot of moving parts: templating engin
12
12
  - 📁 **Scalable structure** — a clean, opinionated project layout that grows with your needs
13
13
  - 🌍 **Open source** — free to use, free to modify, free to share
14
14
 
15
- ![Version](https://img.shields.io/badge/version-2.0.15-blue)
15
+ ![Version](https://img.shields.io/badge/version-2.2.0-blue)
16
16
  ![License](https://img.shields.io/badge/license-Apache--2.0-blue)
17
17
  ![Eleventy](https://img.shields.io/badge/11ty-v3.1.2-black)
18
18
 
@@ -0,0 +1,28 @@
1
+ const esbuild = require("esbuild");
2
+ const glob = require("glob");
3
+ const path = require("path");
4
+ const pkg = require("../package.json");
5
+
6
+ const isWatch = process.argv.includes("--watch");
7
+ const outputDir = pkg.outputDir || "out";
8
+
9
+ const jsFiles = glob.sync("src/frontend/js/pages/*.js");
10
+ const tsFiles = glob.sync("src/frontend/ts/pages/*.ts");
11
+ const entryPoints = [...jsFiles, ...tsFiles];
12
+
13
+ if (entryPoints.length === 0) {
14
+ process.exit(0);
15
+ }
16
+
17
+ const options = {
18
+ entryPoints,
19
+ bundle: true,
20
+ outdir: path.join(outputDir, "js/pages"),
21
+ minify: !isWatch,
22
+ };
23
+
24
+ if (isWatch) {
25
+ esbuild.context(options).then(ctx => ctx.watch()).catch(() => process.exit(1));
26
+ } else {
27
+ esbuild.build(options).catch(() => process.exit(1));
28
+ }
@@ -1,24 +1,20 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
- const ELEVENTY_CONFIG = path.resolve(__dirname, '../.eleventy.js');
4
+ const PACKAGE_JSON = path.resolve(__dirname, '../package.json');
5
5
 
6
- const content = fs.readFileSync(ELEVENTY_CONFIG, 'utf-8');
7
- const match = content.match(/const OUTPUT_DIR\s*=\s*['"`]([^'"`]*)['"`]/);
6
+ const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf-8'));
8
7
 
9
- if (!match) {
10
- console.log('(!) OUTPUT_DIR not found in .eleventy.js');
8
+ if (!pkg.outputDir) {
9
+ console.log('(!) outputDir not found in package.json');
11
10
  process.exit(1);
12
11
  }
13
12
 
14
- const outputDir = match[1];
15
- const absPath = path.isAbsolute(outputDir)
16
- ? outputDir
17
- : path.resolve(__dirname, '..', outputDir);
13
+ const outputDir = path.resolve(__dirname, '..', pkg.outputDir);
18
14
 
19
- if (fs.existsSync(absPath)) {
20
- fs.rmSync(absPath, { recursive: true, force: true });
21
- console.log(`(✓) cleaned → ${absPath}`);
15
+ if (fs.existsSync(outputDir)) {
16
+ fs.rmSync(outputDir, { recursive: true, force: true });
17
+ console.log(`(✓) cleaned → ${outputDir}`);
22
18
  } else {
23
- console.log(`(i) nothing to clean → ${absPath}`);
19
+ console.log(`(i) nothing to clean → ${outputDir}`);
24
20
  }
@@ -2,20 +2,22 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
4
  const ELEVENTY_CONFIG = path.resolve(__dirname, '../../.eleventy.js');
5
- const PACKAGE_JSON = path.resolve(__dirname, '../../package.json');
5
+ const PACKAGE_JSON = path.resolve(__dirname, '../../package.json');
6
+ const TSCONFIG = path.resolve(__dirname, '../../tsconfig.json');
6
7
 
7
- // Regex to locate the OUTPUT_DIR declaration in .eleventy.js.
8
- // Extracted as a constant to avoid writing it by hand in multiple places.
9
8
  const OUTPUT_DIR_REGEX = /const OUTPUT_DIR\s*=\s*['"`]([^'"`]*)['"`]/;
10
9
 
11
10
  // --- Helpers ---
12
11
 
13
- // Reads OUTPUT_DIR value from a given file content string, or returns null
14
12
  function parseOutputDir(content) {
15
13
  const match = content.match(OUTPUT_DIR_REGEX);
16
14
  return match ? match[1] : null;
17
15
  }
18
16
 
17
+ function isTypeScriptProject() {
18
+ return fs.existsSync(TSCONFIG);
19
+ }
20
+
19
21
  // --- Updaters ---
20
22
 
21
23
  function updateEleventyConfig(newPath) {
@@ -39,35 +41,55 @@ function updateEleventyConfig(newPath) {
39
41
  function updatePackageJson(newPath) {
40
42
  const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf-8'));
41
43
 
42
- // Reconstruct all output-dependent scripts from scratch to avoid
43
- // partial string replacement bugs on the outdir flag
44
+ pkg.outputDir = newPath;
45
+
46
+ const usesTs = isTypeScriptProject();
47
+
44
48
  pkg.scripts['build:css'] = `sass src/frontend/scss:${newPath}/css --no-source-map --style=compressed --quiet`;
45
- pkg.scripts['build:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --minify`;
46
49
  pkg.scripts['serve:css'] = `sass --watch src/frontend/scss:${newPath}/css --no-source-map --quiet`;
47
- pkg.scripts['serve:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --watch`;
50
+
51
+ if (usesTs) {
52
+ pkg.scripts['build:js'] = `esbuild "src/frontend/ts/pages/*.ts" --bundle --outdir=${newPath}/js/pages --minify`;
53
+ pkg.scripts['serve:js'] = `esbuild "src/frontend/ts/pages/*.ts" --bundle --outdir=${newPath}/js/pages --watch`;
54
+ } else {
55
+ pkg.scripts['build:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --minify`;
56
+ pkg.scripts['serve:js'] = `esbuild "src/frontend/js/pages/*.js" --bundle --outdir=${newPath}/js/pages --watch`;
57
+ }
48
58
 
49
59
  fs.writeFileSync(PACKAGE_JSON, JSON.stringify(pkg, null, 2), 'utf-8');
50
60
  console.log(`(✓) package.json updated → ${newPath}`);
51
61
  return true;
52
62
  }
53
63
 
64
+ const TSCONFIG_OUTDIR_REGEX = /"outDir"\s*:\s*"[^"]*"/;
65
+
66
+ function updateTsConfig(newPath) {
67
+ if (!isTypeScriptProject()) return;
68
+
69
+ const content = fs.readFileSync(TSCONFIG, 'utf-8');
70
+ const updated = content.replace(TSCONFIG_OUTDIR_REGEX, `"outDir": "./${newPath}/ts"`);
71
+
72
+ if (content === updated) {
73
+ console.log('(!) outDir not found in tsconfig.json');
74
+ return;
75
+ }
76
+
77
+ fs.writeFileSync(TSCONFIG, updated, 'utf-8');
78
+ console.log(`(✓) tsconfig.json updated → ${newPath}/ts`);
79
+ }
80
+
54
81
  // --- Public API ---
55
82
 
56
83
  function updateOutputPath(newPath) {
57
84
  const trimmed = newPath.trim().replace(/\\/g, '/');
58
85
 
59
- // Normalize the path: bare "." becomes "out", everything else gets a
60
- // project-scoped suffix to avoid collisions
61
86
  const normalizedPath = trimmed === '.'
62
87
  ? 'out'
63
88
  : `${trimmed.replace(/\/$/, '')}/${path.basename(process.cwd())}-out`;
64
89
 
65
- // Read the config once and reuse it to get the old path —
66
- // avoids a second disk read inside updateEleventyConfig
67
90
  const eleventyContent = fs.readFileSync(ELEVENTY_CONFIG, 'utf-8');
68
91
  const oldPath = parseOutputDir(eleventyContent);
69
92
 
70
- // Delete the old output folder if it exists
71
93
  if (oldPath) {
72
94
  const oldAbsPath = path.resolve(__dirname, '../../', oldPath);
73
95
  if (fs.existsSync(oldAbsPath)) {
@@ -82,9 +104,9 @@ function updateOutputPath(newPath) {
82
104
 
83
105
  updatePackageJson(normalizedPath);
84
106
  updateEleventyConfig(normalizedPath);
107
+ updateTsConfig(normalizedPath);
85
108
  }
86
109
 
87
- // Returns the current OUTPUT_DIR value from .eleventy.js, or null on failure
88
110
  function getCurrentOutputPath() {
89
111
  try {
90
112
  const content = fs.readFileSync(ELEVENTY_CONFIG, 'utf-8');
@@ -7,16 +7,35 @@ const { getCurrentOutputPath } = require('./updateOutputPath');
7
7
  const { toCamelCase } = require('./utils');
8
8
 
9
9
  const TEMPLATES_DIR = path.join(__dirname, '..', 'res', 'templates');
10
+ const TSCONFIG = path.resolve(__dirname, '../../tsconfig.json');
10
11
 
11
12
  // --- Helpers ---
12
13
 
13
- // Returns the three file targets (scss, js, njk) for a given page name
14
+ function isTypeScriptProject() {
15
+ return fileSystem.existsSync(TSCONFIG);
16
+ }
17
+
18
+ // Returns the three file targets (scss, js/ts, njk) for a given page name
14
19
  function getPageTargets(pageName) {
15
20
  const camelName = toCamelCase(pageName);
21
+ const usesTs = isTypeScriptProject();
22
+
16
23
  return [
17
- { folder: 'src/frontend/scss/pages', templateFile: 'template.scss', fileName: `${camelName}.scss` },
18
- { folder: 'src/frontend/js/pages', templateFile: 'template.js', fileName: `${camelName}.js` },
19
- { folder: 'src/frontend/_routes', templateFile: 'template.njk', fileName: `${pageName}.njk` },
24
+ {
25
+ folder: 'src/frontend/scss/pages',
26
+ templateFile: 'template.scss',
27
+ fileName: `${camelName}.scss`,
28
+ },
29
+ {
30
+ folder: usesTs ? 'src/frontend/ts/pages' : 'src/frontend/js/pages',
31
+ templateFile: usesTs ? 'template.ts' : 'template.js',
32
+ fileName: usesTs ? `${camelName}.ts` : `${camelName}.js`,
33
+ },
34
+ {
35
+ folder: 'src/frontend/_routes',
36
+ templateFile: 'template.njk',
37
+ fileName: `${pageName}.njk`,
38
+ },
20
39
  ];
21
40
  }
22
41
 
@@ -34,7 +53,6 @@ function addPage(pageName) {
34
53
  const srcPath = path.join(TEMPLATES_DIR, templateFile);
35
54
 
36
55
  if (templateFile === 'template.njk') {
37
- // Patch the frontmatter placeholders with the actual page values
38
56
  const content = fileSystem.readFileSync(srcPath, 'utf8')
39
57
  .replace(/^title:.*$/m, `title: "${camelName}"`)
40
58
  .replace(/^permalink:.*$/m, `permalink: "/${pageName}/"`);
@@ -53,11 +71,13 @@ function addPage(pageName) {
53
71
  function renamePage(oldName, newName) {
54
72
  const oldCamel = toCamelCase(oldName);
55
73
  const newCamel = toCamelCase(newName);
74
+ const usesTs = isTypeScriptProject();
75
+ const ext = usesTs ? 'ts' : 'js';
76
+ const jsFolder = usesTs ? 'src/frontend/ts/pages' : 'src/frontend/js/pages';
56
77
 
57
- // Use consistent src/frontend/ paths (matching addPage)
58
78
  const filesToRename = [
59
79
  { src: `src/frontend/scss/pages/${oldCamel}.scss`, dest: `src/frontend/scss/pages/${newCamel}.scss` },
60
- { src: `src/frontend/js/pages/${oldCamel}.js`, dest: `src/frontend/js/pages/${newCamel}.js` },
80
+ { src: `${jsFolder}/${oldCamel}.${ext}`, dest: `${jsFolder}/${newCamel}.${ext}` },
61
81
  { src: `src/frontend/_routes/${oldName}.njk`, dest: `src/frontend/_routes/${newName}.njk` },
62
82
  ];
63
83
 
@@ -70,20 +90,20 @@ function renamePage(oldName, newName) {
70
90
  console.log(`[renamed] ${src} → ${dest}`);
71
91
  });
72
92
 
73
- // Use atomic rename helpers instead of remove + add separately
74
93
  renameLayout(oldName, newName);
75
94
  renameSiteData(oldName, newName);
76
95
  }
77
96
 
78
97
  function removePage(pageName) {
79
98
  const camelName = toCamelCase(pageName);
80
-
81
- // Read the actual current output dir instead of hardcoding "out"
99
+ const usesTs = isTypeScriptProject();
100
+ const ext = usesTs ? 'ts' : 'js';
101
+ const jsFolder = usesTs ? 'src/frontend/ts/pages' : 'src/frontend/js/pages';
82
102
  const OUTPUT_DIR = getCurrentOutputPath() || 'out';
83
103
 
84
104
  const filesToDelete = [
85
105
  `src/frontend/scss/pages/${camelName}.scss`,
86
- `src/frontend/js/pages/${camelName}.js`,
106
+ `${jsFolder}/${camelName}.${ext}`,
87
107
  `src/frontend/_routes/${pageName}.njk`,
88
108
  path.join(OUTPUT_DIR, 'js/pages', `${camelName}.js`),
89
109
  path.join(OUTPUT_DIR, 'css/pages', `${camelName}.css`),
@@ -2,20 +2,12 @@
2
2
  // JAVASCRIPT MODULES IMPORTS
3
3
  //===========================
4
4
 
5
- // Call anywhere
6
- import { showNotification } from '../modules/notification.js';
7
-
8
- // Uncomment of pre-existing modules
9
- // import { initTextAreaAutoExpand } from '../modules/forms/textAreaAutoExpand.js';
10
- // import { initNormalizePhoneNumber } from '../modules/forms/normalizePhoneNumber.js';
5
+ // import { initExampleModule } from '../modules/exampleModule.js';
11
6
 
12
7
  //==========================
13
8
  // PAGE CUSTOM JAVASCRIPT
14
9
  //==========================
15
10
 
16
11
  document.addEventListener("DOMContentLoaded", () => {
17
- // initTextAreaAutoExpand();
18
- // initNormalizePhoneNumber();
19
- });
20
-
21
- showNotification("Example notification", "success", 3000);
12
+ // initExampleModule();
13
+ });
@@ -0,0 +1,13 @@
1
+ //===========================
2
+ // TYPESCRIPT MODULES IMPORTS
3
+ //===========================
4
+
5
+ // import { initExampleModule } from '../modules/exampleModule';
6
+
7
+ //==========================
8
+ // PAGE CUSTOM TYPESCRIPT
9
+ //==========================
10
+
11
+ document.addEventListener("DOMContentLoaded", (): void => {
12
+ // initExampleModule();
13
+ });