@statezero/core 0.1.50 → 0.1.52
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.
|
@@ -25,7 +25,6 @@ export class FileObject {
|
|
|
25
25
|
get status(): "failed" | "uploading" | "uploaded" | "pending";
|
|
26
26
|
get filePath(): any;
|
|
27
27
|
get fileUrl(): any;
|
|
28
|
-
serialize(): any;
|
|
29
28
|
_initializeAndStartUpload(file: any, options: any): any;
|
|
30
29
|
/**
|
|
31
30
|
* Fast upload using S3 presigned URLs with multipart support
|
|
@@ -60,11 +59,6 @@ export class FileObject {
|
|
|
60
59
|
*/
|
|
61
60
|
getBlob(): Blob;
|
|
62
61
|
waitForUpload(): Promise<any>;
|
|
63
|
-
/**
|
|
64
|
-
* Returns a static version of this FileObject that can be stored in IndexedDB
|
|
65
|
-
* Creates a new FileObject using the stored file constructor path
|
|
66
|
-
*/
|
|
67
|
-
asStatic(): any;
|
|
68
62
|
toJSON(): {
|
|
69
63
|
name: any;
|
|
70
64
|
size: any;
|
|
@@ -30,7 +30,7 @@ export class FileObject {
|
|
|
30
30
|
this.completedChunks = 0;
|
|
31
31
|
this.chunkSize = null;
|
|
32
32
|
this.maxConcurrency = null;
|
|
33
|
-
this.uploadPromise =
|
|
33
|
+
this.uploadPromise = Promise.resolve(this.uploadResult);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
// Handle File objects (for upload) - existing code
|
|
@@ -82,25 +82,6 @@ export class FileObject {
|
|
|
82
82
|
}
|
|
83
83
|
return configInstance.buildFileUrl(this.uploadResult.file_url, this.constructor.configKey);
|
|
84
84
|
}
|
|
85
|
-
serialize() {
|
|
86
|
-
const status = this.status;
|
|
87
|
-
if (status === "uploaded" && this.filePath) {
|
|
88
|
-
return this.filePath;
|
|
89
|
-
}
|
|
90
|
-
else if (status === "failed") {
|
|
91
|
-
// Fix: use "failed" instead of "error"
|
|
92
|
-
throw new Error(`Cannot use FileObject in query - upload failed: ${this.uploadError}`);
|
|
93
|
-
}
|
|
94
|
-
else if (status === "uploading") {
|
|
95
|
-
throw new Error(`Cannot use FileObject in query - file is still uploading. Wait for upload to complete before executing the query.`);
|
|
96
|
-
}
|
|
97
|
-
else if (status === "pending") {
|
|
98
|
-
throw new Error(`Cannot use FileObject in query - file upload has not started yet.`);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
throw new Error(`Cannot use FileObject in query - unexpected status: ${status}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
85
|
async _initializeAndStartUpload(file, options) {
|
|
105
86
|
const config = configInstance.getConfig();
|
|
106
87
|
const backend = config.backendConfigs?.[this.constructor.configKey];
|
|
@@ -367,23 +348,7 @@ export class FileObject {
|
|
|
367
348
|
return new Blob([this.fileData], { type: this.type });
|
|
368
349
|
}
|
|
369
350
|
async waitForUpload() {
|
|
370
|
-
|
|
371
|
-
return this.uploadResult;
|
|
372
|
-
}
|
|
373
|
-
if (this.uploadPromise) {
|
|
374
|
-
return this.uploadPromise;
|
|
375
|
-
}
|
|
376
|
-
throw new Error("No upload in progress and file not uploaded");
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Returns a static version of this FileObject that can be stored in IndexedDB
|
|
380
|
-
* Creates a new FileObject using the stored file constructor path
|
|
381
|
-
*/
|
|
382
|
-
asStatic() {
|
|
383
|
-
if (!this.uploaded || !this.uploadResult) {
|
|
384
|
-
throw new Error("Cannot create static version of file that hasn't been uploaded");
|
|
385
|
-
}
|
|
386
|
-
return new this.constructor(this.uploadResult);
|
|
351
|
+
return this.uploadPromise;
|
|
387
352
|
}
|
|
388
353
|
toJSON() {
|
|
389
354
|
return {
|
|
@@ -37,6 +37,51 @@ export function processIncludedEntities(modelStoreRegistry, included, ModelClass
|
|
|
37
37
|
throw new Error(`Failed to process included entities: ${error.message}`);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Recursively processes an object to replace FileObject instances with their file paths.
|
|
42
|
+
* Throws an error if any FileObject is not yet uploaded.
|
|
43
|
+
*
|
|
44
|
+
* @param {any} obj - The object to process
|
|
45
|
+
* @returns {any} The processed object with FileObjects replaced by paths
|
|
46
|
+
*/
|
|
47
|
+
function processFileObjects(obj) {
|
|
48
|
+
if (obj === null || obj === undefined) {
|
|
49
|
+
return obj;
|
|
50
|
+
}
|
|
51
|
+
// Handle FileObject instances
|
|
52
|
+
if (obj instanceof FileObject) {
|
|
53
|
+
const status = obj.status;
|
|
54
|
+
if (status === 'uploaded' && obj.filePath) {
|
|
55
|
+
return obj.filePath;
|
|
56
|
+
}
|
|
57
|
+
else if (status === 'error') {
|
|
58
|
+
throw new Error(`Cannot use FileObject in query - upload failed: ${obj.uploadError}`);
|
|
59
|
+
}
|
|
60
|
+
else if (status === 'uploading') {
|
|
61
|
+
throw new Error(`Cannot use FileObject in query - file is still uploading. Wait for upload to complete before executing the query.`);
|
|
62
|
+
}
|
|
63
|
+
else if (status === 'pending') {
|
|
64
|
+
throw new Error(`Cannot use FileObject in query - file upload has not started yet.`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error(`Cannot use FileObject in query - unexpected status: ${status}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Handle arrays
|
|
71
|
+
if (Array.isArray(obj)) {
|
|
72
|
+
return obj.map(item => processFileObjects(item));
|
|
73
|
+
}
|
|
74
|
+
// Handle plain objects
|
|
75
|
+
if (typeof obj === 'object' && obj.constructor === Object) {
|
|
76
|
+
const processedObj = {};
|
|
77
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
78
|
+
processedObj[key] = processFileObjects(value);
|
|
79
|
+
}
|
|
80
|
+
return processedObj;
|
|
81
|
+
}
|
|
82
|
+
// Return primitive values as-is
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
40
85
|
/**
|
|
41
86
|
* Makes an API call to the backend with the given QuerySet.
|
|
42
87
|
* Automatically handles FileObject replacement with file paths for write operations.
|
|
@@ -84,6 +129,15 @@ export async function makeApiCall(querySet, operationType, args = {}, operationI
|
|
|
84
129
|
"get_or_create", "update_or_create"
|
|
85
130
|
];
|
|
86
131
|
const isWriteOperation = writeOperations.includes(operationType);
|
|
132
|
+
// Process FileObjects for write operations
|
|
133
|
+
if (isWriteOperation) {
|
|
134
|
+
try {
|
|
135
|
+
payload = processFileObjects(payload);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to process file uploads: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
87
141
|
const baseUrl = backend.API_URL.replace(/\/+$/, "");
|
|
88
142
|
const finalUrl = `${baseUrl}/${ModelClass.modelName}/`;
|
|
89
143
|
const headers = backend.getAuthHeaders ? backend.getAuthHeaders() : {};
|
|
@@ -13,7 +13,6 @@ import { FileObject } from './files.js';
|
|
|
13
13
|
import { configInstance } from "../../config.js";
|
|
14
14
|
import { parseStateZeroError, MultipleObjectsReturned, DoesNotExist, } from "./errors.js";
|
|
15
15
|
import axios from "axios";
|
|
16
|
-
import { typeOf } from "mathjs";
|
|
17
16
|
/**
|
|
18
17
|
* A constructor for a Model.
|
|
19
18
|
*
|
|
@@ -108,7 +107,7 @@ export class Model {
|
|
|
108
107
|
value) {
|
|
109
108
|
// Check if it's already a FileObject
|
|
110
109
|
if (value instanceof FileObject) {
|
|
111
|
-
return value
|
|
110
|
+
return value;
|
|
112
111
|
}
|
|
113
112
|
// If it's stored file data from API, wrap it as FileObject
|
|
114
113
|
if (typeof value === "object" && value.file_path) {
|
|
@@ -118,7 +117,7 @@ export class Model {
|
|
|
118
117
|
__setFunctionName(_a, "BackendFileObject"),
|
|
119
118
|
_a.configKey = ModelClass.configKey,
|
|
120
119
|
_a);
|
|
121
|
-
return new BackendFileObject(value)
|
|
120
|
+
return new BackendFileObject(value);
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
123
|
// relationship fields need special handling
|
|
@@ -211,13 +210,6 @@ export class Model {
|
|
|
211
210
|
// Let DateParsingHelpers.serializeDate throw if it fails
|
|
212
211
|
return DateParsingHelpers.serializeDate(value, field, ModelClass.schema);
|
|
213
212
|
}
|
|
214
|
-
// FileObjects need special
|
|
215
|
-
const fileFormats = ["file-path", "image-path"];
|
|
216
|
-
if (ModelClass.schema &&
|
|
217
|
-
fileFormats.includes(ModelClass.schema.properties[field]?.format)) {
|
|
218
|
-
value = this.getField(field);
|
|
219
|
-
return value ? value.serialize() : null;
|
|
220
|
-
}
|
|
221
213
|
return value;
|
|
222
214
|
}
|
|
223
215
|
/**
|
package/package.json
CHANGED