elm-pages 3.0.0-beta.10 → 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.
- package/README.md +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15156 -13244
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/dead-code-review/elm.json +6 -5
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +1 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14574 -12631
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/review/elm.json +6 -6
- package/generator/src/build.js +6 -9
- package/generator/src/cli.js +120 -42
- package/generator/src/codegen.js +11 -10
- package/generator/src/compatibility-key.js +1 -1
- package/generator/src/elm-codegen.js +3 -0
- package/generator/src/render-worker.js +1 -1
- package/generator/src/render.js +222 -37
- package/generator/src/request-cache.js +1 -0
- package/generator/src/rewrite-elm-json.js +3 -3
- package/package.json +12 -12
- package/src/ApiRoute.elm +147 -9
- package/src/DataSource/Env.elm +27 -3
- package/src/DataSource.elm +11 -22
- package/src/Form.elm +32 -32
- package/src/Head.elm +112 -8
- package/src/MultiDict.elm +49 -0
- package/src/Pages/Generate.elm +4 -1
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +455 -0
- package/src/Pages/Manifest.elm +24 -0
- package/src/Pages/Script.elm +100 -0
- package/src/PairingHeap.elm +137 -0
- package/src/Parser/Extra/String.elm +33 -0
- package/src/Parser/Extra.elm +69 -0
- package/src/ProgramTest/ComplexQuery.elm +360 -0
- package/src/ProgramTest/EffectSimulation.elm +122 -0
- package/src/ProgramTest/Failure.elm +367 -0
- package/src/ProgramTest/HtmlHighlighter.elm +116 -0
- package/src/ProgramTest/HtmlParserHacks.elm +58 -0
- package/src/ProgramTest/HtmlRenderer.elm +73 -0
- package/src/ProgramTest/Program.elm +30 -0
- package/src/ProgramTest/StringLines.elm +26 -0
- package/src/ProgramTest/TestHtmlHacks.elm +132 -0
- package/src/ProgramTest/TestHtmlParser.elm +201 -0
- package/src/ProgramTest.elm +2339 -0
- package/src/Query/Extra.elm +55 -0
- package/src/Result/Extra.elm +21 -0
- package/src/Server/Request.elm +2 -2
- package/src/SimulatedEffect/Cmd.elm +69 -0
- package/src/SimulatedEffect/Http.elm +330 -0
- package/src/SimulatedEffect/Navigation.elm +69 -0
- package/src/SimulatedEffect/Ports.elm +62 -0
- package/src/SimulatedEffect/Process.elm +24 -0
- package/src/SimulatedEffect/Sub.elm +48 -0
- package/src/SimulatedEffect/Task.elm +252 -0
- package/src/SimulatedEffect/Time.elm +25 -0
- package/src/SimulatedEffect.elm +42 -0
- package/src/String/Extra.elm +6 -0
- package/src/Test/Http.elm +145 -0
- package/src/TestResult.elm +35 -0
- package/src/TestState.elm +305 -0
- package/src/Url/Extra.elm +100 -0
- package/src/Vendored/Diff.elm +321 -0
- package/src/Vendored/Failure.elm +217 -0
- package/src/Vendored/FormatMonochrome.elm +44 -0
- 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:
|
|
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
|
|
@@ -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.
|
|
14
|
+
"jfmengels/elm-review": "2.10.0",
|
|
15
15
|
"mdgriffith/elm-codegen": "2.0.0",
|
|
16
|
-
"stil4m/elm-syntax": "7.2.
|
|
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.
|
|
27
|
+
"elm/virtual-dom": "1.0.3",
|
|
27
28
|
"elm-community/basics-extra": "4.1.0",
|
|
28
|
-
"elm-community/list-extra": "8.
|
|
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": "
|
|
39
|
+
"elm-explorations/test": "2.0.1"
|
|
40
40
|
},
|
|
41
41
|
"indirect": {}
|
|
42
42
|
}
|
package/generator/src/build.js
CHANGED
|
@@ -31,7 +31,6 @@ let pagesReadyCalled = false;
|
|
|
31
31
|
let activeWorkers = 0;
|
|
32
32
|
let buildError = false;
|
|
33
33
|
|
|
34
|
-
const DIR_PATH = process.cwd();
|
|
35
34
|
const OUTPUT_FILE_NAME = "elm.js";
|
|
36
35
|
|
|
37
36
|
process.on("unhandledRejection", (error) => {
|
|
@@ -39,11 +38,9 @@ process.on("unhandledRejection", (error) => {
|
|
|
39
38
|
process.exitCode = 1;
|
|
40
39
|
});
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
OUTPUT_FILE_NAME
|
|
46
|
-
);
|
|
41
|
+
function ELM_FILE_PATH() {
|
|
42
|
+
return path.join(process.cwd(), "./elm-stuff/elm-pages", OUTPUT_FILE_NAME);
|
|
43
|
+
}
|
|
47
44
|
|
|
48
45
|
async function ensureRequiredDirs() {
|
|
49
46
|
ensureDirSync(`dist`);
|
|
@@ -552,7 +549,7 @@ async function compileCliApp(options) {
|
|
|
552
549
|
path.join(process.cwd(), "elm-stuff/elm-pages")
|
|
553
550
|
);
|
|
554
551
|
|
|
555
|
-
const elmFileContent = await fsPromises.readFile(ELM_FILE_PATH, "utf-8");
|
|
552
|
+
const elmFileContent = await fsPromises.readFile(ELM_FILE_PATH(), "utf-8");
|
|
556
553
|
// Source: https://github.com/elm-explorations/test/blob/d5eb84809de0f8bbf50303efd26889092c800609/src/Elm/Kernel/HtmlAsJson.js
|
|
557
554
|
const forceThunksSource = ` _HtmlAsJson_toJson(x)
|
|
558
555
|
}
|
|
@@ -598,7 +595,7 @@ function _HtmlAsJson_toJson(html) {
|
|
|
598
595
|
`;
|
|
599
596
|
|
|
600
597
|
await fsPromises.writeFile(
|
|
601
|
-
ELM_FILE_PATH,
|
|
598
|
+
ELM_FILE_PATH(),
|
|
602
599
|
elmFileContent
|
|
603
600
|
.replace(
|
|
604
601
|
/return \$elm\$json\$Json\$Encode\$string\(.REPLACE_ME_WITH_JSON_STRINGIFY.\)/g,
|
|
@@ -675,4 +672,4 @@ function defaultPreloadForFile(file) {
|
|
|
675
672
|
* @returns {string}
|
|
676
673
|
*/
|
|
677
674
|
|
|
678
|
-
module.exports = { run };
|
|
675
|
+
module.exports = { run, compileCliApp };
|
package/generator/src/cli.js
CHANGED
|
@@ -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("
|
|
88
|
-
.description("run
|
|
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
|
-
"
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
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();
|
package/generator/src/codegen.js
CHANGED
|
@@ -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
|
-
|
|
177
|
+
),
|
|
178
|
+
copyFileEnsureDir(
|
|
179
179
|
path.join(__dirname, moduleToCopy),
|
|
180
180
|
path.join(`./elm-stuff/elm-pages/client/.elm-pages`, moduleToCopy)
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = { compatibilityKey:
|
|
1
|
+
module.exports = { compatibilityKey: 2 };
|
|
@@ -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
|
});
|
|
@@ -10,7 +10,7 @@ global.staticHttpCache = {};
|
|
|
10
10
|
async function run({ mode, pathname, serverRequest, portsFilePath }) {
|
|
11
11
|
console.time(`${threadId} ${pathname}`);
|
|
12
12
|
try {
|
|
13
|
-
const renderResult = await renderer(
|
|
13
|
+
const renderResult = await renderer.render(
|
|
14
14
|
portsFilePath,
|
|
15
15
|
workerData.basePath,
|
|
16
16
|
requireElm(mode),
|
package/generator/src/render.js
CHANGED
|
@@ -19,18 +19,37 @@ let foundErrors;
|
|
|
19
19
|
let pendingDataSourceResponses;
|
|
20
20
|
let pendingDataSourceCount;
|
|
21
21
|
|
|
22
|
-
module.exports =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
module.exports = { render, runGenerator };
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {string} basePath
|
|
27
|
+
* @param {Object} elmModule
|
|
28
|
+
* @param {string} path
|
|
29
|
+
* @param {{ method: string; hostname: string; query: Record<string, string | undefined>; headers: Record<string, string>; host: string; pathname: string; port: number | null; protocol: string; rawUrl: string; }} request
|
|
30
|
+
* @param {(pattern: string) => void} addDataSourceWatcher
|
|
31
|
+
* @param {boolean} hasFsAccess
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
async function render(
|
|
35
|
+
portsFile,
|
|
36
|
+
basePath,
|
|
37
|
+
elmModule,
|
|
38
|
+
mode,
|
|
39
|
+
path,
|
|
40
|
+
request,
|
|
41
|
+
addDataSourceWatcher,
|
|
42
|
+
hasFsAccess
|
|
43
|
+
) {
|
|
44
|
+
const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(hasFsAccess);
|
|
45
|
+
resetInMemoryFs();
|
|
46
|
+
foundErrors = false;
|
|
47
|
+
pendingDataSourceResponses = [];
|
|
48
|
+
pendingDataSourceCount = 0;
|
|
49
|
+
// since init/update are never called in pre-renders, and DataSource.Http is called using pure NodeJS HTTP fetching
|
|
50
|
+
// we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
|
|
51
|
+
XMLHttpRequest = {};
|
|
52
|
+
const result = await runElmApp(
|
|
34
53
|
portsFile,
|
|
35
54
|
basePath,
|
|
36
55
|
elmModule,
|
|
@@ -38,31 +57,167 @@ module.exports =
|
|
|
38
57
|
path,
|
|
39
58
|
request,
|
|
40
59
|
addDataSourceWatcher,
|
|
60
|
+
fs,
|
|
41
61
|
hasFsAccess
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Object} elmModule
|
|
68
|
+
* @returns
|
|
69
|
+
* @param {string[]} cliOptions
|
|
70
|
+
* @param {any} portsFile
|
|
71
|
+
*/
|
|
72
|
+
async function runGenerator(cliOptions, portsFile, elmModule) {
|
|
73
|
+
global.isRunningGenerator = true;
|
|
74
|
+
const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(true);
|
|
75
|
+
resetInMemoryFs();
|
|
76
|
+
foundErrors = false;
|
|
77
|
+
pendingDataSourceResponses = [];
|
|
78
|
+
pendingDataSourceCount = 0;
|
|
79
|
+
// since init/update are never called in pre-renders, and DataSource.Http is called using pure NodeJS HTTP fetching
|
|
80
|
+
// we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
|
|
81
|
+
XMLHttpRequest = {};
|
|
82
|
+
const result = await runGeneratorAppHelp(
|
|
83
|
+
cliOptions,
|
|
84
|
+
portsFile,
|
|
85
|
+
"",
|
|
86
|
+
elmModule,
|
|
87
|
+
"production",
|
|
88
|
+
"",
|
|
89
|
+
fs,
|
|
90
|
+
true
|
|
91
|
+
);
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @param {string} basePath
|
|
96
|
+
* @param {Object} elmModule
|
|
97
|
+
* @param {string} pagePath
|
|
98
|
+
* @param {string} mode
|
|
99
|
+
* @returns {Promise<({is404: boolean;} & ({kind: 'json';contentJson: string;} | {kind: 'html';htmlString: string;} | {kind: 'api-response';body: string;}))>}
|
|
100
|
+
* @param {string[]} cliOptions
|
|
101
|
+
* @param {any} portsFile
|
|
102
|
+
* @param {typeof import("fs") | import("memfs").IFs} fs
|
|
103
|
+
* @param {boolean} hasFsAccess
|
|
104
|
+
*/
|
|
105
|
+
function runGeneratorAppHelp(
|
|
106
|
+
cliOptions,
|
|
107
|
+
portsFile,
|
|
108
|
+
basePath,
|
|
109
|
+
elmModule,
|
|
110
|
+
mode,
|
|
111
|
+
pagePath,
|
|
112
|
+
fs,
|
|
113
|
+
hasFsAccess
|
|
114
|
+
) {
|
|
115
|
+
const isDevServer = mode !== "build";
|
|
116
|
+
let patternsToWatch = new Set();
|
|
117
|
+
let app = null;
|
|
118
|
+
let killApp;
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
const isBytes = pagePath.match(/content\.dat\/?$/);
|
|
121
|
+
|
|
122
|
+
app = elmModule.Elm.Main.init({
|
|
123
|
+
flags: {
|
|
124
|
+
compatibilityKey,
|
|
125
|
+
argv: ["", "", ...cliOptions],
|
|
126
|
+
versionMessage: "1.2.3",
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
killApp = () => {
|
|
131
|
+
app.ports.toJsPort.unsubscribe(portHandler);
|
|
132
|
+
app.ports.sendPageData.unsubscribe(portHandler);
|
|
133
|
+
app.die();
|
|
134
|
+
app = null;
|
|
135
|
+
// delete require.cache[require.resolve(compiledElmPath)];
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
async function portHandler(/** @type { FromElm } */ newThing) {
|
|
139
|
+
let fromElm;
|
|
140
|
+
let contentDatPayload;
|
|
141
|
+
|
|
142
|
+
fromElm = newThing;
|
|
143
|
+
if (fromElm.command === "log") {
|
|
144
|
+
console.log(fromElm.value);
|
|
145
|
+
} else if (fromElm.tag === "ApiResponse") {
|
|
146
|
+
const args = fromElm.args[0];
|
|
147
|
+
if (mode === "build") {
|
|
148
|
+
global.staticHttpCache = args.staticHttpCache;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
resolve({
|
|
152
|
+
kind: "api-response",
|
|
153
|
+
is404: args.is404,
|
|
154
|
+
statusCode: args.statusCode,
|
|
155
|
+
body: args.body,
|
|
156
|
+
});
|
|
157
|
+
} else if (fromElm.tag === "PageProgress") {
|
|
158
|
+
const args = fromElm.args[0];
|
|
159
|
+
if (mode === "build") {
|
|
160
|
+
global.staticHttpCache = args.staticHttpCache;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (isBytes) {
|
|
164
|
+
resolve({
|
|
165
|
+
kind: "bytes",
|
|
166
|
+
is404: false,
|
|
167
|
+
contentJson: JSON.stringify({
|
|
168
|
+
staticData: args.contentJson,
|
|
169
|
+
is404: false,
|
|
170
|
+
}),
|
|
171
|
+
statusCode: args.statusCode,
|
|
172
|
+
headers: args.headers,
|
|
173
|
+
contentDatPayload,
|
|
174
|
+
});
|
|
175
|
+
} else {
|
|
176
|
+
resolve(
|
|
177
|
+
outputString(basePath, fromElm, isDevServer, contentDatPayload)
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
} else if (fromElm.tag === "DoHttp") {
|
|
181
|
+
const requestToPerform = fromElm.args[0];
|
|
182
|
+
if (
|
|
183
|
+
requestToPerform.url !== "elm-pages-internal://port" &&
|
|
184
|
+
requestToPerform.url.startsWith("elm-pages-internal://")
|
|
185
|
+
) {
|
|
186
|
+
runInternalJob(
|
|
187
|
+
app,
|
|
188
|
+
mode,
|
|
189
|
+
requestToPerform,
|
|
190
|
+
fs,
|
|
191
|
+
hasFsAccess,
|
|
192
|
+
patternsToWatch
|
|
193
|
+
);
|
|
194
|
+
} else {
|
|
195
|
+
runHttpJob(
|
|
196
|
+
portsFile,
|
|
197
|
+
app,
|
|
198
|
+
mode,
|
|
199
|
+
requestToPerform,
|
|
200
|
+
fs,
|
|
201
|
+
hasFsAccess,
|
|
202
|
+
fromElm.args[1]
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
} else if (fromElm.tag === "Errors") {
|
|
206
|
+
foundErrors = true;
|
|
207
|
+
reject(fromElm.args[0].errorsJson);
|
|
208
|
+
} else {
|
|
209
|
+
console.log(fromElm);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
app.ports.toJsPort.subscribe(portHandler);
|
|
213
|
+
app.ports.sendPageData.subscribe(portHandler);
|
|
214
|
+
}).finally(() => {
|
|
215
|
+
try {
|
|
216
|
+
killApp();
|
|
217
|
+
killApp = null;
|
|
218
|
+
} catch (error) {}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
66
221
|
|
|
67
222
|
/**
|
|
68
223
|
* @param {string} basePath
|
|
@@ -302,7 +457,9 @@ async function runInternalJob(
|
|
|
302
457
|
try {
|
|
303
458
|
pendingDataSourceCount += 1;
|
|
304
459
|
|
|
305
|
-
if (requestToPerform.url === "elm-pages-internal://
|
|
460
|
+
if (requestToPerform.url === "elm-pages-internal://log") {
|
|
461
|
+
pendingDataSourceResponses.push(await runLogJob(requestToPerform));
|
|
462
|
+
} else if (requestToPerform.url === "elm-pages-internal://read-file") {
|
|
306
463
|
pendingDataSourceResponses.push(
|
|
307
464
|
await readFileJobNew(requestToPerform, patternsToWatch)
|
|
308
465
|
);
|
|
@@ -322,6 +479,8 @@ async function runInternalJob(
|
|
|
322
479
|
pendingDataSourceResponses.push(
|
|
323
480
|
await runDecryptJob(requestToPerform, patternsToWatch)
|
|
324
481
|
);
|
|
482
|
+
} else if (requestToPerform.url === "elm-pages-internal://write-file") {
|
|
483
|
+
pendingDataSourceResponses.push(await runWriteFileJob(requestToPerform));
|
|
325
484
|
} else {
|
|
326
485
|
throw `Unexpected internal DataSource request format: ${kleur.yellow(
|
|
327
486
|
JSON.stringify(2, null, requestToPerform)
|
|
@@ -362,6 +521,23 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
362
521
|
};
|
|
363
522
|
}
|
|
364
523
|
}
|
|
524
|
+
async function runWriteFileJob(req) {
|
|
525
|
+
const data = req.body.args[0];
|
|
526
|
+
try {
|
|
527
|
+
const fullPathToWrite = path.join(process.cwd(), data.path);
|
|
528
|
+
await fsPromises.mkdir(path.dirname(fullPathToWrite), { recursive: true });
|
|
529
|
+
await fsPromises.writeFile(fullPathToWrite, data.body);
|
|
530
|
+
return jsonResponse(req, null);
|
|
531
|
+
} catch (error) {
|
|
532
|
+
console.trace(error);
|
|
533
|
+
throw {
|
|
534
|
+
title: "DataSource Error",
|
|
535
|
+
message: `DataSource.Generator.writeFile failed for file path: ${kleur.yellow(
|
|
536
|
+
data.path
|
|
537
|
+
)}\n${kleur.red(error.toString())}`,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
}
|
|
365
541
|
|
|
366
542
|
async function runGlobNew(req, patternsToWatch) {
|
|
367
543
|
try {
|
|
@@ -384,6 +560,15 @@ async function runGlobNew(req, patternsToWatch) {
|
|
|
384
560
|
}
|
|
385
561
|
}
|
|
386
562
|
|
|
563
|
+
async function runLogJob(req) {
|
|
564
|
+
try {
|
|
565
|
+
console.log(req.body.args[0].message);
|
|
566
|
+
return jsonResponse(req, null);
|
|
567
|
+
} catch (e) {
|
|
568
|
+
console.log(`Error performing env '${JSON.stringify(req.body)}'`);
|
|
569
|
+
throw e;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
387
572
|
async function runEnvJob(req, patternsToWatch) {
|
|
388
573
|
try {
|
|
389
574
|
const expectedEnv = req.body.args[0];
|