@lobb-js/studio 0.19.1 → 0.20.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 (28) hide show
  1. package/dist/components/dataTable/fieldCell.svelte +38 -37
  2. package/dist/components/dataTable/polymorphicFieldCell.svelte +43 -0
  3. package/dist/components/dataTable/polymorphicFieldCell.svelte.d.ts +9 -0
  4. package/dist/components/dataTable/utils.js +19 -3
  5. package/dist/components/detailView/create/createDetailView.svelte +29 -37
  6. package/dist/components/detailView/fieldInput.svelte +27 -11
  7. package/dist/components/detailView/fieldInput.svelte.d.ts +1 -1
  8. package/dist/components/detailView/update/updateDetailView.svelte +26 -30
  9. package/dist/components/detailView/utils.js +28 -3
  10. package/dist/components/polymorphicInput.svelte +141 -0
  11. package/dist/components/polymorphicInput.svelte.d.ts +10 -0
  12. package/dist/relations.d.ts +14 -0
  13. package/dist/relations.js +47 -0
  14. package/dist/store.types.d.ts +1 -0
  15. package/dist/utils.d.ts +0 -3
  16. package/dist/utils.js +0 -21
  17. package/package.json +2 -2
  18. package/src/lib/components/dataTable/fieldCell.svelte +38 -37
  19. package/src/lib/components/dataTable/polymorphicFieldCell.svelte +43 -0
  20. package/src/lib/components/dataTable/utils.ts +14 -2
  21. package/src/lib/components/detailView/create/createDetailView.svelte +29 -37
  22. package/src/lib/components/detailView/fieldInput.svelte +27 -11
  23. package/src/lib/components/detailView/update/updateDetailView.svelte +26 -30
  24. package/src/lib/components/detailView/utils.ts +24 -3
  25. package/src/lib/components/polymorphicInput.svelte +141 -0
  26. package/src/lib/relations.ts +52 -0
  27. package/src/lib/store.types.ts +1 -0
  28. package/src/lib/utils.ts +0 -21
@@ -1,10 +1,10 @@
1
1
  <script lang="ts">
2
- import { getFieldRelation } from "../../utils";
2
+ import { getFieldRelationTarget, getPolymorphicRelation, isRelationField } from "../../relations";
3
3
  import { ExternalLink } from "lucide-svelte";
4
4
  import UpdateDetailViewButton from "../detailView/update/updateDetailViewButton.svelte";
5
5
  import { getField } from "./utils";
6
6
  import EnumBadge from "./enumBadge.svelte";
7
- import _ from "lodash";
7
+ import PolymorphicFieldCell from "./polymorphicFieldCell.svelte";
8
8
  import { getStudioContext } from "../../context";
9
9
 
10
10
  const { ctx } = getStudioContext();
@@ -26,49 +26,50 @@
26
26
  }: Props = $props();
27
27
 
28
28
  const field = getField(ctx, fieldName, collectionName);
29
- const relation = getFieldRelation(ctx, collectionName, fieldName);
30
- const isRefrenceField = Boolean(
31
- getFieldRelation(ctx, collectionName, fieldName),
32
- );
29
+ const relationTarget = getFieldRelationTarget(ctx, collectionName, fieldName);
30
+ const polymorphicRelation = getPolymorphicRelation(ctx, collectionName, fieldName);
31
+ const isRefrenceField = isRelationField(ctx, collectionName, fieldName);
33
32
  const isPasswordField = ctx.meta.collections[collectionName].fields[fieldName]?.ui?.input?.type === "password";
34
33
  </script>
35
34
 
36
- {#if isPasswordField}
35
+ {#if polymorphicRelation}
36
+ <PolymorphicFieldCell
37
+ collectionField={polymorphicRelation.from.collection_field}
38
+ idField={polymorphicRelation.from.id_field}
39
+ {entry}
40
+ bind:tableParams
41
+ />
42
+ {:else if isRefrenceField}
43
+ {#if value?.id && value.id !== 0}
44
+ <div class="flex items-center gap-2">
45
+ <div>{value.id}</div>
46
+ {#if Object.values(value)[1]}
47
+ <div class="border bg-muted px-3 py-1 rounded-full">
48
+ {Object.values(value)[1]}
49
+ </div>
50
+ {/if}
51
+ <UpdateDetailViewButton
52
+ collectionName={relationTarget!}
53
+ recordId={value.id}
54
+ variant="ghost"
55
+ class="h-5 w-5 px-0 py-0 text-muted-foreground hover:bg-transparent"
56
+ Icon={ExternalLink}
57
+ onSuccessfullSave={async () => {
58
+ tableParams = { ...tableParams };
59
+ }}
60
+ />
61
+ </div>
62
+ {:else if value?.id === 0}
63
+ <div class="text-muted-foreground">PARENT ID</div>
64
+ {:else}
65
+ <div class="text-muted-foreground">NULL</div>
66
+ {/if}
67
+ {:else if isPasswordField}
37
68
  <div class="text-muted-foreground tracking-widest">••••••</div>
38
69
  {:else if value === ""}
39
70
  <div class="text-muted-foreground">EMPTY STRING</div>
40
71
  {:else if value === null || value === undefined}
41
72
  <div class="text-muted-foreground">NULL</div>
42
- {:else if isRefrenceField}
43
- {#if typeof value !== "object"}
44
- <div>{value}</div>
45
- {:else if value.id !== 0}
46
- {@const primaryField = Object.values(value)[1]}
47
- {#if value.id}
48
- <div class="flex items-center gap-2">
49
- <div>{value.id}</div>
50
- {#if primaryField}
51
- <div class="border bg-muted px-3 py-1 rounded-full">
52
- {primaryField}
53
- </div>
54
- {/if}
55
- <UpdateDetailViewButton
56
- collectionName={relation.to.collection}
57
- recordId={value.id}
58
- variant="ghost"
59
- class="h-5 w-5 px-0 py-0 text-muted-foreground hover:bg-transparent"
60
- Icon={ExternalLink}
61
- onSuccessfullSave={async () => {
62
- tableParams = { ...tableParams };
63
- }}
64
- ></UpdateDetailViewButton>
65
- </div>
66
- {:else}
67
- <div class="text-muted-foreground">NULL</div>
68
- {/if}
69
- {:else}
70
- <div class="text-muted-foreground">PARENT ID</div>
71
- {/if}
72
73
  {:else if field?.enum}
73
74
  <EnumBadge {value} enum={field.enum} />
74
75
  {:else if field.type === "datetime"}
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import { ExternalLink, Table } from "lucide-svelte";
3
+ import UpdateDetailViewButton from "../detailView/update/updateDetailViewButton.svelte";
4
+
5
+ interface Props {
6
+ collectionField: string;
7
+ idField: string;
8
+ entry: Record<string, any>;
9
+ tableParams?: any;
10
+ }
11
+
12
+ let {
13
+ collectionField,
14
+ idField,
15
+ entry,
16
+ tableParams = $bindable(),
17
+ }: Props = $props();
18
+
19
+ const targetCollection = $derived(entry[collectionField] ?? null);
20
+ const targetId = $derived(entry[idField] ?? null);
21
+ </script>
22
+
23
+ {#if targetId && targetCollection}
24
+ <div class="flex items-center gap-2">
25
+ <div class="flex items-center gap-1 border bg-muted px-2 py-1 rounded-md text-muted-foreground">
26
+ <Table size="11" />
27
+ {targetCollection}
28
+ </div>
29
+ <div>{targetId}</div>
30
+ <UpdateDetailViewButton
31
+ collectionName={targetCollection}
32
+ recordId={targetId}
33
+ variant="ghost"
34
+ class="h-5 w-5 px-0 py-0 text-muted-foreground hover:bg-transparent"
35
+ Icon={ExternalLink}
36
+ onSuccessfullSave={async () => {
37
+ tableParams = { ...tableParams };
38
+ }}
39
+ />
40
+ </div>
41
+ {:else}
42
+ <div class="text-muted-foreground">NULL</div>
43
+ {/if}
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ collectionField: string;
3
+ idField: string;
4
+ entry: Record<string, any>;
5
+ tableParams?: any;
6
+ }
7
+ declare const PolymorphicFieldCell: import("svelte").Component<Props, {}, "tableParams">;
8
+ type PolymorphicFieldCell = ReturnType<typeof PolymorphicFieldCell>;
9
+ export default PolymorphicFieldCell;
@@ -1,9 +1,14 @@
1
- import { Binary, Braces, Brackets, Calendar, CalendarClock, Clock, Hash, Key, Text, Type, } from "lucide-svelte/icons";
1
+ import { getFieldRelationTarget } from "../../relations";
2
+ import { Binary, Braces, Brackets, Calendar, CalendarClock, Clock, Hash, Key, Link, Text, Type, } from "lucide-svelte/icons";
3
+ import { icons } from "lucide-svelte";
2
4
  export function getCollectionColumns(ctx, collectionName) {
5
+ var _a;
3
6
  var collectionFields = getFields(ctx, collectionName);
4
7
  var headers = [];
5
8
  for (var fieldName in collectionFields) {
6
9
  var field = collectionFields[fieldName];
10
+ if ((_a = field.ui) === null || _a === void 0 ? void 0 : _a.hidden)
11
+ continue;
7
12
  headers.push({
8
13
  id: field.key,
9
14
  subtext: field.type,
@@ -13,7 +18,11 @@ export function getCollectionColumns(ctx, collectionName) {
13
18
  return headers;
14
19
  }
15
20
  export function getFieldIcon(ctx, fieldName, collectionName) {
21
+ var _a, _b, _c;
16
22
  var field = getField(ctx, fieldName, collectionName);
23
+ var uiIcon = (_a = field.ui) === null || _a === void 0 ? void 0 : _a.icon;
24
+ if (uiIcon && uiIcon in icons)
25
+ return icons[uiIcon];
17
26
  if (fieldName === "id") {
18
27
  return Key;
19
28
  }
@@ -33,6 +42,13 @@ export function getFieldIcon(ctx, fieldName, collectionName) {
33
42
  return Binary;
34
43
  }
35
44
  else if (field.type === "integer") {
45
+ var target = getFieldRelationTarget(ctx, collectionName, fieldName);
46
+ if (target) {
47
+ var targetIcon = (_c = (_b = ctx.meta.collections[target]) === null || _b === void 0 ? void 0 : _b.ui) === null || _c === void 0 ? void 0 : _c.icon;
48
+ if (targetIcon && targetIcon in icons)
49
+ return icons[targetIcon];
50
+ return Link;
51
+ }
36
52
  return Hash;
37
53
  }
38
54
  else if (field.type === "long") {
@@ -53,7 +69,7 @@ export function getFieldIcon(ctx, fieldName, collectionName) {
53
69
  else if (field.type === "time") {
54
70
  return Clock;
55
71
  }
56
- throw new Error("(".concat(field.type, ") doesnt have an icon"));
72
+ return Braces;
57
73
  }
58
74
  export function getFields(ctx, collectionName) {
59
75
  return ctx.meta.collections[collectionName].fields;
@@ -78,7 +94,7 @@ export function getCollectionParamsFields(ctx, collectionName, allFields) {
78
94
  var relations = ctx.meta.relations;
79
95
  var foreignFields = relations
80
96
  .filter(function (relation) {
81
- return relation.from.collection === collectionName;
97
+ return relation.type !== "polymorphic" && relation.from.collection === collectionName;
82
98
  })
83
99
  .map(function (relation) {
84
100
  return {
@@ -161,46 +161,38 @@
161
161
  <div class="flex-1 overflow-y-auto">
162
162
  <div class="flex flex-col gap-4 p-4">
163
163
  {#each fieldNames as fieldName}
164
- {@const field = getField(ctx, fieldName, collectionName)}
165
- {@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
166
- <div
167
- class="flex flex-col gap-2"
168
- >
169
- <div
170
- class="flex flex-1 items-end justify-between gap-2 text-xs"
171
- >
172
- <div class="flex gap-2">
173
- <div class="h-fit">{field.label}</div>
174
- <div
175
- class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground"
176
- >
177
- <FieldIcon size="12" />
178
- {field.type}
164
+ {#if !ctx.meta.collections[collectionName].fields[fieldName]?.ui?.hidden}
165
+ {@const field = getField(ctx, fieldName, collectionName)}
166
+ {@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
167
+ <div class="flex flex-col gap-2">
168
+ <div class="flex flex-1 items-end justify-between gap-2 text-xs">
169
+ <div class="flex gap-2">
170
+ <div class="h-fit">{field.label}</div>
171
+ <div class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground">
172
+ <FieldIcon size="12" />
173
+ {field.type}
174
+ </div>
175
+ </div>
176
+ <div>
177
+ <ExtensionsComponents
178
+ name="dvFields.topRight.{collectionName}.{fieldName}"
179
+ utils={getExtensionUtils(lobb, ctx)}
180
+ bind:value={entry[fieldName]}
181
+ />
179
182
  </div>
180
183
  </div>
181
- <div>
182
- <ExtensionsComponents
183
- name="dvFields.topRight.{collectionName}.{fieldName}"
184
- utils={getExtensionUtils(lobb, ctx)}
185
- bind:value={entry[fieldName]}
186
- />
187
- </div>
184
+ <FieldInput
185
+ {collectionName}
186
+ {fieldName}
187
+ bind:value={
188
+ () => entry[fieldName],
189
+ (v) => (entry = { ...entry, [fieldName]: v })
190
+ }
191
+ bind:entry
192
+ errorMessages={fieldsErrors[fieldName]}
193
+ />
188
194
  </div>
189
- <FieldInput
190
- {collectionName}
191
- {fieldName}
192
- bind:value={
193
- () => entry[fieldName],
194
- (v) =>
195
- (entry = {
196
- ...entry,
197
- [fieldName]: v,
198
- })
199
- }
200
- {entry}
201
- errorMessages={fieldsErrors[fieldName]}
202
- />
203
- </div>
195
+ {/if}
204
196
  {/each}
205
197
  </div>
206
198
  {#if showRelatedRecords}
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { getStudioContext } from "../../context";
3
- import { getFieldRelation } from "../../utils";
3
+ import { getFieldRelationTarget, getPolymorphicRelation } from "../../relations";
4
4
  import { Ban, Check, CircleAlert, X } from "lucide-svelte";
5
5
  import { getField } from "../dataTable/utils";
6
6
  import Button from "../ui/button/button.svelte";
@@ -11,6 +11,7 @@
11
11
  import type { EnumOption } from "@lobb-js/core";
12
12
  import Textarea from "../ui/textarea/textarea.svelte";
13
13
  import ForeingKeyInput from "../foreingKeyInput.svelte";
14
+ import PolymorphicInput from "../polymorphicInput.svelte";
14
15
  import ExtensionsComponents from "../extensionsComponents.svelte";
15
16
  import { getExtensionUtils } from "../../extensions/extensionUtils";
16
17
 
@@ -29,7 +30,7 @@
29
30
  fieldName,
30
31
  value = $bindable(),
31
32
  errorMessages = [],
32
- entry,
33
+ entry = $bindable(),
33
34
  }: Props = $props();
34
35
 
35
36
  const ui_input =
@@ -37,10 +38,11 @@
37
38
  const ui =
38
39
  ctx.meta.collections[collectionName].fields[fieldName].ui;
39
40
  const field = getField(ctx, fieldName, collectionName);
40
- const fieldRelation = getFieldRelation(ctx, collectionName, fieldName);
41
+ const fieldRelationTarget = getFieldRelationTarget(ctx, collectionName, fieldName);
42
+ const polymorphicRelation = getPolymorphicRelation(ctx, collectionName, fieldName);
41
43
  const isDisabled = field.key === 'id' || Boolean(ui?.disabled)
42
44
  const disabledClasses = "pointer-events-none opacity-50";
43
- const destructive: boolean = $derived(Boolean(errorMessages.length));
45
+ const destructive: boolean = $derived(!isDisabled && Boolean(errorMessages.length));
44
46
 
45
47
  </script>
46
48
 
@@ -53,13 +55,27 @@
53
55
  style="flex: 2;"
54
56
  >
55
57
  <Button
56
- onclick={() => (value = null)}
58
+ onclick={() => {
59
+ value = null;
60
+ if (polymorphicRelation && entry) {
61
+ entry[polymorphicRelation.from.collection_field] = null;
62
+ entry[polymorphicRelation.from.id_field] = null;
63
+ }
64
+ }}
57
65
  variant="outline"
58
66
  class="absolute right-0 top-0 z-10 mr-1.5 mt-1.5 aspect-square h-6 w-6 p-0"
59
67
  Icon={Ban}
60
68
  tabindex={-1}
61
69
  ></Button>
62
- {#if ui_input}
70
+ {#if polymorphicRelation && entry}
71
+ <PolymorphicInput
72
+ collectionField={polymorphicRelation.from.collection_field}
73
+ idField={polymorphicRelation.from.id_field}
74
+ targetCollections={polymorphicRelation.to}
75
+ bind:entry
76
+ {destructive}
77
+ />
78
+ {:else if ui_input}
63
79
  <FieldCustomInput
64
80
  bind:value
65
81
  type={ui_input.type}
@@ -73,12 +89,12 @@
73
89
  class="bg-muted/30 text-xs"
74
90
  bind:value
75
91
  />
76
- {:else if fieldRelation && entry}
92
+ {:else if fieldRelationTarget && entry}
77
93
  <ExtensionsComponents
78
- name="detailView.fields.foreignKey.{fieldRelation.to.collection}"
94
+ name="detailView.fields.foreignKey.{fieldRelationTarget}"
79
95
  utils={getExtensionUtils(lobb, ctx)}
80
96
  parentCollectionName={collectionName}
81
- collectionName={fieldRelation.to.collection}
97
+ collectionName={fieldRelationTarget}
82
98
  bind:value
83
99
  {entry}
84
100
  fieldName={field.key}
@@ -86,7 +102,7 @@
86
102
  >
87
103
  <ForeingKeyInput
88
104
  parentCollectionName={collectionName}
89
- collectionName={fieldRelation.to.collection}
105
+ collectionName={fieldRelationTarget}
90
106
  bind:value
91
107
  {entry}
92
108
  fieldName={field.key}
@@ -263,7 +279,7 @@
263
279
  bind:value
264
280
  />
265
281
  {/if}
266
- {#if errorMessages}
282
+ {#if !isDisabled && errorMessages}
267
283
  {#each errorMessages as message}
268
284
  <div class="flex gap-1 text-destructive">
269
285
  <CircleAlert size="15" class="translate-y-[0.025rem]" />
@@ -5,6 +5,6 @@ interface Props {
5
5
  errorMessages?: string[];
6
6
  entry?: Record<string, any>;
7
7
  }
8
- declare const FieldInput: import("svelte").Component<Props, {}, "value">;
8
+ declare const FieldInput: import("svelte").Component<Props, {}, "value" | "entry">;
9
9
  type FieldInput = ReturnType<typeof FieldInput>;
10
10
  export default FieldInput;
@@ -113,39 +113,35 @@
113
113
  <div class="flex-1 overflow-y-auto">
114
114
  <div class="flex flex-col gap-4 p-4">
115
115
  {#each fieldNames as fieldName}
116
- {@const field = getField(ctx, fieldName, collectionName)}
117
- {@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
118
- <div
119
- class="flex flex-col gap-2"
120
- >
121
- <div
122
- class="flex flex-1 items-end justify-between gap-2 text-xs"
123
- >
124
- <div class="flex gap-2">
125
- <div class="h-fit">{field.label}</div>
126
- <div
127
- class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground"
128
- >
129
- <FieldIcon size="12" />
130
- {field.type}
116
+ {#if !ctx.meta.collections[collectionName].fields[fieldName]?.ui?.hidden}
117
+ {@const field = getField(ctx, fieldName, collectionName)}
118
+ {@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
119
+ <div class="flex flex-col gap-2">
120
+ <div class="flex flex-1 items-end justify-between gap-2 text-xs">
121
+ <div class="flex gap-2">
122
+ <div class="h-fit">{field.label}</div>
123
+ <div class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground">
124
+ <FieldIcon size="12" />
125
+ {field.type}
126
+ </div>
127
+ </div>
128
+ <div>
129
+ <ExtensionsComponents
130
+ name="dvFields.topRight.{collectionName}.{fieldName}"
131
+ utils={getExtensionUtils(lobb, ctx)}
132
+ bind:value={entry[fieldName]}
133
+ />
131
134
  </div>
132
135
  </div>
133
- <div>
134
- <ExtensionsComponents
135
- name="dvFields.topRight.{collectionName}.{fieldName}"
136
- utils={getExtensionUtils(lobb, ctx)}
137
- bind:value={entry[fieldName]}
138
- />
139
- </div>
136
+ <FieldInput
137
+ {collectionName}
138
+ {fieldName}
139
+ bind:value={entry[fieldName]}
140
+ bind:entry
141
+ errorMessages={fieldsErrors[fieldName]}
142
+ />
140
143
  </div>
141
- <FieldInput
142
- {collectionName}
143
- {fieldName}
144
- bind:value={entry[fieldName]}
145
- {entry}
146
- errorMessages={fieldsErrors[fieldName]}
147
- />
148
- </div>
144
+ {/if}
149
145
  {/each}
150
146
  </div>
151
147
  {#if showRelatedRecords}
@@ -10,7 +10,7 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import Mustache from "mustache";
13
- import { getFieldRelation } from "../../utils";
13
+ import { isRelationField } from "../../relations";
14
14
  import { getField } from "../dataTable/utils";
15
15
  export function getDefaultEntry(ctx, fieldNames, collectionName, values) {
16
16
  return Object.fromEntries(fieldNames.map(function (fieldName) {
@@ -40,11 +40,24 @@ export function serializeEntry(ctx, collectionName, entry, rollback) {
40
40
  // serialize the foreign key field's value
41
41
  for (var _i = 0, _a = Object.entries(entry); _i < _a.length; _i++) {
42
42
  var _b = _a[_i], fieldName = _b[0], fieldValue = _b[1];
43
- var isRefrenceField = Boolean(getFieldRelation(ctx, collectionName, fieldName));
43
+ var isRefrenceField = isRelationField(ctx, collectionName, fieldName);
44
44
  if (isRefrenceField && fieldValue !== null && fieldValue.id !== undefined) {
45
45
  entry[fieldName] = fieldValue.id;
46
46
  }
47
47
  }
48
+ // serialize polymorphic id_field values ({ id: 5, title: "..." } → 5)
49
+ for (var _c = 0, _d = ctx.meta.relations; _c < _d.length; _c++) {
50
+ var relation = _d[_c];
51
+ if (relation.type !== "polymorphic")
52
+ continue;
53
+ if (relation.from.collection !== collectionName)
54
+ continue;
55
+ var idField = relation.from.id_field;
56
+ var fieldValue = entry[idField];
57
+ if (fieldValue !== null && typeof fieldValue === "object" && fieldValue.id !== undefined) {
58
+ entry[idField] = fieldValue.id;
59
+ }
60
+ }
48
61
  // check for related collections properties and serialize them too
49
62
  if (!rollback) {
50
63
  var childrenRelations = ctx.meta.relations.filter(function (relation) { return relation.to.collection === collectionName; });
@@ -118,7 +131,7 @@ export function generateTransactionBody(ctx, collectionName, entry) {
118
131
  }
119
132
  export function parseDetailViewValues(ctx, collectionName, values) {
120
133
  var forignFieldNames = ctx.meta.relations
121
- .filter(function (relation) { return relation.from.collection === collectionName; })
134
+ .filter(function (relation) { return relation.type !== "polymorphic" && relation.from.collection === collectionName; })
122
135
  .map(function (relation) { return relation.from.field; });
123
136
  var childCollectionNames = ctx.meta.relations
124
137
  .filter(function (relation) { return relation.to.collection === collectionName; })
@@ -138,6 +151,18 @@ export function parseDetailViewValues(ctx, collectionName, values) {
138
151
  }
139
152
  }
140
153
  }
154
+ // wrap polymorphic id_field scalar values into { id: value }
155
+ for (var _c = 0, _d = ctx.meta.relations; _c < _d.length; _c++) {
156
+ var relation = _d[_c];
157
+ if (relation.type !== "polymorphic")
158
+ continue;
159
+ if (relation.from.collection !== collectionName)
160
+ continue;
161
+ var idField = relation.from.id_field;
162
+ if (idField in values && typeof values[idField] === 'number') {
163
+ values[idField] = { id: values[idField] };
164
+ }
165
+ }
141
166
  }
142
167
  export function getCollectionFields(ctx, collectionName) {
143
168
  var returnedData = [];