nexabase-console 2.0.1 → 2.0.3
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/README.md +130 -23
- package/dist/app/NexaApp.d.ts +6 -5
- package/dist/app/NexaApp.js +2 -2
- package/dist/app/initializeApp.d.ts +6 -0
- package/dist/app/initializeApp.js +14 -1
- package/dist/auth/Auth.d.ts +38 -6
- package/dist/auth/Auth.js +341 -28
- package/dist/auth/NexaAuthError.d.ts +5 -0
- package/dist/auth/NexaAuthError.js +15 -0
- package/dist/auth/authTypes.d.ts +38 -1
- package/dist/auth/persistence.d.ts +7 -5
- package/dist/auth/persistence.js +42 -13
- package/dist/facade/nexaSDK.d.ts +93 -0
- package/dist/facade/nexaSDK.js +129 -0
- package/dist/firestore/Query.d.ts +9 -1
- package/dist/firestore/Query.js +62 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/storage/Storage.d.ts +5 -0
- package/dist/storage/Storage.js +17 -1
- package/dist/storage/StorageReference.d.ts +18 -0
- package/dist/storage/StorageReference.js +33 -1
- package/dist/types/index.d.ts +17 -8
- package/package.json +1 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nexaSDK = exports.NexaSDKFacade = void 0;
|
|
4
|
+
exports.createNexaSDK = createNexaSDK;
|
|
5
|
+
const initializeApp_1 = require("../app/initializeApp");
|
|
6
|
+
/**
|
|
7
|
+
* Universal NexaBase Client SDK Facade (Domain & Server-Authoritative Logic)
|
|
8
|
+
* Decouples client components & stores from raw primitives like getDocs/runTransaction.
|
|
9
|
+
*/
|
|
10
|
+
class NexaSDKFacade {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.appInstance = null;
|
|
13
|
+
this.customBaseURL = '';
|
|
14
|
+
/* =========================================================================
|
|
15
|
+
* 1. PRODUCTS & INVENTORY DOMAIN
|
|
16
|
+
* ========================================================================= */
|
|
17
|
+
this.products = {
|
|
18
|
+
/**
|
|
19
|
+
* Atomically adjust product stock in server with audit log trail
|
|
20
|
+
*/
|
|
21
|
+
adjustStock: async (params) => {
|
|
22
|
+
return this.call('adjustProductStock', params);
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Quick stock deduction helper
|
|
26
|
+
*/
|
|
27
|
+
deductStock: async (productId, qty, reason = 'sale') => {
|
|
28
|
+
return this.call('adjustProductStock', { productId, delta: -Math.abs(qty), reason });
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Quick stock addition helper
|
|
32
|
+
*/
|
|
33
|
+
addStock: async (productId, qty, reason = 'restock') => {
|
|
34
|
+
return this.call('adjustProductStock', { productId, delta: Math.abs(qty), reason });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/* =========================================================================
|
|
38
|
+
* 2. ORDERS & WAREHOUSE DOMAIN
|
|
39
|
+
* ========================================================================= */
|
|
40
|
+
this.orders = {
|
|
41
|
+
/**
|
|
42
|
+
* Scan tracking number (resi), update shipping status & auto-deduct stock atomically
|
|
43
|
+
*/
|
|
44
|
+
scanResi: async (params) => {
|
|
45
|
+
return this.call('scanResiOrder', params);
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Cancel an order & automatically return deducted stock to inventory
|
|
49
|
+
*/
|
|
50
|
+
cancelOrder: async (params) => {
|
|
51
|
+
return this.call('cancelOrder', params);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/* =========================================================================
|
|
55
|
+
* 3. FINANCIAL & TRANSACTION DOMAIN
|
|
56
|
+
* ========================================================================= */
|
|
57
|
+
this.finance = {
|
|
58
|
+
/**
|
|
59
|
+
* Atomic balance transfer between users with ledger record
|
|
60
|
+
*/
|
|
61
|
+
transferBalance: async (params) => {
|
|
62
|
+
return this.call('transferBalance', params);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/* =========================================================================
|
|
66
|
+
* 4. GENERAL PURPOSE UTILITIES
|
|
67
|
+
* ========================================================================= */
|
|
68
|
+
this.utils = {
|
|
69
|
+
/**
|
|
70
|
+
* Atomic field incrementer on any Firestore document
|
|
71
|
+
*/
|
|
72
|
+
increment: async (params) => {
|
|
73
|
+
return this.call('incrementCounter', params);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
if (options?.app)
|
|
77
|
+
this.appInstance = options.app;
|
|
78
|
+
if (options?.baseURL)
|
|
79
|
+
this.customBaseURL = options.baseURL;
|
|
80
|
+
}
|
|
81
|
+
getApp() {
|
|
82
|
+
if (this.appInstance)
|
|
83
|
+
return this.appInstance;
|
|
84
|
+
return (0, initializeApp_1.getApp)();
|
|
85
|
+
}
|
|
86
|
+
getBaseURL() {
|
|
87
|
+
if (this.customBaseURL)
|
|
88
|
+
return this.customBaseURL;
|
|
89
|
+
if (typeof window !== 'undefined')
|
|
90
|
+
return window.location.origin;
|
|
91
|
+
return 'http://localhost:3000';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Universal Server-Authoritative Cloud Function Caller
|
|
95
|
+
*/
|
|
96
|
+
async call(functionName, data = {}) {
|
|
97
|
+
const app = this.getApp();
|
|
98
|
+
const projectId = app.options.projectId;
|
|
99
|
+
const apiKey = app.options.apiKey;
|
|
100
|
+
const url = `${this.getBaseURL()}/api/functions/${projectId}/${functionName}`;
|
|
101
|
+
const headers = {
|
|
102
|
+
'Content-Type': 'application/json'
|
|
103
|
+
};
|
|
104
|
+
if (apiKey) {
|
|
105
|
+
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
106
|
+
}
|
|
107
|
+
const response = await fetch(url, {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
headers,
|
|
110
|
+
body: JSON.stringify(data)
|
|
111
|
+
});
|
|
112
|
+
const result = await response.json();
|
|
113
|
+
if (!response.ok || result.success === false) {
|
|
114
|
+
throw new Error(result.error || result.message || `Failed to execute function "${functionName}"`);
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.NexaSDKFacade = NexaSDKFacade;
|
|
120
|
+
/**
|
|
121
|
+
* Singleton Default Facade Export
|
|
122
|
+
*/
|
|
123
|
+
exports.nexaSDK = new NexaSDKFacade();
|
|
124
|
+
/**
|
|
125
|
+
* Factory function to create custom facade instance with specific NexaApp
|
|
126
|
+
*/
|
|
127
|
+
function createNexaSDK(app, options) {
|
|
128
|
+
return new NexaSDKFacade({ app, baseURL: options?.baseURL });
|
|
129
|
+
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FieldPath } from './FieldPath';
|
|
2
|
+
import { CollectionReference, Query, QueryConstraint, QuerySnapshot, AggregateField, AggregateSpec, AggregateSpecData, AggregateQuerySnapshot } from '../types/index';
|
|
2
3
|
export declare const query: <T = any>(queryObject: Query<T> | CollectionReference<T>, ...queryConstraints: QueryConstraint[]) => Query<T>;
|
|
3
4
|
export declare const getCachedDocs: <T = any>(queryOrCollection: Query<T> | CollectionReference<T>) => QuerySnapshot<T>;
|
|
4
5
|
export declare const getDocs: <T = any>(queryOrCollection: Query<T> | CollectionReference<T>) => Promise<QuerySnapshot<T>>;
|
|
6
|
+
export declare const count: () => AggregateField<number>;
|
|
7
|
+
export declare const sum: (field: string | FieldPath) => AggregateField<number>;
|
|
8
|
+
export declare const average: (field: string | FieldPath) => AggregateField<number | null>;
|
|
9
|
+
export declare const getAggregateFromServer: <T extends AggregateSpec>(queryOrCollection: Query<any> | CollectionReference<any>, aggregateSpec: T) => Promise<AggregateQuerySnapshot<AggregateSpecData<T>>>;
|
|
10
|
+
export declare const getCountFromServer: <T = any>(queryOrCollection: Query<T> | CollectionReference<T>) => Promise<AggregateQuerySnapshot<{
|
|
11
|
+
count: number;
|
|
12
|
+
}>>;
|
package/dist/firestore/Query.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDocs = exports.getCachedDocs = exports.query = void 0;
|
|
3
|
+
exports.getCountFromServer = exports.getAggregateFromServer = exports.average = exports.sum = exports.count = exports.getDocs = exports.getCachedDocs = exports.query = void 0;
|
|
4
4
|
const SnapshotManager_1 = require("./SnapshotManager");
|
|
5
5
|
const DocumentReference_1 = require("./DocumentReference");
|
|
6
6
|
const NexaError_1 = require("../errors/NexaError");
|
|
@@ -174,3 +174,64 @@ const getDocs = async (queryOrCollection) => {
|
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
176
|
exports.getDocs = getDocs;
|
|
177
|
+
const count = () => {
|
|
178
|
+
return { type: 'count' };
|
|
179
|
+
};
|
|
180
|
+
exports.count = count;
|
|
181
|
+
const sum = (field) => {
|
|
182
|
+
return { type: 'sum', fieldPath: field };
|
|
183
|
+
};
|
|
184
|
+
exports.sum = sum;
|
|
185
|
+
const average = (field) => {
|
|
186
|
+
return { type: 'average', fieldPath: field };
|
|
187
|
+
};
|
|
188
|
+
exports.average = average;
|
|
189
|
+
const getAggregateFromServer = async (queryOrCollection, aggregateSpec) => {
|
|
190
|
+
const querySnapshot = await (0, exports.getDocs)(queryOrCollection);
|
|
191
|
+
const docs = querySnapshot.docs;
|
|
192
|
+
const resultData = {};
|
|
193
|
+
for (const [key, spec] of Object.entries(aggregateSpec)) {
|
|
194
|
+
if (spec.type === 'count') {
|
|
195
|
+
resultData[key] = docs.length;
|
|
196
|
+
}
|
|
197
|
+
else if (spec.type === 'sum') {
|
|
198
|
+
const field = spec.fieldPath || '';
|
|
199
|
+
let sumVal = 0;
|
|
200
|
+
for (const d of docs) {
|
|
201
|
+
const val = (0, helpers_1.getNestedValue)(d.data(), field, d.id);
|
|
202
|
+
if (typeof val === 'number' && !isNaN(val)) {
|
|
203
|
+
sumVal += val;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
resultData[key] = sumVal;
|
|
207
|
+
}
|
|
208
|
+
else if (spec.type === 'average') {
|
|
209
|
+
const field = spec.fieldPath || '';
|
|
210
|
+
let sumVal = 0;
|
|
211
|
+
let countVal = 0;
|
|
212
|
+
for (const d of docs) {
|
|
213
|
+
const val = (0, helpers_1.getNestedValue)(d.data(), field, d.id);
|
|
214
|
+
if (typeof val === 'number' && !isNaN(val)) {
|
|
215
|
+
sumVal += val;
|
|
216
|
+
countVal++;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
resultData[key] = countVal > 0 ? sumVal / countVal : null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
type: 'AggregateQuerySnapshot',
|
|
224
|
+
query: queryOrCollection,
|
|
225
|
+
data: () => resultData
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
exports.getAggregateFromServer = getAggregateFromServer;
|
|
229
|
+
const getCountFromServer = async (queryOrCollection) => {
|
|
230
|
+
const querySnapshot = await (0, exports.getDocs)(queryOrCollection);
|
|
231
|
+
return {
|
|
232
|
+
type: 'AggregateQuerySnapshot',
|
|
233
|
+
query: queryOrCollection,
|
|
234
|
+
data: () => ({ count: querySnapshot.docs.length })
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
exports.getCountFromServer = getCountFromServer;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './app/NexaApp';
|
|
|
3
3
|
export * from './auth/Auth';
|
|
4
4
|
export * from './auth/authTypes';
|
|
5
5
|
export * from './auth/persistence';
|
|
6
|
+
export * from './auth/NexaAuthError';
|
|
6
7
|
export * from './firestore/Firestore';
|
|
7
8
|
export * from './firestore/DocumentReference';
|
|
8
9
|
export * from './firestore/CollectionReference';
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./app/NexaApp"), exports);
|
|
|
21
21
|
__exportStar(require("./auth/Auth"), exports);
|
|
22
22
|
__exportStar(require("./auth/authTypes"), exports);
|
|
23
23
|
__exportStar(require("./auth/persistence"), exports);
|
|
24
|
+
__exportStar(require("./auth/NexaAuthError"), exports);
|
|
24
25
|
// Firestore
|
|
25
26
|
__exportStar(require("./firestore/Firestore"), exports);
|
|
26
27
|
__exportStar(require("./firestore/DocumentReference"), exports);
|
package/dist/storage/Storage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Storage = void 0;
|
|
3
|
+
exports.getStorage = exports.Storage = void 0;
|
|
4
4
|
const UploadTask_1 = require("./UploadTask");
|
|
5
5
|
const NexaError_1 = require("../errors/NexaError");
|
|
6
6
|
class Storage {
|
|
@@ -37,5 +37,21 @@ class Storage {
|
|
|
37
37
|
throw (0, NexaError_1.toNexaError)(err);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
async deleteFile(path) {
|
|
41
|
+
try {
|
|
42
|
+
const res = await this.client.delete(`/api/project/${this.projectId}/storage/file?path=${encodeURIComponent(path)}`);
|
|
43
|
+
return res.data;
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
throw (0, NexaError_1.toNexaError)(err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
40
49
|
}
|
|
41
50
|
exports.Storage = Storage;
|
|
51
|
+
const getStorage = (app) => {
|
|
52
|
+
if (app && typeof app.storage === 'function') {
|
|
53
|
+
return app.storage();
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Invalid NexaApp instance provided to getStorage()');
|
|
56
|
+
};
|
|
57
|
+
exports.getStorage = getStorage;
|
|
@@ -9,5 +9,23 @@ export declare class StorageReferenceImpl implements IStorageReference {
|
|
|
9
9
|
path: string;
|
|
10
10
|
}>;
|
|
11
11
|
getDownloadURL(): Promise<string>;
|
|
12
|
+
delete(): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
message?: string;
|
|
15
|
+
}>;
|
|
12
16
|
}
|
|
13
17
|
export declare const storageRef: (storage: Storage, path: string) => IStorageReference;
|
|
18
|
+
export declare const ref: (storage: Storage, path: string) => IStorageReference;
|
|
19
|
+
export declare const uploadBytes: (storageRef: IStorageReference, file: File | Blob, options?: UploadOptions) => Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
path: string;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const uploadBytesResumable: (storageRef: IStorageReference, file: File | Blob, options?: UploadOptions) => Promise<{
|
|
24
|
+
url: string;
|
|
25
|
+
path: string;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const getDownloadURL: (storageRef: IStorageReference) => Promise<string>;
|
|
28
|
+
export declare const deleteObject: (storageRef: IStorageReference) => Promise<{
|
|
29
|
+
success: boolean;
|
|
30
|
+
message?: string;
|
|
31
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storageRef = exports.StorageReferenceImpl = void 0;
|
|
3
|
+
exports.deleteObject = exports.getDownloadURL = exports.uploadBytesResumable = exports.uploadBytes = exports.ref = exports.storageRef = exports.StorageReferenceImpl = void 0;
|
|
4
4
|
class StorageReferenceImpl {
|
|
5
5
|
constructor(path, storage) {
|
|
6
6
|
this.path = path;
|
|
@@ -12,9 +12,41 @@ class StorageReferenceImpl {
|
|
|
12
12
|
async getDownloadURL() {
|
|
13
13
|
return this.storage.getDownloadURL(this.path);
|
|
14
14
|
}
|
|
15
|
+
async delete() {
|
|
16
|
+
return this.storage.deleteFile(this.path);
|
|
17
|
+
}
|
|
15
18
|
}
|
|
16
19
|
exports.StorageReferenceImpl = StorageReferenceImpl;
|
|
17
20
|
const storageRef = (storage, path) => {
|
|
18
21
|
return new StorageReferenceImpl(path, storage);
|
|
19
22
|
};
|
|
20
23
|
exports.storageRef = storageRef;
|
|
24
|
+
const ref = (storage, path) => {
|
|
25
|
+
return new StorageReferenceImpl(path, storage);
|
|
26
|
+
};
|
|
27
|
+
exports.ref = ref;
|
|
28
|
+
const uploadBytes = async (storageRef, file, options) => {
|
|
29
|
+
if (storageRef.upload) {
|
|
30
|
+
return storageRef.upload(file, options);
|
|
31
|
+
}
|
|
32
|
+
throw new Error('Invalid storage reference');
|
|
33
|
+
};
|
|
34
|
+
exports.uploadBytes = uploadBytes;
|
|
35
|
+
const uploadBytesResumable = (storageRef, file, options) => {
|
|
36
|
+
return (0, exports.uploadBytes)(storageRef, file, options);
|
|
37
|
+
};
|
|
38
|
+
exports.uploadBytesResumable = uploadBytesResumable;
|
|
39
|
+
const getDownloadURL = async (storageRef) => {
|
|
40
|
+
if (storageRef.getDownloadURL) {
|
|
41
|
+
return storageRef.getDownloadURL();
|
|
42
|
+
}
|
|
43
|
+
throw new Error('Invalid storage reference');
|
|
44
|
+
};
|
|
45
|
+
exports.getDownloadURL = getDownloadURL;
|
|
46
|
+
const deleteObject = async (storageRef) => {
|
|
47
|
+
if (storageRef.delete) {
|
|
48
|
+
return storageRef.delete();
|
|
49
|
+
}
|
|
50
|
+
throw new Error('Invalid storage reference');
|
|
51
|
+
};
|
|
52
|
+
exports.deleteObject = deleteObject;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NexaApp } from '../app/NexaApp';
|
|
2
2
|
import type { FieldPath } from '../firestore/FieldPath';
|
|
3
|
+
import type { User } from '../auth/authTypes';
|
|
3
4
|
export interface NexaConfig {
|
|
4
5
|
projectId: string;
|
|
5
6
|
apiKey?: string;
|
|
@@ -7,14 +8,6 @@ export interface NexaConfig {
|
|
|
7
8
|
enablePersistence?: boolean;
|
|
8
9
|
cacheStrategy?: 'network-first' | 'cache-first';
|
|
9
10
|
}
|
|
10
|
-
export interface User {
|
|
11
|
-
id: string;
|
|
12
|
-
email: string;
|
|
13
|
-
name?: string;
|
|
14
|
-
role?: string;
|
|
15
|
-
createdAt?: string;
|
|
16
|
-
[key: string]: any;
|
|
17
|
-
}
|
|
18
11
|
export interface AuthResponse {
|
|
19
12
|
token: string;
|
|
20
13
|
user: User;
|
|
@@ -84,6 +77,22 @@ export interface QuerySnapshot<T = any> {
|
|
|
84
77
|
metadata: SnapshotMetadata;
|
|
85
78
|
docChanges: () => DocumentChange<T>[];
|
|
86
79
|
}
|
|
80
|
+
export interface AggregateField<T = number> {
|
|
81
|
+
type: 'count' | 'sum' | 'average';
|
|
82
|
+
fieldPath?: string | FieldPath;
|
|
83
|
+
_returnType?: T;
|
|
84
|
+
}
|
|
85
|
+
export type AggregateSpec = Record<string, AggregateField<any>>;
|
|
86
|
+
export type AggregateSpecData<T extends AggregateSpec> = {
|
|
87
|
+
[K in keyof T]: T[K] extends AggregateField<infer R> ? R : number;
|
|
88
|
+
};
|
|
89
|
+
export interface AggregateQuerySnapshot<T extends Record<string, any> = {
|
|
90
|
+
count: number;
|
|
91
|
+
}> {
|
|
92
|
+
type: 'AggregateQuerySnapshot';
|
|
93
|
+
query: Query<any> | CollectionReference<any>;
|
|
94
|
+
data: () => T;
|
|
95
|
+
}
|
|
87
96
|
export interface DatabaseReference {
|
|
88
97
|
path: string;
|
|
89
98
|
get: () => Promise<any>;
|
package/package.json
CHANGED