elm-pages 3.0.0-beta.1 → 3.0.0-beta.12

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 (103) hide show
  1. package/README.md +10 -1
  2. package/codegen/elm-pages-codegen.js +803 -284
  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 +1326 -121
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15368 -13272
  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 +1 -1
  14. package/generator/dead-code-review/elm.json +6 -5
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +141 -17
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +218 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
  22. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14574 -12631
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  24. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  25. package/generator/review/elm.json +6 -6
  26. package/generator/src/SharedTemplate.elm +1 -1
  27. package/generator/src/build.js +81 -51
  28. package/generator/src/cli.js +120 -42
  29. package/generator/src/codegen.js +11 -10
  30. package/generator/src/compatibility-key.js +1 -0
  31. package/generator/src/config.js +41 -0
  32. package/generator/src/dev-server.js +36 -56
  33. package/generator/src/elm-codegen.js +3 -0
  34. package/generator/src/generate-template-module-connector.js +0 -28
  35. package/generator/src/pre-render-html.js +31 -17
  36. package/generator/src/render-worker.js +1 -1
  37. package/generator/src/render.js +224 -37
  38. package/generator/src/request-cache.js +1 -0
  39. package/generator/src/rewrite-elm-json.js +3 -3
  40. package/generator/src/seo-renderer.js +11 -4
  41. package/generator/src/vite-utils.js +78 -0
  42. package/generator/template/app/Api.elm +1 -1
  43. package/generator/template/app/Site.elm +6 -1
  44. package/package.json +12 -13
  45. package/src/ApiRoute.elm +146 -11
  46. package/src/DataSource/Env.elm +27 -3
  47. package/src/DataSource/File.elm +1 -1
  48. package/src/DataSource/Internal/Request.elm +0 -5
  49. package/src/DataSource.elm +50 -53
  50. package/src/Form/Field.elm +1 -1
  51. package/src/Form.elm +33 -33
  52. package/src/Head/Seo.elm +16 -27
  53. package/src/Head.elm +237 -7
  54. package/src/HtmlPrinter.elm +7 -3
  55. package/src/MultiDict.elm +49 -0
  56. package/src/Pages/Generate.elm +548 -103
  57. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  58. package/src/Pages/Internal/NotFoundReason.elm +3 -2
  59. package/src/Pages/Internal/Platform/Cli.elm +91 -27
  60. package/src/Pages/Internal/Platform/Cli.elm.bak +1276 -0
  61. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  62. package/src/Pages/Internal/Platform/GeneratorApplication.elm +455 -0
  63. package/src/Pages/Internal/Platform.elm +34 -27
  64. package/src/Pages/Manifest.elm +24 -0
  65. package/src/Pages/ProgramConfig.elm +6 -3
  66. package/src/Pages/Script.elm +100 -0
  67. package/src/PairingHeap.elm +137 -0
  68. package/src/Parser/Extra/String.elm +33 -0
  69. package/src/Parser/Extra.elm +69 -0
  70. package/src/ProgramTest/ComplexQuery.elm +360 -0
  71. package/src/ProgramTest/EffectSimulation.elm +122 -0
  72. package/src/ProgramTest/Failure.elm +367 -0
  73. package/src/ProgramTest/HtmlHighlighter.elm +116 -0
  74. package/src/ProgramTest/HtmlParserHacks.elm +58 -0
  75. package/src/ProgramTest/HtmlRenderer.elm +73 -0
  76. package/src/ProgramTest/Program.elm +30 -0
  77. package/src/ProgramTest/StringLines.elm +26 -0
  78. package/src/ProgramTest/TestHtmlHacks.elm +132 -0
  79. package/src/ProgramTest/TestHtmlParser.elm +201 -0
  80. package/src/ProgramTest.elm +2339 -0
  81. package/src/Query/Extra.elm +55 -0
  82. package/src/Result/Extra.elm +21 -0
  83. package/src/Server/Request.elm +2 -2
  84. package/src/Server/Session.elm +149 -83
  85. package/src/Server/SetCookie.elm +89 -31
  86. package/src/SimulatedEffect/Cmd.elm +69 -0
  87. package/src/SimulatedEffect/Http.elm +330 -0
  88. package/src/SimulatedEffect/Navigation.elm +69 -0
  89. package/src/SimulatedEffect/Ports.elm +62 -0
  90. package/src/SimulatedEffect/Process.elm +24 -0
  91. package/src/SimulatedEffect/Sub.elm +48 -0
  92. package/src/SimulatedEffect/Task.elm +252 -0
  93. package/src/SimulatedEffect/Time.elm +25 -0
  94. package/src/SimulatedEffect.elm +42 -0
  95. package/src/String/Extra.elm +6 -0
  96. package/src/Test/Http.elm +145 -0
  97. package/src/TestResult.elm +35 -0
  98. package/src/TestState.elm +305 -0
  99. package/src/Url/Extra.elm +100 -0
  100. package/src/Vendored/Diff.elm +321 -0
  101. package/src/Vendored/Failure.elm +217 -0
  102. package/src/Vendored/FormatMonochrome.elm +44 -0
  103. package/src/Vendored/Highlightable.elm +53 -0
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 1016531122, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 2434458748, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 1016531122,
85
+ initialSeed: 2434458748,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleNoColor",
88
88
  verbosity: verbosity,
@@ -11,23 +11,23 @@
11
11
  "elm/html": "1.0.0",
12
12
  "elm/regex": "1.0.0",
13
13
  "elm-community/result-extra": "2.4.0",
14
- "jfmengels/elm-review": "2.4.2",
14
+ "jfmengels/elm-review": "2.10.0",
15
15
  "mdgriffith/elm-codegen": "2.0.0",
16
- "stil4m/elm-syntax": "7.2.5",
16
+ "stil4m/elm-syntax": "7.2.9",
17
17
  "the-sett/elm-syntax-dsl": "6.0.2"
18
18
  },
19
19
  "indirect": {
20
20
  "Chadtech/elm-bool-extra": "2.4.2",
21
+ "elm/bytes": "1.0.8",
21
22
  "elm/json": "1.1.3",
22
23
  "elm/parser": "1.1.0",
23
24
  "elm/project-metadata-utils": "1.0.2",
24
25
  "elm/random": "1.0.0",
25
26
  "elm/time": "1.0.0",
26
- "elm/virtual-dom": "1.0.2",
27
+ "elm/virtual-dom": "1.0.3",
27
28
  "elm-community/basics-extra": "4.1.0",
28
- "elm-community/list-extra": "8.3.0",
29
+ "elm-community/list-extra": "8.7.0",
29
30
  "elm-community/maybe-extra": "5.3.0",
30
- "elm-explorations/test": "1.2.2",
31
31
  "miniBill/elm-unicode": "1.0.2",
32
32
  "rtfeldman/elm-hex": "1.0.0",
33
33
  "stil4m/structured-writer": "1.0.3",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "test-dependencies": {
38
38
  "direct": {
39
- "elm-explorations/test": "1.2.2"
39
+ "elm-explorations/test": "2.0.1"
40
40
  },
41
41
  "indirect": {}
42
42
  }
@@ -34,7 +34,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
34
34
  -> sharedModel
35
35
  -> (msg -> mappedMsg)
36
36
  -> View mappedMsg
37
- -> { body : Html mappedMsg, title : String }
37
+ -> { body : List (Html mappedMsg), title : String }
38
38
  , data : DataSource.DataSource sharedData
39
39
  , subscriptions : Path -> sharedModel -> Sub msg
40
40
  , onPageChange :
@@ -16,6 +16,9 @@ const { build } = require("vite");
16
16
  const preRenderHtml = require("./pre-render-html.js");
17
17
  const esbuild = require("esbuild");
18
18
  const { createHash } = require("crypto");
19
+ const { merge_vite_configs } = require("./vite-utils.js");
20
+ const { resolveConfig } = require("./config.js");
21
+ const globby = require("globby");
19
22
 
20
23
  let pool = [];
21
24
  let pagesReady;
@@ -28,7 +31,6 @@ let pagesReadyCalled = false;
28
31
  let activeWorkers = 0;
29
32
  let buildError = false;
30
33
 
31
- const DIR_PATH = process.cwd();
32
34
  const OUTPUT_FILE_NAME = "elm.js";
33
35
 
34
36
  process.on("unhandledRejection", (error) => {
@@ -36,11 +38,9 @@ process.on("unhandledRejection", (error) => {
36
38
  process.exitCode = 1;
37
39
  });
38
40
 
39
- const ELM_FILE_PATH = path.join(
40
- DIR_PATH,
41
- "./elm-stuff/elm-pages",
42
- OUTPUT_FILE_NAME
43
- );
41
+ function ELM_FILE_PATH() {
42
+ return path.join(process.cwd(), "./elm-stuff/elm-pages", OUTPUT_FILE_NAME);
43
+ }
44
44
 
45
45
  async function ensureRequiredDirs() {
46
46
  ensureDirSync(`dist`);
@@ -75,40 +75,31 @@ async function run(options) {
75
75
  const generateCode = codegen.generate(options.base);
76
76
 
77
77
  await generateCode;
78
+
79
+ const config = await resolveConfig();
78
80
  await fsPromises.writeFile(
79
81
  "elm-stuff/elm-pages/index.html",
80
- preRenderHtml.templateHtml()
82
+ preRenderHtml.templateHtml(false, config.headTagsTemplate)
81
83
  );
82
-
83
- const config = await import(
84
- path.join(process.cwd(), "elm-pages.config.mjs")
85
- )
86
- .then(async (elmPagesConfig) => {
87
- return elmPagesConfig.default || {};
88
- })
89
- .catch((error) => {
90
- console.warn(
91
- "No `elm-pages.config.mjs` file found. Using default config."
92
- );
93
- return {};
94
- });
95
- const viteConfig = config.vite || {};
96
-
97
- const buildComplete = build({
98
- configFile: false,
99
- root: process.cwd(),
100
- base: options.base,
101
- ssr: false,
102
-
103
- build: {
104
- manifest: true,
105
- outDir: "dist",
106
- rollupOptions: {
107
- input: "elm-stuff/elm-pages/index.html",
84
+ const viteConfig = merge_vite_configs(
85
+ {
86
+ configFile: false,
87
+ root: process.cwd(),
88
+ base: options.base,
89
+ ssr: false,
90
+
91
+ build: {
92
+ manifest: true,
93
+ outDir: "dist",
94
+ rollupOptions: {
95
+ input: "elm-stuff/elm-pages/index.html",
96
+ },
108
97
  },
109
98
  },
110
- ...viteConfig,
111
- });
99
+ config.vite || {}
100
+ );
101
+
102
+ const buildComplete = build(viteConfig);
112
103
  const compileClientDone = compileElm(options);
113
104
  await buildComplete;
114
105
  await compileClientDone;
@@ -124,10 +115,25 @@ async function run(options) {
124
115
  "dist/elm-stuff/elm-pages/index.html",
125
116
  "utf-8"
126
117
  );
127
- const preloads = `<link rel="modulepreload" href="/${manifest["elm-stuff/elm-pages/index.html"]["file"]}" />`;
118
+ const preloadFiles = [
119
+ `elm.${browserElmHash}.js`,
120
+ ...Object.entries(manifest).map((entry) => entry[1].file),
121
+ ].map((file) => path.join(options.base, file));
122
+ const userProcessedPreloads = preloadFiles.flatMap((file) => {
123
+ const userPreloadForFile = config.preloadTagForFile(file);
124
+ if (userPreloadForFile === true) {
125
+ return [defaultPreloadForFile(file)];
126
+ } else if (userPreloadForFile === false) {
127
+ return [];
128
+ } else if (typeof userPreloadForFile === "string") {
129
+ return [userPreloadForFile];
130
+ } else {
131
+ throw `I expected preloadTagForFile in elm-pages.config.mjs to return a string or boolean, but instead it returned: ${userPreloadForFile}`;
132
+ }
133
+ });
128
134
 
129
135
  const processedIndexTemplate = indexTemplate
130
- .replace("<!-- PLACEHOLDER_PRELOADS -->", preloads)
136
+ .replace("<!-- PLACEHOLDER_PRELOADS -->", userProcessedPreloads.join(""))
131
137
  .replace(
132
138
  '<script defer src="/elm.js" type="text/javascript"></script>',
133
139
  `<script defer src="/elm.${browserElmHash}.js" type="text/javascript"></script>`
@@ -146,21 +152,20 @@ async function run(options) {
146
152
  metafile: true,
147
153
  bundle: true,
148
154
  watch: false,
149
- logLevel: "error",
155
+ logLevel: "silent",
150
156
  })
151
157
  .then((result) => {
152
- global.portsFilePath = Object.keys(result.metafile.outputs)[0];
158
+ try {
159
+ global.portsFilePath = Object.keys(result.metafile.outputs)[0];
160
+ } catch (e) {}
153
161
  })
154
162
  .catch((error) => {
155
- if (
156
- error.errors.length === 1 &&
157
- error.errors[0].text.includes(
158
- `Could not resolve "./port-data-source"`
159
- )
160
- ) {
161
- console.warn("No port-data-source file found.");
162
- } else {
163
- console.error("Failed to load port-data-source file", error);
163
+ const portDataSourceFileFound =
164
+ globby.sync("./port-data-source.*").length > 0;
165
+ if (portDataSourceFileFound) {
166
+ // don't present error if there are no files matching port-data-source
167
+ // if there are files matching port-data-source, warn the user in case something went wrong loading it
168
+ console.error("Failed to start port-data-source watcher", error);
164
169
  }
165
170
  });
166
171
  // TODO extract common code for compiling ports file?
@@ -544,7 +549,7 @@ async function compileCliApp(options) {
544
549
  path.join(process.cwd(), "elm-stuff/elm-pages")
545
550
  );
546
551
 
547
- const elmFileContent = await fsPromises.readFile(ELM_FILE_PATH, "utf-8");
552
+ const elmFileContent = await fsPromises.readFile(ELM_FILE_PATH(), "utf-8");
548
553
  // Source: https://github.com/elm-explorations/test/blob/d5eb84809de0f8bbf50303efd26889092c800609/src/Elm/Kernel/HtmlAsJson.js
549
554
  const forceThunksSource = ` _HtmlAsJson_toJson(x)
550
555
  }
@@ -590,7 +595,7 @@ function _HtmlAsJson_toJson(html) {
590
595
  `;
591
596
 
592
597
  await fsPromises.writeFile(
593
- ELM_FILE_PATH,
598
+ ELM_FILE_PATH(),
594
599
  elmFileContent
595
600
  .replace(
596
601
  /return \$elm\$json\$Json\$Encode\$string\(.REPLACE_ME_WITH_JSON_STRINGIFY.\)/g,
@@ -627,6 +632,31 @@ async function runAdapter(adaptFn, processedIndexTemplate) {
627
632
  }
628
633
  }
629
634
 
635
+ // Source: https://github.com/vitejs/vite/blob/c53ffec3465d2d28d08d29ca61313469e03f5dd6/playground/ssr-vue/src/entry-server.js#L50-L68
636
+ /**
637
+ * @param {string} file
638
+ */
639
+ function defaultPreloadForFile(file) {
640
+ if (file.endsWith(".js")) {
641
+ return `<link rel="modulepreload" crossorigin href="${file}">`;
642
+ } else if (file.endsWith(".css")) {
643
+ return `<link rel="preload" href="${file}" as="style">`;
644
+ } else if (file.endsWith(".woff")) {
645
+ return ` <link rel="preload" href="${file}" as="font" type="font/woff" crossorigin>`;
646
+ } else if (file.endsWith(".woff2")) {
647
+ return ` <link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin>`;
648
+ } else if (file.endsWith(".gif")) {
649
+ return ` <link rel="preload" href="${file}" as="image" type="image/gif">`;
650
+ } else if (file.endsWith(".jpg") || file.endsWith(".jpeg")) {
651
+ return ` <link rel="preload" href="${file}" as="image" type="image/jpeg">`;
652
+ } else if (file.endsWith(".png")) {
653
+ return ` <link rel="preload" href="${file}" as="image" type="image/png">`;
654
+ } else {
655
+ // TODO
656
+ return "";
657
+ }
658
+ }
659
+
630
660
  /** @typedef { { route : string; contentJson : string; head : SeoTag[]; html: string; body: string; } } FromElm */
631
661
  /** @typedef {HeadTag | JsonLdTag} SeoTag */
632
662
  /** @typedef {{ name: string; attributes: string[][]; type: 'head' }} HeadTag */
@@ -642,4 +672,4 @@ async function runAdapter(adaptFn, processedIndexTemplate) {
642
672
  * @returns {string}
643
673
  */
644
674
 
645
- module.exports = { run };
675
+ module.exports = { run, compileCliApp };
@@ -8,9 +8,13 @@ const codegen = require("./codegen.js");
8
8
  const fs = require("fs");
9
9
  const path = require("path");
10
10
  const { restoreColorSafe } = require("./error-formatter");
11
+ const renderer = require("../../generator/src/render");
12
+ const globby = require("globby");
13
+ const esbuild = require("esbuild");
14
+ const copyModifiedElmJson = require("./rewrite-elm-json.js");
15
+ const { ensureDirSync, deleteIfExists } = require("./file-helpers.js");
11
16
 
12
17
  const commander = require("commander");
13
- const { compileCliApp } = require("./compile-elm.js");
14
18
  const { runElmCodegenInstall } = require("./elm-codegen.js");
15
19
  const Argument = commander.Argument;
16
20
  const Option = commander.Option;
@@ -84,66 +88,89 @@ async function main() {
84
88
  });
85
89
 
86
90
  program
87
- .command("codegen <moduleName>")
88
- .description("run a generator")
91
+ .command("run <moduleName>")
92
+ .description("run an elm-pages script")
89
93
  .allowUnknownOption()
90
94
  .allowExcessArguments()
91
95
  .action(async (moduleName, options, options2) => {
96
+ const unprocessedCliOptions = options2.args.splice(
97
+ options2.processedArgs.length,
98
+ options2.args.length
99
+ );
92
100
  if (!/^[A-Z][a-zA-Z0-9_]*(\.[A-Z][a-zA-Z0-9_]*)*$/.test(moduleName)) {
93
101
  throw `Invalid module name "${moduleName}", must be in the format of an Elm module`;
94
102
  }
95
103
  const splitModuleName = moduleName.split(".");
96
104
  const expectedFilePath = path.join(
97
105
  process.cwd(),
98
- "codegen",
106
+ "script/src/",
99
107
  `${splitModuleName.join("/")}.elm`
100
108
  );
101
109
  if (!fs.existsSync(expectedFilePath)) {
102
110
  throw `I couldn't find a module named ${expectedFilePath}`;
103
111
  }
104
112
  try {
105
- await codegen.generate("");
106
- await runElmCodegenInstall();
107
- await compileCliApp(
108
- // { debug: true },
109
- {},
110
- `${splitModuleName.join("/")}.elm`,
111
- path.join(process.cwd(), "codegen/elm-stuff/scaffold.js"),
112
- "codegen",
113
-
114
- path.join(process.cwd(), "codegen/elm-stuff/scaffold.js")
113
+ // await codegen.generate("");
114
+ if (fs.existsSync("./codegen/")) {
115
+ await runElmCodegenInstall();
116
+ }
117
+
118
+ ensureDirSync("./script/elm-stuff");
119
+ ensureDirSync("./script/elm-stuff/elm-pages/.elm-pages");
120
+ await fs.promises.writeFile(
121
+ path.join("./script/elm-stuff/elm-pages/.elm-pages/Main.elm"),
122
+ generatorWrapperFile(moduleName)
123
+ );
124
+ await copyModifiedElmJson(
125
+ "./script/elm.json",
126
+ "./script/elm-stuff/elm-pages/elm.json"
127
+ );
128
+
129
+ const portDataSourceCompiled = esbuild
130
+ .build({
131
+ entryPoints: ["./port-data-source"],
132
+ platform: "node",
133
+ outfile: ".elm-pages/compiled-ports/port-data-source.js",
134
+ assetNames: "[name]-[hash]",
135
+ chunkNames: "chunks/[name]-[hash]",
136
+ outExtension: { ".js": ".js" },
137
+ metafile: true,
138
+ bundle: true,
139
+ watch: false,
140
+ logLevel: "silent",
141
+ })
142
+ .then((result) => {
143
+ try {
144
+ return Object.keys(result.metafile.outputs)[0];
145
+ } catch (e) {
146
+ return null;
147
+ }
148
+ })
149
+ .catch((error) => {
150
+ const portDataSourceFileFound =
151
+ globby.sync("./port-data-source.*").length > 0;
152
+ if (portDataSourceFileFound) {
153
+ // don't present error if there are no files matching port-data-source
154
+ // if there are files matching port-data-source, warn the user in case something went wrong loading it
155
+ console.error("Failed to start port-data-source watcher", error);
156
+ }
157
+ });
158
+ const portsPath = await portDataSourceCompiled;
159
+ const resolvedPortsPath = path.join(process.cwd(), portsPath);
160
+
161
+ process.chdir("./script");
162
+ // TODO have option for compiling with --debug or not (maybe allow running with elm-optimize-level-2 as well?)
163
+ await build.compileCliApp({ debug: "debug" });
164
+ process.chdir("../");
165
+ await renderer.runGenerator(
166
+ unprocessedCliOptions,
167
+ resolvedPortsPath,
168
+ requireElm("./script/elm-stuff/elm-pages/elm.js")
115
169
  );
116
170
  } catch (error) {
117
171
  console.log(restoreColorSafe(error));
118
172
  process.exit(1);
119
173
  }
120
-
121
- const elmScaffoldProgram = getAt(
122
- splitModuleName,
123
- require(path.join(process.cwd(), "./codegen/elm-stuff/scaffold.js")).Elm
124
- );
125
- const program = elmScaffoldProgram.init({
126
- flags: { argv: ["", ...options2.args], versionMessage: "1.2.3" },
127
- });
128
-
129
- safeSubscribe(program, "print", (message) => {
130
- console.log(message);
131
- });
132
- safeSubscribe(program, "printAndExitFailure", (message) => {
133
- console.log(message);
134
- process.exit(1);
135
- });
136
- safeSubscribe(program, "printAndExitSuccess", (message) => {
137
- console.log(message);
138
- process.exit(0);
139
- });
140
- safeSubscribe(program, "writeFile", async (info) => {
141
- const filePath = path.join(process.cwd(), "app", info.path);
142
- await dirHelpers.tryMkdir(path.dirname(filePath));
143
- fs.writeFileSync(filePath, info.body);
144
- console.log("Success! Created file", filePath);
145
- process.exit(0);
146
- });
147
174
  });
148
175
 
149
176
  program
@@ -180,7 +207,8 @@ function getAt(properties, object) {
180
207
  }
181
208
 
182
209
  function safeSubscribe(program, portName, subscribeFunction) {
183
- program.ports[portName] &&
210
+ program.ports &&
211
+ program.ports[portName] &&
184
212
  program.ports[portName].subscribe(subscribeFunction);
185
213
  }
186
214
 
@@ -218,5 +246,55 @@ function normalizeUrl(rawPagePath) {
218
246
  // with detecting whether the path contains the base.
219
247
  return `/${segments.join("/")}`;
220
248
  }
249
+ /**
250
+ * @param {string} compiledElmPath
251
+ */
252
+ function requireElm(compiledElmPath) {
253
+ const warnOriginal = console.warn;
254
+ console.warn = function () {};
255
+
256
+ Elm = require(path.resolve(compiledElmPath));
257
+ console.warn = warnOriginal;
258
+ return Elm;
259
+ }
260
+
261
+ /**
262
+ * @param {string} moduleName
263
+ */
264
+ function generatorWrapperFile(moduleName) {
265
+ return `port module Main exposing (main)
266
+
267
+ import Bytes
268
+ import DataSource exposing (DataSource)
269
+ import Cli.Program as Program
270
+ import Json.Decode as Decode
271
+ import Json.Encode as Encode
272
+ import Pages.Internal.Platform.GeneratorApplication
273
+ import ${moduleName}
274
+
275
+
276
+ main : Program.StatefulProgram Pages.Internal.Platform.GeneratorApplication.Model Pages.Internal.Platform.GeneratorApplication.Msg (DataSource ()) Pages.Internal.Platform.GeneratorApplication.Flags
277
+ main =
278
+ Pages.Internal.Platform.GeneratorApplication.app
279
+ { data = ${moduleName}.run
280
+ , toJsPort = toJsPort
281
+ , fromJsPort = fromJsPort identity
282
+ , gotBatchSub = gotBatchSub identity
283
+ , sendPageData = sendPageData
284
+ }
285
+
286
+
287
+ port toJsPort : Encode.Value -> Cmd msg
288
+
289
+
290
+ port fromJsPort : (Decode.Value -> msg) -> Sub msg
291
+
292
+
293
+ port gotBatchSub : (Decode.Value -> msg) -> Sub msg
294
+
295
+
296
+ port sendPageData : { oldThing : Encode.Value, binaryPageData : Bytes.Bytes } -> Cmd msg
297
+ `;
298
+ }
221
299
 
222
300
  main();
@@ -63,7 +63,7 @@ async function generate(basePath) {
63
63
  browserCode.fetcherModules
64
64
  ),
65
65
  // write modified elm.json to elm-stuff/elm-pages/
66
- copyModifiedElmJson(),
66
+ copyModifiedElmJson("./elm.json", "./elm-stuff/elm-pages/elm.json"),
67
67
  // ...(await listFiles("./Pages/Internal")).map(copyToBoth),
68
68
  ]);
69
69
  }
@@ -174,15 +174,16 @@ async function copyToBoth(moduleToCopy) {
174
174
  copyFileEnsureDir(
175
175
  path.join(__dirname, moduleToCopy),
176
176
  path.join(`./.elm-pages/`, moduleToCopy)
177
- ),
178
- copyFileEnsureDir(
177
+ ),
178
+ copyFileEnsureDir(
179
179
  path.join(__dirname, moduleToCopy),
180
180
  path.join(`./elm-stuff/elm-pages/client/.elm-pages`, moduleToCopy)
181
- ),
182
- copyFileEnsureDir(
181
+ ),
182
+ copyFileEnsureDir(
183
183
  path.join(__dirname, moduleToCopy),
184
184
  path.join(`./elm-stuff/elm-pages/.elm-pages/`, moduleToCopy)
185
- )]);
185
+ ),
186
+ ]);
186
187
  }
187
188
 
188
189
  /**
@@ -190,10 +191,10 @@ async function copyToBoth(moduleToCopy) {
190
191
  * @param {string} to
191
192
  */
192
193
  async function copyFileEnsureDir(from, to) {
193
- await fs.promises.mkdir(path.dirname(to), {
194
- recursive: true,
195
- })
196
- await fs.promises.copyFile(from, to)
194
+ await fs.promises.mkdir(path.dirname(to), {
195
+ recursive: true,
196
+ });
197
+ await fs.promises.copyFile(from, to);
197
198
  }
198
199
 
199
200
  /**
@@ -0,0 +1 @@
1
+ module.exports = { compatibilityKey: 2 };
@@ -0,0 +1,41 @@
1
+ const path = require("path");
2
+
3
+ async function resolveConfig() {
4
+ const initialConfig = await await import(
5
+ path.join(process.cwd(), "elm-pages.config.mjs")
6
+ )
7
+ .then(async (elmPagesConfig) => {
8
+ return (
9
+ elmPagesConfig.default || {
10
+ headTagsTemplate: defaultHeadTagsTemplate,
11
+ }
12
+ );
13
+ })
14
+ .catch((error) => {
15
+ console.warn(
16
+ "No `elm-pages.config.mjs` file found. Using default config."
17
+ );
18
+ return {
19
+ headTagsTemplate: defaultHeadTagsTemplate,
20
+ vite: {},
21
+ };
22
+ });
23
+
24
+ return {
25
+ preloadTagForFile: function () {
26
+ return true;
27
+ },
28
+ headTagsTemplate: defaultHeadTagsTemplate,
29
+ vite: {},
30
+ ...initialConfig,
31
+ };
32
+ }
33
+
34
+ function defaultHeadTagsTemplate(context) {
35
+ return `
36
+ <link rel="stylesheet" href="/style.css" />
37
+ <meta name="generator" content="elm-pages v${context.cliVersion}" />
38
+ `;
39
+ }
40
+
41
+ module.exports = { resolveConfig };