elm-pages 3.0.0-beta.9 → 3.0.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 (165) hide show
  1. package/README.md +2 -2
  2. package/adapter/netlify.js +207 -0
  3. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2731 -2939
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16840 -13653
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  14. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  15. package/generator/dead-code-review/elm.json +9 -7
  16. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  17. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  23. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  24. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  25. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  26. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
  27. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25118 -21832
  28. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  29. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  30. package/generator/review/elm.json +10 -10
  31. package/generator/src/RouteBuilder.elm +93 -128
  32. package/generator/src/SharedTemplate.elm +8 -7
  33. package/generator/src/SiteConfig.elm +3 -2
  34. package/generator/src/basepath-middleware.js +3 -3
  35. package/generator/src/build.js +143 -59
  36. package/generator/src/cli.js +292 -88
  37. package/generator/src/codegen.js +29 -27
  38. package/generator/src/compatibility-key.js +3 -0
  39. package/generator/src/compile-elm.js +43 -26
  40. package/generator/src/config.js +2 -4
  41. package/generator/src/copy-dir.js +2 -2
  42. package/generator/src/dev-server.js +160 -102
  43. package/generator/src/dir-helpers.js +9 -26
  44. package/generator/src/elm-codegen.js +5 -4
  45. package/generator/src/elm-file-constants.js +2 -3
  46. package/generator/src/error-formatter.js +12 -11
  47. package/generator/src/file-helpers.js +3 -4
  48. package/generator/src/generate-template-module-connector.js +23 -23
  49. package/generator/src/init.js +9 -8
  50. package/generator/src/pre-render-html.js +10 -13
  51. package/generator/src/render-test.js +109 -0
  52. package/generator/src/render-worker.js +25 -28
  53. package/generator/src/render.js +320 -143
  54. package/generator/src/request-cache.js +265 -162
  55. package/generator/src/resolve-elm-module.js +64 -0
  56. package/generator/src/rewrite-client-elm-json.js +6 -5
  57. package/generator/src/rewrite-elm-json-help.js +56 -0
  58. package/generator/src/rewrite-elm-json.js +17 -7
  59. package/generator/src/route-codegen-helpers.js +16 -31
  60. package/generator/src/seo-renderer.js +1 -3
  61. package/generator/src/vite-utils.js +1 -2
  62. package/generator/static-code/elm-pages.js +10 -0
  63. package/generator/static-code/hmr.js +79 -13
  64. package/generator/template/app/Api.elm +3 -2
  65. package/generator/template/app/Effect.elm +155 -0
  66. package/generator/template/app/ErrorPage.elm +49 -6
  67. package/generator/template/app/Route/Blog/Slug_.elm +86 -0
  68. package/generator/template/app/Route/Greet.elm +107 -0
  69. package/generator/template/app/Route/Hello.elm +119 -0
  70. package/generator/template/app/Route/Index.elm +26 -25
  71. package/generator/template/app/Shared.elm +38 -39
  72. package/generator/template/app/Site.elm +4 -7
  73. package/generator/template/app/View.elm +9 -8
  74. package/generator/template/codegen/elm.codegen.json +18 -0
  75. package/generator/template/custom-backend-task.ts +3 -0
  76. package/generator/template/elm-pages.config.mjs +13 -0
  77. package/generator/template/elm-tooling.json +0 -3
  78. package/generator/template/elm.json +25 -20
  79. package/generator/template/index.ts +1 -2
  80. package/generator/template/netlify.toml +4 -1
  81. package/generator/template/package.json +10 -4
  82. package/generator/template/script/.elm-pages/compiled-ports/custom-backend-task.mjs +7 -0
  83. package/generator/template/script/custom-backend-task.ts +3 -0
  84. package/generator/template/script/elm.json +61 -0
  85. package/generator/template/script/src/AddRoute.elm +312 -0
  86. package/generator/template/script/src/Stars.elm +42 -0
  87. package/package.json +30 -27
  88. package/src/ApiRoute.elm +249 -82
  89. package/src/BackendTask/Custom.elm +325 -0
  90. package/src/BackendTask/Env.elm +90 -0
  91. package/src/{DataSource → BackendTask}/File.elm +171 -56
  92. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  93. package/src/BackendTask/Http.elm +679 -0
  94. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  95. package/src/BackendTask/Internal/Request.elm +69 -0
  96. package/src/BackendTask/Random.elm +79 -0
  97. package/src/BackendTask/Time.elm +47 -0
  98. package/src/BackendTask.elm +531 -0
  99. package/src/FatalError.elm +90 -0
  100. package/src/FormData.elm +21 -18
  101. package/src/Head/Seo.elm +4 -4
  102. package/src/Head.elm +112 -8
  103. package/src/Internal/ApiRoute.elm +7 -5
  104. package/src/Internal/Request.elm +84 -4
  105. package/src/PageServerResponse.elm +6 -1
  106. package/src/Pages/ConcurrentSubmission.elm +127 -0
  107. package/src/Pages/Form.elm +340 -0
  108. package/src/Pages/FormData.elm +19 -0
  109. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  110. package/src/Pages/Internal/FatalError.elm +5 -0
  111. package/src/Pages/Internal/Msg.elm +93 -0
  112. package/src/Pages/Internal/NotFoundReason.elm +4 -4
  113. package/src/Pages/Internal/Platform/Cli.elm +586 -768
  114. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  115. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  116. package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
  117. package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
  118. package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
  119. package/src/Pages/Internal/Platform.elm +330 -203
  120. package/src/Pages/Internal/ResponseSketch.elm +2 -2
  121. package/src/Pages/Internal/Script.elm +17 -0
  122. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  123. package/src/Pages/Manifest.elm +52 -11
  124. package/src/Pages/Navigation.elm +85 -0
  125. package/src/Pages/PageUrl.elm +26 -12
  126. package/src/Pages/ProgramConfig.elm +32 -22
  127. package/src/Pages/Script.elm +166 -0
  128. package/src/Pages/SiteConfig.elm +3 -2
  129. package/src/Pages/StaticHttp/Request.elm +2 -2
  130. package/src/Pages/StaticHttpRequest.elm +23 -99
  131. package/src/Pages/Url.elm +3 -3
  132. package/src/PagesMsg.elm +88 -0
  133. package/src/QueryParams.elm +21 -172
  134. package/src/RenderRequest.elm +7 -7
  135. package/src/RequestsAndPending.elm +37 -20
  136. package/src/Result/Extra.elm +26 -0
  137. package/src/Scaffold/Form.elm +569 -0
  138. package/src/Scaffold/Route.elm +1431 -0
  139. package/src/Server/Request.elm +476 -1001
  140. package/src/Server/Response.elm +130 -36
  141. package/src/Server/Session.elm +181 -111
  142. package/src/Server/SetCookie.elm +80 -32
  143. package/src/Stub.elm +53 -0
  144. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  145. package/src/{Path.elm → UrlPath.elm} +33 -36
  146. package/generator/template/public/images/icon-png.png +0 -0
  147. package/src/DataSource/Env.elm +0 -38
  148. package/src/DataSource/Http.elm +0 -446
  149. package/src/DataSource/Internal/Request.elm +0 -20
  150. package/src/DataSource/Port.elm +0 -90
  151. package/src/DataSource.elm +0 -546
  152. package/src/Form/Field.elm +0 -717
  153. package/src/Form/FieldStatus.elm +0 -36
  154. package/src/Form/FieldView.elm +0 -417
  155. package/src/Form/FormData.elm +0 -22
  156. package/src/Form/Validation.elm +0 -391
  157. package/src/Form/Value.elm +0 -118
  158. package/src/Form.elm +0 -1683
  159. package/src/FormDecoder.elm +0 -102
  160. package/src/Pages/FormState.elm +0 -256
  161. package/src/Pages/Generate.elm +0 -1242
  162. package/src/Pages/Internal/Form.elm +0 -17
  163. package/src/Pages/Internal/Platform/Cli.elm.bak +0 -1276
  164. package/src/Pages/Msg.elm +0 -79
  165. package/src/Pages/Transition.elm +0 -70
@@ -1,21 +1,30 @@
1
1
  #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ import * as build from "./build.js";
5
+ import * as dev from "./dev-server.js";
6
+ import * as init from "./init.js";
7
+ import * as codegen from "./codegen.js";
8
+ import * as fs from "node:fs";
9
+ import * as path from "node:path";
10
+ import { restoreColorSafe } from "./error-formatter.js";
11
+ import * as renderer from "./render.js";
12
+ import * as globby from "globby";
13
+ import * as esbuild from "esbuild";
14
+ import { rewriteElmJson } from "./rewrite-elm-json.js";
15
+ import { ensureDirSync } from "./file-helpers.js";
16
+ import * as url from "url";
17
+ import { default as which } from "which";
18
+ import * as commander from "commander";
19
+ import { runElmCodegenInstall } from "./elm-codegen.js";
20
+ import { packageVersion } from "./compatibility-key.js";
21
+ import { resolveInputPathOrModuleName } from "./resolve-elm-module.js";
22
+ import { runTerser } from "./build.js";
2
23
 
3
- const build = require("./build.js");
4
- const dirHelpers = require("./dir-helpers.js");
5
- const dev = require("./dev-server.js");
6
- const init = require("./init.js");
7
- const codegen = require("./codegen.js");
8
- const fs = require("fs");
9
- const path = require("path");
10
- const { restoreColorSafe } = require("./error-formatter");
11
-
12
- const commander = require("commander");
13
- const { compileCliApp } = require("./compile-elm.js");
14
- const { runElmCodegenInstall } = require("./elm-codegen.js");
15
24
  const Argument = commander.Argument;
16
25
  const Option = commander.Option;
17
-
18
- const packageVersion = require("../../package.json").version;
26
+ const __filename = url.fileURLToPath(import.meta.url);
27
+ const __dirname = path.dirname(__filename);
19
28
 
20
29
  async function main() {
21
30
  const program = new commander.Command();
@@ -36,9 +45,6 @@ async function main() {
36
45
  )
37
46
  .description("run a full site build")
38
47
  .action(async (options) => {
39
- if (!options.keepCache) {
40
- clearHttpAndPortCache();
41
- }
42
48
  options.base = normalizeUrl(options.base);
43
49
  await build.run(options);
44
50
  });
@@ -69,9 +75,6 @@ async function main() {
69
75
  .option("--base <basePath>", "serve site under a base path", "/")
70
76
  .option("--https", "uses a https server")
71
77
  .action(async (options) => {
72
- if (!options.keepCache) {
73
- clearHttpAndPortCache();
74
- }
75
78
  options.base = normalizeUrl(options.base);
76
79
  await dev.start(options);
77
80
  });
@@ -84,66 +87,193 @@ async function main() {
84
87
  });
85
88
 
86
89
  program
87
- .command("codegen <moduleName>")
88
- .description("run a generator")
90
+ .command("run <elmModulePath>")
91
+ .description("run an elm-pages script")
89
92
  .allowUnknownOption()
90
93
  .allowExcessArguments()
91
- .action(async (moduleName, options, options2) => {
92
- if (!/^[A-Z][a-zA-Z0-9_]*(\.[A-Z][a-zA-Z0-9_]*)*$/.test(moduleName)) {
93
- throw `Invalid module name "${moduleName}", must be in the format of an Elm module`;
94
- }
95
- const splitModuleName = moduleName.split(".");
96
- const expectedFilePath = path.join(
97
- process.cwd(),
98
- "codegen",
99
- `${splitModuleName.join("/")}.elm`
94
+ .helpOption(false) // allow --help to propogate to the Script to show usage
95
+ .action(async (elmModulePath, options, options2) => {
96
+ const unprocessedCliOptions = options2.args.splice(
97
+ options2.processedArgs.length,
98
+ options2.args.length
100
99
  );
101
- if (!fs.existsSync(expectedFilePath)) {
102
- throw `I couldn't find a module named ${expectedFilePath}`;
103
- }
104
100
  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")
101
+ await compileElmForScript(elmModulePath);
102
+
103
+ const { moduleName, projectDirectory, sourceDirectory } =
104
+ resolveInputPathOrModuleName(elmModulePath);
105
+
106
+ const portBackendTaskCompiled = esbuild
107
+ .build({
108
+ entryPoints: [
109
+ path.resolve(projectDirectory, "./custom-backend-task"),
110
+ ],
111
+ platform: "node",
112
+ outfile: path.resolve(
113
+ projectDirectory,
114
+ ".elm-pages/compiled-ports/custom-backend-task.mjs"
115
+ ),
116
+ assetNames: "[name]-[hash]",
117
+ chunkNames: "chunks/[name]-[hash]",
118
+ metafile: true,
119
+ bundle: true,
120
+ format: "esm",
121
+ packages: "external",
122
+ logLevel: "silent",
123
+ })
124
+ .then((result) => {
125
+ try {
126
+ return Object.keys(result.metafile.outputs)[0];
127
+ } catch (e) {
128
+ return null;
129
+ }
130
+ })
131
+ .catch((error) => {
132
+ const portBackendTaskFileFound =
133
+ globby.globbySync(
134
+ path.resolve(projectDirectory, "./custom-backend-task.*")
135
+ ).length > 0;
136
+ if (portBackendTaskFileFound) {
137
+ // don't present error if there are no files matching custom-backend-task
138
+ // if there are files matching custom-backend-task, warn the user in case something went wrong loading it
139
+ console.error("Failed to load custom-backend-task file.", error);
140
+ }
141
+ });
142
+ const portsPath = await portBackendTaskCompiled;
143
+
144
+ const cwd = process.cwd();
145
+ process.chdir(projectDirectory);
146
+ // TODO have option for compiling with --debug or not (maybe allow running with elm-optimize-level-2 as well?)
147
+
148
+ let executableName = await lamderaOrElmFallback();
149
+ await build.compileCliApp({ debug: "debug", executableName });
150
+ fs.renameSync(
151
+ `${projectDirectory}/elm-stuff/elm-pages/elm.js`,
152
+ `${projectDirectory}/elm-stuff/elm-pages/elm.cjs`
153
+ );
154
+ process.chdir(cwd);
155
+ await renderer.runGenerator(
156
+ unprocessedCliOptions,
157
+ portsPath
158
+ ? await import(url.pathToFileURL(path.resolve(portsPath)).href)
159
+ : null,
160
+ await requireElm(`${projectDirectory}/elm-stuff/elm-pages/elm.cjs`),
161
+ moduleName
115
162
  );
116
163
  } catch (error) {
117
164
  console.log(restoreColorSafe(error));
118
165
  process.exit(1);
119
166
  }
167
+ });
168
+
169
+ program
170
+ .command("bundle-script <moduleName>")
171
+ .description("bundle an elm-pages script")
172
+ .option(
173
+ "--debug",
174
+ "Skip elm-optimize-level-2 and run elm make with --debug"
175
+ )
176
+ .option(
177
+ "--output <path>",
178
+ "Output path for compiled script",
179
+ "./myscript.mjs"
180
+ )
181
+ .option(
182
+ "--external <package-or-pattern>",
183
+ "build site to be served under a base path",
184
+ collect,
185
+ []
186
+ )
187
+ .action(async (elmModulePath, options, options2) => {
188
+ const { moduleName, projectDirectory, sourceDirectory } =
189
+ resolveInputPathOrModuleName(elmModulePath);
190
+ await compileElmForScript(elmModulePath);
120
191
 
121
- const elmScaffoldProgram = getAt(
122
- splitModuleName,
123
- require(path.join(process.cwd(), "./codegen/elm-stuff/scaffold.js")).Elm
192
+ const cwd = process.cwd();
193
+ process.chdir(projectDirectory);
194
+ // TODO have option for compiling with --debug or not (maybe allow running with elm-optimize-level-2 as well?)
195
+
196
+ let executableName = await lamderaOrElmFallback();
197
+ await build.compileCliApp({ debug: options.debug, executableName });
198
+ // await runTerser(`${projectDirectory}/elm-stuff/elm-pages/elm.js`);
199
+ fs.renameSync(
200
+ `${projectDirectory}/elm-stuff/elm-pages/elm.js`,
201
+ `${projectDirectory}/elm-stuff/elm-pages/elm.cjs`
124
202
  );
125
- const program = elmScaffoldProgram.init({
126
- flags: { argv: ["", ...options2.args], versionMessage: "1.2.3" },
127
- });
203
+ process.chdir(cwd);
128
204
 
129
- safeSubscribe(program, "print", (message) => {
130
- console.log(message);
131
- });
132
- safeSubscribe(program, "printAndExitFailure", (message) => {
133
- console.log(message);
205
+ try {
206
+ const { moduleName, projectDirectory, sourceDirectory } =
207
+ resolveInputPathOrModuleName(elmModulePath);
208
+
209
+ const portBackendTaskFileFound =
210
+ globby.globbySync(
211
+ path.resolve(projectDirectory, "custom-backend-task.*")
212
+ ).length > 0;
213
+
214
+ const scriptRunner = `${
215
+ portBackendTaskFileFound
216
+ ? `import * as customBackendTask from "${path.resolve(
217
+ projectDirectory,
218
+ "./custom-backend-task"
219
+ )}";`
220
+ : "const customBackendTask = {};"
221
+ }
222
+ import * as renderer from "./render.js";
223
+ import { default as Elm } from "${path.join(
224
+ projectDirectory,
225
+ "elm-stuff/elm-pages/elm.cjs"
226
+ )}";
227
+
228
+ await renderer.runGenerator(
229
+ [...process.argv].splice(2),
230
+ customBackendTask,
231
+ Elm,
232
+ "${moduleName}"
233
+ );
234
+ `;
235
+ // source: https://github.com/evanw/esbuild/pull/2067#issuecomment-1073039746
236
+ const ESM_REQUIRE_SHIM = `
237
+ await(async()=>{let{dirname:e}=await import("path"),{fileURLToPath:i}=await import("url");if(typeof globalThis.__filename>"u"&&(globalThis.__filename=i(import.meta.url)),typeof globalThis.__dirname>"u"&&(globalThis.__dirname=e(globalThis.__filename)),typeof globalThis.require>"u"){let{default:a}=await import("module");globalThis.require=a.createRequire(import.meta.url)}})();
238
+ `;
239
+
240
+ await esbuild.build({
241
+ format: "esm",
242
+ platform: "node",
243
+ stdin: { contents: scriptRunner, resolveDir: __dirname },
244
+ bundle: true,
245
+ // TODO do I need to make the outfile joined with the current working directory?
246
+
247
+ outfile: path.resolve(cwd, options.output),
248
+ external: ["node:*", ...options.external],
249
+ minify: true,
250
+ pure: [
251
+ "A2",
252
+ "A3",
253
+ "A4",
254
+ "A5",
255
+ "A6",
256
+ "A7",
257
+ "A8",
258
+ "A9",
259
+ "F2",
260
+ "F3",
261
+ "F3",
262
+ "F4",
263
+ "F5",
264
+ "F6",
265
+ "F7",
266
+ "F8",
267
+ "F9",
268
+ ],
269
+ absWorkingDir: projectDirectory,
270
+ banner: { js: `#!/usr/bin/env node\n\n${ESM_REQUIRE_SHIM}` },
271
+ });
272
+ // await runTerser(path.resolve(cwd, options.output));
273
+ } catch (error) {
274
+ console.log(restoreColorSafe(error));
134
275
  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
- });
276
+ }
147
277
  });
148
278
 
149
279
  program
@@ -152,7 +282,7 @@ async function main() {
152
282
  .option("--port <number>", "serve site at localhost:<port>", "8000")
153
283
  .action(async (options) => {
154
284
  await codegen.generate("/");
155
- const DocServer = require("elm-doc-preview");
285
+ const DocServer = (await import("elm-doc-preview")).default;
156
286
  const server = new DocServer({
157
287
  port: options.port,
158
288
  browser: true,
@@ -180,29 +310,11 @@ function getAt(properties, object) {
180
310
  }
181
311
 
182
312
  function safeSubscribe(program, portName, subscribeFunction) {
183
- program.ports[portName] &&
313
+ program.ports &&
314
+ program.ports[portName] &&
184
315
  program.ports[portName].subscribe(subscribeFunction);
185
316
  }
186
317
 
187
- function clearHttpAndPortCache() {
188
- const directory = ".elm-pages/http-response-cache";
189
- if (fs.existsSync(directory)) {
190
- fs.readdir(directory, (err, files) => {
191
- if (err) {
192
- throw err;
193
- }
194
-
195
- for (const file of files) {
196
- fs.unlink(path.join(directory, file), (err) => {
197
- if (err) {
198
- throw err;
199
- }
200
- });
201
- }
202
- });
203
- }
204
- }
205
-
206
318
  /**
207
319
  * @param {string} rawPagePath
208
320
  */
@@ -218,5 +330,97 @@ function normalizeUrl(rawPagePath) {
218
330
  // with detecting whether the path contains the base.
219
331
  return `/${segments.join("/")}`;
220
332
  }
333
+ /**
334
+ * @param {string} compiledElmPath
335
+ */
336
+ async function requireElm(compiledElmPath) {
337
+ const warnOriginal = console.warn;
338
+ console.warn = function () {};
339
+
340
+ let Elm = (await import(path.resolve(compiledElmPath))).default;
341
+ console.warn = warnOriginal;
342
+ return Elm;
343
+ }
344
+
345
+ /**
346
+ * @param {string} moduleName
347
+ */
348
+ function generatorWrapperFile(moduleName) {
349
+ return `port module Main exposing (main)
350
+
351
+ import Pages.Internal.Platform.GeneratorApplication
352
+ import ${moduleName}
353
+
354
+
355
+ main : Pages.Internal.Platform.GeneratorApplication.Program
356
+ main =
357
+ Pages.Internal.Platform.GeneratorApplication.app
358
+ { data = ${moduleName}.run
359
+ , toJsPort = toJsPort
360
+ , fromJsPort = fromJsPort identity
361
+ , gotBatchSub = gotBatchSub identity
362
+ , sendPageData = \\_ -> Cmd.none
363
+ }
364
+
365
+
366
+ port toJsPort : Pages.Internal.Platform.GeneratorApplication.JsonValue -> Cmd msg
367
+
368
+
369
+ port fromJsPort : (Pages.Internal.Platform.GeneratorApplication.JsonValue -> msg) -> Sub msg
370
+
371
+
372
+ port gotBatchSub : (Pages.Internal.Platform.GeneratorApplication.JsonValue -> msg) -> Sub msg
373
+ `;
374
+ }
375
+ function collect(value, previous) {
376
+ return previous.concat([value]);
377
+ }
378
+
379
+ async function compileElmForScript(elmModulePath) {
380
+ const { moduleName, projectDirectory, sourceDirectory } =
381
+ resolveInputPathOrModuleName(elmModulePath);
382
+ const splitModuleName = moduleName.split(".");
383
+ const expectedFilePath = path.join(
384
+ sourceDirectory,
385
+ `${splitModuleName.join("/")}.elm`
386
+ );
387
+ if (!fs.existsSync(expectedFilePath)) {
388
+ throw `I couldn't find a module named ${expectedFilePath}`;
389
+ }
390
+ // await codegen.generate("");
391
+ ensureDirSync(path.join(process.cwd(), ".elm-pages", "http-response-cache"));
392
+ if (fs.existsSync("./codegen/")) {
393
+ await runElmCodegenInstall();
394
+ }
395
+
396
+ ensureDirSync(`${projectDirectory}/elm-stuff`);
397
+ ensureDirSync(`${projectDirectory}/elm-stuff/elm-pages/.elm-pages`);
398
+ await fs.promises.writeFile(
399
+ path.join(`${projectDirectory}/elm-stuff/elm-pages/.elm-pages/Main.elm`),
400
+ generatorWrapperFile(moduleName)
401
+ );
402
+ let executableName = await lamderaOrElmFallback();
403
+ try {
404
+ await which("lamdera");
405
+ } catch (error) {
406
+ await which("elm");
407
+ executableName = "elm";
408
+ }
409
+ await rewriteElmJson(
410
+ `${projectDirectory}/elm.json`,
411
+ `${projectDirectory}/elm-stuff/elm-pages/elm.json`,
412
+ { executableName }
413
+ );
414
+ }
415
+
416
+ async function lamderaOrElmFallback() {
417
+ try {
418
+ await which("lamdera");
419
+ return "lamdera";
420
+ } catch (error) {
421
+ await which("elm");
422
+ return "elm";
423
+ }
424
+ }
221
425
 
222
426
  main();
@@ -1,21 +1,24 @@
1
- const fs = require("fs");
2
- const fsExtra = require("fs-extra");
3
- const copyModifiedElmJson = require("./rewrite-elm-json.js");
4
- const copyModifiedElmJsonClient = require("./rewrite-client-elm-json.js");
5
- const { elmPagesCliFile, elmPagesUiFile } = require("./elm-file-constants.js");
6
- const spawnCallback = require("cross-spawn").spawn;
7
- const which = require("which");
8
- const {
9
- generateTemplateModuleConnector,
10
- } = require("./generate-template-module-connector.js");
11
- const path = require("path");
12
- const { ensureDirSync, deleteIfExists } = require("./file-helpers.js");
1
+ import * as fs from "node:fs";
2
+ import * as fsExtra from "fs-extra";
3
+ import { rewriteElmJson } from "./rewrite-elm-json.js";
4
+ import { rewriteClientElmJson } from "./rewrite-client-elm-json.js";
5
+ import { elmPagesCliFile, elmPagesUiFile } from "./elm-file-constants.js";
6
+ import { spawn as spawnCallback } from "cross-spawn";
7
+ import { default as which } from "which";
8
+ import { generateTemplateModuleConnector } from "./generate-template-module-connector.js";
9
+
10
+ import * as path from "path";
11
+ import { ensureDirSync, deleteIfExists } from "./file-helpers.js";
12
+ import { fileURLToPath } from "url";
13
13
  global.builtAt = new Date();
14
14
 
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = path.dirname(__filename);
17
+
15
18
  /**
16
19
  * @param {string} basePath
17
20
  */
18
- async function generate(basePath) {
21
+ export async function generate(basePath) {
19
22
  const cliCode = await generateTemplateModuleConnector(basePath, "cli");
20
23
  const browserCode = await generateTemplateModuleConnector(
21
24
  basePath,
@@ -63,7 +66,7 @@ async function generate(basePath) {
63
66
  browserCode.fetcherModules
64
67
  ),
65
68
  // write modified elm.json to elm-stuff/elm-pages/
66
- copyModifiedElmJson(),
69
+ rewriteElmJson("./elm.json", "./elm-stuff/elm-pages/elm.json"),
67
70
  // ...(await listFiles("./Pages/Internal")).map(copyToBoth),
68
71
  ]);
69
72
  }
@@ -85,7 +88,7 @@ async function newCopyBoth(modulePath) {
85
88
  );
86
89
  }
87
90
 
88
- async function generateClientFolder(basePath) {
91
+ export async function generateClientFolder(basePath) {
89
92
  const browserCode = await generateTemplateModuleConnector(
90
93
  basePath,
91
94
  "browser"
@@ -97,7 +100,7 @@ async function generateClientFolder(basePath) {
97
100
  await newCopyBoth("SharedTemplate.elm");
98
101
  await newCopyBoth("SiteConfig.elm");
99
102
 
100
- await copyModifiedElmJsonClient();
103
+ await rewriteClientElmJson();
101
104
  await fsExtra.copy("./app", "./elm-stuff/elm-pages/client/app", {
102
105
  recursive: true,
103
106
  });
@@ -174,15 +177,16 @@ async function copyToBoth(moduleToCopy) {
174
177
  copyFileEnsureDir(
175
178
  path.join(__dirname, moduleToCopy),
176
179
  path.join(`./.elm-pages/`, moduleToCopy)
177
- ),
178
- copyFileEnsureDir(
180
+ ),
181
+ copyFileEnsureDir(
179
182
  path.join(__dirname, moduleToCopy),
180
183
  path.join(`./elm-stuff/elm-pages/client/.elm-pages`, moduleToCopy)
181
- ),
182
- copyFileEnsureDir(
184
+ ),
185
+ copyFileEnsureDir(
183
186
  path.join(__dirname, moduleToCopy),
184
187
  path.join(`./elm-stuff/elm-pages/.elm-pages/`, moduleToCopy)
185
- )]);
188
+ ),
189
+ ]);
186
190
  }
187
191
 
188
192
  /**
@@ -190,10 +194,10 @@ async function copyToBoth(moduleToCopy) {
190
194
  * @param {string} to
191
195
  */
192
196
  async function copyFileEnsureDir(from, to) {
193
- await fs.promises.mkdir(path.dirname(to), {
194
- recursive: true,
195
- })
196
- await fs.promises.copyFile(from, to)
197
+ await fs.promises.mkdir(path.dirname(to), {
198
+ recursive: true,
199
+ });
200
+ await fs.promises.copyFile(from, to);
197
201
  }
198
202
 
199
203
  /**
@@ -229,5 +233,3 @@ async function listFiles(dir) {
229
233
  function merge(arrays) {
230
234
  return [].concat.apply([], arrays);
231
235
  }
232
-
233
- module.exports = { generate, generateClientFolder };
@@ -0,0 +1,3 @@
1
+ export const compatibilityKey = 20;
2
+
3
+ export const packageVersion = "3.0.0";
@@ -1,18 +1,39 @@
1
- const spawnCallback = require("cross-spawn").spawn;
2
- const fs = require("fs");
3
- const fsHelpers = require("./dir-helpers.js");
4
- const fsPromises = require("fs").promises;
5
- const path = require("path");
6
- const kleur = require("kleur");
7
- const { inject } = require("elm-hot");
8
- const pathToClientElm = path.join(
9
- process.cwd(),
10
- "elm-stuff/elm-pages/",
11
- "browser-elm.js"
12
- );
1
+ import { spawn as spawnCallback } from "cross-spawn";
2
+ import * as fs from "fs";
3
+ import * as fsHelpers from "./dir-helpers.js";
4
+ import * as fsPromises from "fs/promises";
5
+ import * as path from "path";
6
+ import * as kleur from "kleur/colors";
7
+ import { inject } from "elm-hot";
8
+ import { fileURLToPath } from "url";
9
+ import { rewriteElmJson } from "./rewrite-elm-json-help.js";
10
+ import { ensureDirSync } from "./file-helpers.js";
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
13
 
14
- async function compileElmForBrowser(options) {
15
- await runElm(options, "./.elm-pages/Main.elm", pathToClientElm);
14
+ export async function compileElmForBrowser(options) {
15
+ // TODO do I need to make sure this is run from the right cwd? Before it was run outside of this function in the global scope, need to make sure that doesn't change semantics.
16
+ const pathToClientElm = path.join(
17
+ process.cwd(),
18
+ "elm-stuff/elm-pages/",
19
+ "browser-elm.js"
20
+ );
21
+ const secretDir = path.join(process.cwd(), "elm-stuff/elm-pages/browser-elm");
22
+ await fsHelpers.tryMkdir(secretDir);
23
+ rewriteElmJson(process.cwd(), secretDir, function (elmJson) {
24
+ elmJson["source-directories"] = elmJson["source-directories"].map(
25
+ (item) => {
26
+ return "../../../" + item;
27
+ }
28
+ );
29
+ return elmJson;
30
+ });
31
+ await runElm(
32
+ options,
33
+ "../../../.elm-pages/Main.elm",
34
+ pathToClientElm,
35
+ secretDir
36
+ );
16
37
  return fs.promises.writeFile(
17
38
  "./.elm-pages/cache/elm.js",
18
39
  inject(await fs.promises.readFile(pathToClientElm, "utf-8")).replace(
@@ -26,7 +47,7 @@ async function compileElmForBrowser(options) {
26
47
  );
27
48
  }
28
49
 
29
- async function compileCliApp(
50
+ export async function compileCliApp(
30
51
  options,
31
52
  elmEntrypointPath,
32
53
  outputPath,
@@ -79,7 +100,7 @@ function _HtmlAsJson_toJson(html) {
79
100
  `;
80
101
 
81
102
  await fsPromises.writeFile(
82
- readFrom,
103
+ readFrom.replace(/\.js$/, ".cjs"),
83
104
  elmFileContent
84
105
  .replace(
85
106
  /return \$elm\$json\$Json\$Encode\$string\(.REPLACE_ME_WITH_JSON_STRINGIFY.\)/g,
@@ -132,9 +153,11 @@ function spawnElmMake(options, elmEntrypointPath, outputPath, cwd) {
132
153
  }
133
154
  );
134
155
  if (await fsHelpers.fileExists(outputPath)) {
135
- await fsPromises.unlink(outputPath, {
136
- force: true /* ignore errors if file doesn't exist */,
137
- });
156
+ try {
157
+ await fsPromises.unlink(outputPath, {
158
+ force: true /* ignore errors if file doesn't exist */,
159
+ });
160
+ } catch (e) {}
138
161
  }
139
162
  let commandOutput = "";
140
163
 
@@ -211,7 +234,7 @@ async function runElm(options, elmEntrypointPath, outputPath, cwd) {
211
234
  /**
212
235
  * @param {string} [ cwd ]
213
236
  */
214
- async function runElmReview(cwd) {
237
+ export async function runElmReview(cwd) {
215
238
  const startTime = Date.now();
216
239
  return new Promise((resolve, reject) => {
217
240
  const child = spawnCallback(
@@ -284,12 +307,6 @@ function elmOptimizeLevel2(outputPath, cwd) {
284
307
  });
285
308
  }
286
309
 
287
- module.exports = {
288
- compileElmForBrowser,
289
- runElmReview,
290
- compileCliApp,
291
- };
292
-
293
310
  /**
294
311
  * @param {number} start
295
312
  * @param {number} subtract
@@ -1,6 +1,6 @@
1
- const path = require("path");
1
+ import * as path from "path";
2
2
 
3
- async function resolveConfig() {
3
+ export async function resolveConfig() {
4
4
  const initialConfig = await await import(
5
5
  path.join(process.cwd(), "elm-pages.config.mjs")
6
6
  )
@@ -37,5 +37,3 @@ function defaultHeadTagsTemplate(context) {
37
37
  <meta name="generator" content="elm-pages v${context.cliVersion}" />
38
38
  `;
39
39
  }
40
-
41
- module.exports = { resolveConfig };
@@ -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),