@rebasepro/common 0.19.2-canary.gef769df → 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.
- package/dist/data/buildRebaseData.d.ts +2 -12
- package/dist/index.es.js +153 -30
- package/dist/index.es.js.map +1 -1
- package/dist/util/entities.d.ts +17 -0
- package/package.json +3 -3
|
@@ -19,20 +19,10 @@ export interface EntityDataOptions {
|
|
|
19
19
|
*/
|
|
20
20
|
resolveCollection?: (slug: string) => {
|
|
21
21
|
properties?: Record<string, unknown>;
|
|
22
|
+
relations?: unknown[];
|
|
23
|
+
slug?: string;
|
|
22
24
|
} | undefined;
|
|
23
25
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Build a `RebaseData` object from a `DataDriver` using JavaScript Proxy.
|
|
26
|
-
*
|
|
27
|
-
* This is the key bridge: any property access like `data.products` returns
|
|
28
|
-
* a `CollectionAccessor` backed by the underlying DataDriver, without
|
|
29
|
-
* needing per-collection code generation.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* const data = buildRebaseData(driver);
|
|
33
|
-
* await data.products.create({ name: "Camera", price: 299 });
|
|
34
|
-
* const { data: items } = await data.products.find({ where: { status: ["==", "published"] } });
|
|
35
|
-
*/
|
|
36
26
|
export declare function buildRebaseData(driver: DataDriver, options?: EntityDataOptions): RebaseData;
|
|
37
27
|
/**
|
|
38
28
|
* Wrap a flat {@link RebaseSdkData} into a Entity-shaped {@link RebaseData}.
|
package/dist/index.es.js
CHANGED
|
@@ -10,10 +10,28 @@ var DEFAULT_ONE_OF_VALUE = "value";
|
|
|
10
10
|
function isPropertyBuilder(property) {
|
|
11
11
|
return typeof property?.dynamicProps === "function";
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* What a form opens with: a value for every property it can write.
|
|
15
|
+
*
|
|
16
|
+
* `excludeFromApi` columns are left out, and that is the whole of the rule —
|
|
17
|
+
* they are not part of the API surface in either direction, so there is nothing
|
|
18
|
+
* for a form to open showing and nothing it may send back. Including them was
|
|
19
|
+
* not cosmetic: the baseline is what gets submitted, so a new record carried
|
|
20
|
+
* `passwordHash: null` and `emailVerificationToken: null` into the create, and
|
|
21
|
+
* the server refused the whole write with "these columns are the server's to
|
|
22
|
+
* set" — the users collection could not be added to from the panel at all. The
|
|
23
|
+
* fields were invisible on screen (`admin.disabled.hidden`), which is what made
|
|
24
|
+
* the error read as being about the roles the operator *had* just edited.
|
|
25
|
+
*
|
|
26
|
+
* Server-side defaulting does not come through here: `applyDefaultValuesOnCreate`
|
|
27
|
+
* asks each property for its own default, so an excluded column with a declared
|
|
28
|
+
* `defaultValue` is still filled in on an in-process write.
|
|
29
|
+
*/
|
|
13
30
|
function getDefaultValuesFor(properties) {
|
|
14
31
|
if (!properties) return {};
|
|
15
32
|
return Object.entries(properties).map(([key, property]) => {
|
|
16
33
|
if (!property) return {};
|
|
34
|
+
if (property.excludeFromApi) return {};
|
|
17
35
|
const value = getDefaultValueFor(property);
|
|
18
36
|
return value === void 0 ? {} : { [key]: value };
|
|
19
37
|
}).reduce((a, b) => ({
|
|
@@ -124,18 +142,18 @@ function updateUserAutoValues({ inputValues, properties, status, uid }) {
|
|
|
124
142
|
function applyDefaultValuesOnCreate(values, properties) {
|
|
125
143
|
if (!properties) return values ?? {};
|
|
126
144
|
const result = { ...values ?? {} };
|
|
127
|
-
const defaults = getDefaultValuesFor(properties);
|
|
128
145
|
for (const [key, property] of Object.entries(properties)) {
|
|
129
146
|
if (!property) continue;
|
|
130
147
|
if (!declaresDefault(property)) continue;
|
|
148
|
+
const defaultValue = getDefaultValueFor(property);
|
|
131
149
|
if (result[key] !== void 0) {
|
|
132
150
|
if (property.type === "map" && property.defaultValue === void 0 && isPlainObject(result[key])) result[key] = {
|
|
133
|
-
...
|
|
151
|
+
...defaultValue ?? {},
|
|
134
152
|
...result[key]
|
|
135
153
|
};
|
|
136
154
|
continue;
|
|
137
155
|
}
|
|
138
|
-
if (
|
|
156
|
+
if (defaultValue !== void 0) result[key] = defaultValue;
|
|
139
157
|
}
|
|
140
158
|
return result;
|
|
141
159
|
}
|
|
@@ -5825,6 +5843,89 @@ function createPrimaryKeyResolver(options) {
|
|
|
5825
5843
|
};
|
|
5826
5844
|
}
|
|
5827
5845
|
/**
|
|
5846
|
+
* Build the admin's view model out of the row the wire serves.
|
|
5847
|
+
*
|
|
5848
|
+
* The wire has ONE shape, for every consumer: flat columns, typed the way the
|
|
5849
|
+
* database typed them, and a relation rendered as the target's own columns (or
|
|
5850
|
+
* only its foreign key, when nothing asked for it). That is the REST contract,
|
|
5851
|
+
* what `find()` returns, what `listen()` pushes, and what the generated types
|
|
5852
|
+
* describe.
|
|
5853
|
+
*
|
|
5854
|
+
* The admin renders neither of those directly. Its date field requires a real
|
|
5855
|
+
* `Date` and rejects a string outright; its relation cells read `.data.values`
|
|
5856
|
+
* off a relation ref. Those requirements are the *admin's*, so they are met
|
|
5857
|
+
* here — in the browser, from the collection config the panel already has —
|
|
5858
|
+
* rather than by asking the server for a second wire shape.
|
|
5859
|
+
*
|
|
5860
|
+
* That second shape is what this replaces. Until 2026-09-09 the realtime wire
|
|
5861
|
+
* carried the view model and every other read carried flat rows, so `find()`
|
|
5862
|
+
* and `listen()` answered one query two ways; unifying the wire without doing
|
|
5863
|
+
* this conversion is what left every date cell reading "Invalid date value"
|
|
5864
|
+
* and every relation cell "Unexpected value".
|
|
5865
|
+
*
|
|
5866
|
+
* Values already in view-model form pass through untouched: a driver that
|
|
5867
|
+
* still sends `{ __type: "date" }` or a relation ref (the client revives both)
|
|
5868
|
+
* is served by the same walk.
|
|
5869
|
+
*/
|
|
5870
|
+
function toViewModelValues(values, properties, collection, resolveCollection) {
|
|
5871
|
+
if (!properties) return values;
|
|
5872
|
+
const relations = collection ? resolveCollectionRelations(collection) : {};
|
|
5873
|
+
let out;
|
|
5874
|
+
const write = (key, value) => {
|
|
5875
|
+
out = out ?? { ...values };
|
|
5876
|
+
out[key] = value;
|
|
5877
|
+
};
|
|
5878
|
+
for (const [key, rawProperty] of Object.entries(properties)) {
|
|
5879
|
+
const property = rawProperty;
|
|
5880
|
+
if (!property) continue;
|
|
5881
|
+
if (!(key in values)) {
|
|
5882
|
+
const fkRelation = relations[key];
|
|
5883
|
+
const column = fkRelation && "localKey" in fkRelation ? fkRelation.localKey : void 0;
|
|
5884
|
+
const fk = column !== void 0 ? values[column] ?? values[toWireKey(column)] : void 0;
|
|
5885
|
+
const fkTarget = fkRelation?.targetSlug;
|
|
5886
|
+
if (fkTarget && (typeof fk === "string" || typeof fk === "number")) write(key, new EntityRelation(fk, fkTarget));
|
|
5887
|
+
continue;
|
|
5888
|
+
}
|
|
5889
|
+
const value = values[key];
|
|
5890
|
+
if (value === null || value === void 0) continue;
|
|
5891
|
+
const relation = relations[key];
|
|
5892
|
+
if (relation && (property.type === "relation" || property.of?.type === "relation" || property.type === "array")) {
|
|
5893
|
+
const target = relation.targetSlug;
|
|
5894
|
+
if (!target) continue;
|
|
5895
|
+
const targetProperties = resolveCollection?.(target)?.properties;
|
|
5896
|
+
const targetCollection = resolveCollection?.(target);
|
|
5897
|
+
const toRef = (item) => {
|
|
5898
|
+
if (item instanceof EntityRelation) return item;
|
|
5899
|
+
if (typeof item === "object" && item !== null && "__type" in item) return item;
|
|
5900
|
+
if (typeof item === "object" && item !== null) {
|
|
5901
|
+
const row = item;
|
|
5902
|
+
const keys = targetCollection ? resolvePrimaryKeys(targetCollection) : [];
|
|
5903
|
+
const id = keys.length > 0 ? buildCompositeId(row, keys) : row.id;
|
|
5904
|
+
if (id === void 0 || id === null || id === "") return item;
|
|
5905
|
+
return new EntityRelation(id, target, {
|
|
5906
|
+
id,
|
|
5907
|
+
path: target,
|
|
5908
|
+
values: toViewModelValues(row, targetProperties, targetCollection, resolveCollection)
|
|
5909
|
+
});
|
|
5910
|
+
}
|
|
5911
|
+
if (typeof item === "string" || typeof item === "number") return new EntityRelation(item, target);
|
|
5912
|
+
return item;
|
|
5913
|
+
};
|
|
5914
|
+
write(key, Array.isArray(value) ? value.map(toRef) : toRef(value));
|
|
5915
|
+
continue;
|
|
5916
|
+
}
|
|
5917
|
+
if (property.type === "date" && !(value instanceof Date)) {
|
|
5918
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
5919
|
+
const date = new Date(value);
|
|
5920
|
+
write(key, isNaN(date.getTime()) ? null : date);
|
|
5921
|
+
}
|
|
5922
|
+
continue;
|
|
5923
|
+
}
|
|
5924
|
+
if (property.type === "map" && property.properties && typeof value === "object" && !Array.isArray(value)) write(key, toViewModelValues(value, property.properties, void 0, resolveCollection));
|
|
5925
|
+
}
|
|
5926
|
+
return out ?? values;
|
|
5927
|
+
}
|
|
5928
|
+
/**
|
|
5828
5929
|
* Give a flat row the Entity view-model the admin renders.
|
|
5829
5930
|
*
|
|
5830
5931
|
* The address is *derived here* — it is not a column, and the row it came from
|
|
@@ -5835,12 +5936,12 @@ function createPrimaryKeyResolver(options) {
|
|
|
5835
5936
|
* `primaryKeys` empty falls back to a literal `id` on the row: drivers other
|
|
5836
5937
|
* than postgres still serve rows with one, and this keeps them working.
|
|
5837
5938
|
*/
|
|
5838
|
-
function rowToEntity(row, slug, primaryKeys = []) {
|
|
5939
|
+
function rowToEntity(row, slug, primaryKeys = [], toViewModel) {
|
|
5839
5940
|
const { _matches, ...values } = row;
|
|
5840
5941
|
return {
|
|
5841
5942
|
id: primaryKeys.length > 0 ? buildCompositeId(row, primaryKeys) : row.id,
|
|
5842
5943
|
path: slug,
|
|
5843
|
-
values,
|
|
5944
|
+
values: toViewModel ? toViewModel(values) : values,
|
|
5844
5945
|
..._matches ? { searchMatches: _matches } : {}
|
|
5845
5946
|
};
|
|
5846
5947
|
}
|
|
@@ -5860,14 +5961,16 @@ function inlineEnvelope(envelope) {
|
|
|
5860
5961
|
* Replace every relation envelope on a row with the target's flat columns.
|
|
5861
5962
|
*
|
|
5862
5963
|
* The SDK serves one relation shape — the inlined one (see
|
|
5863
|
-
* {@link RestFetchService}) — and
|
|
5864
|
-
*
|
|
5865
|
-
*
|
|
5866
|
-
*
|
|
5964
|
+
* {@link RestFetchService}) — and Postgres now serves it on every read, so
|
|
5965
|
+
* against that driver this walk finds nothing to do. It stays for the drivers
|
|
5966
|
+
* whose own `fetchCollection` still answers with refs: a developer reading
|
|
5967
|
+
* through this accessor gets one shape whichever driver is underneath.
|
|
5867
5968
|
*
|
|
5868
5969
|
* Only applied where the REST pipeline is the contract (see `find`); a driver
|
|
5869
|
-
* without a `restFetchService` keeps whatever it returns
|
|
5870
|
-
*
|
|
5970
|
+
* without a `restFetchService` keeps whatever it returns.
|
|
5971
|
+
*
|
|
5972
|
+
* Note this is NOT how the admin gets its view model — that is built in the
|
|
5973
|
+
* browser by {@link toViewModelValues}, from the same flat row.
|
|
5871
5974
|
*/
|
|
5872
5975
|
function inlineRelationRefs(row) {
|
|
5873
5976
|
let out;
|
|
@@ -5880,7 +5983,7 @@ function inlineRelationRefs(row) {
|
|
|
5880
5983
|
}
|
|
5881
5984
|
return out ?? row;
|
|
5882
5985
|
}
|
|
5883
|
-
function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
5986
|
+
function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
5884
5987
|
const accessor = {
|
|
5885
5988
|
async find(params) {
|
|
5886
5989
|
const filter = params?.where ? deserializeFilter(params.where) : void 0;
|
|
@@ -5929,7 +6032,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5929
6032
|
const last = rows[rows.length - 1];
|
|
5930
6033
|
const nextCursor = hasMore && last && driver.restFetchService?.cursorFor ? driver.restFetchService.cursorFor(slug, last, orderBy) : void 0;
|
|
5931
6034
|
return {
|
|
5932
|
-
data: rows.map((row) => rowToEntity(row, slug, getPks())),
|
|
6035
|
+
data: rows.map((row) => rowToEntity(row, slug, getPks(), toViewModel)),
|
|
5933
6036
|
meta: {
|
|
5934
6037
|
total,
|
|
5935
6038
|
limit,
|
|
@@ -5945,7 +6048,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5945
6048
|
path: slug,
|
|
5946
6049
|
id
|
|
5947
6050
|
});
|
|
5948
|
-
return row ? rowToEntity(row, slug, getPks()) : void 0;
|
|
6051
|
+
return row ? rowToEntity(row, slug, getPks(), toViewModel) : void 0;
|
|
5949
6052
|
},
|
|
5950
6053
|
aggregate: driver.restFetchService?.aggregate ? async (params) => driver.restFetchService.aggregate(slug, {
|
|
5951
6054
|
aggregates: params.select.map(toDriverAggregate),
|
|
@@ -5961,7 +6064,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5961
6064
|
values: data,
|
|
5962
6065
|
id,
|
|
5963
6066
|
status: "new"
|
|
5964
|
-
}), slug, getPks());
|
|
6067
|
+
}), slug, getPks(), toViewModel);
|
|
5965
6068
|
},
|
|
5966
6069
|
createMany: driver.saveMany ? async (data, options) => {
|
|
5967
6070
|
return (await driver.saveMany({
|
|
@@ -5969,7 +6072,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5969
6072
|
rows: data,
|
|
5970
6073
|
upsert: options?.upsert,
|
|
5971
6074
|
onConflict: options?.onConflict
|
|
5972
|
-
})).map((row) => rowToEntity(row, slug, getPks()));
|
|
6075
|
+
})).map((row) => rowToEntity(row, slug, getPks(), toViewModel));
|
|
5973
6076
|
} : void 0,
|
|
5974
6077
|
async update(id, data) {
|
|
5975
6078
|
return rowToEntity(await driver.save({
|
|
@@ -5977,7 +6080,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5977
6080
|
values: data,
|
|
5978
6081
|
id,
|
|
5979
6082
|
status: "existing"
|
|
5980
|
-
}), slug, getPks());
|
|
6083
|
+
}), slug, getPks(), toViewModel);
|
|
5981
6084
|
},
|
|
5982
6085
|
async delete(id) {
|
|
5983
6086
|
return driver.delete({ row: {
|
|
@@ -5993,7 +6096,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
5993
6096
|
id: u.id,
|
|
5994
6097
|
values: u.data
|
|
5995
6098
|
}))
|
|
5996
|
-
})).map((row) => rowToEntity(row, slug, getPks()));
|
|
6099
|
+
})).map((row) => rowToEntity(row, slug, getPks(), toViewModel));
|
|
5997
6100
|
} : void 0,
|
|
5998
6101
|
deleteMany: driver.deleteMany ? async (ids) => {
|
|
5999
6102
|
await driver.deleteMany({
|
|
@@ -6025,7 +6128,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
6025
6128
|
vectorSearch: params?.vectorSearch,
|
|
6026
6129
|
onUpdate: (entities) => {
|
|
6027
6130
|
onUpdate({
|
|
6028
|
-
data: entities.map((row) => rowToEntity(normalize(row), slug, getPks())),
|
|
6131
|
+
data: entities.map((row) => rowToEntity(normalize(row), slug, getPks(), toViewModel)),
|
|
6029
6132
|
meta: {
|
|
6030
6133
|
total: offset + entities.length,
|
|
6031
6134
|
limit,
|
|
@@ -6042,7 +6145,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
6042
6145
|
return driver.listenOne({
|
|
6043
6146
|
path: slug,
|
|
6044
6147
|
id,
|
|
6045
|
-
onUpdate: (entity) => onUpdate(entity ? rowToEntity(normalize(entity), slug, getPks()) : void 0),
|
|
6148
|
+
onUpdate: (entity) => onUpdate(entity ? rowToEntity(normalize(entity), slug, getPks(), toViewModel) : void 0),
|
|
6046
6149
|
onError
|
|
6047
6150
|
});
|
|
6048
6151
|
} : void 0,
|
|
@@ -6084,13 +6187,32 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
6084
6187
|
* await data.products.create({ name: "Camera", price: 299 });
|
|
6085
6188
|
* const { data: items } = await data.products.find({ where: { status: ["==", "published"] } });
|
|
6086
6189
|
*/
|
|
6190
|
+
/**
|
|
6191
|
+
* The view-model converter for one collection, or `undefined` when there is no
|
|
6192
|
+
* collection config to build it from.
|
|
6193
|
+
*
|
|
6194
|
+
* Absent is the honest answer for every consumer that is not the admin: the
|
|
6195
|
+
* flat SDK derives itself from this same layer (`buildSdkData`) and must keep
|
|
6196
|
+
* the wire's own types, and it registers no collection resolver.
|
|
6197
|
+
*/
|
|
6198
|
+
function createViewModelConverter(options) {
|
|
6199
|
+
if (!options?.resolveCollection) return () => void 0;
|
|
6200
|
+
return function converterFor(slug) {
|
|
6201
|
+
return (values) => {
|
|
6202
|
+
const collection = options.resolveCollection?.(slug);
|
|
6203
|
+
if (!collection) return values;
|
|
6204
|
+
return toViewModelValues(values, collection.properties, collection, options.resolveCollection);
|
|
6205
|
+
};
|
|
6206
|
+
};
|
|
6207
|
+
}
|
|
6087
6208
|
function buildRebaseData(driver, options) {
|
|
6088
6209
|
const cache = /* @__PURE__ */ new Map();
|
|
6089
6210
|
const primaryKeysFor = createPrimaryKeyResolver(options);
|
|
6211
|
+
const viewModelFor = createViewModelConverter(options);
|
|
6090
6212
|
function getAccessor(slug) {
|
|
6091
6213
|
let accessor = cache.get(slug);
|
|
6092
6214
|
if (!accessor) {
|
|
6093
|
-
accessor = createDriverAccessor(driver, slug, () => primaryKeysFor(slug));
|
|
6215
|
+
accessor = createDriverAccessor(driver, slug, () => primaryKeysFor(slug), viewModelFor(slug));
|
|
6094
6216
|
cache.set(slug, accessor);
|
|
6095
6217
|
}
|
|
6096
6218
|
return accessor;
|
|
@@ -6355,29 +6477,29 @@ function toSdkCollectionClient(snap, slug = "collection") {
|
|
|
6355
6477
|
* {@link CollectionAccessor}. Every returned row is re-wrapped into the
|
|
6356
6478
|
* `{ id, path, values }` view-model the admin panel renders.
|
|
6357
6479
|
*/
|
|
6358
|
-
function toEntityAccessor(sdk, slug, getPks = () => []) {
|
|
6480
|
+
function toEntityAccessor(sdk, slug, getPks = () => [], toViewModel) {
|
|
6359
6481
|
const accessor = {
|
|
6360
6482
|
async find(params) {
|
|
6361
6483
|
const res = await sdk.find(params);
|
|
6362
6484
|
return {
|
|
6363
|
-
data: res.data.map((row) => rowToEntity(row, slug, getPks())),
|
|
6485
|
+
data: res.data.map((row) => rowToEntity(row, slug, getPks(), toViewModel)),
|
|
6364
6486
|
meta: res.meta
|
|
6365
6487
|
};
|
|
6366
6488
|
},
|
|
6367
6489
|
async findById(id) {
|
|
6368
6490
|
const row = await sdk.findById(id);
|
|
6369
|
-
return row ? rowToEntity(row, slug, getPks()) : void 0;
|
|
6491
|
+
return row ? rowToEntity(row, slug, getPks(), toViewModel) : void 0;
|
|
6370
6492
|
},
|
|
6371
6493
|
async create(data, id) {
|
|
6372
|
-
return rowToEntity(await sdk.create(data, id), slug, getPks());
|
|
6494
|
+
return rowToEntity(await sdk.create(data, id), slug, getPks(), toViewModel);
|
|
6373
6495
|
},
|
|
6374
6496
|
createMany: sdk.createMany ? async (data, options) => {
|
|
6375
|
-
return (await sdk.createMany(data, options)).map((row) => rowToEntity(row, slug, getPks()));
|
|
6497
|
+
return (await sdk.createMany(data, options)).map((row) => rowToEntity(row, slug, getPks(), toViewModel));
|
|
6376
6498
|
} : void 0,
|
|
6377
6499
|
async update(id, data) {
|
|
6378
6500
|
const row = await sdk.update(id, data);
|
|
6379
6501
|
if (!row) throw new Error(`Update returned no data for id ${id}`);
|
|
6380
|
-
return rowToEntity(row, slug, getPks());
|
|
6502
|
+
return rowToEntity(row, slug, getPks(), toViewModel);
|
|
6381
6503
|
},
|
|
6382
6504
|
delete(id) {
|
|
6383
6505
|
return sdk.delete(id);
|
|
@@ -6385,10 +6507,10 @@ function toEntityAccessor(sdk, slug, getPks = () => []) {
|
|
|
6385
6507
|
count: isUnsupported(sdk.count) ? void 0 : (params) => sdk.count(params),
|
|
6386
6508
|
aggregate: isUnsupported(sdk.aggregate) ? void 0 : (params) => sdk.aggregate(params),
|
|
6387
6509
|
listen: isUnsupported(sdk.listen) ? void 0 : (params, onUpdate, onError) => sdk.listen(params, (res) => onUpdate({
|
|
6388
|
-
data: res.data.map((row) => rowToEntity(row, slug, getPks())),
|
|
6510
|
+
data: res.data.map((row) => rowToEntity(row, slug, getPks(), toViewModel)),
|
|
6389
6511
|
meta: res.meta
|
|
6390
6512
|
}), onError),
|
|
6391
|
-
listenById: isUnsupported(sdk.listenById) ? void 0 : (id, onUpdate, onError) => sdk.listenById(id, (row) => onUpdate(row ? rowToEntity(row, slug, getPks()) : void 0), onError),
|
|
6513
|
+
listenById: isUnsupported(sdk.listenById) ? void 0 : (id, onUpdate, onError) => sdk.listenById(id, (row) => onUpdate(row ? rowToEntity(row, slug, getPks(), toViewModel) : void 0), onError),
|
|
6392
6514
|
where(columnOrCondition, operator, value) {
|
|
6393
6515
|
const builder = new QueryBuilder(accessor);
|
|
6394
6516
|
if (typeof columnOrCondition === "object") return builder.where(columnOrCondition);
|
|
@@ -6424,10 +6546,11 @@ function toEntityAccessor(sdk, slug, getPks = () => []) {
|
|
|
6424
6546
|
function wrapAsEntityData(sdkData, options) {
|
|
6425
6547
|
const cache = /* @__PURE__ */ new Map();
|
|
6426
6548
|
const primaryKeysFor = createPrimaryKeyResolver(options);
|
|
6549
|
+
const viewModelFor = createViewModelConverter(options);
|
|
6427
6550
|
function getAccessor(slug) {
|
|
6428
6551
|
let accessor = cache.get(slug);
|
|
6429
6552
|
if (!accessor) {
|
|
6430
|
-
accessor = toEntityAccessor(sdkData.collection(slug), slug, () => primaryKeysFor(slug));
|
|
6553
|
+
accessor = toEntityAccessor(sdkData.collection(slug), slug, () => primaryKeysFor(slug), viewModelFor(slug));
|
|
6431
6554
|
cache.set(slug, accessor);
|
|
6432
6555
|
}
|
|
6433
6556
|
return accessor;
|