nodestack-client 1.0.0 → 1.2.0
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 +286 -248
- package/dist/Client.d.ts +13 -1
- package/dist/Client.d.ts.map +1 -1
- package/dist/index.cjs +115 -7
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +115 -7
- package/dist/index.mjs.map +3 -3
- package/dist/services/CollectionService.d.ts +29 -0
- package/dist/services/CollectionService.d.ts.map +1 -1
- package/dist/services/DemoService.d.ts +27 -0
- package/dist/services/DemoService.d.ts.map +1 -0
- package/dist/services/RecordService.d.ts +1 -0
- package/dist/services/RecordService.d.ts.map +1 -1
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +49 -49
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
BaseService: () => BaseService,
|
|
26
26
|
ClientResponseError: () => ClientResponseError,
|
|
27
27
|
CollectionService: () => CollectionService,
|
|
28
|
+
DemoService: () => DemoService,
|
|
28
29
|
FileService: () => FileService,
|
|
29
30
|
LocalAuthStore: () => LocalAuthStore,
|
|
30
31
|
MemoryAuthStore: () => MemoryAuthStore,
|
|
@@ -243,18 +244,25 @@ var RecordService = class extends BaseService {
|
|
|
243
244
|
get clientWithRealtime() {
|
|
244
245
|
return this.client;
|
|
245
246
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
async getList(pageOrOptions = 1, perPage = 30, options = {}) {
|
|
248
|
+
let pageNum = 1;
|
|
249
|
+
let perPageNum = perPage;
|
|
250
|
+
let queryOpts = options;
|
|
251
|
+
if (typeof pageOrOptions === "object" && pageOrOptions !== null) {
|
|
252
|
+
queryOpts = pageOrOptions;
|
|
253
|
+
pageNum = typeof queryOpts.page === "number" ? queryOpts.page : 1;
|
|
254
|
+
perPageNum = typeof queryOpts.perPage === "number" ? queryOpts.perPage : 30;
|
|
255
|
+
} else if (typeof pageOrOptions === "number") {
|
|
256
|
+
pageNum = pageOrOptions;
|
|
257
|
+
}
|
|
250
258
|
return this.send(
|
|
251
259
|
`/api/collections/${encodeURIComponent(this.collectionName)}/records`,
|
|
252
260
|
{
|
|
253
261
|
method: "GET",
|
|
254
262
|
query: {
|
|
255
|
-
page,
|
|
256
|
-
perPage,
|
|
257
|
-
...
|
|
263
|
+
page: pageNum,
|
|
264
|
+
perPage: perPageNum,
|
|
265
|
+
...queryOpts
|
|
258
266
|
}
|
|
259
267
|
}
|
|
260
268
|
);
|
|
@@ -805,6 +813,66 @@ var CollectionService = class extends BaseService {
|
|
|
805
813
|
});
|
|
806
814
|
return true;
|
|
807
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* Infers schema fields, field types, and sample records from raw JSON (object or array).
|
|
818
|
+
*/
|
|
819
|
+
async inferSchema(data) {
|
|
820
|
+
return this.send("/api/collections/infer-schema", {
|
|
821
|
+
method: "POST",
|
|
822
|
+
body: { data }
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* "Paste JSON → Instant API": Infers field types, creates collection and SQLite columns,
|
|
827
|
+
* and populates all records within 1 second.
|
|
828
|
+
*/
|
|
829
|
+
async importJson(name, data, options = {}) {
|
|
830
|
+
return this.send("/api/collections/import-json", {
|
|
831
|
+
method: "POST",
|
|
832
|
+
body: {
|
|
833
|
+
name,
|
|
834
|
+
data,
|
|
835
|
+
...options
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// src/services/DemoService.ts
|
|
842
|
+
var DemoService = class extends BaseService {
|
|
843
|
+
/**
|
|
844
|
+
* Retrieves the current snapshot availability, metadata, and live drift information.
|
|
845
|
+
*/
|
|
846
|
+
async getStatus() {
|
|
847
|
+
return this.send("/api/demo/status", {
|
|
848
|
+
method: "GET"
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Freezes current database & file storage state as the demo baseline.
|
|
853
|
+
*/
|
|
854
|
+
async snapshot(options) {
|
|
855
|
+
return this.send("/api/demo/snapshot", {
|
|
856
|
+
method: "POST",
|
|
857
|
+
body: options || {}
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Restores the exact pristine demo state in one click.
|
|
862
|
+
*/
|
|
863
|
+
async reset() {
|
|
864
|
+
return this.send("/api/demo/reset", {
|
|
865
|
+
method: "POST"
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Deletes the frozen demo snapshot.
|
|
870
|
+
*/
|
|
871
|
+
async clear() {
|
|
872
|
+
return this.send("/api/demo/snapshot", {
|
|
873
|
+
method: "DELETE"
|
|
874
|
+
});
|
|
875
|
+
}
|
|
808
876
|
};
|
|
809
877
|
|
|
810
878
|
// src/Client.ts
|
|
@@ -815,9 +883,11 @@ var NodeStackClient = class {
|
|
|
815
883
|
realtime;
|
|
816
884
|
admins;
|
|
817
885
|
collections;
|
|
886
|
+
demo;
|
|
818
887
|
customFetch;
|
|
819
888
|
defaultHeaders;
|
|
820
889
|
defaultTimeout;
|
|
890
|
+
chaosOptions = null;
|
|
821
891
|
recordServices = /* @__PURE__ */ new Map();
|
|
822
892
|
constructor(baseUrl = "/", options = {}) {
|
|
823
893
|
this.baseUrl = (baseUrl || "/").replace(/\/+$/, "");
|
|
@@ -825,10 +895,25 @@ var NodeStackClient = class {
|
|
|
825
895
|
this.customFetch = options.fetch;
|
|
826
896
|
this.defaultHeaders = options.headers || {};
|
|
827
897
|
this.defaultTimeout = options.timeout || 12e4;
|
|
898
|
+
this.chaosOptions = options.chaos ? { ...options.chaos } : null;
|
|
828
899
|
this.files = new FileService(this);
|
|
829
900
|
this.realtime = new RealtimeService(this, options.EventSource);
|
|
830
901
|
this.admins = new AdminService(this);
|
|
831
902
|
this.collections = new CollectionService(this);
|
|
903
|
+
this.demo = new DemoService(this);
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Dynamically configure latency & chaos simulation options for all future requests.
|
|
907
|
+
* Pass null to disable client-side chaos injection.
|
|
908
|
+
*/
|
|
909
|
+
setChaos(options) {
|
|
910
|
+
this.chaosOptions = options ? { ...options } : null;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Get active chaos simulation options.
|
|
914
|
+
*/
|
|
915
|
+
getChaos() {
|
|
916
|
+
return this.chaosOptions ? { ...this.chaosOptions } : null;
|
|
832
917
|
}
|
|
833
918
|
collection(name) {
|
|
834
919
|
const colName = String(name);
|
|
@@ -869,6 +954,29 @@ var NodeStackClient = class {
|
|
|
869
954
|
if (this.authStore.token && !headers["Authorization"] && !headers["authorization"]) {
|
|
870
955
|
headers["Authorization"] = `Bearer ${this.authStore.token}`;
|
|
871
956
|
}
|
|
957
|
+
const effectiveChaos = {
|
|
958
|
+
...this.chaosOptions || {},
|
|
959
|
+
...options.chaos || {},
|
|
960
|
+
...options.mockDelay !== void 0 ? { delay: options.mockDelay } : {},
|
|
961
|
+
...options.mockError !== void 0 ? { errorStatus: options.mockError } : {},
|
|
962
|
+
...options.mockFailRate !== void 0 ? { failRate: options.mockFailRate } : {},
|
|
963
|
+
...options.mockJitter !== void 0 ? { jitter: options.mockJitter } : {}
|
|
964
|
+
};
|
|
965
|
+
if (effectiveChaos.delay !== void 0 && !headers["x-mock-delay"] && !headers["mock-delay"]) {
|
|
966
|
+
headers["x-mock-delay"] = String(effectiveChaos.delay);
|
|
967
|
+
}
|
|
968
|
+
if (effectiveChaos.errorStatus !== void 0 && !headers["x-mock-error"] && !headers["mock-error"]) {
|
|
969
|
+
headers["x-mock-error"] = String(effectiveChaos.errorStatus);
|
|
970
|
+
}
|
|
971
|
+
if (effectiveChaos.failRate !== void 0 && !headers["x-mock-fail-rate"] && !headers["mock-fail-rate"]) {
|
|
972
|
+
headers["x-mock-fail-rate"] = String(effectiveChaos.failRate);
|
|
973
|
+
}
|
|
974
|
+
if (effectiveChaos.jitter !== void 0 && !headers["x-mock-jitter"] && !headers["mock-jitter"]) {
|
|
975
|
+
headers["x-mock-jitter"] = String(effectiveChaos.jitter);
|
|
976
|
+
}
|
|
977
|
+
if (effectiveChaos.errorMessage && !headers["x-mock-error-message"] && !headers["mock-error-message"]) {
|
|
978
|
+
headers["x-mock-error-message"] = String(effectiveChaos.errorMessage);
|
|
979
|
+
}
|
|
872
980
|
let body = options.body;
|
|
873
981
|
const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
|
|
874
982
|
const isBlob = typeof Blob !== "undefined" && body instanceof Blob;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/auth/BaseAuthStore.ts", "../src/auth/LocalAuthStore.ts", "../src/errors/ClientResponseError.ts", "../src/services/BaseService.ts", "../src/services/RecordService.ts", "../src/services/FileService.ts", "../src/services/RealtimeService.ts", "../src/services/AdminService.ts", "../src/services/CollectionService.ts", "../src/Client.ts", "../src/auth/MemoryAuthStore.ts"],
|
|
4
|
-
"sourcesContent": ["// Main Client\nexport { NodeStackClient } from './Client';\nexport { NodeStackClient as default } from './Client';\n\n// Errors\nexport { ClientResponseError, ClientResponseErrorOptions } from './errors/ClientResponseError';\n\n// Auth Stores\nexport { BaseAuthStore, AuthChangeListener, decodeJwtPayload } from './auth/BaseAuthStore';\nexport { LocalAuthStore, StorageLike } from './auth/LocalAuthStore';\nexport { MemoryAuthStore } from './auth/MemoryAuthStore';\n\n// Services\nexport { BaseService, ClientInterface } from './services/BaseService';\nexport { RecordService, ClientWithRealtime } from './services/RecordService';\nexport { FileService, FileUrlOptions } from './services/FileService';\nexport { RealtimeService } from './services/RealtimeService';\nexport { AdminService } from './services/AdminService';\nexport { CollectionService } from './services/CollectionService';\n\n// Types & Models\nexport * from './types';\n", "import type { RecordModel, AdminModel } from '../types';\n\nexport type AuthChangeListener = (token: string, model: RecordModel | AdminModel | null) => void;\n\n/**\n * Lightweight helper to decode JWT payload without external dependencies.\n */\nexport function decodeJwtPayload(token: string): Record<string, any> | null {\n if (!token || typeof token !== 'string') return null;\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n\n try {\n let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n while (b64.length % 4) {\n b64 += '=';\n }\n\n let jsonStr: string;\n const globalObj: any =\n typeof globalThis !== 'undefined'\n ? globalThis\n : typeof window !== 'undefined'\n ? window\n : typeof self !== 'undefined'\n ? self\n : {};\n\n if (typeof globalObj.atob === 'function') {\n jsonStr = decodeURIComponent(\n Array.prototype.map\n .call(globalObj.atob(b64), (c: string) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join('')\n );\n } else if (typeof globalObj.Buffer !== 'undefined') {\n jsonStr = globalObj.Buffer.from(b64, 'base64').toString('utf8');\n } else {\n return null;\n }\n\n return JSON.parse(jsonStr);\n } catch {\n return null;\n }\n}\n\n/**\n * Base abstract class for authentication stores.\n */\nexport abstract class BaseAuthStore {\n protected _token: string = '';\n protected _model: RecordModel | AdminModel | null = null;\n private _listeners: Set<AuthChangeListener> = new Set();\n\n public get token(): string {\n return this._token;\n }\n\n public get model(): RecordModel | AdminModel | null {\n return this._model;\n }\n\n /**\n * Returns true if a token exists and has not yet expired.\n */\n public get isValid(): boolean {\n if (!this._token) {\n return false;\n }\n\n const payload = decodeJwtPayload(this._token);\n if (!payload) {\n return false;\n }\n\n if (payload.exp && typeof payload.exp === 'number') {\n const now = Math.floor(Date.now() / 1000);\n return payload.exp > now;\n }\n\n return true;\n }\n\n /**\n * Saves the token and associated user or admin model.\n */\n public save(token: string, model?: RecordModel | AdminModel | null): void {\n this._token = token || '';\n this._model = model || null;\n this.notify();\n }\n\n /**\n * Clears the current authentication state.\n */\n public clear(): void {\n this._token = '';\n this._model = null;\n this.notify();\n }\n\n /**\n * Subscribes to changes in authentication state (token or model).\n * Returns an unbind function.\n */\n public onChange(callback: AuthChangeListener, fireImmediately = false): () => void {\n this._listeners.add(callback);\n if (fireImmediately) {\n try {\n callback(this._token, this._model);\n } catch (err) {\n console.error('[AuthStore] Error in immediate onChange listener:', err);\n }\n }\n\n return () => {\n this._listeners.delete(callback);\n };\n }\n\n /**\n * Triggers all subscribed change listeners.\n */\n protected notify(): void {\n for (const listener of this._listeners) {\n try {\n listener(this._token, this._model);\n } catch (err) {\n console.error('[AuthStore] Error in onChange listener:', err);\n }\n }\n }\n}\n", "import { BaseAuthStore } from './BaseAuthStore';\nimport type { RecordModel, AdminModel } from '../types';\n\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nconst DEFAULT_STORAGE_KEY = 'nodestack_auth';\n\n/**\n * Storage-backed AuthStore that syncs token and model with localStorage\n * (or any custom StorageLike object, such as sessionStorage or AsyncStorage).\n * Safely degrades to memory if storage is not available.\n */\nexport class LocalAuthStore extends BaseAuthStore {\n private storageKey: string;\n private storage?: StorageLike;\n\n constructor(storageKey: string = DEFAULT_STORAGE_KEY, customStorage?: StorageLike) {\n super();\n this.storageKey = storageKey;\n\n if (customStorage) {\n this.storage = customStorage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n this.storage = window.localStorage;\n }\n\n this.loadInitial();\n }\n\n private loadInitial(): void {\n if (!this.storage) return;\n\n try {\n const raw = this.storage.getItem(this.storageKey);\n if (raw) {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed.token === 'string') {\n this._token = parsed.token;\n this._model = parsed.model || null;\n }\n }\n } catch {\n // Ignore parse or storage errors\n }\n }\n\n public override save(token: string, model?: RecordModel | AdminModel | null): void {\n super.save(token, model);\n\n if (this.storage) {\n try {\n this.storage.setItem(\n this.storageKey,\n JSON.stringify({\n token: this._token,\n model: this._model,\n })\n );\n } catch {\n // Storage might be full or disabled\n }\n }\n }\n\n public override clear(): void {\n super.clear();\n\n if (this.storage) {\n try {\n this.storage.removeItem(this.storageKey);\n } catch {\n // Ignore storage error\n }\n }\n }\n}\n", "export interface ClientResponseErrorOptions {\n url?: string;\n status?: number;\n data?: any;\n isAbort?: boolean;\n originalError?: any;\n message?: string;\n}\n\n/**\n * Standardized client response error representing failed HTTP requests\n * or network exceptions when interacting with NodeStack.\n */\nexport class ClientResponseError extends Error {\n public readonly url: string;\n public readonly status: number;\n public readonly data: any;\n public readonly isAbort: boolean;\n public readonly originalError?: any;\n\n constructor(options: ClientResponseErrorOptions = {}) {\n const status = options.status || 0;\n const message =\n options.message ||\n options.data?.message ||\n (status > 0 ? `NodeStack request failed with status ${status}` : 'NodeStack network request failed');\n\n super(message);\n this.name = 'ClientResponseError';\n this.url = options.url || '';\n this.status = status;\n this.data = options.data || {};\n this.isAbort = Boolean(options.isAbort);\n this.originalError = options.originalError;\n\n // Restore prototype chain\n Object.setPrototypeOf(this, ClientResponseError.prototype);\n }\n\n public toJSON() {\n return {\n name: this.name,\n message: this.message,\n url: this.url,\n status: this.status,\n data: this.data,\n isAbort: this.isAbort,\n };\n }\n}\n", "import type { SendOptions } from '../types';\nimport type { BaseAuthStore } from '../auth/BaseAuthStore';\n\nexport interface ClientInterface {\n baseUrl: string;\n authStore: BaseAuthStore;\n send<T = any>(path: string, options?: SendOptions): Promise<T>;\n}\n\n/**\n * Base service class from which all specific domain services inherit.\n */\nexport abstract class BaseService {\n constructor(protected readonly client: ClientInterface) {}\n\n protected send<T = any>(path: string, options: SendOptions = {}): Promise<T> {\n return this.client.send<T>(path, options);\n }\n}\n", "import { BaseService, ClientInterface } from './BaseService';\nimport { ClientResponseError } from '../errors/ClientResponseError';\nimport type {\n ListResult,\n QueryOptions,\n RecordModel,\n RecordAuthResponse,\n ImportResult,\n RealtimeCallback,\n UnsubscribeFunc,\n} from '../types';\n\nexport interface ClientWithRealtime extends ClientInterface {\n realtime: {\n subscribe<R = any>(topic: string, callback: RealtimeCallback<R>): Promise<UnsubscribeFunc>;\n unsubscribe(topic?: string, callback?: RealtimeCallback<any>): Promise<void>;\n };\n}\n\n/**\n * Service for managing CRUD, authentication, file handling, and subscriptions\n * for a specific collection.\n */\nexport class RecordService<T = RecordModel> extends BaseService {\n constructor(\n client: ClientWithRealtime,\n public readonly collectionName: string\n ) {\n super(client);\n }\n\n private get clientWithRealtime(): ClientWithRealtime {\n return this.client as ClientWithRealtime;\n }\n\n /**\n * Returns a paginated list of records matching the query options.\n */\n public async getList(\n page = 1,\n perPage = 30,\n options: QueryOptions = {}\n ): Promise<ListResult<T>> {\n return this.send<ListResult<T>>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/records`,\n {\n method: 'GET',\n query: {\n page,\n perPage,\n ...options,\n },\n }\n );\n }\n\n /**\n * Fetches and aggregates all records in the collection across multiple pages.\n */\n public async getFullList(\n options: QueryOptions & { batch?: number } = {}\n ): Promise<T[]> {\n const batch = Math.max(1, Math.min(500, options.batch || 200));\n const query = { ...options };\n delete query.batch;\n\n const firstPage = await this.getList(1, batch, query);\n const items: T[] = [...firstPage.items];\n\n if (firstPage.totalPages <= 1) {\n return items;\n }\n\n for (let page = 2; page <= firstPage.totalPages; page++) {\n const result = await this.getList(page, batch, query);\n items.push(...result.items);\n }\n\n return items;\n }\n\n /**\n * Returns the first record matching the specified filter expression.\n * Throws ClientResponseError(404) if no record matches.\n */\n public async getFirstListItem(\n filter: string,\n options: QueryOptions = {}\n ): Promise<T> {\n const list = await this.getList(1, 1, {\n ...options,\n filter,\n });\n\n if (!list.items || list.items.length === 0) {\n throw new ClientResponseError({\n status: 404,\n url: `/api/collections/${this.collectionName}/records`,\n message: `The requested record was not found in collection '${this.collectionName}'.`,\n });\n }\n\n return list.items[0];\n }\n\n /**\n * Retrieves a single record by its ID.\n */\n public async getOne(id: string, options: QueryOptions = {}): Promise<T> {\n return this.send<T>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\n {\n method: 'GET',\n query: options,\n }\n );\n }\n\n /**\n * Creates a new record in the collection.\n * Accepts a plain object or FormData (for file uploads).\n */\n public async create(\n data: Record<string, any> | FormData,\n options: QueryOptions = {}\n ): Promise<T> {\n return this.send<T>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/records`,\n {\n method: 'POST',\n body: data,\n query: options,\n }\n );\n }\n\n /**\n * Updates an existing record by its ID.\n * Accepts a plain object or FormData (for file updates).\n */\n public async update(\n id: string,\n data: Record<string, any> | FormData,\n options: QueryOptions = {}\n ): Promise<T> {\n return this.send<T>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\n {\n method: 'PATCH',\n body: data,\n query: options,\n }\n );\n }\n\n /**\n * Deletes a record by its ID.\n */\n public async delete(id: string): Promise<boolean> {\n await this.send<void>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\n {\n method: 'DELETE',\n }\n );\n return true;\n }\n\n /**\n * Authenticates against an auth collection using identity/email and password.\n * On success, automatically persists the token and record to authStore.\n */\n public async authWithPassword(\n identity: string,\n password: string\n ): Promise<RecordAuthResponse<T>> {\n const result = await this.send<RecordAuthResponse<T>>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/auth-with-password`,\n {\n method: 'POST',\n body: { identity, password },\n }\n );\n\n if (result && result.token) {\n this.client.authStore.save(result.token, result.record as any);\n }\n\n return result;\n }\n\n /**\n * Exports records from the collection as CSV or JSON.\n */\n public async export(\n format: 'csv' | 'json' = 'csv',\n options: QueryOptions = {}\n ): Promise<string> {\n return this.send<string>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/export`,\n {\n method: 'GET',\n query: {\n ...options,\n format,\n },\n }\n );\n }\n\n /**\n * Imports records into the collection.\n */\n public async import(\n data: any[] | FormData | Blob | string,\n options: { continueOnError?: boolean } = {}\n ): Promise<ImportResult> {\n return this.send<ImportResult>(\n `/api/collections/${encodeURIComponent(this.collectionName)}/import`,\n {\n method: 'POST',\n body: data,\n query: options,\n }\n );\n }\n\n /**\n * Subscribes to realtime events on this collection or a specific record ID.\n *\n * Example:\n * // Listen to all records in collection:\n * client.collection('posts').subscribe('*', (e) => console.log(e.action, e.record));\n *\n * // Listen to single record changes:\n * client.collection('posts').subscribe('record_id_123', (e) => console.log(e.action, e.record));\n */\n public async subscribe(\n topicOrCallback: string | RealtimeCallback<T>,\n callback?: RealtimeCallback<T>\n ): Promise<UnsubscribeFunc> {\n let topic = '*';\n let cb: RealtimeCallback<T>;\n\n if (typeof topicOrCallback === 'function') {\n topic = '*';\n cb = topicOrCallback;\n } else {\n topic = topicOrCallback;\n cb = callback!;\n }\n\n const fullTopic = topic === '*' ? this.collectionName : `${this.collectionName}/${topic}`;\n return this.clientWithRealtime.realtime.subscribe<T>(fullTopic, cb);\n }\n\n /**\n * Unsubscribes from realtime events for this collection.\n */\n public async unsubscribe(topic?: string): Promise<void> {\n const fullTopic = !topic || topic === '*' ? this.collectionName : `${this.collectionName}/${topic}`;\n return this.clientWithRealtime.realtime.unsubscribe(fullTopic);\n }\n}\n", "import { BaseService } from './BaseService';\n\nexport interface FileUrlOptions {\n download?: boolean;\n token?: string | boolean;\n collection?: string;\n}\n\n/**\n * Service for generating file URLs for assets uploaded to NodeStack.\n */\nexport class FileService extends BaseService {\n /**\n * Generates a fully qualified URL to an uploaded file.\n *\n * @param record - Record object or record ID string\n * @param filename - Name of the file stored on the record\n * @param options - Additional options (download flag, auth token, collection override)\n */\n public getUrl(\n record: { id: string; collection?: string; collectionName?: string; [key: string]: any } | string,\n filename: string,\n options: FileUrlOptions = {}\n ): string {\n if (!filename) return '';\n\n let recordId = '';\n let collectionName = options.collection || '';\n\n if (typeof record === 'string') {\n recordId = record;\n } else if (record && typeof record === 'object') {\n recordId = record.id || '';\n collectionName =\n collectionName ||\n record.collection ||\n record.collectionName ||\n record['@collectionName'] ||\n '';\n }\n\n if (!recordId) {\n throw new Error('[FileService] A valid record or recordId is required to construct a file URL.');\n }\n\n if (!collectionName) {\n throw new Error(\n '[FileService] Collection name is required. Either provide a record with collection info or pass options.collection.'\n );\n }\n\n const cleanBase = (this.client.baseUrl || '').replace(/\\/+$/, '');\n const cleanCol = encodeURIComponent(collectionName);\n const cleanId = encodeURIComponent(recordId);\n const cleanFile = encodeURIComponent(filename);\n\n let url = `${cleanBase}/api/files/${cleanCol}/${cleanId}/${cleanFile}`;\n\n const queryParts: string[] = [];\n\n if (options.download) {\n queryParts.push('download=1');\n }\n\n // Attach token if requested\n if (typeof options.token === 'string' && options.token) {\n queryParts.push(`token=${encodeURIComponent(options.token)}`);\n } else if (options.token === true && this.client.authStore.token) {\n queryParts.push(`token=${encodeURIComponent(this.client.authStore.token)}`);\n }\n\n if (queryParts.length > 0) {\n url += `?${queryParts.join('&')}`;\n }\n\n return url;\n }\n}\n", "import { BaseService, ClientInterface } from './BaseService';\nimport type { RealtimeEvent, RealtimeCallback, UnsubscribeFunc } from '../types';\n\n/**\n * Multiplexed Realtime Server-Sent Events (SSE) service.\n * Manages a single persistent SSE connection and dispatches events to subscribed listeners.\n */\nexport class RealtimeService extends BaseService {\n private eventSource: any = null;\n private clientId: string = '';\n private isConnecting: boolean = false;\n private connectPromise: Promise<string> | null = null;\n private reconnectTimeout: any = null;\n private reconnectAttempts: number = 0;\n private customEventSource?: any;\n\n // Map of topic -> Set of callbacks\n private subscriptions: Map<string, Set<RealtimeCallback<any>>> = new Map();\n\n // Set of registered event names on the active EventSource\n private registeredEventNames: Set<string> = new Set();\n\n constructor(client: ClientInterface, customEventSource?: any) {\n super(client);\n this.customEventSource = customEventSource;\n }\n\n /**\n * Returns whether there is an active EventSource connection.\n */\n public get isConnected(): boolean {\n return Boolean(this.eventSource && this.clientId);\n }\n\n /**\n * Resolves the EventSource constructor available in the current environment.\n */\n private getEventSourceConstructor(): any {\n if (this.customEventSource) {\n return this.customEventSource;\n }\n if (typeof window !== 'undefined' && (window as any).EventSource) {\n return (window as any).EventSource;\n }\n if (typeof globalThis !== 'undefined' && (globalThis as any).EventSource) {\n return (globalThis as any).EventSource;\n }\n throw new Error(\n '[RealtimeService] EventSource is not supported natively in this environment. ' +\n 'Please pass an EventSource polyfill to ClientOptions (e.g. from the \"eventsource\" package).'\n );\n }\n\n /**\n * Connects to the SSE stream if not already connected.\n * Returns the connected clientId.\n */\n public async connect(): Promise<string> {\n if (this.clientId && this.eventSource) {\n return this.clientId;\n }\n\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise<string>((resolve, reject) => {\n try {\n const EventSourceClass = this.getEventSourceConstructor();\n const base = (this.client.baseUrl || '').replace(/\\/+$/, '');\n let url = `${base}/api/realtime`;\n\n if (this.client.authStore.token) {\n url += `?token=${encodeURIComponent(this.client.authStore.token)}`;\n }\n\n this.eventSource = new EventSourceClass(url);\n\n const handleConnect = async (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.clientId = data.clientId;\n this.reconnectAttempts = 0;\n\n // Re-apply any existing subscriptions on the server\n await this.syncSubscriptions();\n\n resolve(this.clientId);\n } catch (err) {\n reject(err);\n }\n };\n\n this.eventSource.addEventListener('NS_CONNECT', handleConnect);\n this.eventSource.addEventListener('NB_CONNECT', handleConnect);\n\n this.eventSource.onerror = (err: any) => {\n if (!this.clientId) {\n reject(err);\n }\n this.handleDisconnect();\n };\n\n // Bind listeners for all known collection topics\n this.bindActiveTopics();\n } catch (err) {\n this.connectPromise = null;\n reject(err);\n }\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n /**\n * Subscribes to realtime updates for a collection or record.\n *\n * @param topic - Collection name ('posts'), wildcard ('*'), or specific record ('posts/rec_123')\n * @param callback - Event listener callback\n * @returns Unsubscribe function\n */\n public async subscribe<T = any>(\n topic: string,\n callback: RealtimeCallback<T>\n ): Promise<UnsubscribeFunc> {\n const cleanTopic = (topic || '*').trim();\n\n if (!this.subscriptions.has(cleanTopic)) {\n this.subscriptions.set(cleanTopic, new Set());\n }\n\n this.subscriptions.get(cleanTopic)!.add(callback);\n\n // If connected, sync subscriptions with server\n if (this.isConnected) {\n this.bindTopicListener(cleanTopic);\n await this.syncSubscriptions();\n } else {\n // Connect and sync\n await this.connect();\n }\n\n return () => this.unsubscribe(cleanTopic, callback);\n }\n\n /**\n * Unsubscribes from a topic or specific callback.\n */\n public async unsubscribe(topic?: string, callback?: RealtimeCallback<any>): Promise<void> {\n if (!topic) {\n // Unsubscribe all\n this.subscriptions.clear();\n if (this.isConnected) {\n await this.syncSubscriptions();\n }\n return;\n }\n\n const cleanTopic = topic.trim();\n if (!this.subscriptions.has(cleanTopic)) {\n return;\n }\n\n if (callback) {\n this.subscriptions.get(cleanTopic)!.delete(callback);\n if (this.subscriptions.get(cleanTopic)!.size === 0) {\n this.subscriptions.delete(cleanTopic);\n }\n } else {\n this.subscriptions.delete(cleanTopic);\n }\n\n if (this.isConnected) {\n await this.syncSubscriptions();\n }\n }\n\n /**\n * Closes the SSE connection and clears state.\n */\n public disconnect(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.eventSource) {\n try {\n this.eventSource.close();\n } catch {}\n this.eventSource = null;\n }\n\n this.clientId = '';\n this.registeredEventNames.clear();\n }\n\n /**\n * Synchronizes active subscriptions with the backend via POST /api/realtime.\n */\n private async syncSubscriptions(): Promise<void> {\n if (!this.clientId) return;\n\n const topics = Array.from(this.subscriptions.keys());\n\n try {\n await this.client.send('/api/realtime', {\n method: 'POST',\n body: {\n clientId: this.clientId,\n subscriptions: topics.length > 0 ? topics : ['__noop__'],\n },\n });\n } catch (err) {\n console.warn('[RealtimeService] Failed to sync subscriptions with server:', err);\n }\n }\n\n /**\n * Binds an EventSource listener for the collection corresponding to a topic.\n */\n private bindTopicListener(topic: string): void {\n if (!this.eventSource) return;\n\n // Determine collection name\n const collectionName = topic.includes('/') ? topic.split('/')[0] : topic;\n\n if (this.registeredEventNames.has(collectionName)) {\n return;\n }\n\n this.registeredEventNames.add(collectionName);\n\n this.eventSource.addEventListener(collectionName, (event: any) => {\n try {\n const payload: RealtimeEvent<any> = JSON.parse(event.data);\n this.dispatchEvent(collectionName, payload);\n } catch (err) {\n console.error(`[RealtimeService] Error handling event for ${collectionName}:`, err);\n }\n });\n }\n\n private bindActiveTopics(): void {\n for (const topic of this.subscriptions.keys()) {\n this.bindTopicListener(topic);\n }\n }\n\n /**\n * Dispatches received SSE events to matching subscribed listeners.\n */\n private dispatchEvent(collectionName: string, event: RealtimeEvent<any>): void {\n const recordId = event.record?.id;\n\n // Check wildcard subscription '*'\n this.triggerListeners('*', event);\n\n // Check collection subscription e.g. 'posts' or 'posts/*'\n this.triggerListeners(collectionName, event);\n this.triggerListeners(`${collectionName}/*`, event);\n\n // Check record-specific subscription e.g. 'posts/rec_123'\n if (recordId) {\n this.triggerListeners(`${collectionName}/${recordId}`, event);\n }\n }\n\n private triggerListeners(topic: string, event: RealtimeEvent<any>): void {\n const callbacks = this.subscriptions.get(topic);\n if (!callbacks || callbacks.size === 0) return;\n\n for (const cb of callbacks) {\n try {\n cb(event);\n } catch (err) {\n console.error(`[RealtimeService] Error in realtime listener for ${topic}:`, err);\n }\n }\n }\n\n /**\n * Handles disconnections and schedules automatic reconnection.\n */\n private handleDisconnect(): void {\n if (this.reconnectTimeout) return;\n\n this.disconnect();\n\n // Exponential backoff up to 10 seconds\n const delay = Math.min(10000, 500 * Math.pow(1.5, this.reconnectAttempts));\n this.reconnectAttempts++;\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n if (this.subscriptions.size > 0) {\n this.connect().catch(() => {});\n }\n }, delay);\n }\n}\n", "import { BaseService } from './BaseService';\nimport type { AdminAuthResponse, AdminModel } from '../types';\n\n/**\n * Service for administrative and superuser actions.\n */\nexport class AdminService extends BaseService {\n /**\n * Checks whether at least one superuser / admin account exists in NodeStack.\n */\n public async hasAdmins(): Promise<boolean> {\n const res = await this.send<{ hasAdmins: boolean }>('/api/admins/has-admins', {\n method: 'GET',\n });\n return Boolean(res?.hasAdmins);\n }\n\n /**\n * Creates the initial superuser account during first-time setup.\n * Automatically persists the returned admin token and model to authStore.\n */\n public async createInitial(email: string, password: string): Promise<AdminAuthResponse> {\n const res = await this.send<AdminAuthResponse>('/api/admins/create-initial', {\n method: 'POST',\n body: { email, password },\n });\n\n if (res?.token) {\n this.client.authStore.save(res.token, res.admin);\n }\n\n return res;\n }\n\n /**\n * Authenticates a superuser / admin using email and password.\n * Automatically persists the returned admin token and model to authStore.\n */\n public async authWithPassword(identity: string, password: string): Promise<AdminAuthResponse> {\n const res = await this.send<AdminAuthResponse>('/api/admins/auth-with-password', {\n method: 'POST',\n body: { identity, password },\n });\n\n if (res?.token) {\n this.client.authStore.save(res.token, res.admin);\n }\n\n return res;\n }\n\n /**\n * Retrieves the currently authenticated superuser's profile.\n */\n public async getMe(): Promise<AdminModel> {\n return this.send<AdminModel>('/api/admins/me', {\n method: 'GET',\n });\n }\n}\n", "import { BaseService } from './BaseService';\n\n/**\n * Service for managing collection schema definitions (Admin only).\n */\nexport class CollectionService extends BaseService {\n /**\n * Retrieves all collection schema models.\n */\n public async getList(): Promise<any[]> {\n const res = await this.send<{ items: any[]; totalItems: number } | any[]>('/api/collections', {\n method: 'GET',\n });\n return Array.isArray(res) ? res : res?.items || [];\n }\n\n /**\n * Retrieves a single collection schema by name or ID.\n */\n public async getOne(nameOrId: string): Promise<any> {\n return this.send<any>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\n method: 'GET',\n });\n }\n\n /**\n * Creates a new collection schema.\n */\n public async create(data: any): Promise<any> {\n return this.send<any>('/api/collections', {\n method: 'POST',\n body: data,\n });\n }\n\n /**\n * Updates an existing collection schema.\n */\n public async update(nameOrId: string, data: any): Promise<any> {\n return this.send<any>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\n method: 'PATCH',\n body: data,\n });\n }\n\n /**\n * Deletes a collection schema and its corresponding SQLite table.\n */\n public async delete(nameOrId: string): Promise<boolean> {\n await this.send<void>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\n method: 'DELETE',\n });\n return true;\n }\n}\n", "import { BaseAuthStore } from './auth/BaseAuthStore';\nimport { LocalAuthStore } from './auth/LocalAuthStore';\nimport { ClientResponseError } from './errors/ClientResponseError';\nimport { RecordService } from './services/RecordService';\nimport { FileService } from './services/FileService';\nimport { RealtimeService } from './services/RealtimeService';\nimport { AdminService } from './services/AdminService';\nimport { CollectionService } from './services/CollectionService';\nimport type {\n ClientOptions,\n SendOptions,\n RecordModel,\n} from './types';\n\n/**\n * Main NodeStack Client SDK entry point.\n */\nexport class NodeStackClient<TCollections extends Record<string, any> = Record<string, RecordModel>> {\n public readonly baseUrl: string;\n public readonly authStore: BaseAuthStore;\n public readonly files: FileService;\n public readonly realtime: RealtimeService;\n public readonly admins: AdminService;\n public readonly collections: CollectionService;\n\n private customFetch?: typeof fetch;\n private defaultHeaders: Record<string, string>;\n private defaultTimeout: number;\n private recordServices: Map<string, RecordService<any>> = new Map();\n\n constructor(baseUrl: string = '/', options: ClientOptions = {}) {\n this.baseUrl = (baseUrl || '/').replace(/\\/+$/, '');\n this.authStore = options.authStore || new LocalAuthStore();\n this.customFetch = options.fetch;\n this.defaultHeaders = options.headers || {};\n this.defaultTimeout = options.timeout || 120000; // 2 minutes default\n\n this.files = new FileService(this);\n this.realtime = new RealtimeService(this, options.EventSource);\n this.admins = new AdminService(this);\n this.collections = new CollectionService(this);\n }\n\n /**\n * Returns a RecordService for interacting with a specific collection.\n * If a schema map type is provided to NodeStackClient, collection names\n * and record response types are automatically inferred and type-safe.\n */\n public collection<K extends keyof TCollections>(name: K): RecordService<TCollections[K]>;\n public collection<T = RecordModel>(name: string): RecordService<T>;\n public collection(name: string): RecordService<any> {\n const colName = String(name);\n let service = this.recordServices.get(colName);\n if (!service) {\n service = new RecordService(this, colName);\n this.recordServices.set(colName, service);\n }\n return service;\n }\n\n /**\n * Sends an HTTP request to NodeStack with automatic authentication,\n * header injection, query serialization, and standardized error handling.\n */\n public async send<T = any>(path: string, options: SendOptions = {}): Promise<T> {\n const fetchFn = this.customFetch || (typeof fetch !== 'undefined' ? fetch : null);\n if (!fetchFn) {\n throw new Error(\n '[NodeStackClient] fetch is not available in this environment. ' +\n 'Please pass a custom fetch implementation to ClientOptions.'\n );\n }\n\n // 1. Build URL & Query parameters\n let url = path.startsWith('http://') || path.startsWith('https://')\n ? path\n : `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n\n if (options.query) {\n const searchParams = new URLSearchParams();\n for (const [key, val] of Object.entries(options.query)) {\n if (val === undefined || val === null) continue;\n searchParams.append(key, String(val));\n }\n const queryStr = searchParams.toString();\n if (queryStr) {\n url += (url.includes('?') ? '&' : '?') + queryStr;\n }\n }\n\n // 2. Prepare headers\n const headers: Record<string, string> = {\n ...this.defaultHeaders,\n ...(options.headers || {}),\n };\n\n if (this.authStore.token && !headers['Authorization'] && !headers['authorization']) {\n headers['Authorization'] = `Bearer ${this.authStore.token}`;\n }\n\n // 3. Serialize body\n let body: any = options.body;\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\n\n if (body !== undefined && body !== null) {\n if (isFormData) {\n // Let the environment compute multipart boundary headers automatically\n delete headers['Content-Type'];\n delete headers['content-type'];\n } else if (isBlob || typeof body === 'string') {\n // Leave body as-is\n } else if (typeof body === 'object') {\n headers['Content-Type'] = 'application/json';\n body = JSON.stringify(body);\n }\n }\n\n // 4. Handle abort signal & timeout\n let signal = options.signal;\n let timeoutId: any = null;\n\n if (!signal && this.defaultTimeout > 0 && typeof AbortController !== 'undefined') {\n const controller = new AbortController();\n signal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), this.defaultTimeout);\n }\n\n try {\n const response = await fetchFn(url, {\n ...options,\n headers,\n body,\n signal,\n });\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return null as any;\n }\n\n const contentType = response.headers.get('content-type') || '';\n let data: any;\n\n if (contentType.includes('application/json')) {\n data = await response.json().catch(() => ({}));\n } else {\n data = await response.text();\n }\n\n if (!response.ok) {\n throw new ClientResponseError({\n url,\n status: response.status,\n data,\n message: typeof data === 'object' && data?.message ? data.message : undefined,\n });\n }\n\n return data as T;\n } catch (err: any) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n if (err instanceof ClientResponseError) {\n throw err;\n }\n\n const isAbort =\n err?.name === 'AbortError' ||\n (signal && signal.aborted) ||\n Boolean(options.signal && options.signal.aborted);\n\n throw new ClientResponseError({\n url,\n status: isAbort ? 0 : 0,\n isAbort,\n originalError: err,\n message: isAbort ? 'Request was aborted' : err?.message || 'Network request failed',\n });\n }\n }\n\n /**\n * Checks backend system health.\n */\n public async health(): Promise<{ status: string; [key: string]: any }> {\n return this.send('/api/health', { method: 'GET' });\n }\n\n /**\n * Retrieves server runtime settings.\n */\n public async settings(): Promise<any> {\n return this.send('/api/settings', { method: 'GET' });\n }\n\n /**\n * Fetches request logs (Admin only).\n */\n public async logs(page = 1, perPage = 50): Promise<any> {\n return this.send('/api/logs', {\n method: 'GET',\n query: { page, perPage },\n });\n }\n\n /**\n * Fetches system metrics & analytics (Admin only).\n */\n public async metrics(): Promise<any> {\n return this.send('/api/metrics', { method: 'GET' });\n }\n}\n", "import { BaseAuthStore } from './BaseAuthStore';\n\n/**\n * In-memory authentication store.\n * Ideal for Node.js scripts, server-side rendering (SSR), and testing environments.\n */\nexport class MemoryAuthStore extends BaseAuthStore {\n // Inherits default in-memory behavior of BaseAuthStore\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/index.ts", "../src/auth/BaseAuthStore.ts", "../src/auth/LocalAuthStore.ts", "../src/errors/ClientResponseError.ts", "../src/services/BaseService.ts", "../src/services/RecordService.ts", "../src/services/FileService.ts", "../src/services/RealtimeService.ts", "../src/services/AdminService.ts", "../src/services/CollectionService.ts", "../src/services/DemoService.ts", "../src/Client.ts", "../src/auth/MemoryAuthStore.ts"],
|
|
4
|
+
"sourcesContent": ["// Main Client\r\nexport { NodeStackClient } from './Client';\r\nexport { NodeStackClient as default } from './Client';\r\n\r\n// Errors\r\nexport { ClientResponseError, ClientResponseErrorOptions } from './errors/ClientResponseError';\r\n\r\n// Auth Stores\r\nexport { BaseAuthStore, AuthChangeListener, decodeJwtPayload } from './auth/BaseAuthStore';\r\nexport { LocalAuthStore, StorageLike } from './auth/LocalAuthStore';\r\nexport { MemoryAuthStore } from './auth/MemoryAuthStore';\r\n\r\n// Services\r\nexport { BaseService, ClientInterface } from './services/BaseService';\r\nexport { RecordService, ClientWithRealtime } from './services/RecordService';\r\nexport { FileService, FileUrlOptions } from './services/FileService';\r\nexport { RealtimeService } from './services/RealtimeService';\r\nexport { AdminService } from './services/AdminService';\r\nexport { CollectionService } from './services/CollectionService';\r\nexport { DemoService } from './services/DemoService';\r\n\r\n// Types & Models\r\nexport * from './types';\r\n", "import type { RecordModel, AdminModel } from '../types';\n\nexport type AuthChangeListener = (token: string, model: RecordModel | AdminModel | null) => void;\n\n/**\n * Lightweight helper to decode JWT payload without external dependencies.\n */\nexport function decodeJwtPayload(token: string): Record<string, any> | null {\n if (!token || typeof token !== 'string') return null;\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n\n try {\n let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n while (b64.length % 4) {\n b64 += '=';\n }\n\n let jsonStr: string;\n const globalObj: any =\n typeof globalThis !== 'undefined'\n ? globalThis\n : typeof window !== 'undefined'\n ? window\n : typeof self !== 'undefined'\n ? self\n : {};\n\n if (typeof globalObj.atob === 'function') {\n jsonStr = decodeURIComponent(\n Array.prototype.map\n .call(globalObj.atob(b64), (c: string) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join('')\n );\n } else if (typeof globalObj.Buffer !== 'undefined') {\n jsonStr = globalObj.Buffer.from(b64, 'base64').toString('utf8');\n } else {\n return null;\n }\n\n return JSON.parse(jsonStr);\n } catch {\n return null;\n }\n}\n\n/**\n * Base abstract class for authentication stores.\n */\nexport abstract class BaseAuthStore {\n protected _token: string = '';\n protected _model: RecordModel | AdminModel | null = null;\n private _listeners: Set<AuthChangeListener> = new Set();\n\n public get token(): string {\n return this._token;\n }\n\n public get model(): RecordModel | AdminModel | null {\n return this._model;\n }\n\n /**\n * Returns true if a token exists and has not yet expired.\n */\n public get isValid(): boolean {\n if (!this._token) {\n return false;\n }\n\n const payload = decodeJwtPayload(this._token);\n if (!payload) {\n return false;\n }\n\n if (payload.exp && typeof payload.exp === 'number') {\n const now = Math.floor(Date.now() / 1000);\n return payload.exp > now;\n }\n\n return true;\n }\n\n /**\n * Saves the token and associated user or admin model.\n */\n public save(token: string, model?: RecordModel | AdminModel | null): void {\n this._token = token || '';\n this._model = model || null;\n this.notify();\n }\n\n /**\n * Clears the current authentication state.\n */\n public clear(): void {\n this._token = '';\n this._model = null;\n this.notify();\n }\n\n /**\n * Subscribes to changes in authentication state (token or model).\n * Returns an unbind function.\n */\n public onChange(callback: AuthChangeListener, fireImmediately = false): () => void {\n this._listeners.add(callback);\n if (fireImmediately) {\n try {\n callback(this._token, this._model);\n } catch (err) {\n console.error('[AuthStore] Error in immediate onChange listener:', err);\n }\n }\n\n return () => {\n this._listeners.delete(callback);\n };\n }\n\n /**\n * Triggers all subscribed change listeners.\n */\n protected notify(): void {\n for (const listener of this._listeners) {\n try {\n listener(this._token, this._model);\n } catch (err) {\n console.error('[AuthStore] Error in onChange listener:', err);\n }\n }\n }\n}\n", "import { BaseAuthStore } from './BaseAuthStore';\nimport type { RecordModel, AdminModel } from '../types';\n\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nconst DEFAULT_STORAGE_KEY = 'nodestack_auth';\n\n/**\n * Storage-backed AuthStore that syncs token and model with localStorage\n * (or any custom StorageLike object, such as sessionStorage or AsyncStorage).\n * Safely degrades to memory if storage is not available.\n */\nexport class LocalAuthStore extends BaseAuthStore {\n private storageKey: string;\n private storage?: StorageLike;\n\n constructor(storageKey: string = DEFAULT_STORAGE_KEY, customStorage?: StorageLike) {\n super();\n this.storageKey = storageKey;\n\n if (customStorage) {\n this.storage = customStorage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n this.storage = window.localStorage;\n }\n\n this.loadInitial();\n }\n\n private loadInitial(): void {\n if (!this.storage) return;\n\n try {\n const raw = this.storage.getItem(this.storageKey);\n if (raw) {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed.token === 'string') {\n this._token = parsed.token;\n this._model = parsed.model || null;\n }\n }\n } catch {\n // Ignore parse or storage errors\n }\n }\n\n public override save(token: string, model?: RecordModel | AdminModel | null): void {\n super.save(token, model);\n\n if (this.storage) {\n try {\n this.storage.setItem(\n this.storageKey,\n JSON.stringify({\n token: this._token,\n model: this._model,\n })\n );\n } catch {\n // Storage might be full or disabled\n }\n }\n }\n\n public override clear(): void {\n super.clear();\n\n if (this.storage) {\n try {\n this.storage.removeItem(this.storageKey);\n } catch {\n // Ignore storage error\n }\n }\n }\n}\n", "export interface ClientResponseErrorOptions {\n url?: string;\n status?: number;\n data?: any;\n isAbort?: boolean;\n originalError?: any;\n message?: string;\n}\n\n/**\n * Standardized client response error representing failed HTTP requests\n * or network exceptions when interacting with NodeStack.\n */\nexport class ClientResponseError extends Error {\n public readonly url: string;\n public readonly status: number;\n public readonly data: any;\n public readonly isAbort: boolean;\n public readonly originalError?: any;\n\n constructor(options: ClientResponseErrorOptions = {}) {\n const status = options.status || 0;\n const message =\n options.message ||\n options.data?.message ||\n (status > 0 ? `NodeStack request failed with status ${status}` : 'NodeStack network request failed');\n\n super(message);\n this.name = 'ClientResponseError';\n this.url = options.url || '';\n this.status = status;\n this.data = options.data || {};\n this.isAbort = Boolean(options.isAbort);\n this.originalError = options.originalError;\n\n // Restore prototype chain\n Object.setPrototypeOf(this, ClientResponseError.prototype);\n }\n\n public toJSON() {\n return {\n name: this.name,\n message: this.message,\n url: this.url,\n status: this.status,\n data: this.data,\n isAbort: this.isAbort,\n };\n }\n}\n", "import type { SendOptions } from '../types';\nimport type { BaseAuthStore } from '../auth/BaseAuthStore';\n\nexport interface ClientInterface {\n baseUrl: string;\n authStore: BaseAuthStore;\n send<T = any>(path: string, options?: SendOptions): Promise<T>;\n}\n\n/**\n * Base service class from which all specific domain services inherit.\n */\nexport abstract class BaseService {\n constructor(protected readonly client: ClientInterface) {}\n\n protected send<T = any>(path: string, options: SendOptions = {}): Promise<T> {\n return this.client.send<T>(path, options);\n }\n}\n", "import { BaseService, ClientInterface } from './BaseService';\r\nimport { ClientResponseError } from '../errors/ClientResponseError';\r\nimport type {\r\n ListResult,\r\n QueryOptions,\r\n RecordModel,\r\n RecordAuthResponse,\r\n ImportResult,\r\n RealtimeCallback,\r\n UnsubscribeFunc,\r\n} from '../types';\r\n\r\nexport interface ClientWithRealtime extends ClientInterface {\r\n realtime: {\r\n subscribe<R = any>(topic: string, callback: RealtimeCallback<R>): Promise<UnsubscribeFunc>;\r\n unsubscribe(topic?: string, callback?: RealtimeCallback<any>): Promise<void>;\r\n };\r\n}\r\n\r\n/**\r\n * Service for managing CRUD, authentication, file handling, and subscriptions\r\n * for a specific collection.\r\n */\r\nexport class RecordService<T = RecordModel> extends BaseService {\r\n constructor(\r\n client: ClientWithRealtime,\r\n public readonly collectionName: string\r\n ) {\r\n super(client);\r\n }\r\n\r\n private get clientWithRealtime(): ClientWithRealtime {\r\n return this.client as ClientWithRealtime;\r\n }\r\n\r\n /**\r\n * Returns a paginated list of records matching the query options.\r\n */\r\n public async getList(options?: QueryOptions): Promise<ListResult<T>>;\r\n public async getList(\r\n page?: number,\r\n perPage?: number,\r\n options?: QueryOptions\r\n ): Promise<ListResult<T>>;\r\n public async getList(\r\n pageOrOptions: number | QueryOptions = 1,\r\n perPage = 30,\r\n options: QueryOptions = {}\r\n ): Promise<ListResult<T>> {\r\n let pageNum = 1;\r\n let perPageNum = perPage;\r\n let queryOpts: QueryOptions = options;\r\n\r\n if (typeof pageOrOptions === 'object' && pageOrOptions !== null) {\r\n queryOpts = pageOrOptions;\r\n pageNum = typeof queryOpts.page === 'number' ? queryOpts.page : 1;\r\n perPageNum = typeof queryOpts.perPage === 'number' ? queryOpts.perPage : 30;\r\n } else if (typeof pageOrOptions === 'number') {\r\n pageNum = pageOrOptions;\r\n }\r\n\r\n return this.send<ListResult<T>>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/records`,\r\n {\r\n method: 'GET',\r\n query: {\r\n page: pageNum,\r\n perPage: perPageNum,\r\n ...queryOpts,\r\n },\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Fetches and aggregates all records in the collection across multiple pages.\r\n */\r\n public async getFullList(\r\n options: QueryOptions & { batch?: number } = {}\r\n ): Promise<T[]> {\r\n const batch = Math.max(1, Math.min(500, options.batch || 200));\r\n const query = { ...options };\r\n delete query.batch;\r\n\r\n const firstPage = await this.getList(1, batch, query);\r\n const items: T[] = [...firstPage.items];\r\n\r\n if (firstPage.totalPages <= 1) {\r\n return items;\r\n }\r\n\r\n for (let page = 2; page <= firstPage.totalPages; page++) {\r\n const result = await this.getList(page, batch, query);\r\n items.push(...result.items);\r\n }\r\n\r\n return items;\r\n }\r\n\r\n /**\r\n * Returns the first record matching the specified filter expression.\r\n * Throws ClientResponseError(404) if no record matches.\r\n */\r\n public async getFirstListItem(\r\n filter: string,\r\n options: QueryOptions = {}\r\n ): Promise<T> {\r\n const list = await this.getList(1, 1, {\r\n ...options,\r\n filter,\r\n });\r\n\r\n if (!list.items || list.items.length === 0) {\r\n throw new ClientResponseError({\r\n status: 404,\r\n url: `/api/collections/${this.collectionName}/records`,\r\n message: `The requested record was not found in collection '${this.collectionName}'.`,\r\n });\r\n }\r\n\r\n return list.items[0];\r\n }\r\n\r\n /**\r\n * Retrieves a single record by its ID.\r\n */\r\n public async getOne(id: string, options: QueryOptions = {}): Promise<T> {\r\n return this.send<T>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\r\n {\r\n method: 'GET',\r\n query: options,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Creates a new record in the collection.\r\n * Accepts a plain object or FormData (for file uploads).\r\n */\r\n public async create(\r\n data: Record<string, any> | FormData,\r\n options: QueryOptions = {}\r\n ): Promise<T> {\r\n return this.send<T>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/records`,\r\n {\r\n method: 'POST',\r\n body: data,\r\n query: options,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Updates an existing record by its ID.\r\n * Accepts a plain object or FormData (for file updates).\r\n */\r\n public async update(\r\n id: string,\r\n data: Record<string, any> | FormData,\r\n options: QueryOptions = {}\r\n ): Promise<T> {\r\n return this.send<T>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\r\n {\r\n method: 'PATCH',\r\n body: data,\r\n query: options,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Deletes a record by its ID.\r\n */\r\n public async delete(id: string): Promise<boolean> {\r\n await this.send<void>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/records/${encodeURIComponent(id)}`,\r\n {\r\n method: 'DELETE',\r\n }\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * Authenticates against an auth collection using identity/email and password.\r\n * On success, automatically persists the token and record to authStore.\r\n */\r\n public async authWithPassword(\r\n identity: string,\r\n password: string\r\n ): Promise<RecordAuthResponse<T>> {\r\n const result = await this.send<RecordAuthResponse<T>>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/auth-with-password`,\r\n {\r\n method: 'POST',\r\n body: { identity, password },\r\n }\r\n );\r\n\r\n if (result && result.token) {\r\n this.client.authStore.save(result.token, result.record as any);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Exports records from the collection as CSV or JSON.\r\n */\r\n public async export(\r\n format: 'csv' | 'json' = 'csv',\r\n options: QueryOptions = {}\r\n ): Promise<string> {\r\n return this.send<string>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/export`,\r\n {\r\n method: 'GET',\r\n query: {\r\n ...options,\r\n format,\r\n },\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Imports records into the collection.\r\n */\r\n public async import(\r\n data: any[] | FormData | Blob | string,\r\n options: { continueOnError?: boolean } = {}\r\n ): Promise<ImportResult> {\r\n return this.send<ImportResult>(\r\n `/api/collections/${encodeURIComponent(this.collectionName)}/import`,\r\n {\r\n method: 'POST',\r\n body: data,\r\n query: options,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Subscribes to realtime events on this collection or a specific record ID.\r\n *\r\n * Example:\r\n * // Listen to all records in collection:\r\n * client.collection('posts').subscribe('*', (e) => console.log(e.action, e.record));\r\n *\r\n * // Listen to single record changes:\r\n * client.collection('posts').subscribe('record_id_123', (e) => console.log(e.action, e.record));\r\n */\r\n public async subscribe(\r\n topicOrCallback: string | RealtimeCallback<T>,\r\n callback?: RealtimeCallback<T>\r\n ): Promise<UnsubscribeFunc> {\r\n let topic = '*';\r\n let cb: RealtimeCallback<T>;\r\n\r\n if (typeof topicOrCallback === 'function') {\r\n topic = '*';\r\n cb = topicOrCallback;\r\n } else {\r\n topic = topicOrCallback;\r\n cb = callback!;\r\n }\r\n\r\n const fullTopic = topic === '*' ? this.collectionName : `${this.collectionName}/${topic}`;\r\n return this.clientWithRealtime.realtime.subscribe<T>(fullTopic, cb);\r\n }\r\n\r\n /**\r\n * Unsubscribes from realtime events for this collection.\r\n */\r\n public async unsubscribe(topic?: string): Promise<void> {\r\n const fullTopic = !topic || topic === '*' ? this.collectionName : `${this.collectionName}/${topic}`;\r\n return this.clientWithRealtime.realtime.unsubscribe(fullTopic);\r\n }\r\n}\r\n", "import { BaseService } from './BaseService';\n\nexport interface FileUrlOptions {\n download?: boolean;\n token?: string | boolean;\n collection?: string;\n}\n\n/**\n * Service for generating file URLs for assets uploaded to NodeStack.\n */\nexport class FileService extends BaseService {\n /**\n * Generates a fully qualified URL to an uploaded file.\n *\n * @param record - Record object or record ID string\n * @param filename - Name of the file stored on the record\n * @param options - Additional options (download flag, auth token, collection override)\n */\n public getUrl(\n record: { id: string; collection?: string; collectionName?: string; [key: string]: any } | string,\n filename: string,\n options: FileUrlOptions = {}\n ): string {\n if (!filename) return '';\n\n let recordId = '';\n let collectionName = options.collection || '';\n\n if (typeof record === 'string') {\n recordId = record;\n } else if (record && typeof record === 'object') {\n recordId = record.id || '';\n collectionName =\n collectionName ||\n record.collection ||\n record.collectionName ||\n record['@collectionName'] ||\n '';\n }\n\n if (!recordId) {\n throw new Error('[FileService] A valid record or recordId is required to construct a file URL.');\n }\n\n if (!collectionName) {\n throw new Error(\n '[FileService] Collection name is required. Either provide a record with collection info or pass options.collection.'\n );\n }\n\n const cleanBase = (this.client.baseUrl || '').replace(/\\/+$/, '');\n const cleanCol = encodeURIComponent(collectionName);\n const cleanId = encodeURIComponent(recordId);\n const cleanFile = encodeURIComponent(filename);\n\n let url = `${cleanBase}/api/files/${cleanCol}/${cleanId}/${cleanFile}`;\n\n const queryParts: string[] = [];\n\n if (options.download) {\n queryParts.push('download=1');\n }\n\n // Attach token if requested\n if (typeof options.token === 'string' && options.token) {\n queryParts.push(`token=${encodeURIComponent(options.token)}`);\n } else if (options.token === true && this.client.authStore.token) {\n queryParts.push(`token=${encodeURIComponent(this.client.authStore.token)}`);\n }\n\n if (queryParts.length > 0) {\n url += `?${queryParts.join('&')}`;\n }\n\n return url;\n }\n}\n", "import { BaseService, ClientInterface } from './BaseService';\nimport type { RealtimeEvent, RealtimeCallback, UnsubscribeFunc } from '../types';\n\n/**\n * Multiplexed Realtime Server-Sent Events (SSE) service.\n * Manages a single persistent SSE connection and dispatches events to subscribed listeners.\n */\nexport class RealtimeService extends BaseService {\n private eventSource: any = null;\n private clientId: string = '';\n private isConnecting: boolean = false;\n private connectPromise: Promise<string> | null = null;\n private reconnectTimeout: any = null;\n private reconnectAttempts: number = 0;\n private customEventSource?: any;\n\n // Map of topic -> Set of callbacks\n private subscriptions: Map<string, Set<RealtimeCallback<any>>> = new Map();\n\n // Set of registered event names on the active EventSource\n private registeredEventNames: Set<string> = new Set();\n\n constructor(client: ClientInterface, customEventSource?: any) {\n super(client);\n this.customEventSource = customEventSource;\n }\n\n /**\n * Returns whether there is an active EventSource connection.\n */\n public get isConnected(): boolean {\n return Boolean(this.eventSource && this.clientId);\n }\n\n /**\n * Resolves the EventSource constructor available in the current environment.\n */\n private getEventSourceConstructor(): any {\n if (this.customEventSource) {\n return this.customEventSource;\n }\n if (typeof window !== 'undefined' && (window as any).EventSource) {\n return (window as any).EventSource;\n }\n if (typeof globalThis !== 'undefined' && (globalThis as any).EventSource) {\n return (globalThis as any).EventSource;\n }\n throw new Error(\n '[RealtimeService] EventSource is not supported natively in this environment. ' +\n 'Please pass an EventSource polyfill to ClientOptions (e.g. from the \"eventsource\" package).'\n );\n }\n\n /**\n * Connects to the SSE stream if not already connected.\n * Returns the connected clientId.\n */\n public async connect(): Promise<string> {\n if (this.clientId && this.eventSource) {\n return this.clientId;\n }\n\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise<string>((resolve, reject) => {\n try {\n const EventSourceClass = this.getEventSourceConstructor();\n const base = (this.client.baseUrl || '').replace(/\\/+$/, '');\n let url = `${base}/api/realtime`;\n\n if (this.client.authStore.token) {\n url += `?token=${encodeURIComponent(this.client.authStore.token)}`;\n }\n\n this.eventSource = new EventSourceClass(url);\n\n const handleConnect = async (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.clientId = data.clientId;\n this.reconnectAttempts = 0;\n\n // Re-apply any existing subscriptions on the server\n await this.syncSubscriptions();\n\n resolve(this.clientId);\n } catch (err) {\n reject(err);\n }\n };\n\n this.eventSource.addEventListener('NS_CONNECT', handleConnect);\n this.eventSource.addEventListener('NB_CONNECT', handleConnect);\n\n this.eventSource.onerror = (err: any) => {\n if (!this.clientId) {\n reject(err);\n }\n this.handleDisconnect();\n };\n\n // Bind listeners for all known collection topics\n this.bindActiveTopics();\n } catch (err) {\n this.connectPromise = null;\n reject(err);\n }\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n /**\n * Subscribes to realtime updates for a collection or record.\n *\n * @param topic - Collection name ('posts'), wildcard ('*'), or specific record ('posts/rec_123')\n * @param callback - Event listener callback\n * @returns Unsubscribe function\n */\n public async subscribe<T = any>(\n topic: string,\n callback: RealtimeCallback<T>\n ): Promise<UnsubscribeFunc> {\n const cleanTopic = (topic || '*').trim();\n\n if (!this.subscriptions.has(cleanTopic)) {\n this.subscriptions.set(cleanTopic, new Set());\n }\n\n this.subscriptions.get(cleanTopic)!.add(callback);\n\n // If connected, sync subscriptions with server\n if (this.isConnected) {\n this.bindTopicListener(cleanTopic);\n await this.syncSubscriptions();\n } else {\n // Connect and sync\n await this.connect();\n }\n\n return () => this.unsubscribe(cleanTopic, callback);\n }\n\n /**\n * Unsubscribes from a topic or specific callback.\n */\n public async unsubscribe(topic?: string, callback?: RealtimeCallback<any>): Promise<void> {\n if (!topic) {\n // Unsubscribe all\n this.subscriptions.clear();\n if (this.isConnected) {\n await this.syncSubscriptions();\n }\n return;\n }\n\n const cleanTopic = topic.trim();\n if (!this.subscriptions.has(cleanTopic)) {\n return;\n }\n\n if (callback) {\n this.subscriptions.get(cleanTopic)!.delete(callback);\n if (this.subscriptions.get(cleanTopic)!.size === 0) {\n this.subscriptions.delete(cleanTopic);\n }\n } else {\n this.subscriptions.delete(cleanTopic);\n }\n\n if (this.isConnected) {\n await this.syncSubscriptions();\n }\n }\n\n /**\n * Closes the SSE connection and clears state.\n */\n public disconnect(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.eventSource) {\n try {\n this.eventSource.close();\n } catch {}\n this.eventSource = null;\n }\n\n this.clientId = '';\n this.registeredEventNames.clear();\n }\n\n /**\n * Synchronizes active subscriptions with the backend via POST /api/realtime.\n */\n private async syncSubscriptions(): Promise<void> {\n if (!this.clientId) return;\n\n const topics = Array.from(this.subscriptions.keys());\n\n try {\n await this.client.send('/api/realtime', {\n method: 'POST',\n body: {\n clientId: this.clientId,\n subscriptions: topics.length > 0 ? topics : ['__noop__'],\n },\n });\n } catch (err) {\n console.warn('[RealtimeService] Failed to sync subscriptions with server:', err);\n }\n }\n\n /**\n * Binds an EventSource listener for the collection corresponding to a topic.\n */\n private bindTopicListener(topic: string): void {\n if (!this.eventSource) return;\n\n // Determine collection name\n const collectionName = topic.includes('/') ? topic.split('/')[0] : topic;\n\n if (this.registeredEventNames.has(collectionName)) {\n return;\n }\n\n this.registeredEventNames.add(collectionName);\n\n this.eventSource.addEventListener(collectionName, (event: any) => {\n try {\n const payload: RealtimeEvent<any> = JSON.parse(event.data);\n this.dispatchEvent(collectionName, payload);\n } catch (err) {\n console.error(`[RealtimeService] Error handling event for ${collectionName}:`, err);\n }\n });\n }\n\n private bindActiveTopics(): void {\n for (const topic of this.subscriptions.keys()) {\n this.bindTopicListener(topic);\n }\n }\n\n /**\n * Dispatches received SSE events to matching subscribed listeners.\n */\n private dispatchEvent(collectionName: string, event: RealtimeEvent<any>): void {\n const recordId = event.record?.id;\n\n // Check wildcard subscription '*'\n this.triggerListeners('*', event);\n\n // Check collection subscription e.g. 'posts' or 'posts/*'\n this.triggerListeners(collectionName, event);\n this.triggerListeners(`${collectionName}/*`, event);\n\n // Check record-specific subscription e.g. 'posts/rec_123'\n if (recordId) {\n this.triggerListeners(`${collectionName}/${recordId}`, event);\n }\n }\n\n private triggerListeners(topic: string, event: RealtimeEvent<any>): void {\n const callbacks = this.subscriptions.get(topic);\n if (!callbacks || callbacks.size === 0) return;\n\n for (const cb of callbacks) {\n try {\n cb(event);\n } catch (err) {\n console.error(`[RealtimeService] Error in realtime listener for ${topic}:`, err);\n }\n }\n }\n\n /**\n * Handles disconnections and schedules automatic reconnection.\n */\n private handleDisconnect(): void {\n if (this.reconnectTimeout) return;\n\n this.disconnect();\n\n // Exponential backoff up to 10 seconds\n const delay = Math.min(10000, 500 * Math.pow(1.5, this.reconnectAttempts));\n this.reconnectAttempts++;\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n if (this.subscriptions.size > 0) {\n this.connect().catch(() => {});\n }\n }, delay);\n }\n}\n", "import { BaseService } from './BaseService';\nimport type { AdminAuthResponse, AdminModel } from '../types';\n\n/**\n * Service for administrative and superuser actions.\n */\nexport class AdminService extends BaseService {\n /**\n * Checks whether at least one superuser / admin account exists in NodeStack.\n */\n public async hasAdmins(): Promise<boolean> {\n const res = await this.send<{ hasAdmins: boolean }>('/api/admins/has-admins', {\n method: 'GET',\n });\n return Boolean(res?.hasAdmins);\n }\n\n /**\n * Creates the initial superuser account during first-time setup.\n * Automatically persists the returned admin token and model to authStore.\n */\n public async createInitial(email: string, password: string): Promise<AdminAuthResponse> {\n const res = await this.send<AdminAuthResponse>('/api/admins/create-initial', {\n method: 'POST',\n body: { email, password },\n });\n\n if (res?.token) {\n this.client.authStore.save(res.token, res.admin);\n }\n\n return res;\n }\n\n /**\n * Authenticates a superuser / admin using email and password.\n * Automatically persists the returned admin token and model to authStore.\n */\n public async authWithPassword(identity: string, password: string): Promise<AdminAuthResponse> {\n const res = await this.send<AdminAuthResponse>('/api/admins/auth-with-password', {\n method: 'POST',\n body: { identity, password },\n });\n\n if (res?.token) {\n this.client.authStore.save(res.token, res.admin);\n }\n\n return res;\n }\n\n /**\n * Retrieves the currently authenticated superuser's profile.\n */\n public async getMe(): Promise<AdminModel> {\n return this.send<AdminModel>('/api/admins/me', {\n method: 'GET',\n });\n }\n}\n", "import { BaseService } from './BaseService';\r\n\r\n/**\r\n * Service for managing collection schema definitions (Admin only).\r\n */\r\nexport class CollectionService extends BaseService {\r\n /**\r\n * Retrieves all collection schema models.\r\n */\r\n public async getList(): Promise<any[]> {\r\n const res = await this.send<{ items: any[]; totalItems: number } | any[]>('/api/collections', {\r\n method: 'GET',\r\n });\r\n return Array.isArray(res) ? res : res?.items || [];\r\n }\r\n\r\n /**\r\n * Retrieves a single collection schema by name or ID.\r\n */\r\n public async getOne(nameOrId: string): Promise<any> {\r\n return this.send<any>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\r\n method: 'GET',\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new collection schema.\r\n */\r\n public async create(data: any): Promise<any> {\r\n return this.send<any>('/api/collections', {\r\n method: 'POST',\r\n body: data,\r\n });\r\n }\r\n\r\n /**\r\n * Updates an existing collection schema.\r\n */\r\n public async update(nameOrId: string, data: any): Promise<any> {\r\n return this.send<any>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\r\n method: 'PATCH',\r\n body: data,\r\n });\r\n }\r\n\r\n /**\r\n * Deletes a collection schema and its corresponding SQLite table.\r\n */\r\n public async delete(nameOrId: string): Promise<boolean> {\r\n await this.send<void>(`/api/collections/${encodeURIComponent(nameOrId)}`, {\r\n method: 'DELETE',\r\n });\r\n return true;\r\n }\r\n\r\n /**\r\n * Infers schema fields, field types, and sample records from raw JSON (object or array).\r\n */\r\n public async inferSchema(data: any): Promise<{\r\n suggestedName?: string;\r\n fields: any[];\r\n recordCount: number;\r\n sampleRecords: any[];\r\n }> {\r\n return this.send('/api/collections/infer-schema', {\r\n method: 'POST',\r\n body: { data },\r\n });\r\n }\r\n\r\n /**\r\n * \"Paste JSON \u2192 Instant API\": Infers field types, creates collection and SQLite columns,\r\n * and populates all records within 1 second.\r\n */\r\n public async importJson(\r\n name: string,\r\n data: any,\r\n options: {\r\n type?: 'base' | 'auth';\r\n schemaOverrides?: any[];\r\n listRule?: string | null;\r\n viewRule?: string | null;\r\n createRule?: string | null;\r\n updateRule?: string | null;\r\n deleteRule?: string | null;\r\n } = {}\r\n ): Promise<{\r\n success: boolean;\r\n collection: any;\r\n recordCount: number;\r\n records: any[];\r\n inferredFields: any[];\r\n durationMs: number;\r\n }> {\r\n return this.send('/api/collections/import-json', {\r\n method: 'POST',\r\n body: {\r\n name,\r\n data,\r\n ...options,\r\n },\r\n });\r\n }\r\n}\r\n", "import { BaseService } from './BaseService';\r\nimport type {\r\n DemoSnapshotStatus,\r\n DemoSnapshotMetadata,\r\n DemoResetResult,\r\n} from '../types';\r\n\r\n/**\r\n * Service for freezing baseline demo state and 1-click restore (\"Reset to Demo State\").\r\n */\r\nexport class DemoService extends BaseService {\r\n /**\r\n * Retrieves the current snapshot availability, metadata, and live drift information.\r\n */\r\n public async getStatus(): Promise<DemoSnapshotStatus> {\r\n return this.send<DemoSnapshotStatus>('/api/demo/status', {\r\n method: 'GET',\r\n });\r\n }\r\n\r\n /**\r\n * Freezes current database & file storage state as the demo baseline.\r\n */\r\n public async snapshot(options?: { name?: string; description?: string }): Promise<DemoSnapshotMetadata> {\r\n return this.send<DemoSnapshotMetadata>('/api/demo/snapshot', {\r\n method: 'POST',\r\n body: options || {},\r\n });\r\n }\r\n\r\n /**\r\n * Restores the exact pristine demo state in one click.\r\n */\r\n public async reset(): Promise<DemoResetResult> {\r\n return this.send<DemoResetResult>('/api/demo/reset', {\r\n method: 'POST',\r\n });\r\n }\r\n\r\n /**\r\n * Deletes the frozen demo snapshot.\r\n */\r\n public async clear(): Promise<void> {\r\n return this.send<void>('/api/demo/snapshot', {\r\n method: 'DELETE',\r\n });\r\n }\r\n}\r\n", "import { BaseAuthStore } from './auth/BaseAuthStore';\r\nimport { LocalAuthStore } from './auth/LocalAuthStore';\r\nimport { ClientResponseError } from './errors/ClientResponseError';\r\nimport { RecordService } from './services/RecordService';\r\nimport { FileService } from './services/FileService';\r\nimport { RealtimeService } from './services/RealtimeService';\r\nimport { AdminService } from './services/AdminService';\r\nimport { CollectionService } from './services/CollectionService';\r\nimport { DemoService } from './services/DemoService';\r\nimport type {\r\n ClientOptions,\r\n SendOptions,\r\n RecordModel,\r\n ChaosOptions,\r\n} from './types';\r\n\r\n/**\r\n * Main NodeStack Client SDK entry point.\r\n */\r\nexport class NodeStackClient<TCollections extends Record<string, any> = Record<string, RecordModel>> {\r\n public readonly baseUrl: string;\r\n public readonly authStore: BaseAuthStore;\r\n public readonly files: FileService;\r\n public readonly realtime: RealtimeService;\r\n public readonly admins: AdminService;\r\n public readonly collections: CollectionService;\r\n public readonly demo: DemoService;\r\n\r\n private customFetch?: typeof fetch;\r\n private defaultHeaders: Record<string, string>;\r\n private defaultTimeout: number;\r\n private chaosOptions: ChaosOptions | null = null;\r\n private recordServices: Map<string, RecordService<any>> = new Map();\r\n\r\n constructor(baseUrl: string = '/', options: ClientOptions = {}) {\r\n this.baseUrl = (baseUrl || '/').replace(/\\/+$/, '');\r\n this.authStore = options.authStore || new LocalAuthStore();\r\n this.customFetch = options.fetch;\r\n this.defaultHeaders = options.headers || {};\r\n this.defaultTimeout = options.timeout || 120000; // 2 minutes default\r\n this.chaosOptions = options.chaos ? { ...options.chaos } : null;\r\n\r\n this.files = new FileService(this);\r\n this.realtime = new RealtimeService(this, options.EventSource);\r\n this.admins = new AdminService(this);\r\n this.collections = new CollectionService(this);\r\n this.demo = new DemoService(this);\r\n }\r\n\r\n /**\r\n * Dynamically configure latency & chaos simulation options for all future requests.\r\n * Pass null to disable client-side chaos injection.\r\n */\r\n public setChaos(options: ChaosOptions | null): void {\r\n this.chaosOptions = options ? { ...options } : null;\r\n }\r\n\r\n /**\r\n * Get active chaos simulation options.\r\n */\r\n public getChaos(): ChaosOptions | null {\r\n return this.chaosOptions ? { ...this.chaosOptions } : null;\r\n }\r\n\r\n /**\r\n * Returns a RecordService for interacting with a specific collection.\r\n * If a schema map type is provided to NodeStackClient, collection names\r\n * and record response types are automatically inferred and type-safe.\r\n */\r\n public collection<K extends keyof TCollections>(name: K): RecordService<TCollections[K]>;\r\n public collection<T = RecordModel>(name: string): RecordService<T>;\r\n public collection(name: string): RecordService<any> {\r\n const colName = String(name);\r\n let service = this.recordServices.get(colName);\r\n if (!service) {\r\n service = new RecordService(this, colName);\r\n this.recordServices.set(colName, service);\r\n }\r\n return service;\r\n }\r\n\r\n /**\r\n * Sends an HTTP request to NodeStack with automatic authentication,\r\n * header injection, query serialization, and standardized error handling.\r\n */\r\n public async send<T = any>(path: string, options: SendOptions = {}): Promise<T> {\r\n const fetchFn = this.customFetch || (typeof fetch !== 'undefined' ? fetch : null);\r\n if (!fetchFn) {\r\n throw new Error(\r\n '[NodeStackClient] fetch is not available in this environment. ' +\r\n 'Please pass a custom fetch implementation to ClientOptions.'\r\n );\r\n }\r\n\r\n // 1. Build URL & Query parameters\r\n let url = path.startsWith('http://') || path.startsWith('https://')\r\n ? path\r\n : `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\r\n\r\n if (options.query) {\r\n const searchParams = new URLSearchParams();\r\n for (const [key, val] of Object.entries(options.query)) {\r\n if (val === undefined || val === null) continue;\r\n searchParams.append(key, String(val));\r\n }\r\n const queryStr = searchParams.toString();\r\n if (queryStr) {\r\n url += (url.includes('?') ? '&' : '?') + queryStr;\r\n }\r\n }\r\n\r\n // 2. Prepare headers\r\n const headers: Record<string, string> = {\r\n ...this.defaultHeaders,\r\n ...(options.headers || {}),\r\n };\r\n\r\n if (this.authStore.token && !headers['Authorization'] && !headers['authorization']) {\r\n headers['Authorization'] = `Bearer ${this.authStore.token}`;\r\n }\r\n\r\n // 2b. Inject Latency & Chaos simulation headers\r\n const effectiveChaos: ChaosOptions = {\r\n ...(this.chaosOptions || {}),\r\n ...(options.chaos || {}),\r\n ...(options.mockDelay !== undefined ? { delay: options.mockDelay } : {}),\r\n ...(options.mockError !== undefined ? { errorStatus: options.mockError } : {}),\r\n ...(options.mockFailRate !== undefined ? { failRate: options.mockFailRate } : {}),\r\n ...(options.mockJitter !== undefined ? { jitter: options.mockJitter } : {}),\r\n };\r\n\r\n if (effectiveChaos.delay !== undefined && !headers['x-mock-delay'] && !headers['mock-delay']) {\r\n headers['x-mock-delay'] = String(effectiveChaos.delay);\r\n }\r\n if (effectiveChaos.errorStatus !== undefined && !headers['x-mock-error'] && !headers['mock-error']) {\r\n headers['x-mock-error'] = String(effectiveChaos.errorStatus);\r\n }\r\n if (effectiveChaos.failRate !== undefined && !headers['x-mock-fail-rate'] && !headers['mock-fail-rate']) {\r\n headers['x-mock-fail-rate'] = String(effectiveChaos.failRate);\r\n }\r\n if (effectiveChaos.jitter !== undefined && !headers['x-mock-jitter'] && !headers['mock-jitter']) {\r\n headers['x-mock-jitter'] = String(effectiveChaos.jitter);\r\n }\r\n if (effectiveChaos.errorMessage && !headers['x-mock-error-message'] && !headers['mock-error-message']) {\r\n headers['x-mock-error-message'] = String(effectiveChaos.errorMessage);\r\n }\r\n\r\n // 3. Serialize body\r\n let body: any = options.body;\r\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\r\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\r\n\r\n if (body !== undefined && body !== null) {\r\n if (isFormData) {\r\n // Let the environment compute multipart boundary headers automatically\r\n delete headers['Content-Type'];\r\n delete headers['content-type'];\r\n } else if (isBlob || typeof body === 'string') {\r\n // Leave body as-is\r\n } else if (typeof body === 'object') {\r\n headers['Content-Type'] = 'application/json';\r\n body = JSON.stringify(body);\r\n }\r\n }\r\n\r\n // 4. Handle abort signal & timeout\r\n let signal = options.signal;\r\n let timeoutId: any = null;\r\n\r\n if (!signal && this.defaultTimeout > 0 && typeof AbortController !== 'undefined') {\r\n const controller = new AbortController();\r\n signal = controller.signal;\r\n timeoutId = setTimeout(() => controller.abort(), this.defaultTimeout);\r\n }\r\n\r\n try {\r\n const response = await fetchFn(url, {\r\n ...options,\r\n headers,\r\n body,\r\n signal,\r\n });\r\n\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n\r\n // Handle 204 No Content\r\n if (response.status === 204) {\r\n return null as any;\r\n }\r\n\r\n const contentType = response.headers.get('content-type') || '';\r\n let data: any;\r\n\r\n if (contentType.includes('application/json')) {\r\n data = await response.json().catch(() => ({}));\r\n } else {\r\n data = await response.text();\r\n }\r\n\r\n if (!response.ok) {\r\n throw new ClientResponseError({\r\n url,\r\n status: response.status,\r\n data,\r\n message: typeof data === 'object' && data?.message ? data.message : undefined,\r\n });\r\n }\r\n\r\n return data as T;\r\n } catch (err: any) {\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n\r\n if (err instanceof ClientResponseError) {\r\n throw err;\r\n }\r\n\r\n const isAbort =\r\n err?.name === 'AbortError' ||\r\n (signal && signal.aborted) ||\r\n Boolean(options.signal && options.signal.aborted);\r\n\r\n throw new ClientResponseError({\r\n url,\r\n status: isAbort ? 0 : 0,\r\n isAbort,\r\n originalError: err,\r\n message: isAbort ? 'Request was aborted' : err?.message || 'Network request failed',\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Checks backend system health.\r\n */\r\n public async health(): Promise<{ status: string; [key: string]: any }> {\r\n return this.send('/api/health', { method: 'GET' });\r\n }\r\n\r\n /**\r\n * Retrieves server runtime settings.\r\n */\r\n public async settings(): Promise<any> {\r\n return this.send('/api/settings', { method: 'GET' });\r\n }\r\n\r\n /**\r\n * Fetches request logs (Admin only).\r\n */\r\n public async logs(page = 1, perPage = 50): Promise<any> {\r\n return this.send('/api/logs', {\r\n method: 'GET',\r\n query: { page, perPage },\r\n });\r\n }\r\n\r\n /**\r\n * Fetches system metrics & analytics (Admin only).\r\n */\r\n public async metrics(): Promise<any> {\r\n return this.send('/api/metrics', { method: 'GET' });\r\n }\r\n}\r\n", "import { BaseAuthStore } from './BaseAuthStore';\n\n/**\n * In-memory authentication store.\n * Ideal for Node.js scripts, server-side rendering (SSR), and testing environments.\n */\nexport class MemoryAuthStore extends BaseAuthStore {\n // Inherits default in-memory behavior of BaseAuthStore\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,6 @@ export { FileService, FileUrlOptions } from './services/FileService';
|
|
|
10
10
|
export { RealtimeService } from './services/RealtimeService';
|
|
11
11
|
export { AdminService } from './services/AdminService';
|
|
12
12
|
export { CollectionService } from './services/CollectionService';
|
|
13
|
+
export { DemoService } from './services/DemoService';
|
|
13
14
|
export * from './types';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAGtD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAG/F,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAGtD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAG/F,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,cAAc,SAAS,CAAC"}
|