@statezero/core 0.1.37 → 0.1.39
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,9 +1,8 @@
|
|
|
1
|
-
import { computed, getCurrentInstance, onBeforeUnmount } from
|
|
2
|
-
import { querysetStoreRegistry } from
|
|
3
|
-
import { metricRegistry } from
|
|
4
|
-
import { syncManager } from
|
|
5
|
-
import {
|
|
6
|
-
import { v7 } from "uuid";
|
|
1
|
+
import { computed, getCurrentInstance, onBeforeUnmount } from 'vue';
|
|
2
|
+
import { querysetStoreRegistry } from '../../syncEngine/registries/querysetStoreRegistry';
|
|
3
|
+
import { metricRegistry } from '../../syncEngine/registries/metricRegistry';
|
|
4
|
+
import { syncManager } from '../../syncEngine/sync';
|
|
5
|
+
import { v7 } from 'uuid';
|
|
7
6
|
syncManager.followAllQuerysets = false;
|
|
8
7
|
export const querysets = new Map(); // Map of composableId -> queryset
|
|
9
8
|
function updateSyncManager() {
|
|
@@ -14,16 +13,11 @@ function updateSyncManager() {
|
|
|
14
13
|
export function useQueryset(querysetFactory) {
|
|
15
14
|
const instance = getCurrentInstance();
|
|
16
15
|
if (!instance) {
|
|
17
|
-
throw new Error(
|
|
16
|
+
throw new Error('useQueryset must be called within a component setup function');
|
|
18
17
|
}
|
|
19
18
|
const composableId = v7();
|
|
20
19
|
let lastQueryset = null;
|
|
21
20
|
onBeforeUnmount(() => {
|
|
22
|
-
// Clear cache when component unmounts
|
|
23
|
-
if (lastQueryset?.semanticKey &&
|
|
24
|
-
wrappedQuerysetCache.has(lastQueryset.semanticKey)) {
|
|
25
|
-
wrappedQuerysetCache.delete(lastQueryset.semanticKey);
|
|
26
|
-
}
|
|
27
21
|
querysets.delete(composableId);
|
|
28
22
|
updateSyncManager();
|
|
29
23
|
});
|
|
@@ -33,12 +27,6 @@ export function useQueryset(querysetFactory) {
|
|
|
33
27
|
const queryset = original?.queryset || original;
|
|
34
28
|
// Only update if queryset actually changed
|
|
35
29
|
if (lastQueryset !== queryset) {
|
|
36
|
-
// Clear cache for previous queryset if it changed
|
|
37
|
-
if (lastQueryset?.semanticKey &&
|
|
38
|
-
lastQueryset !== queryset &&
|
|
39
|
-
wrappedQuerysetCache.has(lastQueryset.semanticKey)) {
|
|
40
|
-
wrappedQuerysetCache.delete(lastQueryset.semanticKey);
|
|
41
|
-
}
|
|
42
30
|
querysets.set(composableId, queryset);
|
|
43
31
|
updateSyncManager();
|
|
44
32
|
lastQueryset = queryset;
|
|
@@ -16,4 +16,3 @@ export function ModelAdaptor(modelInstance: Object, reactivityFn?: Function): an
|
|
|
16
16
|
*/
|
|
17
17
|
export function QuerySetAdaptor(liveQuerySet: Object, reactivityFn?: Function): any | import("vue").Ref;
|
|
18
18
|
export function MetricAdaptor(metric: any): any;
|
|
19
|
-
export const wrappedQuerysetCache: Map<any, any>;
|
|
@@ -35,6 +35,14 @@ export class Model {
|
|
|
35
35
|
* @throws {ValidationError} If an unknown key is found.
|
|
36
36
|
*/
|
|
37
37
|
static validateFields(data: Object): void;
|
|
38
|
+
/**
|
|
39
|
+
* Static method to validate data without creating an instance
|
|
40
|
+
* @param {Object} data - Data to validate
|
|
41
|
+
* @param {string} validateType - 'create' or 'update'
|
|
42
|
+
* @param {boolean} partial - Whether to allow partial validation
|
|
43
|
+
* @returns {Promise<boolean>} Promise that resolves to true if valid, throws error if invalid
|
|
44
|
+
*/
|
|
45
|
+
static validate(data: Object, validateType?: string, partial?: boolean): Promise<boolean>;
|
|
38
46
|
constructor(data?: {});
|
|
39
47
|
_data: {};
|
|
40
48
|
_pk: any;
|
|
@@ -105,6 +113,13 @@ export class Model {
|
|
|
105
113
|
* @throws {Error} If the instance has not been saved (no primary key).
|
|
106
114
|
*/
|
|
107
115
|
refreshFromDb(): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Validates the model instance using the same serialize behavior as save()
|
|
118
|
+
* @param {string} validateType - 'create' or 'update' (defaults to auto-detect)
|
|
119
|
+
* @param {boolean} partial - Whether to allow partial validation
|
|
120
|
+
* @returns {Promise<boolean>} Promise that resolves to true if valid, throws error if invalid
|
|
121
|
+
*/
|
|
122
|
+
validate(validateType?: string, partial?: boolean): Promise<boolean>;
|
|
108
123
|
}
|
|
109
124
|
/**
|
|
110
125
|
* A constructor for a Model.
|
|
@@ -10,6 +10,9 @@ import { QueryExecutor } from "./queryExecutor";
|
|
|
10
10
|
import { wrapReactiveModel } from "../../reactiveAdaptor.js";
|
|
11
11
|
import { DateParsingHelpers } from "./dates.js";
|
|
12
12
|
import { FileObject } from './files.js';
|
|
13
|
+
import { configInstance } from "../../config.js";
|
|
14
|
+
import { parseStateZeroError, MultipleObjectsReturned, DoesNotExist, } from "./errors.js";
|
|
15
|
+
import axios from "axios";
|
|
13
16
|
/**
|
|
14
17
|
* A constructor for a Model.
|
|
15
18
|
*
|
|
@@ -292,6 +295,74 @@ export class Model {
|
|
|
292
295
|
// clear the current data and fresh data will flow
|
|
293
296
|
this._data = {};
|
|
294
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Validates the model instance using the same serialize behavior as save()
|
|
300
|
+
* @param {string} validateType - 'create' or 'update' (defaults to auto-detect)
|
|
301
|
+
* @param {boolean} partial - Whether to allow partial validation
|
|
302
|
+
* @returns {Promise<boolean>} Promise that resolves to true if valid, throws error if invalid
|
|
303
|
+
*/
|
|
304
|
+
async validate(validateType = null, partial = false) {
|
|
305
|
+
const ModelClass = this.constructor;
|
|
306
|
+
if (!validateType) {
|
|
307
|
+
validateType = this.pk ? "update" : "create";
|
|
308
|
+
}
|
|
309
|
+
// Validate the validateType parameter
|
|
310
|
+
if (!["update", "create"].includes(validateType)) {
|
|
311
|
+
throw new Error(`Validation type must be 'update' or 'create', not '${validateType}'`);
|
|
312
|
+
}
|
|
313
|
+
// Use the same serialize logic as save()
|
|
314
|
+
const data = this.serialize();
|
|
315
|
+
// Delegate to static method
|
|
316
|
+
return ModelClass.validate(data, validateType, partial);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Static method to validate data without creating an instance
|
|
320
|
+
* @param {Object} data - Data to validate
|
|
321
|
+
* @param {string} validateType - 'create' or 'update'
|
|
322
|
+
* @param {boolean} partial - Whether to allow partial validation
|
|
323
|
+
* @returns {Promise<boolean>} Promise that resolves to true if valid, throws error if invalid
|
|
324
|
+
*/
|
|
325
|
+
static async validate(data, validateType = "create", partial = false) {
|
|
326
|
+
const ModelClass = this;
|
|
327
|
+
// Validate the validateType parameter
|
|
328
|
+
if (!["update", "create"].includes(validateType)) {
|
|
329
|
+
throw new Error(`Validation type must be 'update' or 'create', not '${validateType}'`);
|
|
330
|
+
}
|
|
331
|
+
// Get backend config and check if it exists
|
|
332
|
+
const config = configInstance.getConfig();
|
|
333
|
+
const backend = config.backendConfigs[ModelClass.configKey];
|
|
334
|
+
if (!backend) {
|
|
335
|
+
throw new Error(`No backend configuration found for key: ${ModelClass.configKey}`);
|
|
336
|
+
}
|
|
337
|
+
// Build URL for validate endpoint
|
|
338
|
+
const baseUrl = backend.API_URL.replace(/\/+$/, "");
|
|
339
|
+
const url = `${baseUrl}/${ModelClass.modelName}/validate/`;
|
|
340
|
+
// Prepare headers
|
|
341
|
+
const headers = {
|
|
342
|
+
"Content-Type": "application/json",
|
|
343
|
+
...(backend.getAuthHeaders ? backend.getAuthHeaders() : {}),
|
|
344
|
+
};
|
|
345
|
+
// Make direct API call to validate endpoint
|
|
346
|
+
try {
|
|
347
|
+
const response = await axios.post(url, {
|
|
348
|
+
data: data,
|
|
349
|
+
validate_type: validateType,
|
|
350
|
+
partial: partial,
|
|
351
|
+
}, { headers });
|
|
352
|
+
// Backend returns {"valid": true} on success
|
|
353
|
+
return response.data.valid === true;
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
if (error.response && error.response.data) {
|
|
357
|
+
const parsedError = parseStateZeroError(error.response.data);
|
|
358
|
+
if (Error.captureStackTrace) {
|
|
359
|
+
Error.captureStackTrace(parsedError, ModelClass.validate);
|
|
360
|
+
}
|
|
361
|
+
throw parsedError;
|
|
362
|
+
}
|
|
363
|
+
throw new Error(`Validation failed: ${error.message}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
295
366
|
}
|
|
296
367
|
/**
|
|
297
368
|
* Creates a new Model instance.
|
package/package.json
CHANGED