elm-pages 3.0.0-beta.2 → 3.0.0-beta.4

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.
@@ -1,7 +1,11 @@
1
1
  module Pages.Review.DeadCodeEliminateData exposing (rule)
2
2
 
3
+ import Dict exposing (Dict)
3
4
  import Elm.Syntax.Declaration as Declaration exposing (Declaration)
5
+ import Elm.Syntax.Exposing exposing (Exposing)
4
6
  import Elm.Syntax.Expression as Expression exposing (Expression)
7
+ import Elm.Syntax.Import exposing (Import)
8
+ import Elm.Syntax.ModuleName exposing (ModuleName)
5
9
  import Elm.Syntax.Node as Node exposing (Node)
6
10
  import Review.Fix
7
11
  import Review.ModuleNameLookupTable as ModuleNameLookupTable exposing (ModuleNameLookupTable)
@@ -9,7 +13,50 @@ import Review.Rule as Rule exposing (Error, Rule)
9
13
 
10
14
 
11
15
  type alias Context =
12
- { lookupTable : ModuleNameLookupTable }
16
+ { lookupTable : ModuleNameLookupTable
17
+ , importContext : Dict (List String) ImportContext
18
+ }
19
+
20
+
21
+ type ImportReference
22
+ = QualifiedReference
23
+ | UnqualifiedReference (List String)
24
+
25
+
26
+ type alias ImportContext =
27
+ { moduleName : ModuleName
28
+ , moduleAlias : Maybe ModuleName
29
+ , exposedFunctions : Exposed
30
+
31
+ --Maybe Exposing
32
+ }
33
+
34
+
35
+ type Exposed
36
+ = AllExposed
37
+ | SomeExposed (List String)
38
+
39
+
40
+ toImportContext : Import -> ( List String, ImportContext )
41
+ toImportContext import_ =
42
+ ( import_.moduleName |> Node.value
43
+ , { moduleName = import_.moduleName |> Node.value
44
+ , moduleAlias = import_.moduleAlias |> Maybe.map Node.value
45
+ , exposedFunctions =
46
+ import_.exposingList
47
+ |> Maybe.map Node.value
48
+ |> Maybe.map
49
+ (\exposingList ->
50
+ case exposingList of
51
+ Elm.Syntax.Exposing.All _ ->
52
+ AllExposed
53
+
54
+ Elm.Syntax.Exposing.Explicit nodes ->
55
+ AllExposed
56
+ )
57
+ |> Maybe.withDefault (SomeExposed [])
58
+ }
59
+ )
13
60
 
14
61
 
15
62
  rule : Rule
@@ -17,6 +64,7 @@ rule =
17
64
  Rule.newModuleRuleSchemaUsingContextCreator "Pages.Review.DeadCodeEliminateData" initialContext
18
65
  |> Rule.withExpressionEnterVisitor expressionVisitor
19
66
  |> Rule.withDeclarationEnterVisitor declarationVisitor
67
+ |> Rule.withImportVisitor importVisitor
20
68
  |> Rule.fromModuleRuleSchema
21
69
 
22
70
 
@@ -25,11 +73,27 @@ initialContext =
25
73
  Rule.initContextCreator
26
74
  (\lookupTable () ->
27
75
  { lookupTable = lookupTable
76
+ , importContext = Dict.empty
28
77
  }
29
78
  )
30
79
  |> Rule.withModuleNameLookupTable
31
80
 
32
81
 
82
+ importVisitor : Node Import -> Context -> ( List (Rule.Error {}), Context )
83
+ importVisitor node context =
84
+ let
85
+ ( key, value ) =
86
+ Node.value node
87
+ |> toImportContext
88
+ in
89
+ ( []
90
+ , { context
91
+ | importContext =
92
+ context.importContext |> Dict.insert key value
93
+ }
94
+ )
95
+
96
+
33
97
  declarationVisitor : Node Declaration -> Context -> ( List (Error {}), Context )
34
98
  declarationVisitor node context =
35
99
  case Node.value node of
@@ -47,7 +111,7 @@ declarationVisitor node context =
47
111
  case Node.value recordSetter of
48
112
  ( keyNode, valueNode ) ->
49
113
  if Node.value keyNode == "data" || Node.value keyNode == "action" then
50
- if isAlreadyApplied (Node.value valueNode) then
114
+ if isAlreadyApplied context.lookupTable (Node.value valueNode) then
51
115
  Nothing
52
116
 
53
117
  else
@@ -66,9 +130,12 @@ declarationVisitor node context =
66
130
  , details = [ "" ]
67
131
  }
68
132
  (Node.range dataValue)
69
- -- TODO need to check the right way to refer to `DataSource.fail` based on imports
70
133
  -- TODO need to replace `action` as well
71
- [ Review.Fix.replaceRangeBy (Node.range dataValue) "data = DataSource.fail \"\"\n "
134
+ [ ("data = "
135
+ ++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
136
+ ++ " \"\"\n "
137
+ )
138
+ |> Review.Fix.replaceRangeBy (Node.range dataValue)
72
139
  ]
73
140
  ]
74
141
  , context
@@ -99,7 +166,7 @@ expressionVisitor node context =
99
166
  case Node.value recordSetter of
100
167
  ( keyNode, valueNode ) ->
101
168
  if Node.value keyNode == "data" || Node.value keyNode == "action" then
102
- if isAlreadyApplied (Node.value valueNode) then
169
+ if isAlreadyApplied context.lookupTable (Node.value valueNode) then
103
170
  Nothing
104
171
 
105
172
  else
@@ -122,16 +189,23 @@ expressionVisitor node context =
122
189
  ++ " = "
123
190
  ++ (case pageBuilderName of
124
191
  "preRender" ->
125
- "\\_ -> DataSource.fail \"\""
192
+ "\\_ -> "
193
+ ++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
194
+ ++ " \"\""
126
195
 
127
196
  "preRenderWithFallback" ->
128
- "\\_ -> DataSource.fail \"\""
197
+ "\\_ -> "
198
+ ++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
199
+ ++ " \"\""
129
200
 
130
201
  "serverRender" ->
131
- "\\_ -> Request.oneOf []\n "
202
+ "\\_ -> "
203
+ ++ referenceFunction context.importContext ( [ "Server", "Request" ], "oneOf" )
204
+ ++ " []\n "
132
205
 
133
206
  "single" ->
134
- "DataSource.fail \"\"\n "
207
+ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
208
+ ++ " \"\"\n "
135
209
 
136
210
  _ ->
137
211
  "data"
@@ -150,18 +224,56 @@ expressionVisitor node context =
150
224
  ( [], context )
151
225
 
152
226
 
153
- isAlreadyApplied : Expression -> Bool
154
- isAlreadyApplied expression =
227
+ referenceFunction : Dict (List String) ImportContext -> ( List String, String ) -> String
228
+ referenceFunction dict ( rawModuleName, rawFunctionName ) =
229
+ let
230
+ ( moduleName, functionName ) =
231
+ case dict |> Dict.get rawModuleName of
232
+ Just import_ ->
233
+ ( import_.moduleAlias |> Maybe.withDefault rawModuleName
234
+ , rawFunctionName
235
+ )
236
+
237
+ Nothing ->
238
+ ( rawModuleName, rawFunctionName )
239
+ in
240
+ moduleName ++ [ functionName ] |> String.join "."
241
+
242
+
243
+ isAlreadyApplied : ModuleNameLookupTable -> Expression -> Bool
244
+ isAlreadyApplied lookupTable expression =
155
245
  case expression of
156
246
  Expression.LambdaExpression info ->
157
247
  case Node.value info.expression of
158
248
  Expression.Application applicationNodes ->
159
249
  case applicationNodes |> List.map Node.value of
160
- (Expression.FunctionOrValue [ "DataSource" ] "fail") :: _ ->
161
- True
250
+ (Expression.FunctionOrValue _ "fail") :: _ ->
251
+ let
252
+ resolvedModuleName : ModuleName
253
+ resolvedModuleName =
254
+ applicationNodes
255
+ |> List.head
256
+ |> Maybe.andThen
257
+ (\functionNode ->
258
+ ModuleNameLookupTable.moduleNameFor lookupTable functionNode
259
+ )
260
+ |> Maybe.withDefault []
261
+ in
262
+ resolvedModuleName == [ "DataSource" ]
162
263
 
163
- (Expression.FunctionOrValue [ "Request" ] "oneOf") :: (Expression.ListExpr []) :: _ ->
164
- True
264
+ (Expression.FunctionOrValue _ "oneOf") :: (Expression.ListExpr []) :: _ ->
265
+ let
266
+ resolvedModuleName : ModuleName
267
+ resolvedModuleName =
268
+ applicationNodes
269
+ |> List.head
270
+ |> Maybe.andThen
271
+ (\functionNode ->
272
+ ModuleNameLookupTable.moduleNameFor lookupTable functionNode
273
+ )
274
+ |> Maybe.withDefault []
275
+ in
276
+ resolvedModuleName == [ "Server", "Request" ]
165
277
 
166
278
  _ ->
167
279
  False
@@ -171,8 +283,19 @@ isAlreadyApplied expression =
171
283
 
172
284
  Expression.Application applicationNodes ->
173
285
  case applicationNodes |> List.map Node.value of
174
- (Expression.FunctionOrValue [ "DataSource" ] "fail") :: _ ->
175
- True
286
+ (Expression.FunctionOrValue _ "fail") :: _ ->
287
+ let
288
+ resolvedModuleName : ModuleName
289
+ resolvedModuleName =
290
+ applicationNodes
291
+ |> List.head
292
+ |> Maybe.andThen
293
+ (\functionNode ->
294
+ ModuleNameLookupTable.moduleNameFor lookupTable functionNode
295
+ )
296
+ |> Maybe.withDefault []
297
+ in
298
+ resolvedModuleName == [ "DataSource" ]
176
299
 
177
300
  _ ->
178
301
  False
@@ -12,6 +12,8 @@ all =
12
12
  \() ->
13
13
  """module Route.Index exposing (Data, Model, Msg, route)
14
14
 
15
+ import Server.Request as Request
16
+
15
17
  import DataSource exposing (DataSource)
16
18
  import RouteBuilder exposing (Page, StaticPayload, single)
17
19
  import Pages.PageUrl exposing (PageUrl)
@@ -64,6 +66,8 @@ data =
64
66
  |> Review.Test.whenFixed
65
67
  """module Route.Index exposing (Data, Model, Msg, route)
66
68
 
69
+ import Server.Request as Request
70
+
67
71
  import DataSource exposing (DataSource)
68
72
  import RouteBuilder exposing (Page, StaticPayload, single)
69
73
  import Pages.PageUrl exposing (PageUrl)
@@ -99,6 +103,104 @@ route =
99
103
  |> RouteBuilder.buildNoState { view = view }
100
104
 
101
105
 
106
+ data : DataSource Data
107
+ data =
108
+ DataSource.succeed ()
109
+ """
110
+ ]
111
+ , test "supports aliased DataSource module import" <|
112
+ \() ->
113
+ """module Route.Index exposing (Data, Model, Msg, route)
114
+
115
+ import Server.Request as Request
116
+ import DataSource as DS
117
+ import RouteBuilder exposing (Page, StaticPayload, single)
118
+ import Pages.PageUrl exposing (PageUrl)
119
+ import Pages.Url
120
+ import Path
121
+ import Route exposing (Route)
122
+ import Shared
123
+ import View exposing (View)
124
+
125
+
126
+ type alias Model =
127
+ {}
128
+
129
+
130
+ type alias Msg =
131
+ ()
132
+
133
+
134
+ type alias RouteParams =
135
+ {}
136
+
137
+
138
+ type alias Data =
139
+ ()
140
+
141
+
142
+ route : StatelessRoute RouteParams Data ActionData
143
+ route =
144
+ single
145
+ { head = head
146
+ , data = data
147
+ }
148
+ |> RouteBuilder.buildNoState { view = view }
149
+
150
+
151
+ data : DataSource Data
152
+ data =
153
+ DataSource.succeed ()
154
+ """
155
+ |> Review.Test.run rule
156
+ |> Review.Test.expectErrors
157
+ [ Review.Test.error
158
+ { message = "Codemod"
159
+ , details =
160
+ [ "" ]
161
+ , under =
162
+ """data = data
163
+ }"""
164
+ }
165
+ |> Review.Test.whenFixed
166
+ """module Route.Index exposing (Data, Model, Msg, route)
167
+
168
+ import Server.Request as Request
169
+ import DataSource as DS
170
+ import RouteBuilder exposing (Page, StaticPayload, single)
171
+ import Pages.PageUrl exposing (PageUrl)
172
+ import Pages.Url
173
+ import Path
174
+ import Route exposing (Route)
175
+ import Shared
176
+ import View exposing (View)
177
+
178
+
179
+ type alias Model =
180
+ {}
181
+
182
+
183
+ type alias Msg =
184
+ ()
185
+
186
+
187
+ type alias RouteParams =
188
+ {}
189
+
190
+
191
+ type alias Data =
192
+ ()
193
+
194
+
195
+ route : StatelessRoute RouteParams Data ActionData
196
+ route =
197
+ single
198
+ { head = head
199
+ , data = DS.fail ""
200
+ }
201
+ |> RouteBuilder.buildNoState { view = view }
202
+
203
+
102
204
  data : DataSource Data
103
205
  data =
104
206
  DataSource.succeed ()
@@ -108,6 +210,8 @@ data =
108
210
  \() ->
109
211
  """module Route.Blog.Slug_ exposing (Data, Model, Msg, route)
110
212
 
213
+ import Server.Request as Request
214
+
111
215
  import DataSource exposing (DataSource)
112
216
  import RouteBuilder exposing (Page, StaticPayload)
113
217
  import Pages.PageUrl exposing (PageUrl)
@@ -160,6 +264,8 @@ data =
160
264
  |> Review.Test.whenFixed
161
265
  """module Route.Blog.Slug_ exposing (Data, Model, Msg, route)
162
266
 
267
+ import Server.Request as Request
268
+
163
269
  import DataSource exposing (DataSource)
164
270
  import RouteBuilder exposing (Page, StaticPayload)
165
271
  import Pages.PageUrl exposing (PageUrl)
@@ -205,6 +311,8 @@ data =
205
311
  \() ->
206
312
  """module Route.Login exposing (Data, Model, Msg, route)
207
313
 
314
+ import Server.Request as Request
315
+
208
316
  type alias Model =
209
317
  {}
210
318
 
@@ -239,6 +347,8 @@ route =
239
347
  |> Review.Test.whenFixed
240
348
  """module Route.Login exposing (Data, Model, Msg, route)
241
349
 
350
+ import Server.Request as Request
351
+
242
352
  type alias Model =
243
353
  {}
244
354
 
@@ -271,6 +381,8 @@ route =
271
381
  |> Review.Test.whenFixed
272
382
  """module Route.Login exposing (Data, Model, Msg, route)
273
383
 
384
+ import Server.Request as Request
385
+
274
386
  type alias Model =
275
387
  {}
276
388
 
@@ -291,12 +403,112 @@ route =
291
403
  , action = \\_ -> Request.oneOf []
292
404
  }
293
405
  |> RouteBuilder.buildNoState { view = view }
406
+ """
407
+ ]
408
+ , test "uses appropriate import alias for Server.Request module" <|
409
+ \() ->
410
+ """module Route.Login exposing (Data, Model, Msg, route)
411
+
412
+ import Server.Request
413
+
414
+ type alias Model =
415
+ {}
416
+
417
+
418
+ type alias Msg =
419
+ ()
420
+
421
+
422
+ type alias RouteParams =
423
+ {}
424
+
425
+
426
+ route : StatelessRoute RouteParams Data ActionData
427
+ route =
428
+ RouteBuilder.serverRender
429
+ { head = head
430
+ , data = data
431
+ , action = action
432
+ }
433
+ |> RouteBuilder.buildNoState { view = view }
434
+ """
435
+ |> Review.Test.run rule
436
+ |> Review.Test.expectErrors
437
+ [ Review.Test.error
438
+ { message = "Codemod"
439
+ , details =
440
+ [ "" ]
441
+ , under =
442
+ """data = data
443
+ ,"""
444
+ }
445
+ |> Review.Test.whenFixed
446
+ """module Route.Login exposing (Data, Model, Msg, route)
447
+
448
+ import Server.Request
449
+
450
+ type alias Model =
451
+ {}
452
+
453
+
454
+ type alias Msg =
455
+ ()
456
+
457
+
458
+ type alias RouteParams =
459
+ {}
460
+
461
+
462
+ route : StatelessRoute RouteParams Data ActionData
463
+ route =
464
+ RouteBuilder.serverRender
465
+ { head = head
466
+ , data = \\_ -> Server.Request.oneOf []
467
+ , action = action
468
+ }
469
+ |> RouteBuilder.buildNoState { view = view }
470
+ """
471
+ , Review.Test.error
472
+ { message = "Codemod"
473
+ , details =
474
+ [ "" ]
475
+ , under =
476
+ """action = action
477
+ }"""
478
+ }
479
+ |> Review.Test.whenFixed
480
+ """module Route.Login exposing (Data, Model, Msg, route)
481
+
482
+ import Server.Request
483
+
484
+ type alias Model =
485
+ {}
486
+
487
+
488
+ type alias Msg =
489
+ ()
490
+
491
+
492
+ type alias RouteParams =
493
+ {}
494
+
495
+
496
+ route : StatelessRoute RouteParams Data ActionData
497
+ route =
498
+ RouteBuilder.serverRender
499
+ { head = head
500
+ , data = data
501
+ , action = \\_ -> Server.Request.oneOf []
502
+ }
503
+ |> RouteBuilder.buildNoState { view = view }
294
504
  """
295
505
  ]
296
506
  , test "no Request.oneOf fix after replacement is made" <|
297
507
  \() ->
298
508
  """module Route.Login exposing (Data, Model, Msg, route)
299
509
 
510
+ import Server.Request as Request
511
+
300
512
  type alias Model =
301
513
  {}
302
514
 
@@ -323,6 +535,8 @@ route =
323
535
  \() ->
324
536
  """module Route.Index exposing (Data, Model, Msg, route)
325
537
 
538
+ import Server.Request as Request
539
+
326
540
  import DataSource exposing (DataSource)
327
541
  import RouteBuilder exposing (Page, StaticPayload)
328
542
  import Pages.PageUrl exposing (PageUrl)
@@ -368,6 +582,8 @@ data =
368
582
  \() ->
369
583
  """module Shared exposing (Data, Model, Msg, template)
370
584
 
585
+ import Server.Request as Request
586
+
371
587
  import Browser.Navigation
372
588
  import DataSource
373
589
  import Html exposing (Html)
@@ -416,6 +632,8 @@ type alias Model =
416
632
  |> Review.Test.whenFixed
417
633
  """module Shared exposing (Data, Model, Msg, template)
418
634
 
635
+ import Server.Request as Request
636
+
419
637
  import Browser.Navigation
420
638
  import DataSource
421
639
  import Html exposing (Html)
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 2471752417, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 1646606691, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 2471752417,
85
+ initialSeed: 1646606691,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleNoColor",
88
88
  verbosity: verbosity,
@@ -82,12 +82,10 @@ async function runElmCodegenCli(templates, basePath, phase) {
82
82
  }
83
83
  });
84
84
  const filesToGenerate = await promise;
85
- console.dir(filesToGenerate.map((file) => file.path));
86
85
 
87
86
  return filesToGenerate;
88
87
  }
89
88
 
90
-
91
89
  /**
92
90
  *
93
91
  * @param {string[][]} templates
@@ -153,8 +151,6 @@ function sortScore(name) {
153
151
  );
154
152
  }
155
153
 
156
-
157
-
158
154
  function fetcherModule(name) {
159
155
  let moduleName = name.join(".");
160
156
  // TODO need to account for splat routes/etc.
@@ -226,7 +222,6 @@ submit toMsg options =
226
222
  `;
227
223
  }
228
224
 
229
-
230
225
  /**
231
226
  * Convert Strings from camelCase to kebab-case
232
227
  * @param {string} input
@@ -236,5 +231,4 @@ function camelToKebab(input) {
236
231
  return input.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
237
232
  }
238
233
 
239
-
240
234
  module.exports = { generateTemplateModuleConnector, sortTemplates };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elm-pages",
3
- "version": "3.0.0-beta.2",
3
+ "version": "3.0.0-beta.4",
4
4
  "homepage": "https://elm-pages.com",
5
5
  "moduleResolution": "node",
6
6
  "description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
@@ -10,7 +10,6 @@
10
10
  "test": "./test.sh",
11
11
  "test:snapshot": "(cd examples/escaping && npm install && npm test) && (cd examples/base-path && npm install && npm test)",
12
12
  "cypress": "npm start & cypress run",
13
- "prepare": "npm run build:generator",
14
13
  "build:generator": "elm-codegen install && (cd codegen && lamdera make Generate.elm --output elm-pages-codegen.js)",
15
14
  "review": "elm-review"
16
15
  },
@@ -6,7 +6,7 @@ module Form.Field exposing
6
6
  , required, withClientValidation, withInitialValue, map
7
7
  , email, password, search, telephone, url, textarea
8
8
  , withMax, withMin, withStep, withMinLength, withMaxLength
9
- , No(..), Yes(..)
9
+ , No, Yes
10
10
  )
11
11
 
12
12
  {-|
package/src/Head/Seo.elm CHANGED
@@ -455,9 +455,9 @@ tags (Content common details) =
455
455
  -}
456
456
  [ ( "og:type", "article" |> Head.raw |> Just )
457
457
  , ( "article:section", articleDetails.section |> Maybe.map Head.raw )
458
- , ( "article:published_time", articleDetails.publishedTime |> Maybe.map (DateOrDateTime.dateOrDateTimeToIso8601String >> Head.raw) )
459
- , ( "article:modified_time", articleDetails.modifiedTime |> Maybe.map (DateOrDateTime.dateOrDateTimeToIso8601String >> Head.raw) )
460
- , ( "article:expiration_time", articleDetails.expirationTime |> Maybe.map (DateOrDateTime.dateOrDateTimeToIso8601String >> Head.raw) )
458
+ , ( "article:published_time", articleDetails.publishedTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
459
+ , ( "article:modified_time", articleDetails.modifiedTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
460
+ , ( "article:expiration_time", articleDetails.expirationTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
461
461
  ]
462
462
  ++ List.map
463
463
  (\tag -> ( "article:tag", tag |> Head.raw |> Just ))
@@ -466,7 +466,7 @@ tags (Content common details) =
466
466
  Book bookDetails ->
467
467
  [ ( "og:type", "book" |> Head.raw |> Just )
468
468
  , ( "og:isbn", bookDetails.isbn |> Maybe.map Head.raw )
469
- , ( "og:release_date", bookDetails.releaseDate |> Maybe.map (DateOrDateTime.dateOrDateTimeToIso8601String >> Head.raw) )
469
+ , ( "og:release_date", bookDetails.releaseDate |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
470
470
  ]
471
471
  ++ List.map
472
472
  (\tag -> ( "book:tag", tag |> Head.raw |> Just ))