elm-pages 2.1.11 → 3.0.0-beta.1
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/codegen/elm-pages-codegen.js +38507 -0
- 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.elmi +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/Reporter.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.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/{template/public/style.css → dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +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 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25651 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/package.json +1 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
- package/generator/dead-code-review/elm.json +35 -0
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +181 -0
- package/generator/dead-code-review/src/ReviewConfig.elm +9 -0
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +455 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -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/lock +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 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
- package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
- package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
- package/generator/review/elm.json +13 -4
- package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
- package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
- package/generator/src/RouteBuilder.elm +420 -0
- package/generator/src/SharedTemplate.elm +4 -5
- package/generator/src/SiteConfig.elm +3 -9
- package/generator/src/build.js +308 -95
- package/generator/src/cli.js +103 -8
- package/generator/src/codegen.js +192 -35
- package/generator/src/compile-elm.js +183 -31
- package/generator/src/dev-server.js +353 -96
- package/generator/src/elm-application.json +3 -1
- package/generator/src/elm-codegen.js +34 -0
- package/generator/src/elm-file-constants.js +2 -0
- package/generator/src/error-formatter.js +20 -1
- package/generator/src/generate-template-module-connector.js +125 -927
- package/generator/src/hello.ts +5 -0
- package/generator/src/pre-render-html.js +58 -104
- package/generator/src/render-worker.js +27 -13
- package/generator/src/render.js +252 -197
- package/generator/src/request-cache-fs.js +18 -0
- package/generator/src/request-cache.js +128 -56
- package/generator/src/rewrite-client-elm-json.js +49 -0
- package/generator/src/route-codegen-helpers.js +62 -1
- package/generator/static-code/dev-style.css +22 -0
- package/generator/static-code/elm-pages.js +43 -39
- package/generator/static-code/hmr.js +98 -88
- package/generator/template/app/Api.elm +25 -0
- package/generator/template/app/ErrorPage.elm +38 -0
- package/generator/template/app/Route/Index.elm +87 -0
- package/generator/template/{src → app}/Shared.elm +34 -13
- package/generator/template/app/Site.elm +19 -0
- package/generator/template/{src → app}/View.elm +0 -0
- package/generator/template/elm-pages.config.mjs +5 -0
- package/generator/template/elm.json +1 -0
- package/generator/template/{public/index.js → index.ts} +7 -3
- package/generator/template/package.json +4 -4
- package/generator/template/public/favicon.ico +0 -0
- package/generator/template/public/images/icon-png.png +0 -0
- package/generator/template/src/.gitkeep +0 -0
- package/generator/template/style.css +4 -0
- package/package.json +33 -23
- package/src/ApiRoute.elm +176 -43
- package/src/BuildError.elm +10 -1
- package/src/CookieParser.elm +84 -0
- package/src/DataSource/Env.elm +38 -0
- package/src/DataSource/File.elm +27 -16
- package/src/DataSource/Glob.elm +126 -80
- package/src/DataSource/Http.elm +283 -304
- package/src/DataSource/Internal/Glob.elm +5 -21
- package/src/DataSource/Internal/Request.elm +25 -0
- package/src/DataSource/Port.elm +17 -14
- package/src/DataSource.elm +55 -318
- package/src/Form/Field.elm +717 -0
- package/src/Form/FieldStatus.elm +36 -0
- package/src/Form/FieldView.elm +417 -0
- package/src/Form/FormData.elm +22 -0
- package/src/Form/Validation.elm +391 -0
- package/src/Form/Value.elm +118 -0
- package/src/Form.elm +1683 -0
- package/src/FormData.elm +58 -0
- package/src/FormDecoder.elm +102 -0
- package/src/Head/Seo.elm +12 -4
- package/src/Head.elm +12 -2
- package/src/HtmlPrinter.elm +1 -1
- package/src/Internal/ApiRoute.elm +17 -4
- package/src/Internal/Request.elm +7 -0
- package/src/PageServerResponse.elm +68 -0
- package/src/Pages/ContentCache.elm +1 -229
- package/src/Pages/Fetcher.elm +58 -0
- package/src/Pages/FormState.elm +256 -0
- package/src/Pages/Generate.elm +800 -0
- package/src/Pages/Internal/Form.elm +17 -0
- package/src/Pages/Internal/NotFoundReason.elm +3 -55
- package/src/Pages/Internal/Platform/Cli.elm +777 -579
- package/src/Pages/Internal/Platform/Effect.elm +5 -5
- package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
- package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
- package/src/Pages/Internal/Platform.elm +1244 -504
- package/src/Pages/Internal/ResponseSketch.elm +19 -0
- package/src/Pages/Internal/RoutePattern.elm +596 -45
- package/src/Pages/Manifest.elm +26 -0
- package/src/Pages/Msg.elm +79 -0
- package/src/Pages/ProgramConfig.elm +67 -14
- package/src/Pages/SiteConfig.elm +3 -6
- package/src/Pages/StaticHttp/Request.elm +4 -2
- package/src/Pages/StaticHttpRequest.elm +50 -215
- package/src/Pages/Transition.elm +70 -0
- package/src/Path.elm +1 -0
- package/src/Pattern.elm +98 -0
- package/src/RenderRequest.elm +2 -2
- package/src/RequestsAndPending.elm +111 -9
- package/src/Server/Request.elm +1253 -0
- package/src/Server/Response.elm +292 -0
- package/src/Server/Session.elm +316 -0
- package/src/Server/SetCookie.elm +169 -0
- package/src/TerminalText.elm +1 -1
- package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
- package/generator/src/Page.elm +0 -359
- package/generator/src/codegen-template-module.js +0 -183
- package/generator/src/elm-pages-js-minified.js +0 -1
- package/generator/template/src/Api.elm +0 -14
- package/generator/template/src/Page/Index.elm +0 -69
- package/generator/template/src/Site.elm +0 -41
- package/src/DataSource/ServerRequest.elm +0 -60
- package/src/Internal/OptimizedDecoder.elm +0 -18
- package/src/KeepOrDiscard.elm +0 -6
- package/src/OptimizedDecoder/Pipeline.elm +0 -335
- package/src/OptimizedDecoder.elm +0 -818
- package/src/Pages/Internal/ApplicationType.elm +0 -6
- package/src/Pages/Secrets.elm +0 -83
- package/src/Secrets.elm +0 -111
- package/src/SecretsDict.elm +0 -45
|
@@ -2,14 +2,17 @@ const globby = require("globby");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const mm = require("micromatch");
|
|
4
4
|
const routeHelpers = require("./route-codegen-helpers");
|
|
5
|
+
const { runElmCodegenInstall } = require("./elm-codegen");
|
|
6
|
+
const { compileCliApp } = require("./compile-elm");
|
|
7
|
+
const { restoreColorSafe } = require("./error-formatter");
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* @param {string} basePath
|
|
8
11
|
* @param {'browser' | 'cli'} phase
|
|
9
12
|
*/
|
|
10
|
-
function generateTemplateModuleConnector(basePath, phase) {
|
|
11
|
-
const templates = globby.sync(["
|
|
12
|
-
const captures = mm.capture("
|
|
13
|
+
async function generateTemplateModuleConnector(basePath, phase) {
|
|
14
|
+
const templates = globby.sync(["app/Route/**/*.elm"], {}).map((file) => {
|
|
15
|
+
const captures = mm.capture("app/Route/**/*.elm", file);
|
|
13
16
|
if (captures) {
|
|
14
17
|
return path.join(captures[0], captures[1]).split(path.sep);
|
|
15
18
|
} else {
|
|
@@ -19,7 +22,7 @@ function generateTemplateModuleConnector(basePath, phase) {
|
|
|
19
22
|
if (templates.length <= 0) {
|
|
20
23
|
throw {
|
|
21
24
|
path: "",
|
|
22
|
-
name: "
|
|
25
|
+
name: "Main",
|
|
23
26
|
problems: [
|
|
24
27
|
{
|
|
25
28
|
title: "Could not generate entrypoint",
|
|
@@ -36,803 +39,76 @@ function generateTemplateModuleConnector(basePath, phase) {
|
|
|
36
39
|
],
|
|
37
40
|
};
|
|
38
41
|
}
|
|
42
|
+
let elmCodegenFiles = null;
|
|
43
|
+
try {
|
|
44
|
+
elmCodegenFiles = await runElmCodegenCli(
|
|
45
|
+
sortTemplates(templates),
|
|
46
|
+
basePath,
|
|
47
|
+
phase
|
|
48
|
+
);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.log(restoreColorSafe(error));
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
const routesModule = elmCodegenFiles[0].contents;
|
|
54
|
+
const newMain = elmCodegenFiles[1].contents;
|
|
39
55
|
|
|
40
56
|
return {
|
|
41
|
-
mainModule:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
import Json.Decode
|
|
49
|
-
import Json.Encode
|
|
50
|
-
import Pages.Flags
|
|
51
|
-
import ${
|
|
52
|
-
phase === "browser"
|
|
53
|
-
? "Pages.Internal.Platform"
|
|
54
|
-
: "Pages.Internal.Platform.Cli"
|
|
55
|
-
}
|
|
56
|
-
import Pages.Manifest as Manifest
|
|
57
|
-
import Shared
|
|
58
|
-
import Site
|
|
59
|
-
import Head
|
|
60
|
-
import Html exposing (Html)
|
|
61
|
-
import Pages.Internal.NotFoundReason
|
|
62
|
-
import Pages.PageUrl exposing (PageUrl)
|
|
63
|
-
import Path exposing (Path)
|
|
64
|
-
import Pages.Internal.RoutePattern
|
|
65
|
-
import Url
|
|
66
|
-
import DataSource exposing (DataSource)
|
|
67
|
-
import QueryParams
|
|
68
|
-
|
|
69
|
-
${templates.map((name) => `import Page.${name.join(".")}`).join("\n")}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
type alias Model =
|
|
73
|
-
{ global : Shared.Model
|
|
74
|
-
, page : PageModel
|
|
75
|
-
, current :
|
|
76
|
-
Maybe
|
|
77
|
-
{ path :
|
|
78
|
-
{ path : Path
|
|
79
|
-
, query : Maybe String
|
|
80
|
-
, fragment : Maybe String
|
|
81
|
-
}
|
|
82
|
-
, metadata : Maybe Route
|
|
83
|
-
, pageUrl : Maybe PageUrl
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
type PageModel
|
|
89
|
-
= ${templates
|
|
90
|
-
.map(
|
|
91
|
-
(name) =>
|
|
92
|
-
`Model${pathNormalizedName(name)} Page.${moduleName(name)}.Model\n`
|
|
93
|
-
)
|
|
94
|
-
.join(" | ")}
|
|
95
|
-
| NotFound
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
type Msg
|
|
101
|
-
= MsgGlobal Shared.Msg
|
|
102
|
-
| OnPageChange
|
|
103
|
-
{ protocol : Url.Protocol
|
|
104
|
-
, host : String
|
|
105
|
-
, port_ : Maybe Int
|
|
106
|
-
, path : Path
|
|
107
|
-
, query : Maybe String
|
|
108
|
-
, fragment : Maybe String
|
|
109
|
-
, metadata : Maybe Route
|
|
110
|
-
}
|
|
111
|
-
| ${templates
|
|
112
|
-
.map(
|
|
113
|
-
(name) =>
|
|
114
|
-
`Msg${pathNormalizedName(name)} Page.${moduleName(name)}.Msg\n`
|
|
115
|
-
)
|
|
116
|
-
.join(" | ")}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
type PageData
|
|
120
|
-
= Data404NotFoundPage____
|
|
121
|
-
| ${templates
|
|
122
|
-
.map(
|
|
123
|
-
(name) =>
|
|
124
|
-
`Data${pathNormalizedName(name)} Page.${moduleName(name)}.Data\n`
|
|
125
|
-
)
|
|
126
|
-
.join(" | ")}
|
|
127
|
-
|
|
128
|
-
|
|
57
|
+
mainModule: newMain,
|
|
58
|
+
routesModule,
|
|
59
|
+
fetcherModules: templates.map((name) => {
|
|
60
|
+
return [name, fetcherModule(name)];
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
129
64
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
65
|
+
async function runElmCodegenCli(templates, basePath, phase) {
|
|
66
|
+
// await runElmCodegenInstall();
|
|
67
|
+
// try {
|
|
68
|
+
// await compileCliApp(
|
|
69
|
+
// // { debug: true },
|
|
70
|
+
// {},
|
|
71
|
+
// `Generate.elm`,
|
|
72
|
+
// path.join(process.cwd(), "elm-stuff/elm-pages-codegen.js"),
|
|
73
|
+
// path.join(__dirname, "../../codegen"),
|
|
74
|
+
|
|
75
|
+
// path.join(process.cwd(), "elm-stuff/elm-pages-codegen.js")
|
|
76
|
+
// );
|
|
77
|
+
// } catch (error) {
|
|
78
|
+
// console.log(restoreColorSafe(error));
|
|
79
|
+
// process.exit(1);
|
|
80
|
+
// // throw error;
|
|
81
|
+
// }
|
|
82
|
+
|
|
83
|
+
const filePath = path.join(__dirname, `../../codegen/elm-pages-codegen.js`);
|
|
84
|
+
|
|
85
|
+
// TODO use uncached require here to prevent stale code from running
|
|
86
|
+
|
|
87
|
+
const promise = new Promise((resolve, reject) => {
|
|
88
|
+
const elmPagesCodegen = require(filePath).Elm.Generate;
|
|
89
|
+
// path.join(
|
|
90
|
+
// process.cwd(),
|
|
91
|
+
// "./elm-stuff/elm-pages-codegen.js")
|
|
92
|
+
|
|
93
|
+
const app = elmPagesCodegen.init({
|
|
94
|
+
flags: { templates: templates, basePath, phase },
|
|
95
|
+
});
|
|
96
|
+
if (app.ports.onSuccessSend) {
|
|
97
|
+
app.ports.onSuccessSend.subscribe(resolve);
|
|
133
98
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
-> PageData
|
|
137
|
-
->
|
|
138
|
-
{ view : Model -> { title : String, body : Html Msg }
|
|
139
|
-
, head : List Head.Tag
|
|
140
|
-
}
|
|
141
|
-
view page maybePageUrl globalData pageData =
|
|
142
|
-
case ( page.route, pageData ) of
|
|
143
|
-
${templates
|
|
144
|
-
.map(
|
|
145
|
-
(name) =>
|
|
146
|
-
`( Just ${
|
|
147
|
-
emptyRouteParams(name)
|
|
148
|
-
? `Route.${routeHelpers.routeVariant(name)}`
|
|
149
|
-
: `(Route.${routeHelpers.routeVariant(name)} s)`
|
|
150
|
-
}, Data${routeHelpers.routeVariant(name)} data ) ->
|
|
151
|
-
{ view =
|
|
152
|
-
\\model ->
|
|
153
|
-
case model.page of
|
|
154
|
-
Model${pathNormalizedName(name)} subModel ->
|
|
155
|
-
Page.${moduleName(name)}.page.view
|
|
156
|
-
maybePageUrl
|
|
157
|
-
model.global
|
|
158
|
-
subModel
|
|
159
|
-
{ data = data
|
|
160
|
-
, sharedData = globalData
|
|
161
|
-
, routeParams = ${
|
|
162
|
-
emptyRouteParams(name) ? "{}" : "s"
|
|
163
|
-
}
|
|
164
|
-
, path = page.path
|
|
165
|
-
}
|
|
166
|
-
|> View.map Msg${pathNormalizedName(name)}
|
|
167
|
-
|> Shared.template.view globalData page model.global MsgGlobal
|
|
168
|
-
|
|
169
|
-
_ ->
|
|
170
|
-
{ title = "Model mismatch", body = Html.text <| "Model mismatch" }
|
|
171
|
-
, head = ${
|
|
172
|
-
phase === "browser"
|
|
173
|
-
? "[]"
|
|
174
|
-
: `Page.${moduleName(name)}.page.head
|
|
175
|
-
{ data = data
|
|
176
|
-
, sharedData = globalData
|
|
177
|
-
, routeParams = ${emptyRouteParams(name) ? "{}" : "s"}
|
|
178
|
-
, path = page.path
|
|
179
|
-
}
|
|
180
|
-
`
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
`
|
|
184
|
-
)
|
|
185
|
-
.join("\n\n ")}
|
|
186
|
-
_ ->
|
|
187
|
-
{ head = []
|
|
188
|
-
, view =
|
|
189
|
-
\\_ ->
|
|
190
|
-
{ title = "Page not found"
|
|
191
|
-
, body =
|
|
192
|
-
Html.div []
|
|
193
|
-
[ Html.text "This page could not be found."
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
init :
|
|
202
|
-
Maybe Shared.Model
|
|
203
|
-
-> Pages.Flags.Flags
|
|
204
|
-
-> Shared.Data
|
|
205
|
-
-> PageData
|
|
206
|
-
-> Maybe Browser.Navigation.Key
|
|
207
|
-
->
|
|
208
|
-
Maybe
|
|
209
|
-
{ path :
|
|
210
|
-
{ path : Path
|
|
211
|
-
, query : Maybe String
|
|
212
|
-
, fragment : Maybe String
|
|
213
|
-
}
|
|
214
|
-
, metadata : Maybe Route
|
|
215
|
-
, pageUrl : Maybe PageUrl
|
|
216
|
-
}
|
|
217
|
-
-> ( Model, Cmd Msg )
|
|
218
|
-
init currentGlobalModel userFlags sharedData pageData navigationKey maybePagePath =
|
|
219
|
-
let
|
|
220
|
-
( sharedModel, globalCmd ) =
|
|
221
|
-
currentGlobalModel |> Maybe.map (\\m -> ( m, Cmd.none )) |> Maybe.withDefault (Shared.template.init navigationKey userFlags maybePagePath)
|
|
222
|
-
|
|
223
|
-
( templateModel, templateCmd ) =
|
|
224
|
-
case ( ( Maybe.map2 Tuple.pair (maybePagePath |> Maybe.andThen .metadata) (maybePagePath |> Maybe.map .path) ), pageData ) of
|
|
225
|
-
${templates
|
|
226
|
-
.map(
|
|
227
|
-
(name) => `( Just ( ${
|
|
228
|
-
emptyRouteParams(name)
|
|
229
|
-
? `Route.${routeHelpers.routeVariant(name)}`
|
|
230
|
-
: `(Route.${routeHelpers.routeVariant(
|
|
231
|
-
name
|
|
232
|
-
)} routeParams)`
|
|
233
|
-
}, justPath ), Data${pathNormalizedName(
|
|
234
|
-
name
|
|
235
|
-
)} thisPageData ) ->
|
|
236
|
-
Page.${moduleName(name)}.page.init
|
|
237
|
-
(Maybe.andThen .pageUrl maybePagePath)
|
|
238
|
-
sharedModel
|
|
239
|
-
{ data = thisPageData
|
|
240
|
-
, sharedData = sharedData
|
|
241
|
-
, routeParams = ${
|
|
242
|
-
emptyRouteParams(name) ? "{}" : "routeParams"
|
|
243
|
-
}
|
|
244
|
-
, path = justPath.path
|
|
245
|
-
}
|
|
246
|
-
|> Tuple.mapBoth Model${pathNormalizedName(
|
|
247
|
-
name
|
|
248
|
-
)} (Cmd.map Msg${pathNormalizedName(name)})
|
|
249
|
-
`
|
|
250
|
-
)
|
|
251
|
-
.join("\n ")}
|
|
252
|
-
_ ->
|
|
253
|
-
( NotFound, Cmd.none )
|
|
254
|
-
in
|
|
255
|
-
( { global = sharedModel
|
|
256
|
-
, page = templateModel
|
|
257
|
-
, current = maybePagePath
|
|
258
|
-
}
|
|
259
|
-
, Cmd.batch
|
|
260
|
-
[ templateCmd
|
|
261
|
-
, globalCmd |> Cmd.map MsgGlobal
|
|
262
|
-
]
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
update : Shared.Data -> PageData -> Maybe Browser.Navigation.Key -> Msg -> Model -> ( Model, Cmd Msg )
|
|
268
|
-
update sharedData pageData navigationKey msg model =
|
|
269
|
-
case msg of
|
|
270
|
-
MsgGlobal msg_ ->
|
|
271
|
-
let
|
|
272
|
-
( sharedModel, globalCmd ) =
|
|
273
|
-
Shared.template.update msg_ model.global
|
|
274
|
-
in
|
|
275
|
-
( { model | global = sharedModel }
|
|
276
|
-
, globalCmd |> Cmd.map MsgGlobal
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
OnPageChange record ->
|
|
280
|
-
(init (Just model.global) Pages.Flags.PreRenderFlags sharedData pageData navigationKey <|
|
|
281
|
-
Just
|
|
282
|
-
{ path =
|
|
283
|
-
{ path = record.path
|
|
284
|
-
, query = record.query
|
|
285
|
-
, fragment = record.fragment
|
|
286
|
-
}
|
|
287
|
-
, metadata = record.metadata
|
|
288
|
-
, pageUrl =
|
|
289
|
-
Just
|
|
290
|
-
{ protocol = record.protocol
|
|
291
|
-
, host = record.host
|
|
292
|
-
, port_ = record.port_
|
|
293
|
-
, path = record.path
|
|
294
|
-
, query = record.query |> Maybe.map QueryParams.fromString
|
|
295
|
-
, fragment = record.fragment
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
)
|
|
299
|
-
|> (\\( updatedModel, cmd ) ->
|
|
300
|
-
case Shared.template.onPageChange of
|
|
301
|
-
Nothing ->
|
|
302
|
-
( updatedModel, cmd )
|
|
303
|
-
|
|
304
|
-
Just thingy ->
|
|
305
|
-
let
|
|
306
|
-
( updatedGlobalModel, globalCmd ) =
|
|
307
|
-
Shared.template.update
|
|
308
|
-
(thingy
|
|
309
|
-
{ path = record.path
|
|
310
|
-
, query = record.query
|
|
311
|
-
, fragment = record.fragment
|
|
312
|
-
}
|
|
313
|
-
)
|
|
314
|
-
model.global
|
|
315
|
-
in
|
|
316
|
-
( { updatedModel
|
|
317
|
-
| global = updatedGlobalModel
|
|
318
|
-
}
|
|
319
|
-
, Cmd.batch [ cmd, Cmd.map MsgGlobal globalCmd ]
|
|
320
|
-
)
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
${templates
|
|
325
|
-
.map(
|
|
326
|
-
(name) => `
|
|
327
|
-
Msg${pathNormalizedName(name)} msg_ ->
|
|
328
|
-
let
|
|
329
|
-
( updatedPageModel, pageCmd, ( newGlobalModel, newGlobalCmd ) ) =
|
|
330
|
-
case ( model.page, pageData, Maybe.map3 (\\a b c -> ( a, b, c )) (model.current |> Maybe.andThen .metadata) (model.current |> Maybe.andThen .pageUrl) (model.current |> Maybe.map .path) ) of
|
|
331
|
-
( Model${pathNormalizedName(
|
|
332
|
-
name
|
|
333
|
-
)} pageModel, Data${pathNormalizedName(
|
|
334
|
-
name
|
|
335
|
-
)} thisPageData, Just ( ${routeHelpers.destructureRoute(
|
|
336
|
-
name,
|
|
337
|
-
"routeParams"
|
|
338
|
-
)}, pageUrl, justPage ) ) ->
|
|
339
|
-
Page.${moduleName(name)}.page.update
|
|
340
|
-
pageUrl
|
|
341
|
-
{ data = thisPageData
|
|
342
|
-
, sharedData = sharedData
|
|
343
|
-
, routeParams = ${routeHelpers.referenceRouteParams(
|
|
344
|
-
name,
|
|
345
|
-
"routeParams"
|
|
346
|
-
)}
|
|
347
|
-
, path = justPage.path
|
|
348
|
-
}
|
|
349
|
-
navigationKey
|
|
350
|
-
msg_
|
|
351
|
-
pageModel
|
|
352
|
-
model.global
|
|
353
|
-
|> mapBoth Model${pathNormalizedName(
|
|
354
|
-
name
|
|
355
|
-
)} (Cmd.map Msg${pathNormalizedName(name)})
|
|
356
|
-
|> (\\( a, b, c ) ->
|
|
357
|
-
case c of
|
|
358
|
-
Just sharedMsg ->
|
|
359
|
-
( a, b, Shared.template.update sharedMsg model.global )
|
|
360
|
-
|
|
361
|
-
Nothing ->
|
|
362
|
-
( a, b, ( model.global, Cmd.none ) )
|
|
363
|
-
)
|
|
364
|
-
|
|
365
|
-
_ ->
|
|
366
|
-
( model.page, Cmd.none, ( model.global, Cmd.none ) )
|
|
367
|
-
in
|
|
368
|
-
( { model | page = updatedPageModel, global = newGlobalModel }
|
|
369
|
-
, Cmd.batch [ pageCmd, newGlobalCmd |> Cmd.map MsgGlobal ]
|
|
370
|
-
)
|
|
371
|
-
`
|
|
372
|
-
)
|
|
373
|
-
.join("\n ")}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
type alias SiteConfig =
|
|
377
|
-
{ canonicalUrl : String
|
|
378
|
-
, manifest : Manifest.Config
|
|
99
|
+
if (app.ports.onInfoSend) {
|
|
100
|
+
app.ports.onInfoSend.subscribe((info) => console.log(info));
|
|
379
101
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
templateSubscriptions route path model =
|
|
383
|
-
case ( model.page, route ) of
|
|
384
|
-
${templates
|
|
385
|
-
.map(
|
|
386
|
-
(name) => `
|
|
387
|
-
( Model${pathNormalizedName(
|
|
388
|
-
name
|
|
389
|
-
)} templateModel, Just ${routeHelpers.destructureRoute(
|
|
390
|
-
name,
|
|
391
|
-
"routeParams"
|
|
392
|
-
)} ) ->
|
|
393
|
-
Page.${moduleName(name)}.page.subscriptions
|
|
394
|
-
Nothing -- TODO wire through value
|
|
395
|
-
${routeHelpers.referenceRouteParams(name, "routeParams")}
|
|
396
|
-
path
|
|
397
|
-
templateModel
|
|
398
|
-
model.global
|
|
399
|
-
|> Sub.map Msg${pathNormalizedName(name)}
|
|
400
|
-
`
|
|
401
|
-
)
|
|
402
|
-
.join("\n ")}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
_ ->
|
|
406
|
-
Sub.none
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
main : ${
|
|
410
|
-
phase === "browser"
|
|
411
|
-
? "Pages.Internal.Platform.Program Model Msg PageData Shared.Data"
|
|
412
|
-
: "Pages.Internal.Platform.Cli.Program (Maybe Route)"
|
|
102
|
+
if (app.ports.onFailureSend) {
|
|
103
|
+
app.ports.onFailureSend.subscribe(reject);
|
|
413
104
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
? "Pages.Internal.Platform.application"
|
|
418
|
-
: "Pages.Internal.Platform.Cli.cliApplication"
|
|
419
|
-
}
|
|
420
|
-
{ init = init Nothing
|
|
421
|
-
, urlToRoute = Route.urlToRoute
|
|
422
|
-
, routeToPath = \\route -> route |> Maybe.map Route.routeToPath |> Maybe.withDefault []
|
|
423
|
-
, site = ${phase === "browser" ? `Nothing` : `Just Site.config`}
|
|
424
|
-
, getStaticRoutes = ${
|
|
425
|
-
phase === "browser"
|
|
426
|
-
? `DataSource.succeed []`
|
|
427
|
-
: `getStaticRoutes |> DataSource.map (List.map Just)`
|
|
428
|
-
}
|
|
429
|
-
, handleRoute = handleRoute
|
|
430
|
-
, view = view
|
|
431
|
-
, update = update
|
|
432
|
-
, subscriptions =
|
|
433
|
-
\\route path model ->
|
|
434
|
-
Sub.batch
|
|
435
|
-
[ Shared.template.subscriptions path model.global |> Sub.map MsgGlobal
|
|
436
|
-
, templateSubscriptions route path model
|
|
437
|
-
]
|
|
438
|
-
, onPageChange = OnPageChange
|
|
439
|
-
, toJsPort = toJsPort
|
|
440
|
-
, fromJsPort = fromJsPort identity
|
|
441
|
-
, data = dataForRoute
|
|
442
|
-
, sharedData = Shared.template.data
|
|
443
|
-
, apiRoutes = ${
|
|
444
|
-
phase === "browser"
|
|
445
|
-
? `\\_ -> []`
|
|
446
|
-
: `\\htmlToString -> pathsToGenerateHandler :: routePatterns :: manifestHandler :: Api.routes getStaticRoutes htmlToString`
|
|
447
|
-
}
|
|
448
|
-
, pathPatterns = routePatterns3
|
|
449
|
-
, basePath = [ ${basePath
|
|
450
|
-
.split("/")
|
|
451
|
-
.filter((segment) => segment !== "")
|
|
452
|
-
.map((segment) => `"${segment}"`)
|
|
453
|
-
.join(", ")} ]
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
dataForRoute : Maybe Route -> DataSource PageData
|
|
457
|
-
dataForRoute route =
|
|
458
|
-
case route of
|
|
459
|
-
Nothing ->
|
|
460
|
-
DataSource.succeed Data404NotFoundPage____
|
|
461
|
-
${templates
|
|
462
|
-
.map(
|
|
463
|
-
(name) =>
|
|
464
|
-
`Just ${
|
|
465
|
-
emptyRouteParams(name)
|
|
466
|
-
? `Route.${routeHelpers.routeVariant(name)}`
|
|
467
|
-
: `(Route.${routeHelpers.routeVariant(name)} routeParams)`
|
|
468
|
-
} ->\n Page.${name.join(
|
|
469
|
-
"."
|
|
470
|
-
)}.page.data ${routeHelpers.referenceRouteParams(
|
|
471
|
-
name,
|
|
472
|
-
"routeParams"
|
|
473
|
-
)} |> DataSource.map Data${routeHelpers.routeVariant(name)}`
|
|
474
|
-
)
|
|
475
|
-
.join("\n ")}
|
|
476
|
-
|
|
477
|
-
handleRoute : Maybe Route -> DataSource (Maybe Pages.Internal.NotFoundReason.NotFoundReason)
|
|
478
|
-
handleRoute maybeRoute =
|
|
479
|
-
case maybeRoute of
|
|
480
|
-
Nothing ->
|
|
481
|
-
DataSource.succeed Nothing
|
|
482
|
-
|
|
483
|
-
${templates
|
|
484
|
-
.map(
|
|
485
|
-
(name) =>
|
|
486
|
-
`Just (Route.${routeHelpers.routeVariant(name)}${
|
|
487
|
-
routeHelpers.parseRouteParams(name).length === 0
|
|
488
|
-
? ""
|
|
489
|
-
: " routeParams"
|
|
490
|
-
}) ->\n Page.${name.join(
|
|
491
|
-
"."
|
|
492
|
-
)}.page.handleRoute { moduleName = [ ${name
|
|
493
|
-
.map((part) => `"${part}"`)
|
|
494
|
-
.join(", ")} ], routePattern = ${routeHelpers.toElmPathPattern(
|
|
495
|
-
name
|
|
496
|
-
)} } (\\param -> [ ${routeHelpers
|
|
497
|
-
.parseRouteParams(name)
|
|
498
|
-
.map(
|
|
499
|
-
(param) =>
|
|
500
|
-
`( "${param.name}", ${paramAsElmString(param)} param.${
|
|
501
|
-
param.name
|
|
502
|
-
} )`
|
|
503
|
-
)
|
|
504
|
-
.join(", ")} ]) ${routeHelpers.referenceRouteParams(
|
|
505
|
-
name,
|
|
506
|
-
"routeParams"
|
|
507
|
-
)}`
|
|
508
|
-
)
|
|
509
|
-
.join("\n ")}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
stringToString : String -> String
|
|
513
|
-
stringToString string =
|
|
514
|
-
"\\"" ++ string ++ "\\""
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
nonEmptyToString : ( String, List String ) -> String
|
|
518
|
-
nonEmptyToString ( first, rest ) =
|
|
519
|
-
"( "
|
|
520
|
-
++ stringToString first
|
|
521
|
-
++ ", [ "
|
|
522
|
-
++ (rest
|
|
523
|
-
|> List.map stringToString
|
|
524
|
-
|> String.join ", "
|
|
525
|
-
)
|
|
526
|
-
++ " ] )"
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
listToString : List String -> String
|
|
530
|
-
listToString strings =
|
|
531
|
-
"[ "
|
|
532
|
-
++ (strings
|
|
533
|
-
|> List.map stringToString
|
|
534
|
-
|> String.join ", "
|
|
535
|
-
)
|
|
536
|
-
++ " ]"
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
maybeToString : Maybe String -> String
|
|
540
|
-
maybeToString maybeString =
|
|
541
|
-
case maybeString of
|
|
542
|
-
Just string ->
|
|
543
|
-
"Just " ++ stringToString string
|
|
544
|
-
|
|
545
|
-
Nothing ->
|
|
546
|
-
"Nothing"
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
routePatterns : ApiRoute.ApiRoute ApiRoute.Response
|
|
552
|
-
routePatterns =
|
|
553
|
-
ApiRoute.succeed
|
|
554
|
-
(Json.Encode.list
|
|
555
|
-
(\\{ kind, pathPattern } ->
|
|
556
|
-
Json.Encode.object
|
|
557
|
-
[ ( "kind", Json.Encode.string kind )
|
|
558
|
-
, ( "pathPattern", Json.Encode.string pathPattern )
|
|
559
|
-
]
|
|
560
|
-
)
|
|
561
|
-
[ ${sortTemplates(templates)
|
|
562
|
-
.map((name) => {
|
|
563
|
-
return `{ kind = Page.${moduleName(
|
|
564
|
-
name
|
|
565
|
-
)}.page.kind, pathPattern = "${routeHelpers.toPathPattern(
|
|
566
|
-
name
|
|
567
|
-
)}" }`;
|
|
568
|
-
})
|
|
569
|
-
.join("\n , ")}
|
|
570
|
-
|
|
571
|
-
]
|
|
572
|
-
|> (\\json -> DataSource.succeed { body = Json.Encode.encode 0 json })
|
|
573
|
-
)
|
|
574
|
-
|> ApiRoute.literal "route-patterns.json"
|
|
575
|
-
|> ApiRoute.single
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
routePatterns2 : List String
|
|
579
|
-
routePatterns2 =
|
|
580
|
-
[ ${sortTemplates(templates)
|
|
581
|
-
.map((name) => {
|
|
582
|
-
return `"${routeHelpers.toPathPattern(name)}"`;
|
|
583
|
-
})
|
|
584
|
-
.join("\n , ")}
|
|
585
|
-
]
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
routePatterns3 : List Pages.Internal.RoutePattern.RoutePattern
|
|
589
|
-
routePatterns3 =
|
|
590
|
-
[ ${sortTemplates(templates)
|
|
591
|
-
.map((name) => {
|
|
592
|
-
return `${routeHelpers.toElmPathPattern(name)}`;
|
|
593
|
-
})
|
|
594
|
-
.join("\n , ")}
|
|
595
|
-
]
|
|
596
|
-
|
|
597
|
-
getStaticRoutes : DataSource (List Route)
|
|
598
|
-
getStaticRoutes =
|
|
599
|
-
DataSource.combine
|
|
600
|
-
[ ${templates
|
|
601
|
-
.map((name) => {
|
|
602
|
-
return `Page.${moduleName(
|
|
603
|
-
name
|
|
604
|
-
)}.page.staticRoutes |> DataSource.map (List.map ${
|
|
605
|
-
emptyRouteParams(name)
|
|
606
|
-
? `(\\_ -> Route.${pathNormalizedName(name)}))`
|
|
607
|
-
: `Route.${pathNormalizedName(name)})`
|
|
608
|
-
}`;
|
|
609
|
-
})
|
|
610
|
-
.join("\n , ")}
|
|
611
|
-
]
|
|
612
|
-
|> DataSource.map List.concat
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
pathsToGenerateHandler : ApiRoute.ApiRoute ApiRoute.Response
|
|
616
|
-
pathsToGenerateHandler =
|
|
617
|
-
ApiRoute.succeed
|
|
618
|
-
(DataSource.map2
|
|
619
|
-
(\\pageRoutes apiRoutes ->
|
|
620
|
-
{ body =
|
|
621
|
-
(pageRoutes ++ (apiRoutes |> List.map (\\api -> "/" ++ api)))
|
|
622
|
-
|> Json.Encode.list Json.Encode.string
|
|
623
|
-
|> Json.Encode.encode 0
|
|
624
|
-
}
|
|
625
|
-
)
|
|
626
|
-
(DataSource.map
|
|
627
|
-
(List.map
|
|
628
|
-
(\\route ->
|
|
629
|
-
route
|
|
630
|
-
|> Route.toPath
|
|
631
|
-
|> Path.toAbsolute
|
|
632
|
-
)
|
|
633
|
-
)
|
|
634
|
-
getStaticRoutes
|
|
635
|
-
)
|
|
636
|
-
((manifestHandler :: Api.routes getStaticRoutes (\\_ -> ""))
|
|
637
|
-
|> List.map ApiRoute.getBuildTimeRoutes
|
|
638
|
-
|> DataSource.combine
|
|
639
|
-
|> DataSource.map List.concat
|
|
640
|
-
)
|
|
641
|
-
)
|
|
642
|
-
|> ApiRoute.literal "all-paths.json"
|
|
643
|
-
|> ApiRoute.single
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
manifestHandler : ApiRoute.ApiRoute ApiRoute.Response
|
|
647
|
-
manifestHandler =
|
|
648
|
-
ApiRoute.succeed
|
|
649
|
-
(Site.config
|
|
650
|
-
|> .data
|
|
651
|
-
|> DataSource.map
|
|
652
|
-
(\\data ->
|
|
653
|
-
Site.config.manifest data
|
|
654
|
-
|> manifestToFile (Site.config.canonicalUrl)
|
|
655
|
-
)
|
|
656
|
-
)
|
|
657
|
-
|> ApiRoute.literal "manifest.json"
|
|
658
|
-
|> ApiRoute.single
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
manifestToFile : String -> Manifest.Config -> { body : String }
|
|
662
|
-
manifestToFile resolvedCanonicalUrl manifestConfig =
|
|
663
|
-
manifestConfig
|
|
664
|
-
|> Manifest.toJson resolvedCanonicalUrl
|
|
665
|
-
|> (\\manifestJsonValue ->
|
|
666
|
-
{ body = Json.Encode.encode 0 manifestJsonValue
|
|
667
|
-
}
|
|
668
|
-
)
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
port toJsPort : Json.Encode.Value -> Cmd msg
|
|
672
|
-
|
|
673
|
-
port fromJsPort : (Json.Decode.Value -> msg) -> Sub msg
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
mapBoth : (a -> b) -> (c -> d) -> ( a, c, e ) -> ( b, d, e )
|
|
677
|
-
mapBoth fnA fnB ( a, b, c ) =
|
|
678
|
-
( fnA a, fnB b, c )
|
|
679
|
-
`,
|
|
680
|
-
routesModule: `module Route exposing (Route(..), link, matchers, routeToPath, toLink, urlToRoute, toPath)
|
|
681
|
-
|
|
682
|
-
{-|
|
|
683
|
-
|
|
684
|
-
@docs Route, link, matchers, routeToPath, toLink, urlToRoute, toPath
|
|
685
|
-
|
|
686
|
-
-}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
import Html exposing (Attribute, Html)
|
|
690
|
-
import Html.Attributes as Attr
|
|
691
|
-
import Path exposing (Path)
|
|
692
|
-
import Pages.Internal.Router
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
{-| -}
|
|
696
|
-
type Route
|
|
697
|
-
= ${templates.map(routeHelpers.routeVariantDefinition).join("\n | ")}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
{-| -}
|
|
701
|
-
urlToRoute : { url | path : String } -> Maybe Route
|
|
702
|
-
urlToRoute url =
|
|
703
|
-
url.path
|
|
704
|
-
|> withoutBaseUrl
|
|
705
|
-
|> Pages.Internal.Router.firstMatch matchers
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
baseUrl : String
|
|
709
|
-
baseUrl =
|
|
710
|
-
"${basePath}"
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
baseUrlAsPath : List String
|
|
714
|
-
baseUrlAsPath =
|
|
715
|
-
baseUrl
|
|
716
|
-
|> String.split "/"
|
|
717
|
-
|> List.filter (not << String.isEmpty)
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
withoutBaseUrl path =
|
|
721
|
-
if (path |> String.startsWith baseUrl) then
|
|
722
|
-
String.dropLeft (String.length baseUrl) path
|
|
723
|
-
else
|
|
724
|
-
path
|
|
725
|
-
|
|
726
|
-
{-| -}
|
|
727
|
-
matchers : List (Pages.Internal.Router.Matcher Route)
|
|
728
|
-
matchers =
|
|
729
|
-
[ ${sortTemplates(templates)
|
|
730
|
-
.map(
|
|
731
|
-
(name) => `{ pattern = "^${routeRegex(name).pattern}$"
|
|
732
|
-
, toRoute = ${routeRegex(name).toRoute}
|
|
733
|
-
}\n`
|
|
734
|
-
)
|
|
735
|
-
.join(" , ")}
|
|
736
|
-
]
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
{-| -}
|
|
740
|
-
routeToPath : Route -> List String
|
|
741
|
-
routeToPath route =
|
|
742
|
-
case route of
|
|
743
|
-
${templates
|
|
744
|
-
.map(
|
|
745
|
-
(name) =>
|
|
746
|
-
`${routeHelpers.routeVariant(name)}${
|
|
747
|
-
routeHelpers.parseRouteParams(name).length === 0
|
|
748
|
-
? ""
|
|
749
|
-
: ` params`
|
|
750
|
-
} ->\n List.concat [ ${routeHelpers
|
|
751
|
-
.parseRouteParamsWithStatic(name)
|
|
752
|
-
.map((param) => {
|
|
753
|
-
switch (param.kind) {
|
|
754
|
-
case "static": {
|
|
755
|
-
return param.name === "Index"
|
|
756
|
-
? `[]`
|
|
757
|
-
: `[ "${camelToKebab(param.name)}" ]`;
|
|
758
|
-
}
|
|
759
|
-
case "optional": {
|
|
760
|
-
return `Pages.Internal.Router.maybeToList params.${param.name}`;
|
|
761
|
-
}
|
|
762
|
-
case "required-splat": {
|
|
763
|
-
return `Pages.Internal.Router.nonEmptyToList params.${param.name}`;
|
|
764
|
-
}
|
|
765
|
-
case "dynamic": {
|
|
766
|
-
return `[ params.${param.name} ]`;
|
|
767
|
-
}
|
|
768
|
-
case "optional-splat": {
|
|
769
|
-
return `params.${param.name}`;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
})} ]`
|
|
773
|
-
)
|
|
774
|
-
.join("\n ")}
|
|
775
|
-
|
|
776
|
-
{-| -}
|
|
777
|
-
toPath : Route -> Path
|
|
778
|
-
toPath route =
|
|
779
|
-
(baseUrlAsPath ++ (route |> routeToPath)) |> String.join "/" |> Path.fromString
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
{-| -}
|
|
783
|
-
toString : Route -> String
|
|
784
|
-
toString route =
|
|
785
|
-
route |> toPath |> Path.toAbsolute
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
{-| -}
|
|
789
|
-
toLink : (List (Attribute msg) -> tag) -> Route -> tag
|
|
790
|
-
toLink toAnchorTag route =
|
|
791
|
-
toAnchorTag
|
|
792
|
-
[ route |> toString |> Attr.href
|
|
793
|
-
, Attr.attribute "elm-pages:prefetch" ""
|
|
794
|
-
]
|
|
795
|
-
|
|
105
|
+
});
|
|
106
|
+
const filesToGenerate = await promise;
|
|
107
|
+
console.dir(filesToGenerate.map((file) => file.path));
|
|
796
108
|
|
|
797
|
-
|
|
798
|
-
link : Route -> List (Attribute msg) -> List (Html msg) -> Html msg
|
|
799
|
-
link route attributes children =
|
|
800
|
-
toLink
|
|
801
|
-
(\\anchorAttrs ->
|
|
802
|
-
Html.a
|
|
803
|
-
(anchorAttrs ++ attributes)
|
|
804
|
-
children
|
|
805
|
-
)
|
|
806
|
-
route
|
|
807
|
-
`,
|
|
808
|
-
};
|
|
109
|
+
return filesToGenerate;
|
|
809
110
|
}
|
|
810
111
|
|
|
811
|
-
function emptyRouteParams(name) {
|
|
812
|
-
return routeHelpers.parseRouteParams(name).length === 0;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* @param {string} segment
|
|
817
|
-
* @returns {'static' | 'dynamic' | 'optional' | 'index' | 'required-splat' | 'optional-splat'}
|
|
818
|
-
*/
|
|
819
|
-
function segmentKind(segment) {
|
|
820
|
-
if (segment === "Index") {
|
|
821
|
-
return "index";
|
|
822
|
-
}
|
|
823
|
-
const routeParamMatch = segment.match(/([A-Z][A-Za-z0-9]*)(_?_?)$/);
|
|
824
|
-
const segmentKind = (routeParamMatch && routeParamMatch[2]) || "";
|
|
825
|
-
const isSplat = routeParamMatch && routeParamMatch[1] === "SPLAT";
|
|
826
|
-
if (segmentKind === "") {
|
|
827
|
-
return "static";
|
|
828
|
-
} else if (segmentKind === "_") {
|
|
829
|
-
return isSplat ? "required-splat" : "dynamic";
|
|
830
|
-
} else if (segmentKind === "__") {
|
|
831
|
-
return isSplat ? "optional-splat" : "optional";
|
|
832
|
-
} else {
|
|
833
|
-
throw "Unhandled segmentKind";
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
112
|
|
|
837
113
|
/**
|
|
838
114
|
*
|
|
@@ -899,122 +175,80 @@ function sortScore(name) {
|
|
|
899
175
|
);
|
|
900
176
|
}
|
|
901
177
|
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
.flatMap((section) => {
|
|
913
|
-
const routeParamMatch = section.match(/([A-Z][A-Za-z0-9]*)(_?_?)$/);
|
|
914
|
-
const maybeParam = routeParamMatch && routeParamMatch[1];
|
|
915
|
-
switch (segmentKind(section)) {
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
function fetcherModule(name) {
|
|
181
|
+
let moduleName = name.join(".");
|
|
182
|
+
// TODO need to account for splat routes/etc.
|
|
183
|
+
let modulePath = name.join("/");
|
|
184
|
+
let fetcherPath = routeHelpers
|
|
185
|
+
.parseRouteParamsWithStatic(name)
|
|
186
|
+
.map((param) => {
|
|
187
|
+
switch (param.kind) {
|
|
916
188
|
case "static": {
|
|
917
|
-
return
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
return [`\\\\/`];
|
|
189
|
+
return param.name === "Index"
|
|
190
|
+
? `[]`
|
|
191
|
+
: `[ "${camelToKebab(param.name)}" ]`;
|
|
921
192
|
}
|
|
922
|
-
case "
|
|
923
|
-
return
|
|
193
|
+
case "optional": {
|
|
194
|
+
return `Pages.Internal.Router.maybeToList params.${param.name}`;
|
|
924
195
|
}
|
|
925
196
|
case "required-splat": {
|
|
926
|
-
return
|
|
197
|
+
return `Pages.Internal.Router.nonEmptyToList params.${param.name}`;
|
|
927
198
|
}
|
|
928
|
-
case "
|
|
929
|
-
return [
|
|
199
|
+
case "dynamic": {
|
|
200
|
+
return `[ params.${param.name} ]`;
|
|
930
201
|
}
|
|
931
|
-
case "optional": {
|
|
932
|
-
return
|
|
202
|
+
case "optional-splat": {
|
|
203
|
+
return `params.${param.name}`;
|
|
933
204
|
}
|
|
934
205
|
}
|
|
935
206
|
})
|
|
936
|
-
.join("");
|
|
207
|
+
.join(", ");
|
|
937
208
|
|
|
938
|
-
|
|
939
|
-
case matches of
|
|
940
|
-
[ ${parsedParams
|
|
941
|
-
.flatMap((parsedParam) => {
|
|
942
|
-
switch (parsedParam.kind) {
|
|
943
|
-
case "optional": {
|
|
944
|
-
return parsedParam.name;
|
|
945
|
-
}
|
|
946
|
-
case "dynamic": {
|
|
947
|
-
return `Just ${parsedParam.name}`;
|
|
948
|
-
}
|
|
949
|
-
case "required-splat": {
|
|
950
|
-
return `Just splat`;
|
|
951
|
-
}
|
|
952
|
-
case "optional-splat": {
|
|
953
|
-
return `splat`;
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
})
|
|
957
|
-
.join(", ")} ] ->
|
|
958
|
-
Just ${
|
|
959
|
-
parsedParams.length === 0
|
|
960
|
-
? pathNormalizedName(name)
|
|
961
|
-
: `( ${pathNormalizedName(name)} { ${parsedParams.map(
|
|
962
|
-
(param) => {
|
|
963
|
-
return `${param.name} = ${prefixThing(param)}${
|
|
964
|
-
param.name
|
|
965
|
-
}`;
|
|
966
|
-
}
|
|
967
|
-
)} } )`
|
|
968
|
-
}
|
|
969
|
-
_ ->
|
|
970
|
-
Nothing
|
|
209
|
+
return `module Fetcher.${moduleName} exposing (submit)
|
|
971
210
|
|
|
972
|
-
|
|
211
|
+
{-| -}
|
|
973
212
|
|
|
974
|
-
|
|
975
|
-
|
|
213
|
+
import Bytes exposing (Bytes)
|
|
214
|
+
import Bytes.Decode
|
|
215
|
+
import FormDecoder
|
|
216
|
+
import Http
|
|
217
|
+
import Pages.Fetcher
|
|
218
|
+
import Route.${moduleName}
|
|
976
219
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
220
|
+
|
|
221
|
+
submit :
|
|
222
|
+
(Result Http.Error Route.${moduleName}.ActionData -> msg)
|
|
223
|
+
->
|
|
224
|
+
{ fields : List ( String, String )
|
|
225
|
+
, headers : List ( String, String )
|
|
226
|
+
}
|
|
227
|
+
-> Pages.Fetcher.Fetcher msg
|
|
228
|
+
submit toMsg options =
|
|
229
|
+
{ decoder =
|
|
230
|
+
\\bytesResult ->
|
|
231
|
+
bytesResult
|
|
232
|
+
|> Result.andThen
|
|
233
|
+
(\\okBytes ->
|
|
234
|
+
okBytes
|
|
235
|
+
|> Bytes.Decode.decode Route.${moduleName}.w3_decode_ActionData
|
|
236
|
+
|> Result.fromMaybe (Http.BadBody "Couldn't decode bytes.")
|
|
237
|
+
)
|
|
238
|
+
|> toMsg
|
|
239
|
+
, fields = options.fields
|
|
240
|
+
, headers = ("elm-pages-action-only", "true") :: options.headers
|
|
241
|
+
, url = ${
|
|
242
|
+
fetcherPath === ""
|
|
243
|
+
? 'Just "/content.dat"'
|
|
244
|
+
: `[ ${fetcherPath}, [ "content.dat" ] ] |> List.concat |> String.join "/" |> Just`
|
|
245
|
+
}
|
|
987
246
|
}
|
|
988
|
-
|
|
247
|
+
|> Pages.Fetcher.Fetcher
|
|
248
|
+
`;
|
|
989
249
|
}
|
|
990
250
|
|
|
991
|
-
/**
|
|
992
|
-
* @param {string[]} name
|
|
993
|
-
*/
|
|
994
|
-
function routePathList(name) {
|
|
995
|
-
return withoutTrailingIndex(name)
|
|
996
|
-
.map((section) => {
|
|
997
|
-
const routeParamMatch = section.match(/([A-Z][A-Za-z0-9]*)_$/);
|
|
998
|
-
const maybeParam = routeParamMatch && routeParamMatch[1];
|
|
999
|
-
if (maybeParam) {
|
|
1000
|
-
return `params.${maybeParam.toLowerCase()}`;
|
|
1001
|
-
} else {
|
|
1002
|
-
return `"${camelToKebab(section)}"`;
|
|
1003
|
-
}
|
|
1004
|
-
})
|
|
1005
|
-
.join(", ");
|
|
1006
|
-
}
|
|
1007
251
|
|
|
1008
|
-
/**
|
|
1009
|
-
* @param {string[]} name
|
|
1010
|
-
*/
|
|
1011
|
-
function withoutTrailingIndex(name) {
|
|
1012
|
-
if (name[name.length - 1] === "Index") {
|
|
1013
|
-
return name.slice(0, -1);
|
|
1014
|
-
} else {
|
|
1015
|
-
return name;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
252
|
/**
|
|
1019
253
|
* Convert Strings from camelCase to kebab-case
|
|
1020
254
|
* @param {string} input
|
|
@@ -1023,42 +257,6 @@ function withoutTrailingIndex(name) {
|
|
|
1023
257
|
function camelToKebab(input) {
|
|
1024
258
|
return input.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1025
259
|
}
|
|
1026
|
-
/**
|
|
1027
|
-
* @param {string[]} name
|
|
1028
|
-
*/
|
|
1029
|
-
function isParameterizedRoute(name) {
|
|
1030
|
-
return name.some((section) => section.includes("_"));
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
/**
|
|
1034
|
-
* @param {string[]} name
|
|
1035
|
-
*/
|
|
1036
|
-
function pathNormalizedName(name) {
|
|
1037
|
-
return name.join("__");
|
|
1038
|
-
}
|
|
1039
260
|
|
|
1040
|
-
/**
|
|
1041
|
-
* @param {string[]} name
|
|
1042
|
-
*/
|
|
1043
|
-
function moduleName(name) {
|
|
1044
|
-
return name.join(".");
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
function paramAsElmString(param) {
|
|
1048
|
-
switch (param.kind) {
|
|
1049
|
-
case "dynamic": {
|
|
1050
|
-
return "stringToString";
|
|
1051
|
-
}
|
|
1052
|
-
case "optional": {
|
|
1053
|
-
return "maybeToString";
|
|
1054
|
-
}
|
|
1055
|
-
case "required-splat": {
|
|
1056
|
-
return "nonEmptyToString";
|
|
1057
|
-
}
|
|
1058
|
-
case "optional-splat": {
|
|
1059
|
-
return "listToString";
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
261
|
|
|
1064
262
|
module.exports = { generateTemplateModuleConnector, sortTemplates };
|