primate 0.27.3 → 0.27.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primate",
3
- "version": "0.27.3",
3
+ "version": "0.27.5",
4
4
  "description": "Polymorphic development platform",
5
5
  "homepage": "https://primatejs.com",
6
6
  "bugs": "https://github.com/primatejs/primate/issues",
@@ -18,7 +18,7 @@
18
18
  "directory": "packages/primate"
19
19
  },
20
20
  "dependencies": {
21
- "rcompat": "^0.5.0"
21
+ "rcompat": "^0.5.1"
22
22
  },
23
23
  "engines": {
24
24
  "node": ">=18"
package/src/dispatch.js CHANGED
@@ -17,6 +17,9 @@ export default (patches = {}) => (object, raw, cased = true) => {
17
17
 
18
18
  return object[cased ? property : property.toLowerCase()];
19
19
  },
20
+ json() {
21
+ return JSON.parse(JSON.stringify(object));
22
+ },
20
23
  toString() {
21
24
  return JSON.stringify(object);
22
25
  },
package/src/errors.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "module": "primate",
3
3
  "errors": {
4
- "CannotParseBody": {
5
- "message": "cannot parse body {0} as {1}",
6
- "fix": "use a different content type or fix body",
7
- "level": "Warn"
4
+ "MismatchedBody": {
5
+ "message": "{0}: {1}",
6
+ "fix": "make sure the body payload corresponds to the used content type",
7
+ "level": "Error"
8
8
  },
9
9
  "DoubleFileExtension": {
10
10
  "message": "double file extension {0}",
@@ -51,9 +51,9 @@ export default app => {
51
51
  const hooks = [...app.modules.route, guard(app, guards)];
52
52
 
53
53
  // handle request
54
- const response = (await cascade(hooks, handler))(pathed);
54
+ const response = await (await cascade(hooks, handler))(pathed);
55
55
  const $layouts = { layouts: await get_layouts(layouts, request) };
56
- return (await respond(await response))(app, $layouts, pathed);
56
+ return (await respond(response))(app, $layouts, pathed);
57
57
  }).orelse(async error => {
58
58
  app.log.auto(error);
59
59
 
@@ -1,20 +1,28 @@
1
1
  import { URL, Body } from "rcompat/http";
2
2
  import { from, valmap } from "rcompat/object";
3
+ import { tryreturn } from "rcompat/async";
4
+ import errors from "../errors.js";
3
5
 
4
6
  const deslash = url => url.replaceAll(/(?<!http:)\/{2,}/gu, _ => "/");
5
7
 
8
+ const parse_body = (body, headers, url) =>
9
+ tryreturn(async _ => {
10
+ console.log("HHHH");
11
+ return Body.parse(body, headers.get("content-type")) ?? {};
12
+ }).orelse(error => errors.MismatchedBody.throw(url.pathname, error.message));
13
+
6
14
  export default dispatch => async original => {
7
- const { body, headers } = original;
15
+ const { headers } = original;
8
16
  const url = new URL(deslash(globalThis.decodeURIComponent(original.url)));
9
17
  const cookies = headers.get("cookie");
18
+ const body = await parse_body(original.body, headers, url);
10
19
 
11
- return { original, url,
12
- body: await Body.parse(body, headers.get("content-type")) ?? {},
20
+ return { original, url, body,
21
+ async_function: async () => "1",
13
22
  ...valmap({
14
- query: [from(url.searchParams), url.search],
15
- headers: [from(headers), headers, false],
16
- cookies: [from(cookies?.split(";").map(cookie => cookie.trim().split("="))
17
- ?? []), cookies],
18
- }, value => dispatch(...value)),
19
- };
23
+ query: [from(url.searchParams), url.search],
24
+ headers: [from(headers), headers, false],
25
+ cookies: [from(cookies?.split(";").map(cookie =>
26
+ cookie.trim().split("=")) ?? []), cookies],
27
+ }, value => dispatch(...value)) };
20
28
  };
@@ -1,4 +1,4 @@
1
1
  import { Headers } from "rcompat/http";
2
2
 
3
- export const isResponse = value =>
3
+ export default value =>
4
4
  value.body !== undefined && value.headers instanceof Headers;
@@ -1,2 +1 @@
1
- export { isResponse } from "./duck.js";
2
1
  export { default as respond } from "./respond.js";
@@ -1,26 +1,26 @@
1
1
  import { Blob } from "rcompat/fs";
2
2
  import { URL } from "rcompat/http";
3
3
  import { text, json, stream, redirect } from "primate";
4
- import { isResponse as isResponseDuck } from "./duck.js";
4
+ import is_response_duck from "./duck.js";
5
5
 
6
- const isText = value => {
6
+ const is_text = value => {
7
7
  if (typeof value === "string") {
8
8
  return text(value);
9
9
  }
10
10
  throw new Error(`no handler found for ${value}`);
11
11
  };
12
12
 
13
- const isNonNullObject = value => typeof value === "object" && value !== null;
14
- const isObject = value => isNonNullObject(value)
15
- ? json(value) : isText(value);
16
- const isResponse = value => isResponseDuck(value)
17
- ? _ => value : isObject(value);
13
+ const is_non_null_object = value => typeof value === "object" && value !== null;
14
+ const is_object = value => is_non_null_object(value)
15
+ ? json(value) : is_text(value);
16
+ const is_response = value => is_response_duck(value)
17
+ ? _ => value : is_object(value);
18
18
  const isStream = value => value instanceof ReadableStream
19
- ? stream(value) : isResponse(value);
20
- const isBlob = value => value instanceof Blob
19
+ ? stream(value) : is_response(value);
20
+ const is_blob = value => value instanceof Blob
21
21
  ? stream(value) : isStream(value);
22
- const isURL = value => value instanceof URL
23
- ? redirect(value.href) : isBlob(value);
24
- const guess = value => isURL(value);
22
+ const is_URL = value => value instanceof URL
23
+ ? redirect(value.href) : is_blob(value);
24
+ const guess = value => is_URL(value);
25
25
 
26
26
  export default result => typeof result === "function" ? result : guess(result);
@@ -28,23 +28,20 @@ const post = async app => {
28
28
  if (await app.path.types.exists()) {
29
29
  await app.stage(app.path.types, location.types);
30
30
  }
31
- const types = await loaders.types(app.log, app.runpath(location.types));
31
+ const user_types = await loaders.types(app.log, app.runpath(location.types));
32
+ const types = { ...app.types, ...user_types };
33
+
32
34
  const staged = app.runpath(location.routes);
33
35
  for (const path of await staged.collect()) {
34
36
  await app.extensions[path.extension]
35
37
  ?.route(staged, path.debase(`${staged}/`), types);
36
38
  }
37
39
  const routes = await loaders.routes(app);
38
-
39
- return {
40
- ...app,
41
- types,
42
- routes,
43
- dispatch: dispatch(app.types),
44
- layout: {
45
- depth: Math.max(...routes.map(({ layouts }) => layouts.length)) + 1,
46
- },
40
+ const layout = {
41
+ depth: Math.max(...routes.map(({ layouts }) => layouts.length)) + 1,
47
42
  };
43
+
44
+ return { ...app, types, routes, dispatch: dispatch(types), layout };
48
45
  };
49
46
 
50
47
  export default async app =>
@@ -6,8 +6,8 @@ import fs from "./common.js";
6
6
 
7
7
  const filter = path => /^[a-z]/u.test(path.name);
8
8
 
9
- export default async (log, directory) => {
10
- const types = (await fs({ log, directory, name: "types", filter }))
9
+ export default async (log, directory, load = fs) => {
10
+ const types = (await load({ log, directory, name: "types", filter }))
11
11
  .map(([name, type]) => [name, type.default]);
12
12
 
13
13
  const resolve = name => new Path(directory, name);