elm-pages 3.0.0-beta.3 → 3.0.0-beta.31

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 (129) hide show
  1. package/README.md +10 -1
  2. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16458 -13724
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  14. package/generator/dead-code-review/elm.json +9 -7
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  23. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  24. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  25. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  26. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +24542 -21748
  27. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  28. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  29. package/generator/review/elm.json +10 -10
  30. package/generator/src/RouteBuilder.elm +113 -107
  31. package/generator/src/SharedTemplate.elm +3 -2
  32. package/generator/src/SiteConfig.elm +3 -2
  33. package/generator/src/basepath-middleware.js +3 -3
  34. package/generator/src/build.js +125 -88
  35. package/generator/src/cli.js +273 -88
  36. package/generator/src/codegen.js +29 -27
  37. package/generator/src/compatibility-key.js +3 -0
  38. package/generator/src/compile-elm.js +43 -26
  39. package/generator/src/config.js +39 -0
  40. package/generator/src/copy-dir.js +2 -2
  41. package/generator/src/dev-server.js +150 -133
  42. package/generator/src/dir-helpers.js +9 -26
  43. package/generator/src/elm-codegen.js +5 -4
  44. package/generator/src/elm-file-constants.js +2 -3
  45. package/generator/src/error-formatter.js +12 -11
  46. package/generator/src/file-helpers.js +3 -4
  47. package/generator/src/generate-template-module-connector.js +23 -22
  48. package/generator/src/init.js +9 -8
  49. package/generator/src/pre-render-html.js +39 -28
  50. package/generator/src/render-test.js +109 -0
  51. package/generator/src/render-worker.js +25 -28
  52. package/generator/src/render.js +320 -142
  53. package/generator/src/request-cache.js +252 -163
  54. package/generator/src/resolve-elm-module.js +63 -0
  55. package/generator/src/rewrite-client-elm-json.js +6 -5
  56. package/generator/src/rewrite-elm-json-help.js +56 -0
  57. package/generator/src/rewrite-elm-json.js +17 -7
  58. package/generator/src/route-codegen-helpers.js +16 -31
  59. package/generator/src/seo-renderer.js +12 -7
  60. package/generator/src/vite-utils.js +77 -0
  61. package/generator/static-code/hmr.js +79 -13
  62. package/generator/template/app/Api.elm +6 -5
  63. package/generator/template/app/Effect.elm +123 -0
  64. package/generator/template/app/ErrorPage.elm +37 -6
  65. package/generator/template/app/Route/Index.elm +17 -10
  66. package/generator/template/app/Shared.elm +24 -47
  67. package/generator/template/app/Site.elm +19 -6
  68. package/generator/template/app/View.elm +1 -8
  69. package/generator/template/elm-tooling.json +0 -3
  70. package/generator/template/elm.json +32 -24
  71. package/generator/template/package.json +10 -4
  72. package/package.json +29 -27
  73. package/src/ApiRoute.elm +199 -61
  74. package/src/BackendTask/Custom.elm +325 -0
  75. package/src/BackendTask/Env.elm +90 -0
  76. package/src/{DataSource → BackendTask}/File.elm +128 -43
  77. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  78. package/src/BackendTask/Http.elm +673 -0
  79. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  80. package/src/BackendTask/Internal/Request.elm +28 -0
  81. package/src/BackendTask/Random.elm +79 -0
  82. package/src/BackendTask/Time.elm +47 -0
  83. package/src/BackendTask.elm +537 -0
  84. package/src/FatalError.elm +89 -0
  85. package/src/Form/Field.elm +21 -9
  86. package/src/Form/FieldView.elm +94 -14
  87. package/src/Form.elm +275 -400
  88. package/src/Head.elm +237 -7
  89. package/src/HtmlPrinter.elm +7 -3
  90. package/src/Internal/ApiRoute.elm +7 -5
  91. package/src/PageServerResponse.elm +6 -1
  92. package/src/Pages/FormState.elm +6 -5
  93. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  94. package/src/Pages/Internal/FatalError.elm +5 -0
  95. package/src/Pages/Internal/Form.elm +21 -1
  96. package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
  97. package/src/Pages/Internal/Platform/Cli.elm +598 -763
  98. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  99. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  100. package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
  101. package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
  102. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
  103. package/src/Pages/Internal/Platform.elm +216 -102
  104. package/src/Pages/Internal/Script.elm +17 -0
  105. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  106. package/src/Pages/Manifest.elm +29 -4
  107. package/src/Pages/PageUrl.elm +23 -9
  108. package/src/Pages/ProgramConfig.elm +14 -10
  109. package/src/Pages/Script.elm +109 -0
  110. package/src/Pages/SiteConfig.elm +3 -2
  111. package/src/Pages/StaticHttp/Request.elm +2 -2
  112. package/src/Pages/StaticHttpRequest.elm +23 -98
  113. package/src/PagesMsg.elm +92 -0
  114. package/src/Path.elm +16 -19
  115. package/src/QueryParams.elm +21 -172
  116. package/src/RequestsAndPending.elm +8 -19
  117. package/src/Result/Extra.elm +26 -0
  118. package/src/Scaffold/Form.elm +560 -0
  119. package/src/Scaffold/Route.elm +1388 -0
  120. package/src/Server/Request.elm +43 -37
  121. package/src/Server/Session.elm +62 -42
  122. package/src/Server/SetCookie.elm +12 -4
  123. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  124. package/src/DataSource/Env.elm +0 -38
  125. package/src/DataSource/Http.elm +0 -446
  126. package/src/DataSource/Internal/Request.elm +0 -20
  127. package/src/DataSource/Port.elm +0 -90
  128. package/src/DataSource.elm +0 -538
  129. package/src/Pages/Generate.elm +0 -800
@@ -1,5 +1,5 @@
1
- const util = require("util");
2
- const fsSync = require("fs");
1
+ const util = require("node:util");
2
+ const fsSync = require("node:fs");
3
3
  const fs = {
4
4
  writeFile: util.promisify(fsSync.writeFile),
5
5
  mkdir: util.promisify(fsSync.mkdir),
@@ -1,36 +1,78 @@
1
- const path = require("path");
2
- const fs = require("fs");
3
- const which = require("which");
4
- const chokidar = require("chokidar");
5
- const { URL } = require("url");
6
- const {
1
+ import * as path from "path";
2
+ import * as fs from "fs";
3
+ import { default as which } from "which";
4
+ import * as chokidar from "chokidar";
5
+ import { URL } from "url";
6
+ import {
7
7
  compileElmForBrowser,
8
8
  runElmReview,
9
9
  compileCliApp,
10
- } = require("./compile-elm.js");
11
- const http = require("http");
12
- const https = require("https");
13
- const codegen = require("./codegen.js");
14
- const kleur = require("kleur");
15
- const serveStatic = require("serve-static");
16
- const connect = require("connect");
17
- const { restoreColorSafe } = require("./error-formatter");
18
- const { Worker, SHARE_ENV } = require("worker_threads");
19
- const os = require("os");
20
- const { ensureDirSync } = require("./file-helpers.js");
21
- const baseMiddleware = require("./basepath-middleware.js");
22
- const devcert = require("devcert");
23
- const busboy = require("busboy");
24
- const { createServer: createViteServer } = require("vite");
25
- const cliVersion = require("../../package.json").version;
26
- const esbuild = require("esbuild");
10
+ } from "./compile-elm.js";
11
+ import * as http from "http";
12
+ import * as https from "https";
13
+ import * as codegen from "./codegen.js";
14
+ import * as kleur from "kleur/colors";
15
+ import { default as serveStatic } from "serve-static";
16
+ import { default as connect } from "connect";
17
+ import { restoreColorSafe } from "./error-formatter.js";
18
+ import { Worker, SHARE_ENV } from "worker_threads";
19
+ import * as os from "os";
20
+ import { ensureDirSync } from "./file-helpers.js";
21
+ import { baseMiddleware } from "./basepath-middleware.js";
22
+ import * as devcert from "devcert";
23
+ import * as busboy from "busboy";
24
+ import { createServer as createViteServer } from "vite";
25
+ import * as esbuild from "esbuild";
26
+ import { merge_vite_configs } from "./vite-utils.js";
27
+ import { templateHtml } from "./pre-render-html.js";
28
+ import { resolveConfig } from "./config.js";
29
+ import * as globby from "globby";
30
+ import { fileURLToPath } from "url";
31
+
32
+ const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = path.dirname(__filename);
27
34
 
28
35
  /**
29
36
  * @param {{ port: string; base: string; https: boolean; debug: boolean; }} options
30
37
  */
31
- async function start(options) {
38
+ export async function start(options) {
32
39
  let threadReadyQueue = [];
33
40
  let pool = [];
41
+
42
+ function invalidatePool() {
43
+ pool.forEach((thread) => {
44
+ if (thread.used) {
45
+ thread.stale = true;
46
+ }
47
+ });
48
+ restartIdleWorkersIfStale();
49
+ }
50
+
51
+ function restartIdleWorkersIfStale() {
52
+ pool.forEach((thread) => {
53
+ if (thread.stale && thread.ready) {
54
+ reinitThread(thread);
55
+ }
56
+ });
57
+ }
58
+
59
+ function reinitThread(thisThread) {
60
+ thisThread.worker && thisThread.worker.terminate();
61
+ // TODO remove event listeners to avoid memory leak?
62
+ // thread.worker.removeAllListeners("message");
63
+ // thread.worker.removeAllListeners("error");
64
+ thisThread.ready = false;
65
+ thisThread.stale = false;
66
+ thisThread.used = false;
67
+ thisThread.worker = new Worker(path.join(__dirname, "./render-worker.js"), {
68
+ env: SHARE_ENV,
69
+ workerData: { basePath: options.base },
70
+ });
71
+ thisThread.worker.once("online", () => {
72
+ thisThread.ready = true;
73
+ });
74
+ }
75
+
34
76
  ensureDirSync(path.join(process.cwd(), ".elm-pages", "http-response-cache"));
35
77
  const cpuCount = os.cpus().length;
36
78
 
@@ -42,6 +84,7 @@ async function start(options) {
42
84
  const serveCachedFiles = serveStatic(".elm-pages/cache", { index: false });
43
85
  const generatedFilesDirectory = "elm-stuff/elm-pages/generated-files";
44
86
  fs.mkdirSync(generatedFilesDirectory, { recursive: true });
87
+
45
88
  const serveStaticCode = serveStatic(
46
89
  path.join(__dirname, "../static-code"),
47
90
  {}
@@ -117,63 +160,79 @@ async function start(options) {
117
160
  watcher.add(sourceDirs);
118
161
  }
119
162
 
120
- const viteConfig = await import(
121
- path.join(process.cwd(), "elm-pages.config.mjs")
122
- )
123
- .then(async (elmPagesConfig) => {
124
- return elmPagesConfig.default.vite || {};
125
- })
126
- .catch((error) => {
127
- console.warn(
128
- kleur.yellow(
129
- "No `elm-pages.config.mjs` file found. Using default config."
130
- )
131
- );
132
- return {};
133
- });
134
- const vite = await createViteServer({
135
- server: { middlewareMode: "ssr", base: options.base, port: options.port },
136
- configFile: false,
137
- root: process.cwd(),
138
- base: options.base,
139
- ...viteConfig,
140
- });
141
- esbuild
142
- .build({
143
- entryPoints: ["./port-data-source"],
144
- platform: "node",
145
- assetNames: "[name]-[hash]",
146
- chunkNames: "chunks/[name]-[hash]",
147
- outExtension: { ".js": ".js" },
148
- metafile: true,
149
- bundle: true,
150
- watch: true,
151
- logLevel: "error",
152
-
153
- outdir: ".elm-pages/compiled-ports",
154
- entryNames: "[dir]/[name]-[hash]",
155
-
156
- plugins: [
157
- {
158
- name: "example",
159
- setup(build) {
160
- build.onEnd((result) => {
163
+ const config = await resolveConfig();
164
+ const vite = await createViteServer(
165
+ merge_vite_configs(
166
+ {
167
+ server: {
168
+ middlewareMode: true,
169
+ base: options.base,
170
+ port: options.port,
171
+ },
172
+ appType: "custom",
173
+ configFile: false,
174
+ root: process.cwd(),
175
+ base: options.base,
176
+ },
177
+
178
+ config.vite
179
+ )
180
+ );
181
+
182
+ const ctx = await esbuild.context({
183
+ entryPoints: ["./custom-backend-task"],
184
+ platform: "node",
185
+ assetNames: "[name]-[hash]",
186
+ chunkNames: "chunks/[name]-[hash]",
187
+ outExtension: { ".js": ".mjs" },
188
+ format: "esm",
189
+ metafile: true,
190
+ bundle: true,
191
+ packages: "external",
192
+ logLevel: "silent",
193
+ outdir: ".elm-pages/compiled-ports",
194
+ entryNames: "[dir]/[name]-[hash]",
195
+
196
+ plugins: [
197
+ {
198
+ name: "example",
199
+ setup(build) {
200
+ build.onEnd(async (result) => {
201
+ try {
161
202
  global.portsFilePath = Object.keys(result.metafile.outputs)[0];
162
203
 
163
204
  clients.forEach((client) => {
164
205
  client.response.write(`data: content.dat\n\n`);
165
206
  });
166
- });
167
- },
207
+ } catch (e) {
208
+ const portBackendTaskFileFound =
209
+ globby.globbySync("./custom-backend-task.*").length > 0;
210
+ if (portBackendTaskFileFound) {
211
+ // don't present error if there are no files matching custom-backend-task
212
+ // if there are files matching custom-backend-task, warn the user in case something went wrong loading it
213
+ const messages = (
214
+ await esbuild.formatMessages(result.errors, {
215
+ kind: "error",
216
+ color: true,
217
+ })
218
+ ).join("\n");
219
+ global.portsFilePath = {
220
+ __internalElmPagesError: messages,
221
+ };
222
+
223
+ clients.forEach((client) => {
224
+ client.response.write(`data: content.dat\n\n`);
225
+ });
226
+ } else {
227
+ global.portsFilePath = null;
228
+ }
229
+ }
230
+ });
168
231
  },
169
- ],
170
- })
171
- .then((result) => {
172
- console.log("Watching port-data-source...");
173
- })
174
- .catch((error) => {
175
- console.error("Failed to start port-data-source watcher", error);
176
- });
232
+ },
233
+ ],
234
+ });
235
+ await ctx.watch();
177
236
 
178
237
  const app = connect()
179
238
  .use(timeMiddleware())
@@ -206,33 +265,19 @@ async function start(options) {
206
265
  watcher.on("all", async function (eventName, pathThatChanged) {
207
266
  if (pathThatChanged === "elm.json") {
208
267
  watchElmSourceDirs(false);
268
+ } else if (
269
+ pathThatChanged.startsWith("app/Route") &&
270
+ !pathThatChanged.endsWith(".elm")
271
+ ) {
272
+ // this happens when a folder is created in app/Route. Ignore this case.
209
273
  } else if (pathThatChanged.endsWith(".elm")) {
274
+ invalidatePool();
210
275
  if (elmMakeRunning) {
211
276
  } else {
212
277
  let codegenError = null;
213
278
  if (needToRerunCodegen(eventName, pathThatChanged)) {
214
279
  try {
215
280
  await codegen.generate(options.base);
216
- clientElmMakeProcess = compileElmForBrowser(options);
217
- pendingCliCompile = compileCliApp(
218
- options,
219
- ".elm-pages/Main.elm",
220
- path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
221
- // "elm.js",
222
- "elm-stuff/elm-pages/",
223
- path.join("elm-stuff/elm-pages/", "elm.js")
224
- );
225
-
226
- Promise.all([clientElmMakeProcess, pendingCliCompile])
227
- .then(() => {
228
- elmMakeRunning = false;
229
- })
230
- .catch(() => {
231
- elmMakeRunning = false;
232
- });
233
- clients.forEach((client) => {
234
- client.response.write(`data: elm.js\n\n`);
235
- });
236
281
  } catch (error) {
237
282
  codegenError = error;
238
283
  }
@@ -250,10 +295,7 @@ async function start(options) {
250
295
  pendingCliCompile = compileCliApp(
251
296
  options,
252
297
  ".elm-pages/Main.elm",
253
-
254
298
  path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
255
-
256
- // "elm.js",
257
299
  "elm-stuff/elm-pages/",
258
300
  path.join("elm-stuff/elm-pages/", "elm.js")
259
301
  );
@@ -274,18 +316,18 @@ async function start(options) {
274
316
  // TODO use similar logic in the workers? Or don't use cache at all?
275
317
  // const changedPathRelative = path.relative(process.cwd(), pathThatChanged);
276
318
  //
277
- // Object.keys(global.staticHttpCache).forEach((dataSourceKey) => {
278
- // if (dataSourceKey.includes(`file://${changedPathRelative}`)) {
279
- // delete global.staticHttpCache[dataSourceKey];
319
+ // Object.keys(global.staticHttpCache).forEach((backendTaskKey) => {
320
+ // if (backendTaskKey.includes(`file://${changedPathRelative}`)) {
321
+ // delete global.staticHttpCache[backendTaskKey];
280
322
  // } else if (
281
323
  // (eventName === "add" ||
282
324
  // eventName === "unlink" ||
283
325
  // eventName === "change" ||
284
326
  // eventName === "addDir" ||
285
327
  // eventName === "unlinkDir") &&
286
- // dataSourceKey.startsWith("glob://")
328
+ // backendTaskKey.startsWith("glob://")
287
329
  // ) {
288
- // delete global.staticHttpCache[dataSourceKey];
330
+ // delete global.staticHttpCache[backendTaskKey];
289
331
  // }
290
332
  // });
291
333
  clients.forEach((client) => {
@@ -336,6 +378,8 @@ async function start(options) {
336
378
  };
337
379
 
338
380
  readyThread.ready = false;
381
+ await pendingCliCompile;
382
+ readyThread.used = true;
339
383
  readyThread.worker.postMessage({
340
384
  mode: "dev-server",
341
385
  pathname,
@@ -459,35 +503,7 @@ async function start(options) {
459
503
  }
460
504
  case "html": {
461
505
  try {
462
- const template =
463
- /*html*/
464
- `<!DOCTYPE html>
465
- <!-- ROOT --><html lang="en">
466
- <head>
467
- <script src="/hmr.js" type="text/javascript"></script>
468
- <script src="/elm.js" type="text/javascript"></script>
469
- <link rel="stylesheet" href="/style.css">
470
- <link rel="stylesheet" href="/dev-style.css">
471
- <script src="/elm-pages.js" type="module"></script>
472
- <meta charset="UTF-8" />
473
- <meta name="viewport" content="width=device-width,initial-scale=1" />
474
- <title><!-- PLACEHOLDER_TITLE --></title>
475
- <meta name="generator" content="elm-pages v${cliVersion}" />
476
- <meta name="mobile-web-app-capable" content="yes" />
477
- <meta name="theme-color" content="#ffffff" />
478
- <meta name="apple-mobile-web-app-capable" content="yes" />
479
- <meta
480
- name="apple-mobile-web-app-status-bar-style"
481
- content="black-translucent"
482
- />
483
- <!-- PLACEHOLDER_HEAD_AND_DATA -->
484
- </head>
485
- <body>
486
- <div data-url="" display="none"></div>
487
- <!-- PLACEHOLDER_HTML -->
488
- </body>
489
- </html>
490
- `;
506
+ const template = templateHtml(true, config.headTagsTemplate);
491
507
  const processedTemplate = await vite.transformIndexHtml(
492
508
  req.originalUrl,
493
509
  template
@@ -610,6 +626,7 @@ async function start(options) {
610
626
  }
611
627
 
612
628
  function runPendingWork() {
629
+ restartIdleWorkersIfStale();
613
630
  const readyThreads = pool.filter((thread) => thread.ready);
614
631
  readyThreads.forEach((readyThread) => {
615
632
  const startTask = threadReadyQueue.shift();
@@ -634,6 +651,7 @@ async function start(options) {
634
651
  workerData: { basePath },
635
652
  }),
636
653
  ready: false,
654
+ used: false,
637
655
  };
638
656
  newWorker.worker.once("online", () => {
639
657
  newWorker.ready = true;
@@ -804,4 +822,3 @@ function paramsToObject(entries) {
804
822
  }
805
823
  return result;
806
824
  }
807
- module.exports = { start };
@@ -1,5 +1,7 @@
1
- const util = require("util");
2
- const fsSync = require("fs");
1
+ import * as util from "node:util";
2
+ import * as fsSync from "node:fs";
3
+ import * as path from "node:path";
4
+
3
5
  const fs = {
4
6
  writeFile: util.promisify(fsSync.writeFile),
5
7
  writeFileSync: fsSync.writeFileSync,
@@ -15,14 +17,14 @@ const fs = {
15
17
  /**
16
18
  * @param {import("fs").PathLike} dirName
17
19
  */
18
- async function tryMkdir(dirName) {
20
+ export async function tryMkdir(dirName) {
19
21
  const exists = await fs.exists(dirName);
20
22
  if (!exists) {
21
23
  await fs.mkdir(dirName, { recursive: true });
22
24
  }
23
25
  }
24
26
 
25
- function fileExists(file) {
27
+ export function fileExists(file) {
26
28
  return fsSync.promises
27
29
  .access(file, fsSync.constants.F_OK)
28
30
  .then(() => true)
@@ -33,18 +35,16 @@ function fileExists(file) {
33
35
  * @param {string} filePath
34
36
  * @param {string} data
35
37
  */
36
- function writeFileSyncSafe(filePath, data) {
38
+ export function writeFileSyncSafe(filePath, data) {
37
39
  fsSync.mkdirSync(path.dirname(filePath), { recursive: true });
38
40
  fs.writeFileSync(filePath, data);
39
41
  }
40
42
 
41
- const path = require("path");
42
-
43
43
  /**
44
44
  * @param {string} srcDirectory
45
45
  * @param {string} destDir
46
46
  */
47
- async function copyDirFlat(srcDirectory, destDir) {
47
+ export async function copyDirFlat(srcDirectory, destDir) {
48
48
  const items = await fs.readdir(srcDirectory);
49
49
  items.forEach(function (childItemName) {
50
50
  copyDirNested(
@@ -58,7 +58,7 @@ async function copyDirFlat(srcDirectory, destDir) {
58
58
  * @param {string} src
59
59
  * @param {string} dest
60
60
  */
61
- async function copyDirNested(src, dest) {
61
+ export async function copyDirNested(src, dest) {
62
62
  var exists = fsSync.existsSync(src);
63
63
  var stats = exists && fsSync.statSync(src);
64
64
  var isDirectory = exists && stats.isDirectory();
@@ -75,20 +75,3 @@ async function copyDirNested(src, dest) {
75
75
  fs.copyFile(src, dest);
76
76
  }
77
77
  }
78
-
79
- module.exports = {
80
- writeFile: fs.writeFile,
81
- writeFileSync: fs.writeFileSync,
82
- readFile: fs.readFile,
83
- readFileSync: fsSync.readFileSync,
84
- copyFile: fs.copyFile,
85
- exists: fs.exists,
86
- writeFileSyncSafe,
87
- tryMkdir,
88
- copyDirFlat,
89
- copyDirNested,
90
- rmSync: fs.rm,
91
- rm: fs.rm,
92
- existsSync: fs.existsSync,
93
- fileExists: fileExists,
94
- };
@@ -1,6 +1,6 @@
1
- const spawnCallback = require("cross-spawn").spawn;
1
+ import { spawn as spawnCallback } from "cross-spawn";
2
2
 
3
- function runElmCodegenInstall() {
3
+ export function runElmCodegenInstall() {
4
4
  return new Promise(async (resolve, reject) => {
5
5
  const subprocess = spawnCallback(`elm-codegen`, ["install"], {
6
6
  // ignore stdout
@@ -17,6 +17,9 @@ function runElmCodegenInstall() {
17
17
  subprocess.stderr.on("data", function (data) {
18
18
  commandOutput += data;
19
19
  });
20
+ subprocess.stdout.on("data", function (data) {
21
+ commandOutput += data;
22
+ });
20
23
  subprocess.on("error", function () {
21
24
  reject(commandOutput);
22
25
  });
@@ -30,5 +33,3 @@ function runElmCodegenInstall() {
30
33
  });
31
34
  });
32
35
  }
33
-
34
- module.exports = { runElmCodegenInstall };
@@ -1,4 +1,4 @@
1
- function elmPagesUiFile() {
1
+ export function elmPagesUiFile() {
2
2
  return `module Pages exposing (builtAt)
3
3
 
4
4
  import Time
@@ -12,7 +12,6 @@ builtAt =
12
12
  `;
13
13
  }
14
14
 
15
- function elmPagesCliFile() {
15
+ export function elmPagesCliFile() {
16
16
  return elmPagesUiFile();
17
17
  }
18
- module.exports = { elmPagesUiFile, elmPagesCliFile };
@@ -1,4 +1,6 @@
1
- const kleur = require("kleur");
1
+ "use strict";
2
+
3
+ import * as kleur from "kleur/colors";
2
4
 
3
5
  /* Thanks to elm-live for this code!
4
6
  https://github.com/wking-io/elm-live/blob/e317b4914c471addea7243c47f28dcebe27a5d36/lib/src/build.js#L65
@@ -13,11 +15,12 @@ const kleur = require("kleur");
13
15
  * @param {string} rule
14
16
  * @param {string} path
15
17
  * */
16
- const parseHeader = (rule, path) =>
17
- kleur.cyan(
18
- `-- ${rule.replace("-", " ")} --------------- ${path || ""}
18
+ function parseHeader(rule, path) {
19
+ return kleur.cyan(
20
+ `-- ${(rule || "").replace("-", " ")} --------------- ${path || ""}
19
21
  `
20
22
  );
23
+ }
21
24
 
22
25
  /**
23
26
  * parseMsg :: String|Object -> String
@@ -55,9 +58,6 @@ function toKleurColor(color) {
55
58
  case "33BBC8": {
56
59
  return "cyan";
57
60
  }
58
- case "33BBC8": {
59
- return "cyan";
60
- }
61
61
  case "FFFF00": {
62
62
  return "yellow";
63
63
  }
@@ -81,7 +81,7 @@ function toKleurColor(color) {
81
81
  /**
82
82
  * @param {RootObject} error
83
83
  * */
84
- const restoreColor = (error) => {
84
+ export const restoreColor = (error) => {
85
85
  try {
86
86
  if (error.type === "compile-errors") {
87
87
  return error.errors
@@ -110,7 +110,7 @@ const restoreColor = (error) => {
110
110
  * @param {string} error
111
111
  * @returns {string}
112
112
  */
113
- function restoreColorSafe(error) {
113
+ export function restoreColorSafe(error) {
114
114
  try {
115
115
  if (typeof error === "string") {
116
116
  const asJson = JSON.parse(error);
@@ -137,7 +137,10 @@ const restoreProblem =
137
137
  parseHeader(info.rule, path),
138
138
  ...info.formatted.map(parseMsg),
139
139
  ].join("");
140
+ } else if (typeof info.message === "string") {
141
+ return info.message;
140
142
  } else {
143
+ // console.log("info.message", info.message);
141
144
  return [
142
145
  parseHeader(info.title, path),
143
146
  ...info.message.map(parseMsg),
@@ -145,8 +148,6 @@ const restoreProblem =
145
148
  }
146
149
  };
147
150
 
148
- module.exports = { restoreColor, restoreColorSafe };
149
-
150
151
  /** @typedef { CompilerError | ReportError | IElmReviewError } RootObject */
151
152
 
152
153
  /** @typedef { { type: "compile-errors"; errors: Error_[]; } } CompilerError */
@@ -1,7 +1,6 @@
1
- const fs = require("fs");
2
- module.exports = { ensureDirSync, deleteIfExists };
1
+ import * as fs from "node:fs";
3
2
 
4
- function ensureDirSync(dirpath) {
3
+ export function ensureDirSync(dirpath) {
5
4
  try {
6
5
  fs.mkdirSync(dirpath, { recursive: true });
7
6
  } catch (err) {
@@ -9,7 +8,7 @@ function ensureDirSync(dirpath) {
9
8
  }
10
9
  }
11
10
 
12
- function deleteIfExists(/** @type string */ filePath) {
11
+ export function deleteIfExists(/** @type string */ filePath) {
13
12
  if (fs.existsSync(filePath)) {
14
13
  fs.unlinkSync(filePath);
15
14
  }
@@ -1,24 +1,25 @@
1
- const globby = require("globby");
2
- const path = require("path");
3
- const mm = require("micromatch");
4
- const routeHelpers = require("./route-codegen-helpers");
5
- const { runElmCodegenInstall } = require("./elm-codegen");
6
- const { compileCliApp } = require("./compile-elm");
7
- const { restoreColorSafe } = require("./error-formatter");
1
+ import * as globby from "globby";
2
+ import * as path from "path";
3
+ import { default as mm } from "micromatch";
4
+ import * as routeHelpers from "./route-codegen-helpers.js";
5
+ import { restoreColorSafe } from "./error-formatter.js";
6
+ import { fileURLToPath } from "url";
8
7
 
9
8
  /**
10
9
  * @param {string} basePath
11
10
  * @param {'browser' | 'cli'} phase
12
11
  */
13
- async function generateTemplateModuleConnector(basePath, phase) {
14
- const templates = globby.sync(["app/Route/**/*.elm"], {}).map((file) => {
15
- const captures = mm.capture("app/Route/**/*.elm", file);
16
- if (captures) {
17
- return path.join(captures[0], captures[1]).split(path.sep);
18
- } else {
19
- return [];
20
- }
21
- });
12
+ export async function generateTemplateModuleConnector(basePath, phase) {
13
+ const templates = globby
14
+ .globbySync(["app/Route/**/*.elm"], {})
15
+ .map((file) => {
16
+ const captures = mm.capture("app/Route/**/*.elm", file);
17
+ if (captures) {
18
+ return path.join(captures[0], captures[1]).split(path.sep);
19
+ } else {
20
+ return [];
21
+ }
22
+ });
22
23
  if (templates.length <= 0) {
23
24
  throw {
24
25
  path: "",
@@ -63,10 +64,12 @@ async function generateTemplateModuleConnector(basePath, phase) {
63
64
  }
64
65
 
65
66
  async function runElmCodegenCli(templates, basePath, phase) {
66
- const filePath = path.join(__dirname, `../../codegen/elm-pages-codegen.js`);
67
+ const __filename = fileURLToPath(import.meta.url);
68
+ const __dirname = path.dirname(__filename);
69
+ const filePath = path.join(__dirname, `../../codegen/elm-pages-codegen.cjs`);
67
70
 
68
- const promise = new Promise((resolve, reject) => {
69
- const elmPagesCodegen = require(filePath).Elm.Generate;
71
+ const promise = new Promise(async (resolve, reject) => {
72
+ const elmPagesCodegen = (await import(filePath)).default.Elm.Generate;
70
73
 
71
74
  const app = elmPagesCodegen.init({
72
75
  flags: { templates: templates, basePath, phase },
@@ -91,7 +94,7 @@ async function runElmCodegenCli(templates, basePath, phase) {
91
94
  * @param {string[][]} templates
92
95
  * @returns
93
96
  */
94
- function sortTemplates(templates) {
97
+ export function sortTemplates(templates) {
95
98
  return templates.sort((first, second) => {
96
99
  const a = sortScore(first);
97
100
  const b = sortScore(second);
@@ -230,5 +233,3 @@ submit toMsg options =
230
233
  function camelToKebab(input) {
231
234
  return input.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
232
235
  }
233
-
234
- module.exports = { generateTemplateModuleConnector, sortTemplates };