@protobase/server 0.12.14 → 0.12.16

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,4 +1,5 @@
1
1
  import { relatedErrors } from "./view-related.js";
2
+ import { cardPhotosErrors } from "./view-card-photos.js";
2
3
  import { addressErrors, addressPlaceholders, appHrefError, displayFields, fieldRefsIn, hrefPlaceholders } from "@protobase/schema";
3
4
  //#region src/check-views.ts
4
5
  const linkFields = (run) => run?.kind !== "link" ? [] : "to" in run ? addressPlaceholders(run.to) : hrefPlaceholders(run.href);
@@ -58,7 +59,7 @@ const widgetErrors = (view, model, fieldTypes) => Object.entries(view.fields).fl
58
59
  * Fails at startup when a view uses a sensitive field where it would show empty, a display or custom section names a
59
60
  * field the resource does not have, labels or colours values its enum does not have, shows a field with a field type of
60
61
  * `fieldTypes` (each with the storage types it shows) that does not show it,
61
- * has a related section that does not fit the resources, or a link to an address the app does not have.
62
+ * has a related section or a cards display's photos that do not fit the resources, or a link to an address the app does not have.
62
63
  */
63
64
  const checkViews = (registry, views, pages = [], fieldTypes = {}) => {
64
65
  const models = Object.fromEntries(registry.entries.map((entry) => [entry.name, entry.model]));
@@ -67,6 +68,7 @@ const checkViews = (registry, views, pages = [], fieldTypes = {}) => {
67
68
  const model = models[view.resource];
68
69
  if (!model) return [];
69
70
  const related = view.layout.flatMap((item) => item.kind === "related" ? relatedErrors(item, view.resource, models).map((error) => `related "${item.title}": ${error}`) : []);
71
+ const photos = (view.list?.displays ?? []).flatMap((display) => display.kind === "cards" && display.photos ? cardPhotosErrors(display.photos, view.resource, models).map((error) => `display "${display.name}" photos: ${error}`) : []);
70
72
  return [
71
73
  ...sensitiveErrors(view, model),
72
74
  ...unknownFieldErrors(view, model),
@@ -74,6 +76,7 @@ const checkViews = (registry, views, pages = [], fieldTypes = {}) => {
74
76
  ...valueColorErrors(view, model),
75
77
  ...widgetErrors(view, model, fieldTypes),
76
78
  ...related,
79
+ ...photos,
77
80
  ...linkErrors(view, model, models, pageNames)
78
81
  ].map((problem) => `View "${view.resource}": ${problem}`);
79
82
  });
@@ -1,4 +1,5 @@
1
1
  import { relatedErrors } from "./view-related.js";
2
+ import { cardPhotosErrors } from "./view-card-photos.js";
2
3
  import { resolveFieldPath } from "@protobase/layout";
3
4
  import { addressErrors, hrefPlaceholders, navRecentErrors, pruneByShape, shapes, tableDisplay } from "@protobase/schema";
4
5
  //#region src/view-access.ts
@@ -20,7 +21,7 @@ const keepDefault = ({ default: opens, displays, ...list }) => {
20
21
  ...opens !== void 0 && kept && { default: opens }
21
22
  };
22
23
  };
23
- const listShape = shapes.object({
24
+ const listShape = (resource, models) => shapes.object({
24
25
  columns: shapes.list(shapes.field),
25
26
  sort: shapes.list(shapes.tuple(shapes.field, shapes.data)),
26
27
  search: shapes.list(shapes.field),
@@ -36,7 +37,8 @@ const listShape = shapes.object({
36
37
  badge: shapes.field,
37
38
  meta: shapes.list(shapes.field),
38
39
  flags: shapes.list(shapes.field),
39
- card: shapes.data
40
+ card: shapes.data,
41
+ photos: shapes.map((photos) => cardPhotosErrors(photos, resource, models).length === 0 ? photos : void 0)
40
42
  }),
41
43
  custom: shapes.object({
42
44
  kind: shapes.data,
@@ -135,7 +137,7 @@ const viewShape = (resource, model, models) => shapes.object({
135
137
  icon: shapes.data,
136
138
  help: shapes.data,
137
139
  fields: shapes.keys(),
138
- list: listShape,
140
+ list: listShape(resource, models),
139
141
  filters: shapes.list(widgetShape),
140
142
  layout: shapes.list(layoutShape(resource, models)),
141
143
  chart: shapes.object({
@@ -0,0 +1,20 @@
1
+ import { matchErrors, sortErrors } from "./view-related.js";
2
+ //#region src/view-card-photos.ts
3
+ /**
4
+ * What is wrong with the photos of a cards display on `resource`, against these models; empty when the cards can show
5
+ * them. Against the full models it checks the config; against a caller's models, whether that caller can load them.
6
+ */
7
+ const cardPhotosErrors = (photos, resource, models) => {
8
+ const owner = models[resource];
9
+ const target = models[photos.resource];
10
+ if (!owner || !target) return [`unknown resource "${owner ? photos.resource : resource}"`];
11
+ if (owner.primaryKey.length !== 1) return [`${resource} has a composite key, so its cards cannot match photos`];
12
+ const image = Object.hasOwn(target.fields, photos.image) ? target.fields[photos.image] : void 0;
13
+ return [
14
+ ...matchErrors(target, photos.field, resource),
15
+ ...!image ? [`unknown field "${photos.image}" on ${target.name}`] : image.type === "file" ? [] : [`"${photos.image}" on ${target.name} is not a file field`],
16
+ ...sortErrors(target, photos.sort).map((error) => `sort: ${error}`)
17
+ ];
18
+ };
19
+ //#endregion
20
+ export { cardPhotosErrors };
@@ -56,4 +56,4 @@ const relatedErrors = (item, resource, models) => {
56
56
  ];
57
57
  };
58
58
  //#endregion
59
- export { relatedErrors, throughKey };
59
+ export { matchErrors, relatedErrors, sortErrors, throughKey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protobase/server",
3
- "version": "0.12.14",
3
+ "version": "0.12.16",
4
4
  "description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@better-auth/passkey": "^1.7.7",
33
- "@protobase/layout": "0.12.14",
34
- "@protobase/query": "0.12.14",
35
- "@protobase/schema": "0.12.14",
33
+ "@protobase/layout": "0.12.16",
34
+ "@protobase/query": "0.12.16",
35
+ "@protobase/schema": "0.12.16",
36
36
  "@scalar/hono-api-reference": "^0.12.10",
37
37
  "@sentry/core": "^11.7.0",
38
38
  "@simplewebauthn/server": "^13.3.1",