elm-pages 2.1.11 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  2. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  3. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  4. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  5. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
  8. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
  9. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
  10. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
  11. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  12. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  13. package/generator/{template/public/style.css → review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
  23. package/generator/review/elm.json +13 -4
  24. package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
  25. package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
  26. package/generator/src/RouteBuilder.elm +420 -0
  27. package/generator/src/SharedTemplate.elm +4 -5
  28. package/generator/src/SiteConfig.elm +3 -9
  29. package/generator/src/build.js +308 -95
  30. package/generator/src/cli.js +103 -8
  31. package/generator/src/codegen.js +192 -35
  32. package/generator/src/compile-elm.js +183 -31
  33. package/generator/src/dev-server.js +353 -96
  34. package/generator/src/elm-application.json +3 -1
  35. package/generator/src/elm-codegen.js +34 -0
  36. package/generator/src/elm-file-constants.js +2 -0
  37. package/generator/src/error-formatter.js +20 -1
  38. package/generator/src/generate-template-module-connector.js +120 -924
  39. package/generator/src/hello.ts +5 -0
  40. package/generator/src/pre-render-html.js +58 -104
  41. package/generator/src/render-worker.js +27 -13
  42. package/generator/src/render.js +252 -197
  43. package/generator/src/request-cache-fs.js +18 -0
  44. package/generator/src/request-cache.js +128 -56
  45. package/generator/src/rewrite-client-elm-json.js +49 -0
  46. package/generator/src/route-codegen-helpers.js +62 -1
  47. package/generator/static-code/dev-style.css +22 -0
  48. package/generator/static-code/elm-pages.js +43 -39
  49. package/generator/static-code/hmr.js +98 -88
  50. package/generator/template/app/Api.elm +25 -0
  51. package/generator/template/app/ErrorPage.elm +38 -0
  52. package/generator/template/app/Route/Index.elm +87 -0
  53. package/generator/template/{src → app}/Shared.elm +34 -13
  54. package/generator/template/app/Site.elm +19 -0
  55. package/generator/template/{src → app}/View.elm +0 -0
  56. package/generator/template/elm-pages.config.mjs +5 -0
  57. package/generator/template/elm.json +1 -0
  58. package/generator/template/{public/index.js → index.ts} +7 -3
  59. package/generator/template/package.json +4 -4
  60. package/generator/template/public/favicon.ico +0 -0
  61. package/generator/template/public/images/icon-png.png +0 -0
  62. package/generator/template/src/.gitkeep +0 -0
  63. package/generator/template/style.css +4 -0
  64. package/package.json +30 -23
  65. package/src/ApiRoute.elm +176 -43
  66. package/src/BuildError.elm +10 -1
  67. package/src/CookieParser.elm +84 -0
  68. package/src/DataSource/Env.elm +38 -0
  69. package/src/DataSource/File.elm +27 -16
  70. package/src/DataSource/Glob.elm +126 -80
  71. package/src/DataSource/Http.elm +283 -304
  72. package/src/DataSource/Internal/Glob.elm +5 -21
  73. package/src/DataSource/Internal/Request.elm +25 -0
  74. package/src/DataSource/Port.elm +17 -14
  75. package/src/DataSource.elm +55 -318
  76. package/src/Form/Field.elm +717 -0
  77. package/src/Form/FieldStatus.elm +36 -0
  78. package/src/Form/FieldView.elm +417 -0
  79. package/src/Form/FormData.elm +22 -0
  80. package/src/Form/Validation.elm +391 -0
  81. package/src/Form/Value.elm +118 -0
  82. package/src/Form.elm +1683 -0
  83. package/src/FormData.elm +58 -0
  84. package/src/FormDecoder.elm +102 -0
  85. package/src/Head/Seo.elm +12 -4
  86. package/src/Head.elm +12 -2
  87. package/src/HtmlPrinter.elm +1 -1
  88. package/src/Internal/ApiRoute.elm +17 -4
  89. package/src/Internal/Request.elm +7 -0
  90. package/src/PageServerResponse.elm +68 -0
  91. package/src/Pages/ContentCache.elm +1 -229
  92. package/src/Pages/Fetcher.elm +58 -0
  93. package/src/Pages/FormState.elm +256 -0
  94. package/src/Pages/Generate.elm +800 -0
  95. package/src/Pages/Internal/Form.elm +17 -0
  96. package/src/Pages/Internal/NotFoundReason.elm +3 -55
  97. package/src/Pages/Internal/Platform/Cli.elm +777 -579
  98. package/src/Pages/Internal/Platform/Effect.elm +5 -5
  99. package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
  100. package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
  101. package/src/Pages/Internal/Platform.elm +1244 -504
  102. package/src/Pages/Internal/ResponseSketch.elm +19 -0
  103. package/src/Pages/Internal/RoutePattern.elm +596 -45
  104. package/src/Pages/Manifest.elm +26 -0
  105. package/src/Pages/Msg.elm +79 -0
  106. package/src/Pages/ProgramConfig.elm +67 -14
  107. package/src/Pages/SiteConfig.elm +3 -6
  108. package/src/Pages/StaticHttp/Request.elm +4 -2
  109. package/src/Pages/StaticHttpRequest.elm +50 -215
  110. package/src/Pages/Transition.elm +70 -0
  111. package/src/Path.elm +1 -0
  112. package/src/Pattern.elm +98 -0
  113. package/src/RenderRequest.elm +2 -2
  114. package/src/RequestsAndPending.elm +111 -9
  115. package/src/Server/Request.elm +1253 -0
  116. package/src/Server/Response.elm +292 -0
  117. package/src/Server/Session.elm +316 -0
  118. package/src/Server/SetCookie.elm +169 -0
  119. package/src/TerminalText.elm +1 -1
  120. package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
  121. package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
  122. package/generator/src/Page.elm +0 -359
  123. package/generator/src/codegen-template-module.js +0 -183
  124. package/generator/src/elm-pages-js-minified.js +0 -1
  125. package/generator/template/src/Api.elm +0 -14
  126. package/generator/template/src/Page/Index.elm +0 -69
  127. package/generator/template/src/Site.elm +0 -41
  128. package/src/DataSource/ServerRequest.elm +0 -60
  129. package/src/Internal/OptimizedDecoder.elm +0 -18
  130. package/src/KeepOrDiscard.elm +0 -6
  131. package/src/OptimizedDecoder/Pipeline.elm +0 -335
  132. package/src/OptimizedDecoder.elm +0 -818
  133. package/src/Pages/Internal/ApplicationType.elm +0 -6
  134. package/src/Pages/Secrets.elm +0 -83
  135. package/src/Secrets.elm +0 -111
  136. package/src/SecretsDict.elm +0 -45
@@ -0,0 +1,19 @@
1
+ module Pages.Internal.ResponseSketch exposing (ResponseSketch(..))
2
+
3
+ {-|
4
+
5
+ @docs ResponseSketch
6
+
7
+ -}
8
+
9
+ import Pages.Internal.NotFoundReason exposing (NotFoundReason)
10
+ import Path exposing (Path)
11
+
12
+
13
+ {-| -}
14
+ type ResponseSketch data action shared
15
+ = RenderPage data (Maybe action)
16
+ | HotUpdate data shared (Maybe action)
17
+ | Redirect String
18
+ | NotFound { reason : NotFoundReason, path : Path }
19
+ | Action action
@@ -1,13 +1,21 @@
1
- module Pages.Internal.RoutePattern exposing (Ending(..), RoutePattern, Segment(..), codec, view)
1
+ module Pages.Internal.RoutePattern exposing
2
+ ( Ending(..), RoutePattern, Segment(..), view, toVariant, routeToBranch
3
+ , Param(..), RouteParam(..), fromModuleName, hasRouteParams, repeatWithoutOptionalEnding, toModuleName, toRouteParamTypes, toRouteParamsRecord, toVariantName
4
+ )
2
5
 
3
6
  {-| Exposed for internal use only (used in generated code).
4
7
 
5
- @docs Ending, RoutePattern, Segment, codec, view
8
+ @docs Ending, RoutePattern, Segment, view, toVariant, routeToBranch
9
+
10
+ @docs Param, RouteParam, fromModuleName, hasRouteParams, repeatWithoutOptionalEnding, toModuleName, toRouteParamTypes, toRouteParamsRecord, toVariantName
6
11
 
7
12
  -}
8
13
 
9
- import Codec exposing (Codec)
14
+ import Elm
15
+ import Elm.Annotation exposing (Annotation)
16
+ import Elm.CodeGen
10
17
  import Html exposing (Html)
18
+ import Regex exposing (Regex)
11
19
 
12
20
 
13
21
  {-| -}
@@ -18,63 +26,506 @@ type alias RoutePattern =
18
26
 
19
27
 
20
28
  {-| -}
21
- type Ending
22
- = Optional String
23
- | RequiredSplat
24
- | OptionalSplat
29
+ toModuleName : RoutePattern -> List String
30
+ toModuleName route =
31
+ let
32
+ segmentsAsModuleParts : List String
33
+ segmentsAsModuleParts =
34
+ route.segments
35
+ |> List.foldl
36
+ (\segment soFar ->
37
+ case segment of
38
+ StaticSegment name ->
39
+ soFar ++ [ name ]
40
+
41
+ DynamicSegment name ->
42
+ soFar ++ [ name ++ "_" ]
43
+ )
44
+ []
45
+ in
46
+ case route.ending of
47
+ Nothing ->
48
+ segmentsAsModuleParts
49
+
50
+ Just ending ->
51
+ segmentsAsModuleParts ++ [ endingToVariantName ending |> Tuple.first ]
25
52
 
26
53
 
27
54
  {-| -}
28
- type Segment
29
- = StaticSegment String
30
- | DynamicSegment String
55
+ fromModuleName : List String -> Maybe RoutePattern
56
+ fromModuleName moduleNameSegments =
57
+ case moduleNameSegments |> List.reverse of
58
+ lastSegment :: firstSegmentsInReverse ->
59
+ case tryAsEnding lastSegment of
60
+ Just ending ->
61
+ { segments =
62
+ firstSegmentsInReverse
63
+ |> List.reverse
64
+ |> List.map segmentToParam
65
+ , ending = Just ending
66
+ }
67
+ |> Just
68
+
69
+ Nothing ->
70
+ { segments =
71
+ moduleNameSegments
72
+ |> List.map segmentToParam
73
+ , ending = Nothing
74
+ }
75
+ |> Just
76
+
77
+ [] ->
78
+ Just { segments = [], ending = Nothing }
31
79
 
32
80
 
33
81
  {-| -}
34
- codec : Codec RoutePattern
35
- codec =
36
- Codec.object RoutePattern
37
- |> Codec.field "segments" .segments (Codec.list segmentCodec)
38
- |> Codec.field "ending" .ending (Codec.maybe endingCodec)
39
- |> Codec.buildObject
82
+ toRouteParamsRecord : RoutePattern -> List ( String, Annotation )
83
+ toRouteParamsRecord pattern =
84
+ (pattern.segments
85
+ |> List.concatMap
86
+ (\segment ->
87
+ case segment of
88
+ StaticSegment _ ->
89
+ []
40
90
 
91
+ DynamicSegment name ->
92
+ [ ( name |> decapitalize, Elm.Annotation.string ) ]
93
+ )
94
+ )
95
+ ++ (case pattern.ending of
96
+ Nothing ->
97
+ []
41
98
 
42
- segmentCodec : Codec Segment
43
- segmentCodec =
44
- Codec.custom
45
- (\vStatic vDynamic value ->
46
- case value of
47
- StaticSegment string ->
48
- vStatic string
99
+ Just OptionalSplat ->
100
+ [ ( "splat"
101
+ , Elm.Annotation.list Elm.Annotation.string
102
+ )
103
+ ]
49
104
 
50
- DynamicSegment string ->
51
- vDynamic string
52
- )
53
- |> Codec.variant1 "StaticSegment" StaticSegment Codec.string
54
- |> Codec.variant1 "DynamicSegment" DynamicSegment Codec.string
55
- |> Codec.buildCustom
105
+ Just RequiredSplat ->
106
+ [ ( "splat"
107
+ , Elm.Annotation.tuple
108
+ Elm.Annotation.string
109
+ (Elm.Annotation.list Elm.Annotation.string)
110
+ )
111
+ ]
112
+
113
+ Just (Optional name) ->
114
+ [ ( name |> decapitalize
115
+ , Elm.Annotation.maybe Elm.Annotation.string
116
+ )
117
+ ]
118
+ )
56
119
 
57
120
 
58
- endingCodec : Codec Ending
59
- endingCodec =
60
- Codec.custom
61
- (\vOptional vRequiredSplat vOptionalSplat value ->
62
- case value of
63
- Optional string ->
64
- vOptional string
121
+ {-| -}
122
+ toRouteParamTypes : RoutePattern -> List ( String, Param )
123
+ toRouteParamTypes pattern =
124
+ (pattern.segments
125
+ |> List.concatMap
126
+ (\segment ->
127
+ case segment of
128
+ StaticSegment _ ->
129
+ []
65
130
 
66
- RequiredSplat ->
67
- vRequiredSplat
131
+ DynamicSegment name ->
132
+ [ ( name |> decapitalize, RequiredParam ) ]
133
+ )
134
+ )
135
+ ++ (case pattern.ending of
136
+ Nothing ->
137
+ []
68
138
 
69
- OptionalSplat ->
70
- vOptionalSplat
71
- )
72
- |> Codec.variant1 "Optional" Optional Codec.string
73
- |> Codec.variant0 "RequiredSplat" RequiredSplat
74
- |> Codec.variant0 "OptionalSplat" OptionalSplat
75
- |> Codec.buildCustom
139
+ Just OptionalSplat ->
140
+ [ ( "splat"
141
+ , OptionalSplatParam
142
+ )
143
+ ]
144
+
145
+ Just RequiredSplat ->
146
+ [ ( "splat"
147
+ , RequiredSplatParam
148
+ )
149
+ ]
150
+
151
+ Just (Optional name) ->
152
+ [ ( name |> decapitalize
153
+ , OptionalParam
154
+ )
155
+ ]
156
+ )
157
+
158
+
159
+ {-| -}
160
+ routeToBranch : RoutePattern -> List ( Elm.CodeGen.Pattern, Elm.CodeGen.Expression )
161
+ routeToBranch route =
162
+ case route.segments of
163
+ [ StaticSegment "Index" ] ->
164
+ [ ( Elm.CodeGen.listPattern [], Elm.CodeGen.val "Index" ) ]
165
+
166
+ _ ->
167
+ case route.ending of
168
+ Just ending ->
169
+ [ ( (case ending of
170
+ Optional _ ->
171
+ Elm.CodeGen.listPattern
172
+
173
+ _ ->
174
+ unconsPattern
175
+ )
176
+ ((route.segments
177
+ |> List.map
178
+ (\segment ->
179
+ case segment of
180
+ StaticSegment name ->
181
+ Elm.CodeGen.stringPattern (toKebab name)
182
+
183
+ DynamicSegment name ->
184
+ Elm.CodeGen.varPattern (decapitalize name)
185
+ )
186
+ )
187
+ ++ (case ending of
188
+ Optional name ->
189
+ [ Elm.CodeGen.varPattern (decapitalize name) ]
190
+
191
+ RequiredSplat ->
192
+ [ Elm.CodeGen.varPattern "splatFirst"
193
+ , Elm.CodeGen.varPattern "splatRest"
194
+ ]
195
+
196
+ OptionalSplat ->
197
+ [ Elm.CodeGen.varPattern "splat" ]
198
+ )
199
+ )
200
+ , toRecordVariant False route
201
+ )
202
+ ]
203
+ ++ (case ending of
204
+ Optional _ ->
205
+ [ ( Elm.CodeGen.listPattern
206
+ (route.segments
207
+ |> List.map
208
+ (\segment ->
209
+ case segment of
210
+ StaticSegment name ->
211
+ Elm.CodeGen.stringPattern (toKebab name)
212
+
213
+ DynamicSegment name ->
214
+ Elm.CodeGen.varPattern (decapitalize name)
215
+ )
216
+ )
217
+ , toRecordVariant True route
218
+ )
219
+ ]
220
+
221
+ _ ->
222
+ []
223
+ )
224
+
225
+ Nothing ->
226
+ [ ( Elm.CodeGen.listPattern
227
+ (route.segments
228
+ |> List.map
229
+ (\segment ->
230
+ case segment of
231
+ StaticSegment name ->
232
+ Elm.CodeGen.stringPattern (toKebab name)
233
+
234
+ DynamicSegment name ->
235
+ Elm.CodeGen.varPattern (decapitalize name)
236
+ )
237
+ )
238
+ , toRecordVariant False route
239
+ )
240
+ ]
241
+
242
+
243
+ {-| -}
244
+ type RouteParam
245
+ = StaticParam String
246
+ | DynamicParam String
247
+ | OptionalParam2 String
248
+ | RequiredSplatParam2
249
+ | OptionalSplatParam2
250
+
251
+
252
+ {-| -}
253
+ hasRouteParams : RoutePattern -> Bool
254
+ hasRouteParams route =
255
+ route
256
+ |> toVariantName
257
+ |> .params
258
+ |> List.any (not << isStatic)
259
+
260
+
261
+ {-| -}
262
+ isStatic : RouteParam -> Bool
263
+ isStatic routeParam =
264
+ case routeParam of
265
+ StaticParam _ ->
266
+ True
267
+
268
+ _ ->
269
+ False
270
+
271
+
272
+ {-| -}
273
+ repeatWithoutOptionalEnding : List RouteParam -> Maybe (List RouteParam)
274
+ repeatWithoutOptionalEnding routeParams =
275
+ case routeParams |> List.reverse of
276
+ (OptionalParam2 _) :: reverseRest ->
277
+ List.reverse reverseRest |> Just
278
+
279
+ OptionalSplatParam2 :: reverseRest ->
280
+ List.reverse reverseRest |> Just
281
+
282
+ _ ->
283
+ Nothing
284
+
285
+
286
+ {-| -}
287
+ toVariantName : RoutePattern -> { variantName : String, params : List RouteParam }
288
+ toVariantName route =
289
+ let
290
+ something : List ( String, Maybe RouteParam )
291
+ something =
292
+ route.segments
293
+ |> List.map
294
+ (\segment ->
295
+ case segment of
296
+ DynamicSegment name ->
297
+ ( name ++ "_"
298
+ , DynamicParam (decapitalize name)
299
+ |> Just
300
+ )
301
+
302
+ StaticSegment name ->
303
+ ( name
304
+ , if name == "Index" then
305
+ Nothing
306
+
307
+ else
308
+ Just (StaticParam (decapitalize name))
309
+ )
310
+ )
311
+
312
+ something2 : List ( String, Maybe RouteParam )
313
+ something2 =
314
+ something
315
+ ++ ([ Maybe.map
316
+ (\ending ->
317
+ case ending of
318
+ Optional name ->
319
+ ( name ++ "__"
320
+ , Just (OptionalParam2 (decapitalize name))
321
+ )
322
+
323
+ RequiredSplat ->
324
+ ( "SPLAT_"
325
+ , RequiredSplatParam2
326
+ |> Just
327
+ )
328
+
329
+ OptionalSplat ->
330
+ ( "SPLAT__"
331
+ , OptionalSplatParam2
332
+ |> Just
333
+ )
334
+ )
335
+ route.ending
336
+ ]
337
+ |> List.filterMap identity
338
+ )
339
+ in
340
+ something2
341
+ |> List.map Tuple.first
342
+ |> String.join "__"
343
+ |> (\name ->
344
+ { variantName = name
345
+ , params = something2 |> List.filterMap Tuple.second
346
+ }
347
+ )
348
+
349
+
350
+ {-| -}
351
+ toRecordVariant : Bool -> RoutePattern -> Elm.CodeGen.Expression
352
+ toRecordVariant nothingCase route =
353
+ let
354
+ constructorName : String
355
+ constructorName =
356
+ route |> toVariantName |> .variantName
357
+
358
+ innerType : Maybe Elm.CodeGen.Expression
359
+ innerType =
360
+ case fieldThings of
361
+ [] ->
362
+ Nothing
363
+
364
+ nonEmpty ->
365
+ nonEmpty |> Elm.CodeGen.record |> Just
366
+
367
+ fieldThings : List ( String, Elm.CodeGen.Expression )
368
+ fieldThings =
369
+ route
370
+ |> toVariantName
371
+ |> .params
372
+ |> List.filterMap
373
+ (\param ->
374
+ case param of
375
+ OptionalParam2 name ->
376
+ Just
377
+ ( decapitalize name
378
+ , if nothingCase then
379
+ Elm.CodeGen.val "Nothing"
76
380
 
381
+ else
382
+ [ Elm.CodeGen.val "Just", Elm.CodeGen.val (decapitalize name) ] |> Elm.CodeGen.apply
383
+ )
77
384
 
385
+ StaticParam _ ->
386
+ Nothing
387
+
388
+ DynamicParam name ->
389
+ Just
390
+ ( decapitalize name
391
+ , Elm.CodeGen.val (decapitalize name)
392
+ )
393
+
394
+ RequiredSplatParam2 ->
395
+ Just
396
+ ( "splat"
397
+ , Elm.CodeGen.tuple [ Elm.CodeGen.val "splatFirst", Elm.CodeGen.val "splatRest" ]
398
+ )
399
+
400
+ OptionalSplatParam2 ->
401
+ Just ( "splat", Elm.CodeGen.val "splat" )
402
+ )
403
+ in
404
+ case innerType of
405
+ Just innerRecord ->
406
+ Elm.CodeGen.apply
407
+ [ constructorName |> Elm.CodeGen.val
408
+ , innerRecord
409
+ ]
410
+
411
+ Nothing ->
412
+ constructorName |> Elm.CodeGen.val
413
+
414
+
415
+ {-| -}
416
+ toVariant : RoutePattern -> Elm.Variant
417
+ toVariant pattern =
418
+ if List.isEmpty pattern.segments && pattern.ending == Nothing then
419
+ Elm.variant "Index"
420
+
421
+ else
422
+ let
423
+ allSegments : List ( String, Maybe ( String, Annotation ) )
424
+ allSegments =
425
+ (pattern.segments
426
+ |> List.map
427
+ (\segment ->
428
+ case segment of
429
+ DynamicSegment name ->
430
+ ( name ++ "_", Just ( decapitalize name, Elm.Annotation.string ) )
431
+
432
+ StaticSegment name ->
433
+ ( name, Nothing )
434
+ )
435
+ )
436
+ ++ ([ Maybe.map endingToVariantName pattern.ending
437
+ ]
438
+ |> List.filterMap identity
439
+ )
440
+
441
+ fieldThings : List ( String, Annotation )
442
+ fieldThings =
443
+ allSegments
444
+ |> List.filterMap Tuple.second
445
+
446
+ noArgsOrNonEmptyRecordArg : List Annotation
447
+ noArgsOrNonEmptyRecordArg =
448
+ case fieldThings of
449
+ [] ->
450
+ []
451
+
452
+ nonEmpty ->
453
+ nonEmpty |> Elm.Annotation.record |> List.singleton
454
+ in
455
+ Elm.variantWith
456
+ (allSegments
457
+ |> List.map Tuple.first
458
+ |> String.join "__"
459
+ )
460
+ noArgsOrNonEmptyRecordArg
461
+
462
+
463
+ {-| -}
464
+ endingToVariantNameFields : Ending -> ( String, Maybe ( String, Elm.CodeGen.Expression ) )
465
+ endingToVariantNameFields ending =
466
+ case ending of
467
+ Optional name ->
468
+ ( name ++ "__"
469
+ , Just ( decapitalize name, [ Elm.CodeGen.val "Just", Elm.CodeGen.val (decapitalize name) ] |> Elm.CodeGen.apply )
470
+ )
471
+
472
+ RequiredSplat ->
473
+ ( "SPLAT_"
474
+ , Just
475
+ ( "splat"
476
+ , Elm.CodeGen.tuple
477
+ [ Elm.CodeGen.val "splatFirst"
478
+ , Elm.CodeGen.val "splatRest"
479
+ ]
480
+ )
481
+ )
482
+
483
+ OptionalSplat ->
484
+ ( "SPLAT__"
485
+ , Just ( "splat", Elm.CodeGen.val "splat" )
486
+ )
487
+
488
+
489
+ {-| -}
490
+ endingToVariantName : Ending -> ( String, Maybe ( String, Annotation ) )
491
+ endingToVariantName ending =
492
+ case ending of
493
+ Optional name ->
494
+ ( name ++ "__", Just ( decapitalize name, Elm.Annotation.maybe Elm.Annotation.string ) )
495
+
496
+ RequiredSplat ->
497
+ ( "SPLAT_"
498
+ , Just
499
+ ( "splat"
500
+ , Elm.Annotation.tuple
501
+ Elm.Annotation.string
502
+ (Elm.Annotation.list Elm.Annotation.string)
503
+ )
504
+ )
505
+
506
+ OptionalSplat ->
507
+ ( "SPLAT__"
508
+ , Just
509
+ ( "splat"
510
+ , Elm.Annotation.list Elm.Annotation.string
511
+ )
512
+ )
513
+
514
+
515
+ {-| -}
516
+ type Ending
517
+ = Optional String
518
+ | RequiredSplat
519
+ | OptionalSplat
520
+
521
+
522
+ {-| -}
523
+ type Segment
524
+ = StaticSegment String
525
+ | DynamicSegment String
526
+
527
+
528
+ {-| -}
78
529
  segmentToString : Segment -> String
79
530
  segmentToString segment =
80
531
  case segment of
@@ -113,6 +564,7 @@ view routePattern =
113
564
  )
114
565
 
115
566
 
567
+ {-| -}
116
568
  toString_ : List Segment -> String
117
569
  toString_ segments =
118
570
  "/"
@@ -120,3 +572,102 @@ toString_ segments =
120
572
  |> List.map segmentToString
121
573
  |> String.join "/"
122
574
  )
575
+
576
+
577
+ {-| -}
578
+ tryAsEnding : String -> Maybe Ending
579
+ tryAsEnding segment =
580
+ if segment == "SPLAT__" then
581
+ OptionalSplat
582
+ |> Just
583
+
584
+ else if segment == "SPLAT_" then
585
+ RequiredSplat
586
+ |> Just
587
+
588
+ else if segment |> String.endsWith "__" then
589
+ (segment
590
+ |> String.dropRight 2
591
+ |> Optional
592
+ )
593
+ |> Just
594
+
595
+ else
596
+ Nothing
597
+
598
+
599
+ {-| -}
600
+ segmentToParam : String -> Segment
601
+ segmentToParam segment =
602
+ if segment |> String.endsWith "_" then
603
+ segment
604
+ |> String.dropRight 1
605
+ |> DynamicSegment
606
+
607
+ else
608
+ segment
609
+ |> StaticSegment
610
+
611
+
612
+ {-| Decapitalize the first letter of a string.
613
+ decapitalize "This is a phrase" == "this is a phrase"
614
+ decapitalize "Hello, World" == "hello, World"
615
+ -}
616
+ decapitalize : String -> String
617
+ decapitalize word =
618
+ -- Source: https://github.com/elm-community/string-extra/blob/4.0.1/src/String/Extra.elm
619
+ changeCase Char.toLower word
620
+
621
+
622
+ {-| Change the case of the first letter of a string to either uppercase or
623
+ lowercase, depending of the value of `wantedCase`. This is an internal
624
+ function for use in `toSentenceCase` and `decapitalize`.
625
+ -}
626
+ changeCase : (Char -> Char) -> String -> String
627
+ changeCase mutator word =
628
+ -- Source: https://github.com/elm-community/string-extra/blob/4.0.1/src/String/Extra.elm
629
+ String.uncons word
630
+ |> Maybe.map (\( head, tail ) -> String.cons (mutator head) tail)
631
+ |> Maybe.withDefault ""
632
+
633
+
634
+ {-| -}
635
+ type Param
636
+ = RequiredParam
637
+ | OptionalParam
638
+ | RequiredSplatParam
639
+ | OptionalSplatParam
640
+
641
+
642
+ {-| -}
643
+ unconsPattern : List Elm.CodeGen.Pattern -> Elm.CodeGen.Pattern
644
+ unconsPattern list =
645
+ case list of
646
+ [] ->
647
+ Elm.CodeGen.listPattern []
648
+
649
+ listFirst :: listRest ->
650
+ List.foldl
651
+ (\soFar item ->
652
+ soFar
653
+ |> Elm.CodeGen.unConsPattern item
654
+ )
655
+ listFirst
656
+ listRest
657
+
658
+
659
+ {-| -}
660
+ toKebab : String -> String
661
+ toKebab string =
662
+ string
663
+ |> decapitalize
664
+ |> String.trim
665
+ |> Regex.replace (regexFromString "([A-Z])") (.match >> String.append "-")
666
+ |> Regex.replace (regexFromString "[_-\\s]+") (always "-")
667
+ |> String.toLower
668
+
669
+
670
+ {-| -}
671
+ regexFromString : String -> Regex
672
+ regexFromString =
673
+ Regex.fromString >> Maybe.withDefault Regex.never