elm-pages 2.1.10 → 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 +14 -5
  58. package/generator/template/{public/index.js → index.ts} +7 -3
  59. package/generator/template/package.json +5 -5
  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
@@ -1,12 +1,14 @@
1
1
  // @ts-check
2
2
 
3
3
  const path = require("path");
4
+ const mm = require("micromatch");
4
5
  const matter = require("gray-matter");
5
6
  const globby = require("globby");
6
7
  const fsPromises = require("fs").promises;
7
8
  const preRenderHtml = require("./pre-render-html.js");
8
9
  const { lookupOrPerform } = require("./request-cache.js");
9
10
  const kleur = require("kleur");
11
+ const cookie = require("cookie-signature");
10
12
  kleur.enabled = true;
11
13
 
12
14
  process.on("unhandledRejection", (error) => {
@@ -22,31 +24,41 @@ module.exports =
22
24
  * @param {string} basePath
23
25
  * @param {Object} elmModule
24
26
  * @param {string} path
25
- * @param {import('aws-lambda').APIGatewayProxyEvent} request
27
+ * @param {{ method: string; hostname: string; query: Record<string, string | undefined>; headers: Record<string, string>; host: string; pathname: string; port: number | null; protocol: string; rawUrl: string; }} request
26
28
  * @param {(pattern: string) => void} addDataSourceWatcher
29
+ * @param {boolean} hasFsAccess
27
30
  * @returns
28
31
  */
29
32
  async function run(
33
+ portsFile,
30
34
  basePath,
31
35
  elmModule,
32
36
  mode,
33
37
  path,
34
38
  request,
35
- addDataSourceWatcher
39
+ addDataSourceWatcher,
40
+ hasFsAccess
36
41
  ) {
42
+ const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(
43
+ hasFsAccess
44
+ );
45
+ resetInMemoryFs();
37
46
  foundErrors = false;
38
47
  pendingDataSourceResponses = [];
39
48
  pendingDataSourceCount = 0;
40
- // since init/update are never called in pre-renders, and DataSource.Http is called using undici
49
+ // since init/update are never called in pre-renders, and DataSource.Http is called using pure NodeJS HTTP fetching
41
50
  // we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
42
51
  XMLHttpRequest = {};
43
52
  const result = await runElmApp(
53
+ portsFile,
44
54
  basePath,
45
55
  elmModule,
46
56
  mode,
47
57
  path,
48
58
  request,
49
- addDataSourceWatcher
59
+ addDataSourceWatcher,
60
+ fs,
61
+ hasFsAccess
50
62
  );
51
63
  return result;
52
64
  };
@@ -56,49 +68,61 @@ module.exports =
56
68
  * @param {Object} elmModule
57
69
  * @param {string} pagePath
58
70
  * @param {string} mode
59
- * @param {import('aws-lambda').APIGatewayProxyEvent} request
71
+ * @param {{ method: string; hostname: string; query: string; headers: Object; host: string; pathname: string; port: string; protocol: string; rawUrl: string; }} request
60
72
  * @param {(pattern: string) => void} addDataSourceWatcher
61
73
  * @returns {Promise<({is404: boolean} & ( { kind: 'json'; contentJson: string} | { kind: 'html'; htmlString: string } | { kind: 'api-response'; body: string; }) )>}
62
74
  */
63
75
  function runElmApp(
76
+ portsFile,
64
77
  basePath,
65
78
  elmModule,
66
79
  mode,
67
80
  pagePath,
68
81
  request,
69
- addDataSourceWatcher
82
+ addDataSourceWatcher,
83
+ fs,
84
+ hasFsAccess
70
85
  ) {
71
86
  const isDevServer = mode !== "build";
72
87
  let patternsToWatch = new Set();
73
88
  let app = null;
74
89
  let killApp;
75
90
  return new Promise((resolve, reject) => {
76
- const isJson = pagePath.match(/content\.json\/?$/);
77
- const route = pagePath.replace(/content\.json\/?$/, "");
91
+ const isBytes = pagePath.match(/content\.dat\/?$/);
92
+ const route = pagePath
93
+ .replace(/content\.json\/?$/, "")
94
+ .replace(/content\.dat\/?$/, "");
78
95
 
79
96
  const modifiedRequest = { ...request, path: route };
80
97
  // console.log("StaticHttp cache keys", Object.keys(global.staticHttpCache));
81
- app = elmModule.Elm.TemplateModulesBeta.init({
98
+ app = elmModule.Elm.Main.init({
82
99
  flags: {
83
- secrets: process.env,
84
- staticHttpCache: global.staticHttpCache || {},
85
100
  mode,
86
101
  request: {
87
102
  payload: modifiedRequest,
88
103
  kind: "single-page",
89
- jsonOnly: !!isJson,
104
+ jsonOnly: !!isBytes,
90
105
  },
91
106
  },
92
107
  });
93
108
 
94
109
  killApp = () => {
95
110
  app.ports.toJsPort.unsubscribe(portHandler);
111
+ app.ports.sendPageData.unsubscribe(portHandler);
96
112
  app.die();
97
113
  app = null;
98
114
  // delete require.cache[require.resolve(compiledElmPath)];
99
115
  };
100
116
 
101
- async function portHandler(/** @type { FromElm } */ fromElm) {
117
+ async function portHandler(/** @type { FromElm } */ newThing) {
118
+ let fromElm;
119
+ let contentDatPayload;
120
+ if ("oldThing" in newThing) {
121
+ fromElm = newThing.oldThing;
122
+ contentDatPayload = newThing.binaryPageData;
123
+ } else {
124
+ fromElm = newThing;
125
+ }
102
126
  if (fromElm.command === "log") {
103
127
  console.log(fromElm.value);
104
128
  } else if (fromElm.tag === "ApiResponse") {
@@ -119,51 +143,63 @@ function runElmApp(
119
143
  global.staticHttpCache = args.staticHttpCache;
120
144
  }
121
145
 
122
- if (isJson) {
146
+ if (isBytes) {
123
147
  resolve({
124
- kind: "json",
125
- is404: args.is404,
148
+ kind: "bytes",
149
+ is404: false,
126
150
  contentJson: JSON.stringify({
127
151
  staticData: args.contentJson,
128
- is404: args.is404,
152
+ is404: false,
129
153
  }),
154
+ statusCode: args.statusCode,
155
+ headers: args.headers,
156
+ contentDatPayload,
130
157
  });
131
158
  } else {
132
- resolve(outputString(basePath, fromElm, isDevServer));
133
- }
134
- } else if (fromElm.tag === "ReadFile") {
135
- const filePath = fromElm.args[0];
136
- try {
137
- patternsToWatch.add(filePath);
138
-
139
- runJob(app, filePath);
140
- } catch (error) {
141
- sendError(app, {
142
- title: "DataSource.File Error",
143
- message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
144
- filePath
145
- )}`,
146
- });
159
+ resolve(
160
+ outputString(basePath, fromElm, isDevServer, contentDatPayload)
161
+ );
147
162
  }
148
163
  } else if (fromElm.tag === "DoHttp") {
149
164
  const requestToPerform = fromElm.args[0];
150
- runHttpJob(app, mode, requestToPerform);
151
- } else if (fromElm.tag === "Glob") {
152
- const globPattern = fromElm.args[0];
153
- patternsToWatch.add(globPattern);
154
- runGlobJob(app, globPattern);
165
+ if (
166
+ requestToPerform.url !== "elm-pages-internal://port" &&
167
+ requestToPerform.url.startsWith("elm-pages-internal://")
168
+ ) {
169
+ runInternalJob(
170
+ app,
171
+ mode,
172
+ requestToPerform,
173
+ fs,
174
+ hasFsAccess,
175
+ patternsToWatch
176
+ );
177
+ } else {
178
+ runHttpJob(
179
+ portsFile,
180
+ app,
181
+ mode,
182
+ requestToPerform,
183
+ fs,
184
+ hasFsAccess,
185
+ fromElm.args[1]
186
+ );
187
+ }
155
188
  } else if (fromElm.tag === "Errors") {
156
189
  foundErrors = true;
157
- reject(fromElm.args[0]);
190
+ reject(fromElm.args[0].errorsJson);
158
191
  } else {
159
192
  console.log(fromElm);
160
193
  }
161
194
  }
162
195
  app.ports.toJsPort.subscribe(portHandler);
196
+ app.ports.sendPageData.subscribe(portHandler);
163
197
  }).finally(() => {
164
198
  addDataSourceWatcher(patternsToWatch);
165
- killApp();
166
- killApp = null;
199
+ try {
200
+ killApp();
201
+ killApp = null;
202
+ } catch (error) {}
167
203
  });
168
204
  }
169
205
  /**
@@ -174,21 +210,27 @@ function runElmApp(
174
210
  async function outputString(
175
211
  basePath,
176
212
  /** @type { PageProgress } */ fromElm,
177
- isDevServer
213
+ isDevServer,
214
+ contentDatPayload
178
215
  ) {
179
216
  const args = fromElm.args[0];
180
217
  let contentJson = {};
181
218
  contentJson["staticData"] = args.contentJson;
182
219
  contentJson["is404"] = args.is404;
183
220
  contentJson["path"] = args.route;
221
+ contentJson["statusCode"] = args.statusCode;
222
+ contentJson["headers"] = args.headers;
184
223
  const normalizedRoute = args.route.replace(/index$/, "");
185
224
 
186
225
  return {
187
226
  is404: args.is404,
188
227
  route: normalizedRoute,
189
- htmlString: preRenderHtml(basePath, args, contentJson, isDevServer),
228
+ htmlString: preRenderHtml.wrapHtml(basePath, args, contentDatPayload),
190
229
  contentJson: args.contentJson,
230
+ statusCode: args.statusCode,
231
+ headers: args.headers,
191
232
  kind: "html",
233
+ contentDatPayload,
192
234
  };
193
235
  }
194
236
 
@@ -201,73 +243,30 @@ async function outputString(
201
243
 
202
244
  /** @typedef { { head: any[]; errors: any[]; contentJson: any[]; html: string; route: string; title: string; } } Arg */
203
245
 
204
- /**
205
- * @param {string} string
206
- */
207
- function jsonOrNull(string) {
208
- try {
209
- return JSON.parse(string);
210
- } catch (e) {
211
- return { invalidJson: e.toString() };
212
- }
213
- }
214
-
215
- async function runJob(app, filePath) {
216
- pendingDataSourceCount += 1;
217
- try {
218
- const fileContents = (
219
- await fsPromises.readFile(path.join(process.cwd(), filePath))
220
- ).toString();
221
- const parsedFile = matter(fileContents);
222
-
223
- pendingDataSourceResponses.push({
224
- request: {
225
- masked: {
226
- url: `file://${filePath}`,
227
- method: "GET",
228
- headers: [],
229
- body: { tag: "EmptyBody", args: [] },
230
- },
231
- unmasked: {
232
- url: `file://${filePath}`,
233
- method: "GET",
234
- headers: [],
235
- body: { tag: "EmptyBody", args: [] },
236
- },
237
- },
238
- response: JSON.stringify({
239
- parsedFrontmatter: parsedFile.data,
240
- withoutFrontmatter: parsedFile.content,
241
- rawFile: fileContents,
242
- jsonFile: jsonOrNull(fileContents),
243
- }),
244
- });
245
- } catch (e) {
246
- sendError(app, {
247
- title: "Error reading file",
248
- message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
249
- filePath
250
- )}`,
251
- });
252
- } finally {
253
- pendingDataSourceCount -= 1;
254
- flushIfDone(app);
255
- }
256
- }
257
-
258
- async function runHttpJob(app, mode, requestToPerform) {
246
+ async function runHttpJob(
247
+ portsFile,
248
+ app,
249
+ mode,
250
+ requestToPerform,
251
+ fs,
252
+ hasFsAccess,
253
+ useCache
254
+ ) {
259
255
  pendingDataSourceCount += 1;
260
256
  try {
261
257
  const responseFilePath = await lookupOrPerform(
258
+ portsFile,
262
259
  mode,
263
- requestToPerform.unmasked
260
+ requestToPerform,
261
+ hasFsAccess,
262
+ useCache
264
263
  );
265
264
 
266
265
  pendingDataSourceResponses.push({
267
266
  request: requestToPerform,
268
- response: (
269
- await fsPromises.readFile(responseFilePath, "utf8")
270
- ).toString(),
267
+ response: JSON.parse(
268
+ (await fs.promises.readFile(responseFilePath, "utf8")).toString()
269
+ ),
271
270
  });
272
271
  } catch (error) {
273
272
  sendError(app, error);
@@ -277,129 +276,173 @@ async function runHttpJob(app, mode, requestToPerform) {
277
276
  }
278
277
  }
279
278
 
280
- async function runGlobJob(app, globPattern) {
279
+ function stringResponse(request, string) {
280
+ return {
281
+ request,
282
+ response: { bodyKind: "string", body: string },
283
+ };
284
+ }
285
+ function jsonResponse(request, json) {
286
+ return {
287
+ request,
288
+ response: { bodyKind: "json", body: json },
289
+ };
290
+ }
291
+
292
+ async function runInternalJob(
293
+ app,
294
+ mode,
295
+ requestToPerform,
296
+ fs,
297
+ hasFsAccess,
298
+ patternsToWatch
299
+ ) {
281
300
  try {
282
- // if (pendingDataSourceCount > 0) {
283
- // console.log(`Waiting for ${pendingDataSourceCount} pending data sources`);
284
- // }
285
301
  pendingDataSourceCount += 1;
286
302
 
287
- pendingDataSourceResponses.push(await globTask(globPattern));
303
+ if (requestToPerform.url === "elm-pages-internal://read-file") {
304
+ pendingDataSourceResponses.push(
305
+ await readFileJobNew(requestToPerform, patternsToWatch)
306
+ );
307
+ } else if (requestToPerform.url === "elm-pages-internal://glob") {
308
+ pendingDataSourceResponses.push(
309
+ await runGlobNew(requestToPerform, patternsToWatch)
310
+ );
311
+ } else if (requestToPerform.url === "elm-pages-internal://env") {
312
+ pendingDataSourceResponses.push(
313
+ await runEnvJob(requestToPerform, patternsToWatch)
314
+ );
315
+ } else if (requestToPerform.url === "elm-pages-internal://encrypt") {
316
+ pendingDataSourceResponses.push(
317
+ await runEncryptJob(requestToPerform, patternsToWatch)
318
+ );
319
+ } else if (requestToPerform.url === "elm-pages-internal://decrypt") {
320
+ pendingDataSourceResponses.push(
321
+ await runDecryptJob(requestToPerform, patternsToWatch)
322
+ );
323
+ } else {
324
+ throw `Unexpected internal DataSource request format: ${kleur.yellow(
325
+ JSON.stringify(2, null, requestToPerform)
326
+ )}`;
327
+ }
288
328
  } catch (error) {
289
- console.log(`Error running glob pattern ${globPattern}`);
290
- throw error;
329
+ sendError(app, error);
291
330
  } finally {
292
331
  pendingDataSourceCount -= 1;
293
332
  flushIfDone(app);
294
333
  }
295
334
  }
296
335
 
297
- function flushIfDone(app) {
298
- if (foundErrors) {
299
- pendingDataSourceResponses = [];
300
- } else if (pendingDataSourceCount === 0) {
301
- // console.log(
302
- // `Flushing ${pendingDataSourceResponses.length} items in ${timeUntilThreshold}ms`
303
- // );
336
+ async function readFileJobNew(req, patternsToWatch) {
337
+ const filePath = req.body.args[1];
338
+ try {
339
+ patternsToWatch.add(filePath);
304
340
 
305
- flushQueue(app);
306
- }
307
- }
341
+ const fileContents = // TODO can I remove this hack?
342
+ (
343
+ await fsPromises.readFile(
344
+ path.join(process.env.LAMBDA_TASK_ROOT || process.cwd(), filePath)
345
+ )
346
+ ).toString();
347
+ const parsedFile = matter(fileContents);
308
348
 
309
- function flushQueue(app) {
310
- const temp = pendingDataSourceResponses;
311
- pendingDataSourceResponses = [];
312
- // console.log("@@@ FLUSHING", temp.length);
313
- app.ports.fromJsPort.send({
314
- tag: "GotBatch",
315
- data: temp,
316
- });
349
+ return jsonResponse(req, {
350
+ parsedFrontmatter: parsedFile.data,
351
+ withoutFrontmatter: parsedFile.content,
352
+ rawFile: fileContents,
353
+ });
354
+ } catch (error) {
355
+ throw {
356
+ title: "DataSource.File Error",
357
+ message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
358
+ filePath
359
+ )}\n${kleur.red(error.toString())}`,
360
+ };
361
+ }
317
362
  }
318
363
 
319
- /**
320
- * @param {string} filePath
321
- * @returns {Promise<Object>}
322
- */
323
- async function readFileTask(app, filePath) {
324
- // console.log(`Read file ${filePath}`);
364
+ async function runGlobNew(req, patternsToWatch) {
325
365
  try {
326
- const fileContents = (
327
- await fsPromises.readFile(path.join(process.cwd(), filePath))
328
- ).toString();
329
- // console.log(`DONE reading file ${filePath}`);
330
- const parsedFile = matter(fileContents);
366
+ const { pattern, options } = req.body.args[0];
367
+ const matchedPaths = await globby(pattern, options);
368
+ patternsToWatch.add(pattern);
331
369
 
332
- return {
333
- request: {
334
- masked: {
335
- url: `file://${filePath}`,
336
- method: "GET",
337
- headers: [],
338
- body: { tag: "EmptyBody", args: [] },
339
- },
340
- unmasked: {
341
- url: `file://${filePath}`,
342
- method: "GET",
343
- headers: [],
344
- body: { tag: "EmptyBody", args: [] },
345
- },
346
- },
347
- response: JSON.stringify({
348
- parsedFrontmatter: parsedFile.data,
349
- withoutFrontmatter: parsedFile.content,
350
- rawFile: fileContents,
351
- jsonFile: jsonOrNull(fileContents),
352
- }),
353
- };
370
+ return jsonResponse(
371
+ req,
372
+ matchedPaths.map((fullPath) => {
373
+ return {
374
+ fullPath,
375
+ captures: mm.capture(pattern, fullPath),
376
+ };
377
+ })
378
+ );
354
379
  } catch (e) {
355
- sendError(app, {
356
- title: "Error reading file",
357
- message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
358
- filePath
359
- )}`,
360
- });
380
+ console.log(`Error performing glob '${JSON.stringify(req.body)}'`);
381
+ throw e;
361
382
  }
362
383
  }
363
384
 
364
- /**
365
- * @param {string} globPattern
366
- * @returns {Promise<Object>}
367
- */
368
- async function globTask(globPattern) {
385
+ async function runEnvJob(req, patternsToWatch) {
369
386
  try {
370
- const matchedPaths = await globby(globPattern);
371
- // console.log("Got glob path", matchedPaths);
372
-
373
- return {
374
- request: {
375
- masked: {
376
- url: `glob://${globPattern}`,
377
- method: "GET",
378
- headers: [],
379
- body: { tag: "EmptyBody", args: [] },
380
- },
381
- unmasked: {
382
- url: `glob://${globPattern}`,
383
- method: "GET",
384
- headers: [],
385
- body: { tag: "EmptyBody", args: [] },
386
- },
387
- },
388
- response: JSON.stringify(matchedPaths),
389
- };
387
+ const expectedEnv = req.body.args[0];
388
+ return jsonResponse(req, process.env[expectedEnv] || null);
390
389
  } catch (e) {
391
- console.log(`Error performing glob '${globPattern}'`);
390
+ console.log(`Error performing env '${JSON.stringify(req.body)}'`);
392
391
  throw e;
393
392
  }
394
393
  }
394
+ async function runEncryptJob(req, patternsToWatch) {
395
+ try {
396
+ return jsonResponse(
397
+ req,
398
+ cookie.sign(
399
+ JSON.stringify(req.body.args[0].values, null, 0),
400
+ req.body.args[0].secret
401
+ )
402
+ );
403
+ } catch (e) {
404
+ throw {
405
+ title: "DataSource Encrypt Error",
406
+ message:
407
+ e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
408
+ };
409
+ }
410
+ }
411
+ async function runDecryptJob(req, patternsToWatch) {
412
+ try {
413
+ // TODO if unsign returns `false`, need to have an `Err` in Elm because decryption failed
414
+ const signed = tryDecodeCookie(
415
+ req.body.args[0].input,
416
+ req.body.args[0].secrets
417
+ );
418
+
419
+ return jsonResponse(req, JSON.parse(signed || "null"));
420
+ } catch (e) {
421
+ throw {
422
+ title: "DataSource Decrypt Error",
423
+ message:
424
+ e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
425
+ };
426
+ }
427
+ }
428
+
429
+ function flushIfDone(app) {
430
+ if (foundErrors) {
431
+ pendingDataSourceResponses = [];
432
+ } else if (pendingDataSourceCount === 0) {
433
+ // console.log(
434
+ // `Flushing ${pendingDataSourceResponses.length} items in ${timeUntilThreshold}ms`
435
+ // );
395
436
 
396
- function requireUncached(mode, filePath) {
397
- if (mode === "dev-server") {
398
- // for the build command, we can skip clearing the cache because it won't change while the build is running
399
- // in the dev server, we want to clear the cache to get a the latest code each time it runs
400
- delete require.cache[require.resolve(filePath)];
437
+ flushQueue(app);
401
438
  }
402
- return require(filePath);
439
+ }
440
+
441
+ function flushQueue(app) {
442
+ const temp = pendingDataSourceResponses;
443
+ pendingDataSourceResponses = [];
444
+ // console.log("@@@ FLUSHING", temp.length);
445
+ app.ports.gotBatchSub.send(temp);
403
446
  }
404
447
 
405
448
  /**
@@ -414,3 +457,15 @@ function sendError(app, error) {
414
457
  data: error,
415
458
  });
416
459
  }
460
+ function tryDecodeCookie(input, secrets) {
461
+ if (secrets.length > 0) {
462
+ const signed = cookie.unsign(input, secrets[0]);
463
+ if (signed) {
464
+ return signed;
465
+ } else {
466
+ return tryDecodeCookie(input, secrets.slice(1));
467
+ }
468
+ } else {
469
+ return null;
470
+ }
471
+ }
@@ -0,0 +1,18 @@
1
+ module.exports = function (/** @type {boolean} */ hasFsAccess) {
2
+ if (hasFsAccess) {
3
+ return {
4
+ fs: require("fs"),
5
+ resetInMemoryFs: () => {},
6
+ };
7
+ } else {
8
+ const { vol, fs, Volume } = require("memfs");
9
+ vol.fromJSON({});
10
+ // vol.reset();
11
+ return {
12
+ fs: fs,
13
+ resetInMemoryFs: () => {
14
+ vol.reset();
15
+ },
16
+ };
17
+ }
18
+ };