@statezero/core 0.1.97 → 0.1.99
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.
|
@@ -223,7 +223,7 @@ export class QueryExecutor {
|
|
|
223
223
|
};
|
|
224
224
|
const operation = OperationFactory.createUpdateOperation(querySet, apiCallArgs.data, querySet.build().filter);
|
|
225
225
|
const estimatedCount = operation.instances.length;
|
|
226
|
-
let liveResult = [estimatedCount, { [modelName]: estimatedCount }];
|
|
226
|
+
let liveResult = [estimatedCount, { [modelName]: estimatedCount }, []];
|
|
227
227
|
const promise = makeApiCall(querySet, operationType, apiCallArgs, operation.operationId)
|
|
228
228
|
.then((response) => {
|
|
229
229
|
const { data, included } = response.data || {};
|
|
@@ -233,7 +233,7 @@ export class QueryExecutor {
|
|
|
233
233
|
: [];
|
|
234
234
|
operation.updateStatus(Status.CONFIRMED, updatedObjects);
|
|
235
235
|
const updatedCount = response.metadata?.updated_count ?? 0;
|
|
236
|
-
liveResult = [updatedCount, { [modelName]: updatedCount }];
|
|
236
|
+
liveResult = [updatedCount, { [modelName]: updatedCount }, updatedObjects];
|
|
237
237
|
breakThenable(liveResult);
|
|
238
238
|
return liveResult;
|
|
239
239
|
})
|
|
@@ -258,13 +258,13 @@ export class QueryExecutor {
|
|
|
258
258
|
const operation = OperationFactory.createDeleteOperation(querySet);
|
|
259
259
|
// live placeholder: assume we delete all existing pks
|
|
260
260
|
const estimatedCount = operation.instances.length;
|
|
261
|
-
let liveResult = [estimatedCount, { [modelName]: estimatedCount }];
|
|
261
|
+
let liveResult = [estimatedCount, { [modelName]: estimatedCount }, []];
|
|
262
262
|
const promise = makeApiCall(querySet, operationType, {}, operation.operationId)
|
|
263
263
|
.then((response) => {
|
|
264
264
|
const deletedCount = response.metadata.deleted_count;
|
|
265
265
|
const deletedInstances = response.metadata.rows_deleted;
|
|
266
266
|
operation.updateStatus(Status.CONFIRMED, deletedInstances);
|
|
267
|
-
liveResult = [deletedCount, { [modelName]: deletedCount }];
|
|
267
|
+
liveResult = [deletedCount, { [modelName]: deletedCount }, deletedInstances || []];
|
|
268
268
|
breakThenable(liveResult);
|
|
269
269
|
return liveResult;
|
|
270
270
|
})
|
|
@@ -468,7 +468,7 @@ export class QueryExecutor {
|
|
|
468
468
|
// Use factory to create operation
|
|
469
469
|
const operation = OperationFactory.createDeleteInstanceOperation(querySet, args);
|
|
470
470
|
// 1) placeholder result
|
|
471
|
-
let liveResult = [1, { [modelName]: 1 }];
|
|
471
|
+
let liveResult = [1, { [modelName]: 1 }, []];
|
|
472
472
|
// 2) async call
|
|
473
473
|
const promise = makeApiCall(querySet, operationType, args, operation.operationId)
|
|
474
474
|
.then((response) => {
|
|
@@ -477,10 +477,12 @@ export class QueryExecutor {
|
|
|
477
477
|
if (typeof response.data === "number") {
|
|
478
478
|
deletedCount = response.data;
|
|
479
479
|
}
|
|
480
|
+
// Get deleted instances from metadata if available
|
|
481
|
+
const deletedInstances = response.metadata?.rows_deleted || [args];
|
|
480
482
|
// Confirm operation
|
|
481
483
|
operation.updateStatus(Status.CONFIRMED, [args]);
|
|
482
484
|
// Swap in real result and freeze
|
|
483
|
-
liveResult = [deletedCount, { [modelName]: deletedCount }];
|
|
485
|
+
liveResult = [deletedCount, { [modelName]: deletedCount }, deletedInstances];
|
|
484
486
|
breakThenable(liveResult);
|
|
485
487
|
return liveResult;
|
|
486
488
|
})
|
|
@@ -80,6 +80,14 @@ export class QuerySet<T> {
|
|
|
80
80
|
* @returns {Object} The serialized conditions.
|
|
81
81
|
*/
|
|
82
82
|
private _serializeConditions;
|
|
83
|
+
/**
|
|
84
|
+
* Serializes a value based on its type (handles arrays, Model instances, Dates, primitives)
|
|
85
|
+
*
|
|
86
|
+
* @private
|
|
87
|
+
* @param {any} value - The value to serialize
|
|
88
|
+
* @returns {any} The serialized value
|
|
89
|
+
*/
|
|
90
|
+
private _serializeValue;
|
|
83
91
|
/**
|
|
84
92
|
* Filters the QuerySet with the provided conditions.
|
|
85
93
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MultipleObjectsReturned, DoesNotExist, parseStateZeroError, } from "./errors.js";
|
|
2
2
|
import { Model } from "./model.js";
|
|
3
|
-
import { ModelSerializer } from "./serializers.js";
|
|
3
|
+
import { ModelSerializer, relationshipFieldSerializer, dateFieldSerializer } from "./serializers.js";
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import { QueryExecutor } from "./queryExecutor.js";
|
|
6
6
|
import { json } from "stream/consumers";
|
|
@@ -110,8 +110,57 @@ export class QuerySet {
|
|
|
110
110
|
if (!conditions || typeof conditions !== "object") {
|
|
111
111
|
return conditions;
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
const serializedConditions = {};
|
|
114
|
+
for (const [fieldPath, value] of Object.entries(conditions)) {
|
|
115
|
+
serializedConditions[fieldPath] = this._serializeValue(value);
|
|
116
|
+
}
|
|
117
|
+
return serializedConditions;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Serializes a value based on its type (handles arrays, Model instances, Dates, primitives)
|
|
121
|
+
*
|
|
122
|
+
* @private
|
|
123
|
+
* @param {any} value - The value to serialize
|
|
124
|
+
* @returns {any} The serialized value
|
|
125
|
+
*/
|
|
126
|
+
_serializeValue(value) {
|
|
127
|
+
// Handle arrays (for __in lookups)
|
|
128
|
+
if (Array.isArray(value)) {
|
|
129
|
+
return value.map(item => this._serializeValue(item));
|
|
130
|
+
}
|
|
131
|
+
// Handle Model instances (objects with pk, serialize method, and constructor with configKey/modelName)
|
|
132
|
+
// Note: Model instances are objects, not classes (typeof instance === 'object')
|
|
133
|
+
if (value &&
|
|
134
|
+
typeof value === 'object' &&
|
|
135
|
+
!(value instanceof Date) && // Exclude Date objects
|
|
136
|
+
'pk' in value &&
|
|
137
|
+
'serialize' in value &&
|
|
138
|
+
typeof value.serialize === 'function' &&
|
|
139
|
+
value.constructor &&
|
|
140
|
+
'configKey' in value.constructor &&
|
|
141
|
+
'modelName' in value.constructor) {
|
|
142
|
+
return relationshipFieldSerializer.toInternal(value);
|
|
143
|
+
}
|
|
144
|
+
// Handle Date objects
|
|
145
|
+
// Without field context, we default to datetime format (ISO string with time)
|
|
146
|
+
// Unless it's exactly midnight in UTC, which likely indicates a date-only field
|
|
147
|
+
if (value instanceof Date) {
|
|
148
|
+
// Check if it's midnight UTC (likely a date-only value)
|
|
149
|
+
const hours = value.getUTCHours();
|
|
150
|
+
const minutes = value.getUTCMinutes();
|
|
151
|
+
const seconds = value.getUTCSeconds();
|
|
152
|
+
const milliseconds = value.getUTCMilliseconds();
|
|
153
|
+
if (hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) {
|
|
154
|
+
// It's midnight UTC - serialize as date-only (YYYY-MM-DD)
|
|
155
|
+
return value.toISOString().split('T')[0];
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Has time component - serialize as full datetime
|
|
159
|
+
return value.toISOString();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Everything else (strings, numbers, booleans, null) - return as-is
|
|
163
|
+
return value;
|
|
115
164
|
}
|
|
116
165
|
/**
|
|
117
166
|
* Filters the QuerySet with the provided conditions.
|
package/package.json
CHANGED