@statezero/core 0.1.5 → 0.1.6

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,10 +1,10 @@
1
- import { Manager } from './manager.js';
2
- import { ValidationError } from './errors.js';
3
- import { modelStoreRegistry } from '../../syncEngine/registries/modelStoreRegistry.js';
4
- import { isNil } from 'lodash-es';
5
- import { QueryExecutor } from './queryExecutor';
6
- import { wrapReactiveModel } from '../../reactiveAdaptor.js';
7
- import { DateParsingHelpers } from './dates.js';
1
+ import { Manager } from "./manager.js";
2
+ import { ValidationError } from "./errors.js";
3
+ import { modelStoreRegistry } from "../../syncEngine/registries/modelStoreRegistry.js";
4
+ import { isNil } from "lodash-es";
5
+ import { QueryExecutor } from "./queryExecutor";
6
+ import { wrapReactiveModel } from "../../reactiveAdaptor.js";
7
+ import { DateParsingHelpers } from "./dates.js";
8
8
  /**
9
9
  * A constructor for a Model.
10
10
  *
@@ -54,7 +54,7 @@ export class Model {
54
54
  * Instantiate from pk using queryset scoped singletons
55
55
  */
56
56
  static fromPk(pk, querySet) {
57
- let qsId = querySet ? querySet.__uuid : '';
57
+ let qsId = querySet ? querySet.__uuid : "";
58
58
  let key = `${qsId}__${this.configKey}__${this.modelName}__${pk}`;
59
59
  if (!this.instanceCache.has(key)) {
60
60
  const instance = new this();
@@ -90,15 +90,15 @@ export class Model {
90
90
  // footgun - fieldInfo.ModelClass() calls the arrow function that lazily gets the model class
91
91
  let relPkField = fieldInfo.ModelClass().primaryKeyField;
92
92
  switch (fieldInfo.relationshipType) {
93
- case 'many-to-many':
93
+ case "many-to-many":
94
94
  // value is an array
95
95
  if (!Array.isArray(value) && value)
96
96
  throw new Error(`Data corruption: m2m field for ${ModelClass.modelName} stored as ${value}`);
97
97
  // set each pk to the full model object for that pk
98
- value = value.map(pk => fieldInfo.ModelClass().fromPk(pk));
98
+ value = value.map((pk) => fieldInfo.ModelClass().fromPk(pk));
99
99
  break;
100
- case 'one-to-one':
101
- case 'foreign-key':
100
+ case "one-to-one":
101
+ case "foreign-key":
102
102
  // footgun - fieldInfo.ModelClass() calls the arrow function that lazily gets the model class
103
103
  if (!isNil(value))
104
104
  value = fieldInfo.ModelClass().fromPk(value);
@@ -135,13 +135,13 @@ export class Model {
135
135
  return;
136
136
  const allowedFields = this.fields;
137
137
  for (const key of Object.keys(data)) {
138
- if (key === 'repr' || key === 'type')
138
+ if (key === "repr" || key === "type")
139
139
  continue;
140
140
  // Handle nested fields by splitting on double underscore
141
141
  // and taking just the base field name
142
- const baseField = key.split('__')[0];
142
+ const baseField = key.split("__")[0];
143
143
  if (!allowedFields.includes(baseField)) {
144
- let errorMsg = `Invalid field: ${baseField}. Allowed fields are: ${allowedFields.join(', ')}`;
144
+ let errorMsg = `Invalid field: ${baseField}. Allowed fields are: ${allowedFields.join(", ")}`;
145
145
  console.error(errorMsg);
146
146
  throw new ValidationError(errorMsg);
147
147
  }
@@ -165,6 +165,18 @@ export class Model {
165
165
  if (storedValue)
166
166
  value = storedValue[field];
167
167
  }
168
+ if (ModelClass.relationshipFields &&
169
+ ModelClass.relationshipFields.has(field) &&
170
+ value) {
171
+ let fieldInfo = ModelClass.relationshipFields.get(field);
172
+ switch (fieldInfo.relationshipType) {
173
+ case "many-to-many":
174
+ return value.map((instance) => instance.pk ? instance.pk : instance);
175
+ case "one-to-one":
176
+ case "foreign-key":
177
+ return value.pk ? value.pk : value;
178
+ }
179
+ }
168
180
  return value;
169
181
  }
170
182
  /**
@@ -192,16 +204,20 @@ export class Model {
192
204
  async save() {
193
205
  const ModelClass = this.constructor;
194
206
  const pkField = ModelClass.primaryKeyField;
195
- const querySet = !this.pk ? ModelClass.objects.newQuerySet() : ModelClass.objects.filter({ [pkField]: this.pk });
207
+ const querySet = !this.pk
208
+ ? ModelClass.objects.newQuerySet()
209
+ : ModelClass.objects.filter({ [pkField]: this.pk });
196
210
  const data = this.serialize();
197
211
  let instance;
198
212
  if (!this.pk) {
199
213
  // Create new instance
200
- instance = await QueryExecutor.execute(querySet, 'create', { data });
214
+ instance = await QueryExecutor.execute(querySet, "create", { data });
201
215
  }
202
216
  else {
203
217
  // Update existing instance
204
- instance = await QueryExecutor.execute(querySet, 'update_instance', { data });
218
+ instance = await QueryExecutor.execute(querySet, "update_instance", {
219
+ data,
220
+ });
205
221
  }
206
222
  this._pk = instance.pk;
207
223
  this._data = {};
@@ -218,14 +234,14 @@ export class Model {
218
234
  */
219
235
  async delete() {
220
236
  if (!this.pk) {
221
- throw new Error('Cannot delete unsaved instance');
237
+ throw new Error("Cannot delete unsaved instance");
222
238
  }
223
239
  const ModelClass = this.constructor;
224
240
  const pkField = ModelClass.primaryKeyField;
225
241
  const querySet = ModelClass.objects.filter({ [pkField]: this.pk });
226
242
  // Pass the instance data with primary key as the args
227
243
  const args = { [pkField]: this.pk };
228
- const result = await QueryExecutor.execute(querySet, 'delete_instance', args);
244
+ const result = await QueryExecutor.execute(querySet, "delete_instance", args);
229
245
  // result -> [deletedCount, { [modelName]: deletedCount }];
230
246
  return result;
231
247
  }
@@ -237,10 +253,12 @@ export class Model {
237
253
  */
238
254
  async refreshFromDb() {
239
255
  if (!this.pk) {
240
- throw new Error('Cannot refresh unsaved instance');
256
+ throw new Error("Cannot refresh unsaved instance");
241
257
  }
242
258
  const ModelClass = this.constructor;
243
- const fresh = await ModelClass.objects.get({ [ModelClass.primaryKeyField]: this.pk });
259
+ const fresh = await ModelClass.objects.get({
260
+ [ModelClass.primaryKeyField]: this.pk,
261
+ });
244
262
  // clear the current data and fresh data will flow
245
263
  this._data = {};
246
264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "module": "ESNext",
6
6
  "description": "The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate",