elm-pages 3.0.0-beta.3 → 3.0.0-beta.30
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 +10 -1
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- 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/Pages-Review-DeadCodeEliminateDataTest.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 +1327 -122
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
- 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 +4 -4
- package/generator/dead-code-review/elm.json +8 -6
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
- 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 +1327 -122
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
- 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 +4 -4
- package/generator/review/elm.json +8 -8
- package/generator/src/RouteBuilder.elm +113 -107
- package/generator/src/SharedTemplate.elm +3 -2
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +123 -87
- package/generator/src/cli.js +256 -77
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +25 -25
- package/generator/src/config.js +39 -0
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +150 -133
- package/generator/src/dir-helpers.js +9 -26
- package/generator/src/elm-codegen.js +5 -4
- package/generator/src/elm-file-constants.js +2 -3
- package/generator/src/error-formatter.js +12 -11
- package/generator/src/file-helpers.js +3 -4
- package/generator/src/generate-template-module-connector.js +23 -22
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +39 -28
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +322 -142
- package/generator/src/request-cache.js +252 -163
- package/generator/src/rewrite-client-elm-json.js +5 -5
- package/generator/src/rewrite-elm-json.js +7 -7
- package/generator/src/route-codegen-helpers.js +16 -31
- package/generator/src/seo-renderer.js +12 -7
- package/generator/src/vite-utils.js +77 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +6 -5
- package/generator/template/app/Effect.elm +123 -0
- package/generator/template/app/ErrorPage.elm +37 -6
- package/generator/template/app/Route/Index.elm +17 -10
- package/generator/template/app/Shared.elm +24 -47
- package/generator/template/app/Site.elm +19 -6
- package/generator/template/app/View.elm +1 -8
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +34 -25
- package/generator/template/package.json +10 -4
- package/package.json +23 -22
- package/src/ApiRoute.elm +199 -61
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +128 -43
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +673 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +28 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +537 -0
- package/src/FatalError.elm +89 -0
- package/src/Form/Field.elm +21 -9
- package/src/Form/FieldView.elm +94 -14
- package/src/Form.elm +275 -400
- package/src/Head.elm +237 -7
- package/src/HtmlPrinter.elm +7 -3
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/FormState.elm +6 -5
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Form.elm +21 -1
- package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
- package/src/Pages/Internal/Platform/Cli.elm +507 -763
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
- package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
- package/src/Pages/Internal/Platform.elm +215 -102
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +29 -4
- package/src/Pages/PageUrl.elm +23 -9
- package/src/Pages/ProgramConfig.elm +14 -10
- package/src/Pages/Script.elm +109 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -98
- package/src/PagesMsg.elm +92 -0
- package/src/Path.elm +16 -19
- package/src/QueryParams.elm +21 -172
- package/src/RequestsAndPending.elm +8 -19
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +484 -0
- package/src/Scaffold/Route.elm +1376 -0
- package/src/Server/Request.elm +43 -37
- package/src/Server/Session.elm +34 -34
- package/src/Server/SetCookie.elm +1 -1
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- package/src/DataSource/Env.elm +0 -38
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
- package/src/DataSource.elm +0 -538
- package/src/Pages/Generate.elm +0 -800
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
module.exports = { gather };
|
|
2
|
-
|
|
3
1
|
/** @typedef { { type: 'root'; keyValuePair: [string, string] } } RootTagModifier */
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* @param {( SeoTag | RootTagModifier )[]} tags
|
|
7
5
|
*/
|
|
8
|
-
function gather(tags) {
|
|
6
|
+
export function gather(tags) {
|
|
9
7
|
const withoutRootModifiers = tags.flatMap((value) => {
|
|
10
8
|
if (value.type === "root") {
|
|
11
9
|
return [];
|
|
@@ -43,11 +41,16 @@ function headTag(rootModifiers) {
|
|
|
43
41
|
|
|
44
42
|
function toString(/** @type { SeoTag[] } */ tags) {
|
|
45
43
|
return tags
|
|
46
|
-
.
|
|
44
|
+
.flatMap((headTag) => {
|
|
47
45
|
if (headTag.type === "head") {
|
|
48
|
-
return appendTag(headTag);
|
|
46
|
+
return [appendTag(headTag)];
|
|
49
47
|
} else if (headTag.type === "json-ld") {
|
|
50
|
-
return appendJsonLdTag(headTag);
|
|
48
|
+
return [appendJsonLdTag(headTag)];
|
|
49
|
+
} else if (headTag.type === "stripped") {
|
|
50
|
+
console.warn(
|
|
51
|
+
`WARNING: Head.nonLoadingTag value ignored because it used a loading tag: ${headTag.message}`
|
|
52
|
+
);
|
|
53
|
+
return [];
|
|
51
54
|
} else {
|
|
52
55
|
throw new Error(`Unknown tag type ${JSON.stringify(headTag)}`);
|
|
53
56
|
}
|
|
@@ -55,7 +58,7 @@ function toString(/** @type { SeoTag[] } */ tags) {
|
|
|
55
58
|
.join("");
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
/** @typedef {HeadTag | JsonLdTag} SeoTag */
|
|
61
|
+
/** @typedef {HeadTag | JsonLdTag | StrippedTag} SeoTag */
|
|
59
62
|
|
|
60
63
|
/** @typedef {{ name: string; attributes: string[][]; type: 'head' }} HeadTag */
|
|
61
64
|
function appendTag(/** @type {HeadTag} */ tagDetails) {
|
|
@@ -66,6 +69,8 @@ function appendTag(/** @type {HeadTag} */ tagDetails) {
|
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
/** @typedef {{ contents: Object; type: 'json-ld' }} JsonLdTag */
|
|
72
|
+
/** @typedef {{ message: string; type: 'stripped' }} StrippedTag */
|
|
73
|
+
|
|
69
74
|
function appendJsonLdTag(/** @type {JsonLdTag} */ tagDetails) {
|
|
70
75
|
return `<script type="application/ld+json">
|
|
71
76
|
${JSON.stringify(tagDetails.contents)}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** This code is from https://github.com/sveltejs/kit/blob/3b457f67d4d7c59fc63bb3f600a490e4dacc2e62/packages/kit/src/exports/vite/utils.js */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {...import('vite').UserConfig} configs
|
|
5
|
+
* @returns {import('vite').UserConfig}
|
|
6
|
+
*/
|
|
7
|
+
export function merge_vite_configs(...configs) {
|
|
8
|
+
return deep_merge(
|
|
9
|
+
...configs.map((config) => ({
|
|
10
|
+
...config,
|
|
11
|
+
resolve: {
|
|
12
|
+
...config.resolve,
|
|
13
|
+
alias: normalize_alias(config.resolve?.alias || {}),
|
|
14
|
+
},
|
|
15
|
+
}))
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Takes zero or more objects and returns a new object that has all the values
|
|
21
|
+
* deeply merged together. None of the original objects will be mutated at any
|
|
22
|
+
* level, and the returned object will have no references to the original
|
|
23
|
+
* objects at any depth. If there's a conflict the last one wins, except for
|
|
24
|
+
* arrays which will be combined.
|
|
25
|
+
* @param {...Object} objects
|
|
26
|
+
* @returns {Record<string, any>} the merged object
|
|
27
|
+
*/
|
|
28
|
+
function deep_merge(...objects) {
|
|
29
|
+
const result = {};
|
|
30
|
+
/** @type {string[]} */
|
|
31
|
+
objects.forEach((o) => merge_into(result, o));
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* normalize kit.vite.resolve.alias as an array
|
|
37
|
+
* @param {import('vite').AliasOptions} o
|
|
38
|
+
* @returns {import('vite').Alias[]}
|
|
39
|
+
*/
|
|
40
|
+
function normalize_alias(o) {
|
|
41
|
+
if (Array.isArray(o)) return o;
|
|
42
|
+
return Object.entries(o).map(([find, replacement]) => ({
|
|
43
|
+
find,
|
|
44
|
+
replacement,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Merges b into a, recursively, mutating a.
|
|
50
|
+
* @param {Record<string, any>} a
|
|
51
|
+
* @param {Record<string, any>} b
|
|
52
|
+
*/
|
|
53
|
+
function merge_into(a, b) {
|
|
54
|
+
/**
|
|
55
|
+
* Checks for "plain old Javascript object", typically made as an object
|
|
56
|
+
* literal. Excludes Arrays and built-in types like Buffer.
|
|
57
|
+
* @param {any} x
|
|
58
|
+
*/
|
|
59
|
+
const is_plain_object = (x) =>
|
|
60
|
+
typeof x === "object" && x.constructor === Object;
|
|
61
|
+
|
|
62
|
+
for (const prop in b) {
|
|
63
|
+
if (is_plain_object(b[prop])) {
|
|
64
|
+
if (!is_plain_object(a[prop])) {
|
|
65
|
+
a[prop] = {};
|
|
66
|
+
}
|
|
67
|
+
merge_into(a[prop], b[prop]);
|
|
68
|
+
} else if (Array.isArray(b[prop])) {
|
|
69
|
+
if (!Array.isArray(a[prop])) {
|
|
70
|
+
a[prop] = [];
|
|
71
|
+
}
|
|
72
|
+
a[prop].push(...b[prop]);
|
|
73
|
+
} else {
|
|
74
|
+
a[prop] = b[prop];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -5,15 +5,69 @@ var eventSource = null;
|
|
|
5
5
|
let updateAppContentJson = new Promise((resolve, reject) => resolve(() => {}));
|
|
6
6
|
|
|
7
7
|
function connect(sendContentJsonPort, initialErrorPage) {
|
|
8
|
+
let reconnectFrequencySeconds = 1;
|
|
9
|
+
// reconnect logic based on: https://stackoverflow.com/a/61148682/383983
|
|
8
10
|
// Listen for the server to tell us that an HMR update is available
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (initialErrorPage) {
|
|
12
|
-
handleEvent(sendContentJsonPort, { data: "content.dat" });
|
|
11
|
+
function waitFunc() {
|
|
12
|
+
return reconnectFrequencySeconds * 1000;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
function tryToSetupFunc() {
|
|
15
|
+
setupEventSource();
|
|
16
|
+
reconnectFrequencySeconds *= 2;
|
|
17
|
+
if (reconnectFrequencySeconds >= 8) {
|
|
18
|
+
reconnectFrequencySeconds = 8;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function reconnectFunc() {
|
|
22
|
+
console.log(
|
|
23
|
+
`Attempting dev server reconnect in ${reconnectFrequencySeconds}...`
|
|
24
|
+
);
|
|
25
|
+
setTimeout(tryToSetupFunc, waitFunc());
|
|
26
|
+
}
|
|
27
|
+
function setupEventSource() {
|
|
28
|
+
eventSource = new EventSource("/stream");
|
|
29
|
+
window.reloadOnOk = initialErrorPage;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
if (initialErrorPage) {
|
|
33
|
+
handleEvent(sendContentJsonPort, { data: "content.dat" });
|
|
34
|
+
}
|
|
35
|
+
} catch (e) {}
|
|
36
|
+
eventSource.onopen = async function () {
|
|
37
|
+
hideError();
|
|
38
|
+
reconnectFrequencySeconds = 1;
|
|
39
|
+
};
|
|
40
|
+
eventSource.onerror = async function (evt) {
|
|
41
|
+
eventSource && eventSource.close();
|
|
42
|
+
reconnectFunc();
|
|
43
|
+
|
|
44
|
+
showReconnectBanner();
|
|
45
|
+
};
|
|
46
|
+
eventSource.onmessage = async function (evt) {
|
|
47
|
+
handleEvent(sendContentJsonPort, evt);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
setupEventSource();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function showReconnectBanner() {
|
|
55
|
+
showError({
|
|
56
|
+
type: "compile-errors",
|
|
57
|
+
errors: [
|
|
58
|
+
{
|
|
59
|
+
path: "",
|
|
60
|
+
name: "",
|
|
61
|
+
problems: [
|
|
62
|
+
{
|
|
63
|
+
title: "",
|
|
64
|
+
// region: "",
|
|
65
|
+
message: ["Dev server is disconnected..."],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
});
|
|
17
71
|
}
|
|
18
72
|
|
|
19
73
|
async function handleEvent(sendContentJsonPort, evt) {
|
|
@@ -28,8 +82,7 @@ async function handleEvent(sendContentJsonPort, evt) {
|
|
|
28
82
|
|
|
29
83
|
try {
|
|
30
84
|
await fetchContentJson;
|
|
31
|
-
|
|
32
|
-
thenApplyHmr(elmJsResponse);
|
|
85
|
+
thenApplyHmr(await elmJsRequest);
|
|
33
86
|
} catch (errorJson) {
|
|
34
87
|
if (typeof errorJson === "string") {
|
|
35
88
|
errorJson = JSON.parse(errorJson);
|
|
@@ -116,8 +169,7 @@ var myDisposeCallback = function () {
|
|
|
116
169
|
var module = {
|
|
117
170
|
hot: {
|
|
118
171
|
accept: async function () {
|
|
119
|
-
|
|
120
|
-
sendInUpdatedContentJson();
|
|
172
|
+
(await updateAppContentJson)();
|
|
121
173
|
},
|
|
122
174
|
|
|
123
175
|
dispose: function (callback) {
|
|
@@ -224,8 +276,11 @@ function htmlSanitize(str, type) {
|
|
|
224
276
|
);
|
|
225
277
|
}
|
|
226
278
|
|
|
227
|
-
|
|
228
|
-
`-- ${title.replace("-", " ")} --------------- ${
|
|
279
|
+
function parseHeader(title, path) {
|
|
280
|
+
return `-- ${(title || "ERROR").replace("-", " ")} --------------- ${
|
|
281
|
+
path || ""
|
|
282
|
+
}`;
|
|
283
|
+
}
|
|
229
284
|
|
|
230
285
|
/*
|
|
231
286
|
|-------------------------------------------------------------------------------
|
|
@@ -253,6 +308,14 @@ const parseConsoleErrors =
|
|
|
253
308
|
* */
|
|
254
309
|
(info) => {
|
|
255
310
|
if (info.rule) {
|
|
311
|
+
if (info.details) {
|
|
312
|
+
return joinMessage(
|
|
313
|
+
info.details.reduce(consoleMsg, {
|
|
314
|
+
error: [consoleHeader(info.rule, path)],
|
|
315
|
+
style: [styleColor("blue")],
|
|
316
|
+
})
|
|
317
|
+
);
|
|
318
|
+
}
|
|
256
319
|
return joinMessage(
|
|
257
320
|
info.formatted.reduce(consoleMsg, {
|
|
258
321
|
error: [consoleHeader(info.rule, path)],
|
|
@@ -313,6 +376,9 @@ const parseHtmlErrors = (path) => (info) => {
|
|
|
313
376
|
if (info.rule) {
|
|
314
377
|
return info.formatted.reduce(htmlMsg, htmlHeader(info.rule, path));
|
|
315
378
|
} else {
|
|
379
|
+
if (info.details) {
|
|
380
|
+
return info.details.reduce(htmlMsg, htmlHeader(info.title, path));
|
|
381
|
+
}
|
|
316
382
|
return info.message.reduce(htmlMsg, htmlHeader(info.title, path));
|
|
317
383
|
}
|
|
318
384
|
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
module Api exposing (routes)
|
|
2
2
|
|
|
3
|
-
import ApiRoute
|
|
4
|
-
import
|
|
3
|
+
import ApiRoute
|
|
4
|
+
import BackendTask exposing (BackendTask)
|
|
5
|
+
import FatalError exposing (FatalError)
|
|
5
6
|
import Html exposing (Html)
|
|
6
7
|
import Pages.Manifest as Manifest
|
|
7
8
|
import Route exposing (Route)
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
routes :
|
|
11
|
-
|
|
12
|
-
-> (Html Never -> String)
|
|
13
|
-
-> List (ApiRoute ApiRoute.Response)
|
|
12
|
+
BackendTask FatalError (List Route)
|
|
13
|
+
-> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
|
|
14
|
+
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
|
14
15
|
routes getStaticRoutes htmlToString =
|
|
15
16
|
[]
|
|
16
17
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
module Effect exposing (Effect(..), batch, fromCmd, map, none, perform)
|
|
2
|
+
|
|
3
|
+
import Browser.Navigation
|
|
4
|
+
import Form.FormData exposing (FormData)
|
|
5
|
+
import Http
|
|
6
|
+
import Json.Decode as Decode
|
|
7
|
+
import Pages.Fetcher
|
|
8
|
+
import Url exposing (Url)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
type Effect msg
|
|
12
|
+
= None
|
|
13
|
+
| Cmd (Cmd msg)
|
|
14
|
+
| Batch (List (Effect msg))
|
|
15
|
+
| SetField { formId : String, name : String, value : String }
|
|
16
|
+
| FetchRouteData
|
|
17
|
+
{ data : Maybe FormData
|
|
18
|
+
, toMsg : Result Http.Error Url -> msg
|
|
19
|
+
}
|
|
20
|
+
| Submit
|
|
21
|
+
{ values : FormData
|
|
22
|
+
, toMsg : Result Http.Error Url -> msg
|
|
23
|
+
}
|
|
24
|
+
| SubmitFetcher (Pages.Fetcher.Fetcher msg)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
type alias RequestInfo =
|
|
28
|
+
{ contentType : String
|
|
29
|
+
, body : String
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
none : Effect msg
|
|
34
|
+
none =
|
|
35
|
+
None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
batch : List (Effect msg) -> Effect msg
|
|
39
|
+
batch =
|
|
40
|
+
Batch
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
fromCmd : Cmd msg -> Effect msg
|
|
44
|
+
fromCmd =
|
|
45
|
+
Cmd
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
map : (a -> b) -> Effect a -> Effect b
|
|
49
|
+
map fn effect =
|
|
50
|
+
case effect of
|
|
51
|
+
None ->
|
|
52
|
+
None
|
|
53
|
+
|
|
54
|
+
Cmd cmd ->
|
|
55
|
+
Cmd (Cmd.map fn cmd)
|
|
56
|
+
|
|
57
|
+
Batch list ->
|
|
58
|
+
Batch (List.map (map fn) list)
|
|
59
|
+
|
|
60
|
+
FetchRouteData fetchInfo ->
|
|
61
|
+
FetchRouteData
|
|
62
|
+
{ data = fetchInfo.data
|
|
63
|
+
, toMsg = fetchInfo.toMsg >> fn
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Submit fetchInfo ->
|
|
67
|
+
Submit
|
|
68
|
+
{ values = fetchInfo.values
|
|
69
|
+
, toMsg = fetchInfo.toMsg >> fn
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
SetField info ->
|
|
73
|
+
SetField info
|
|
74
|
+
|
|
75
|
+
SubmitFetcher fetcher ->
|
|
76
|
+
fetcher
|
|
77
|
+
|> Pages.Fetcher.map fn
|
|
78
|
+
|> SubmitFetcher
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
perform :
|
|
82
|
+
{ fetchRouteData :
|
|
83
|
+
{ data : Maybe FormData
|
|
84
|
+
, toMsg : Result Http.Error Url -> pageMsg
|
|
85
|
+
}
|
|
86
|
+
-> Cmd msg
|
|
87
|
+
, submit :
|
|
88
|
+
{ values : FormData
|
|
89
|
+
, toMsg : Result Http.Error Url -> pageMsg
|
|
90
|
+
}
|
|
91
|
+
-> Cmd msg
|
|
92
|
+
, runFetcher :
|
|
93
|
+
Pages.Fetcher.Fetcher pageMsg
|
|
94
|
+
-> Cmd msg
|
|
95
|
+
, fromPageMsg : pageMsg -> msg
|
|
96
|
+
, key : Browser.Navigation.Key
|
|
97
|
+
, setField : { formId : String, name : String, value : String } -> Cmd msg
|
|
98
|
+
}
|
|
99
|
+
-> Effect pageMsg
|
|
100
|
+
-> Cmd msg
|
|
101
|
+
perform ({ fromPageMsg, key } as helpers) effect =
|
|
102
|
+
case effect of
|
|
103
|
+
None ->
|
|
104
|
+
Cmd.none
|
|
105
|
+
|
|
106
|
+
Cmd cmd ->
|
|
107
|
+
Cmd.map fromPageMsg cmd
|
|
108
|
+
|
|
109
|
+
SetField info ->
|
|
110
|
+
helpers.setField info
|
|
111
|
+
|
|
112
|
+
Batch list ->
|
|
113
|
+
Cmd.batch (List.map (perform helpers) list)
|
|
114
|
+
|
|
115
|
+
FetchRouteData fetchInfo ->
|
|
116
|
+
helpers.fetchRouteData
|
|
117
|
+
fetchInfo
|
|
118
|
+
|
|
119
|
+
Submit record ->
|
|
120
|
+
helpers.submit record
|
|
121
|
+
|
|
122
|
+
SubmitFetcher record ->
|
|
123
|
+
helpers.runFetcher record
|
|
@@ -1,6 +1,36 @@
|
|
|
1
|
-
module ErrorPage exposing (ErrorPage(..), internalError, notFound, statusCode, view)
|
|
1
|
+
module ErrorPage exposing (ErrorPage(..), Model, Msg, head, init, internalError, notFound, statusCode, update, view)
|
|
2
2
|
|
|
3
|
+
import Effect exposing (Effect)
|
|
4
|
+
import Head
|
|
3
5
|
import Html exposing (Html)
|
|
6
|
+
import View exposing (View)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type Msg
|
|
10
|
+
= NoOp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
type alias Model =
|
|
14
|
+
{}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
init : ErrorPage -> ( Model, Effect Msg )
|
|
18
|
+
init errorPage =
|
|
19
|
+
( {}
|
|
20
|
+
, Effect.none
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
update : ErrorPage -> Msg -> Model -> ( Model, Effect Msg )
|
|
25
|
+
update errorPage msg model =
|
|
26
|
+
case msg of
|
|
27
|
+
NoOp ->
|
|
28
|
+
( {}, Effect.none )
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
head : ErrorPage -> List Head.Tag
|
|
32
|
+
head errorPage =
|
|
33
|
+
[]
|
|
4
34
|
|
|
5
35
|
|
|
6
36
|
type ErrorPage
|
|
@@ -18,13 +48,14 @@ internalError =
|
|
|
18
48
|
InternalError
|
|
19
49
|
|
|
20
50
|
|
|
21
|
-
view : ErrorPage ->
|
|
22
|
-
view error =
|
|
51
|
+
view : ErrorPage -> Model -> View Msg
|
|
52
|
+
view error model =
|
|
23
53
|
{ body =
|
|
24
|
-
Html.div []
|
|
25
|
-
[ Html.text "
|
|
54
|
+
[ Html.div []
|
|
55
|
+
[ Html.p [] [ Html.text "Page not found. Maybe try another URL?" ]
|
|
26
56
|
]
|
|
27
|
-
|
|
57
|
+
]
|
|
58
|
+
, title = "Page Not Found"
|
|
28
59
|
}
|
|
29
60
|
|
|
30
61
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
module Route.Index exposing (Data, Model, Msg, route)
|
|
1
|
+
module Route.Index exposing (ActionData, Data, Model, Msg, route)
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import BackendTask exposing (BackendTask)
|
|
4
|
+
import FatalError exposing (FatalError)
|
|
4
5
|
import Head
|
|
5
6
|
import Head.Seo as Seo
|
|
6
7
|
import Html
|
|
7
|
-
import Html.Attributes as Attr
|
|
8
|
+
import Html.Styled.Attributes as Attr
|
|
9
|
+
import PagesMsg exposing (PagesMsg)
|
|
8
10
|
import Pages.PageUrl exposing (PageUrl)
|
|
9
11
|
import Pages.Url
|
|
10
12
|
import Path
|
|
11
|
-
import
|
|
13
|
+
import Route
|
|
14
|
+
import RouteBuilder exposing (StatefulRoute, StatelessRoute, App)
|
|
12
15
|
import Shared
|
|
13
16
|
import View exposing (View)
|
|
14
17
|
|
|
@@ -25,7 +28,7 @@ type alias RouteParams =
|
|
|
25
28
|
{}
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
type alias
|
|
31
|
+
type alias ActionData =
|
|
29
32
|
{}
|
|
30
33
|
|
|
31
34
|
|
|
@@ -38,13 +41,17 @@ route =
|
|
|
38
41
|
|> RouteBuilder.buildNoState { view = view }
|
|
39
42
|
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
type alias Data =
|
|
45
|
+
()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
data : BackendTask FatalError Data
|
|
42
49
|
data =
|
|
43
|
-
|
|
50
|
+
BackendTask.succeed ()
|
|
44
51
|
|
|
45
52
|
|
|
46
53
|
head :
|
|
47
|
-
|
|
54
|
+
App Data ActionData RouteParams
|
|
48
55
|
-> List Head.Tag
|
|
49
56
|
head static =
|
|
50
57
|
Seo.summary
|
|
@@ -66,8 +73,8 @@ head static =
|
|
|
66
73
|
view :
|
|
67
74
|
Maybe PageUrl
|
|
68
75
|
-> Shared.Model
|
|
69
|
-
->
|
|
70
|
-
-> View Msg
|
|
76
|
+
-> App Data ActionData RouteParams
|
|
77
|
+
-> View (PagesMsg Msg)
|
|
71
78
|
view maybeUrl sharedModel static =
|
|
72
79
|
{ title = "elm-pages is running"
|
|
73
80
|
, body =
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template)
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import BackendTask exposing (BackendTask)
|
|
4
|
+
import Effect exposing (Effect)
|
|
5
|
+
import FatalError exposing (FatalError)
|
|
5
6
|
import Html exposing (Html)
|
|
6
|
-
import Html.Events
|
|
7
7
|
import Pages.Flags
|
|
8
8
|
import Pages.PageUrl exposing (PageUrl)
|
|
9
9
|
import Path exposing (Path)
|
|
@@ -19,13 +19,16 @@ template =
|
|
|
19
19
|
, view = view
|
|
20
20
|
, data = data
|
|
21
21
|
, subscriptions = subscriptions
|
|
22
|
-
, onPageChange =
|
|
22
|
+
, onPageChange = Just OnPageChange
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
type Msg
|
|
27
|
-
=
|
|
28
|
-
|
|
27
|
+
= OnPageChange
|
|
28
|
+
{ path : Path
|
|
29
|
+
, query : Maybe String
|
|
30
|
+
, fragment : Maybe String
|
|
31
|
+
}
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
type alias Data =
|
|
@@ -37,13 +40,12 @@ type SharedMsg
|
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
type alias Model =
|
|
40
|
-
{
|
|
43
|
+
{ showMobileMenu : Bool
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
|
|
44
47
|
init :
|
|
45
|
-
|
|
46
|
-
-> Pages.Flags.Flags
|
|
48
|
+
Pages.Flags.Flags
|
|
47
49
|
->
|
|
48
50
|
Maybe
|
|
49
51
|
{ path :
|
|
@@ -54,21 +56,18 @@ init :
|
|
|
54
56
|
, metadata : route
|
|
55
57
|
, pageUrl : Maybe PageUrl
|
|
56
58
|
}
|
|
57
|
-
-> ( Model,
|
|
58
|
-
init
|
|
59
|
-
( {
|
|
60
|
-
,
|
|
59
|
+
-> ( Model, Effect Msg )
|
|
60
|
+
init flags maybePagePath =
|
|
61
|
+
( { showMobileMenu = False }
|
|
62
|
+
, Effect.none
|
|
61
63
|
)
|
|
62
64
|
|
|
63
65
|
|
|
64
|
-
update : Msg -> Model -> ( Model,
|
|
66
|
+
update : Msg -> Model -> ( Model, Effect Msg )
|
|
65
67
|
update msg model =
|
|
66
68
|
case msg of
|
|
67
|
-
|
|
68
|
-
( model,
|
|
69
|
-
|
|
70
|
-
MenuClicked ->
|
|
71
|
-
( { model | showMenu = not model.showMenu }, Cmd.none )
|
|
69
|
+
OnPageChange _ ->
|
|
70
|
+
( { model | showMobileMenu = False }, Effect.none )
|
|
72
71
|
|
|
73
72
|
|
|
74
73
|
subscriptions : Path -> Model -> Sub Msg
|
|
@@ -76,9 +75,9 @@ subscriptions _ _ =
|
|
|
76
75
|
Sub.none
|
|
77
76
|
|
|
78
77
|
|
|
79
|
-
data :
|
|
78
|
+
data : BackendTask FatalError Data
|
|
80
79
|
data =
|
|
81
|
-
|
|
80
|
+
BackendTask.succeed ()
|
|
82
81
|
|
|
83
82
|
|
|
84
83
|
view :
|
|
@@ -90,32 +89,10 @@ view :
|
|
|
90
89
|
-> Model
|
|
91
90
|
-> (Msg -> msg)
|
|
92
91
|
-> View msg
|
|
93
|
-
-> { body : Html msg, title : String }
|
|
94
|
-
view
|
|
92
|
+
-> { body : List (Html msg), title : String }
|
|
93
|
+
view stars page model toMsg pageView =
|
|
95
94
|
{ body =
|
|
96
|
-
Html.div []
|
|
97
|
-
|
|
98
|
-
[ Html.button
|
|
99
|
-
[ Html.Events.onClick MenuClicked ]
|
|
100
|
-
[ Html.text
|
|
101
|
-
(if model.showMenu then
|
|
102
|
-
"Close Menu"
|
|
103
|
-
|
|
104
|
-
else
|
|
105
|
-
"Open Menu"
|
|
106
|
-
)
|
|
107
|
-
]
|
|
108
|
-
, if model.showMenu then
|
|
109
|
-
Html.ul []
|
|
110
|
-
[ Html.li [] [ Html.text "Menu item 1" ]
|
|
111
|
-
, Html.li [] [ Html.text "Menu item 2" ]
|
|
112
|
-
]
|
|
113
|
-
|
|
114
|
-
else
|
|
115
|
-
Html.text ""
|
|
116
|
-
]
|
|
117
|
-
|> Html.map toMsg
|
|
118
|
-
, Html.main_ [] pageView.body
|
|
119
|
-
]
|
|
95
|
+
[ Html.div [] pageView.body
|
|
96
|
+
]
|
|
120
97
|
, title = pageView.title
|
|
121
98
|
}
|
|
@@ -1,19 +1,32 @@
|
|
|
1
|
-
module Site exposing (config)
|
|
1
|
+
module Site exposing (canonicalUrl, config)
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import BackendTask exposing (BackendTask)
|
|
4
|
+
import FatalError exposing (FatalError)
|
|
4
5
|
import Head
|
|
6
|
+
import MimeType
|
|
7
|
+
import Pages.Url
|
|
5
8
|
import SiteConfig exposing (SiteConfig)
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
config : SiteConfig
|
|
9
12
|
config =
|
|
10
|
-
{ canonicalUrl =
|
|
13
|
+
{ canonicalUrl = canonicalUrl
|
|
11
14
|
, head = head
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
|
|
15
|
-
head :
|
|
18
|
+
head : BackendTask FatalError (List Head.Tag)
|
|
16
19
|
head =
|
|
17
|
-
[ Head.
|
|
20
|
+
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
|
21
|
+
, Head.metaName "mobile-web-app-capable" (Head.raw "yes")
|
|
22
|
+
, Head.metaName "theme-color" (Head.raw "#ffffff")
|
|
23
|
+
, Head.metaName "apple-mobile-web-app-capable" (Head.raw "yes")
|
|
24
|
+
, Head.metaName "apple-mobile-web-app-status-bar-style" (Head.raw "black-translucent")
|
|
25
|
+
, Head.sitemapLink "/sitemap.xml"
|
|
18
26
|
]
|
|
19
|
-
|>
|
|
27
|
+
|> BackendTask.succeed
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
canonicalUrl : String
|
|
31
|
+
canonicalUrl =
|
|
32
|
+
"https://elm-pages.com"
|