fauxbase 0.1.2 → 0.4.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/dist/index.d.cts CHANGED
@@ -48,12 +48,19 @@ interface FieldOptions {
48
48
  }
49
49
  interface LocalDriverConfig {
50
50
  type: 'local';
51
- persist?: 'memory' | 'localStorage';
51
+ persist?: 'memory' | 'localStorage' | 'indexeddb';
52
+ dbName?: string;
52
53
  }
53
54
  interface HttpDriverConfig {
54
55
  type: 'http';
55
56
  baseUrl: string;
56
57
  preset?: string;
58
+ timeout?: number;
59
+ retry?: {
60
+ maxRetries?: number;
61
+ baseDelay?: number;
62
+ };
63
+ headers?: Record<string, string>;
57
64
  }
58
65
  type DriverConfig = LocalDriverConfig | HttpDriverConfig;
59
66
  interface SeedDefinition<T = any> {
@@ -81,6 +88,22 @@ declare class ValidationError extends FauxbaseError {
81
88
  declare class ForbiddenError extends FauxbaseError {
82
89
  constructor(message?: string);
83
90
  }
91
+ declare class NetworkError extends FauxbaseError {
92
+ constructor(message?: string);
93
+ }
94
+ declare class TimeoutError extends FauxbaseError {
95
+ constructor(message?: string);
96
+ }
97
+ declare class HttpError extends FauxbaseError {
98
+ readonly status: number;
99
+ constructor(message: string, status: number, details?: Record<string, string>);
100
+ toJSON(): {
101
+ status: number;
102
+ error: string;
103
+ code: string;
104
+ details?: Record<string, string>;
105
+ };
106
+ }
84
107
 
85
108
  declare abstract class Entity {
86
109
  id: string;
@@ -129,8 +152,11 @@ declare abstract class Service<T extends Entity> {
129
152
  abstract endpoint: string;
130
153
  protected driver: Driver;
131
154
  protected resourceName: string;
155
+ protected client: any;
132
156
  /** @internal — called by createClient to wire the service */
133
157
  _init(driver: Driver, resourceName: string): void;
158
+ /** @internal — called by createClient to give services access to the client */
159
+ _setClient(client: any): void;
134
160
  list(query?: QueryParams): Promise<PagedResponse<T>>;
135
161
  get(id: string): Promise<ApiResponse<T>>;
136
162
  create(data: Partial<T>): Promise<ApiResponse<T>>;
@@ -150,15 +176,212 @@ declare abstract class Service<T extends Entity> {
150
176
  private runHooks;
151
177
  }
152
178
 
179
+ type AuthProvider$1 = () => {
180
+ token: string;
181
+ } | null;
182
+ interface HttpDriverOptions extends HttpDriverConfig {
183
+ timeout?: number;
184
+ retry?: {
185
+ maxRetries?: number;
186
+ baseDelay?: number;
187
+ };
188
+ headers?: Record<string, string>;
189
+ }
190
+ declare class HttpDriver implements Driver {
191
+ private baseUrl;
192
+ private preset;
193
+ private timeout;
194
+ private maxRetries;
195
+ private baseDelay;
196
+ private defaultHeaders;
197
+ private endpoints;
198
+ private authProvider;
199
+ constructor(config: HttpDriverOptions);
200
+ setAuthProvider(provider: AuthProvider$1): void;
201
+ registerEndpoint(resource: string, endpoint: string): void;
202
+ private getEndpoint;
203
+ private buildUrl;
204
+ private buildHeaders;
205
+ private request;
206
+ private throwMappedError;
207
+ list<T>(resource: string, query: QueryParams): Promise<PagedResponse<T>>;
208
+ get<T>(resource: string, id: string): Promise<ApiResponse<T>>;
209
+ create<T>(resource: string, data: Partial<T>): Promise<ApiResponse<T>>;
210
+ update<T>(resource: string, id: string, data: Partial<T>): Promise<ApiResponse<T>>;
211
+ delete<T>(resource: string, id: string): Promise<ApiResponse<T>>;
212
+ count(resource: string, filter?: Record<string, any>): Promise<number>;
213
+ bulkCreate<T>(resource: string, data: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
214
+ bulkUpdate<T>(resource: string, updates: Array<{
215
+ id: string;
216
+ data: Partial<T>;
217
+ }>): Promise<ApiResponse<T[]>>;
218
+ bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
219
+ count: number;
220
+ }>>;
221
+ seed(): void;
222
+ getSeedVersion(): string | null;
223
+ setSeedVersion(): void;
224
+ clear(): void;
225
+ }
226
+
227
+ interface LoginCredentials {
228
+ email: string;
229
+ password: string;
230
+ }
231
+ interface AuthState {
232
+ userId: string;
233
+ email: string;
234
+ userName?: string;
235
+ role?: string;
236
+ token: string;
237
+ }
238
+ interface AuthContext {
239
+ userId: string;
240
+ userName?: string;
241
+ }
242
+ declare abstract class AuthService<T extends Entity> extends Service<T> {
243
+ private authState;
244
+ private saveState;
245
+ private httpDriver;
246
+ /** @internal — called by createClient to wire persistence */
247
+ _initAuth(loadState: () => AuthState | null, saveState: (state: AuthState | null) => void): void;
248
+ /** @internal — called by createClient when using HttpDriver */
249
+ _setHttpMode(driver: HttpDriver): void;
250
+ login(credentials: LoginCredentials): Promise<T>;
251
+ register(data: Partial<T>): Promise<T>;
252
+ logout(): void;
253
+ get currentUser(): T | null;
254
+ get isLoggedIn(): boolean;
255
+ get token(): string | null;
256
+ hasRole(role: string): boolean;
257
+ getAuthContext(): AuthContext | null;
258
+ private localLogin;
259
+ private localRegister;
260
+ private httpLogin;
261
+ private httpRegister;
262
+ private generateToken;
263
+ private persistState;
264
+ }
265
+
153
266
  type ClientServices<S extends Record<string, new (...args: any[]) => Service<any>>> = {
154
267
  [K in keyof S]: InstanceType<S[K]>;
155
268
  };
156
- declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>>(config: {
269
+ type ClientResult<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined> = ClientServices<S> & (A extends new (...args: any[]) => AuthService<any> ? {
270
+ auth: InstanceType<A>;
271
+ } : {}) & {
272
+ readonly ready: Promise<void>;
273
+ };
274
+ declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined = undefined>(config: {
157
275
  driver?: DriverConfig;
158
276
  services: S;
159
277
  seeds?: SeedDefinition[];
160
- }): ClientServices<S>;
278
+ auth?: A;
279
+ overrides?: Record<string, {
280
+ driver: DriverConfig;
281
+ }>;
282
+ }): ClientResult<S, A>;
161
283
 
162
284
  declare function seed<T>(entityClass: new (...args: any[]) => T, data: Array<Partial<T>>): SeedDefinition<T>;
163
285
 
164
- export { type ApiResponse, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, ForbiddenError, type HookType, type HttpDriverConfig, type LocalDriverConfig, NotFoundError, type PageMeta, type PagedResponse, type QueryParams, type SeedDefinition, Service, type SortParams, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, field, relation, seed };
286
+ interface StorageBackend {
287
+ getAll(resource: string): Record<string, any>[];
288
+ getById(resource: string, id: string): Record<string, any> | undefined;
289
+ set(resource: string, id: string, data: Record<string, any>): void;
290
+ remove(resource: string, id: string): void;
291
+ clear(resource: string): void;
292
+ getMeta(key: string): string | null;
293
+ setMeta(key: string, value: string): void;
294
+ }
295
+ type AuthProvider = () => {
296
+ userId: string;
297
+ userName?: string;
298
+ } | null;
299
+ declare class LocalDriver implements Driver {
300
+ private storage;
301
+ private entityClasses;
302
+ private authProvider;
303
+ private _ready;
304
+ private _isReady;
305
+ constructor(config: LocalDriverConfig);
306
+ get ready(): Promise<void>;
307
+ get isReady(): boolean;
308
+ setAuthProvider(provider: AuthProvider): void;
309
+ getStorageBackend(): StorageBackend;
310
+ registerEntity(resource: string, entityClass: Function): void;
311
+ list<T>(resource: string, query: QueryParams): Promise<PagedResponse<T>>;
312
+ get<T>(resource: string, id: string): Promise<ApiResponse<T>>;
313
+ create<T>(resource: string, data: Partial<T>): Promise<ApiResponse<T>>;
314
+ update<T>(resource: string, id: string, data: Partial<T>): Promise<ApiResponse<T>>;
315
+ delete<T>(resource: string, id: string): Promise<ApiResponse<T>>;
316
+ count(resource: string, filter?: Record<string, any>): Promise<number>;
317
+ bulkCreate<T>(resource: string, data: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
318
+ bulkUpdate<T>(resource: string, updates: Array<{
319
+ id: string;
320
+ data: Partial<T>;
321
+ }>): Promise<ApiResponse<T[]>>;
322
+ bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
323
+ count: number;
324
+ }>>;
325
+ seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
326
+ getSeedVersion(): string | null;
327
+ setSeedVersion(version: string): void;
328
+ clear(resource: string): void;
329
+ }
330
+
331
+ type FilterStyle = 'django' | 'dot' | 'bracket' | 'nestjs';
332
+ interface Preset {
333
+ name: string;
334
+ response: {
335
+ single: (raw: any) => {
336
+ data: any;
337
+ };
338
+ list: (raw: any) => {
339
+ items: any[];
340
+ meta: Record<string, any>;
341
+ };
342
+ error: (raw: any) => {
343
+ error: string;
344
+ code: string;
345
+ details?: Record<string, string>;
346
+ };
347
+ };
348
+ meta: {
349
+ page: string;
350
+ size: string;
351
+ totalItems: string;
352
+ totalPages: string;
353
+ };
354
+ query: {
355
+ filterStyle: FilterStyle;
356
+ pageParam: string;
357
+ sizeParam: string;
358
+ sortParam?: string;
359
+ sortFormat: string;
360
+ pageOffset?: number;
361
+ };
362
+ auth: {
363
+ loginUrl: string;
364
+ registerUrl: string;
365
+ logoutUrl?: string;
366
+ tokenField: string;
367
+ userField: string;
368
+ headerFormat: string;
369
+ };
370
+ }
371
+ declare function definePreset(config: Preset): Preset;
372
+
373
+ declare const defaultPreset: Preset;
374
+
375
+ declare const springBootPreset: Preset;
376
+
377
+ declare const laravelPreset: Preset;
378
+
379
+ declare const djangoPreset: Preset;
380
+
381
+ declare const nestjsPreset: Preset;
382
+
383
+ declare const expressPreset: Preset;
384
+
385
+ declare function getPreset(name: string): Preset;
386
+
387
+ export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
package/dist/index.d.ts CHANGED
@@ -48,12 +48,19 @@ interface FieldOptions {
48
48
  }
49
49
  interface LocalDriverConfig {
50
50
  type: 'local';
51
- persist?: 'memory' | 'localStorage';
51
+ persist?: 'memory' | 'localStorage' | 'indexeddb';
52
+ dbName?: string;
52
53
  }
53
54
  interface HttpDriverConfig {
54
55
  type: 'http';
55
56
  baseUrl: string;
56
57
  preset?: string;
58
+ timeout?: number;
59
+ retry?: {
60
+ maxRetries?: number;
61
+ baseDelay?: number;
62
+ };
63
+ headers?: Record<string, string>;
57
64
  }
58
65
  type DriverConfig = LocalDriverConfig | HttpDriverConfig;
59
66
  interface SeedDefinition<T = any> {
@@ -81,6 +88,22 @@ declare class ValidationError extends FauxbaseError {
81
88
  declare class ForbiddenError extends FauxbaseError {
82
89
  constructor(message?: string);
83
90
  }
91
+ declare class NetworkError extends FauxbaseError {
92
+ constructor(message?: string);
93
+ }
94
+ declare class TimeoutError extends FauxbaseError {
95
+ constructor(message?: string);
96
+ }
97
+ declare class HttpError extends FauxbaseError {
98
+ readonly status: number;
99
+ constructor(message: string, status: number, details?: Record<string, string>);
100
+ toJSON(): {
101
+ status: number;
102
+ error: string;
103
+ code: string;
104
+ details?: Record<string, string>;
105
+ };
106
+ }
84
107
 
85
108
  declare abstract class Entity {
86
109
  id: string;
@@ -129,8 +152,11 @@ declare abstract class Service<T extends Entity> {
129
152
  abstract endpoint: string;
130
153
  protected driver: Driver;
131
154
  protected resourceName: string;
155
+ protected client: any;
132
156
  /** @internal — called by createClient to wire the service */
133
157
  _init(driver: Driver, resourceName: string): void;
158
+ /** @internal — called by createClient to give services access to the client */
159
+ _setClient(client: any): void;
134
160
  list(query?: QueryParams): Promise<PagedResponse<T>>;
135
161
  get(id: string): Promise<ApiResponse<T>>;
136
162
  create(data: Partial<T>): Promise<ApiResponse<T>>;
@@ -150,15 +176,212 @@ declare abstract class Service<T extends Entity> {
150
176
  private runHooks;
151
177
  }
152
178
 
179
+ type AuthProvider$1 = () => {
180
+ token: string;
181
+ } | null;
182
+ interface HttpDriverOptions extends HttpDriverConfig {
183
+ timeout?: number;
184
+ retry?: {
185
+ maxRetries?: number;
186
+ baseDelay?: number;
187
+ };
188
+ headers?: Record<string, string>;
189
+ }
190
+ declare class HttpDriver implements Driver {
191
+ private baseUrl;
192
+ private preset;
193
+ private timeout;
194
+ private maxRetries;
195
+ private baseDelay;
196
+ private defaultHeaders;
197
+ private endpoints;
198
+ private authProvider;
199
+ constructor(config: HttpDriverOptions);
200
+ setAuthProvider(provider: AuthProvider$1): void;
201
+ registerEndpoint(resource: string, endpoint: string): void;
202
+ private getEndpoint;
203
+ private buildUrl;
204
+ private buildHeaders;
205
+ private request;
206
+ private throwMappedError;
207
+ list<T>(resource: string, query: QueryParams): Promise<PagedResponse<T>>;
208
+ get<T>(resource: string, id: string): Promise<ApiResponse<T>>;
209
+ create<T>(resource: string, data: Partial<T>): Promise<ApiResponse<T>>;
210
+ update<T>(resource: string, id: string, data: Partial<T>): Promise<ApiResponse<T>>;
211
+ delete<T>(resource: string, id: string): Promise<ApiResponse<T>>;
212
+ count(resource: string, filter?: Record<string, any>): Promise<number>;
213
+ bulkCreate<T>(resource: string, data: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
214
+ bulkUpdate<T>(resource: string, updates: Array<{
215
+ id: string;
216
+ data: Partial<T>;
217
+ }>): Promise<ApiResponse<T[]>>;
218
+ bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
219
+ count: number;
220
+ }>>;
221
+ seed(): void;
222
+ getSeedVersion(): string | null;
223
+ setSeedVersion(): void;
224
+ clear(): void;
225
+ }
226
+
227
+ interface LoginCredentials {
228
+ email: string;
229
+ password: string;
230
+ }
231
+ interface AuthState {
232
+ userId: string;
233
+ email: string;
234
+ userName?: string;
235
+ role?: string;
236
+ token: string;
237
+ }
238
+ interface AuthContext {
239
+ userId: string;
240
+ userName?: string;
241
+ }
242
+ declare abstract class AuthService<T extends Entity> extends Service<T> {
243
+ private authState;
244
+ private saveState;
245
+ private httpDriver;
246
+ /** @internal — called by createClient to wire persistence */
247
+ _initAuth(loadState: () => AuthState | null, saveState: (state: AuthState | null) => void): void;
248
+ /** @internal — called by createClient when using HttpDriver */
249
+ _setHttpMode(driver: HttpDriver): void;
250
+ login(credentials: LoginCredentials): Promise<T>;
251
+ register(data: Partial<T>): Promise<T>;
252
+ logout(): void;
253
+ get currentUser(): T | null;
254
+ get isLoggedIn(): boolean;
255
+ get token(): string | null;
256
+ hasRole(role: string): boolean;
257
+ getAuthContext(): AuthContext | null;
258
+ private localLogin;
259
+ private localRegister;
260
+ private httpLogin;
261
+ private httpRegister;
262
+ private generateToken;
263
+ private persistState;
264
+ }
265
+
153
266
  type ClientServices<S extends Record<string, new (...args: any[]) => Service<any>>> = {
154
267
  [K in keyof S]: InstanceType<S[K]>;
155
268
  };
156
- declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>>(config: {
269
+ type ClientResult<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined> = ClientServices<S> & (A extends new (...args: any[]) => AuthService<any> ? {
270
+ auth: InstanceType<A>;
271
+ } : {}) & {
272
+ readonly ready: Promise<void>;
273
+ };
274
+ declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined = undefined>(config: {
157
275
  driver?: DriverConfig;
158
276
  services: S;
159
277
  seeds?: SeedDefinition[];
160
- }): ClientServices<S>;
278
+ auth?: A;
279
+ overrides?: Record<string, {
280
+ driver: DriverConfig;
281
+ }>;
282
+ }): ClientResult<S, A>;
161
283
 
162
284
  declare function seed<T>(entityClass: new (...args: any[]) => T, data: Array<Partial<T>>): SeedDefinition<T>;
163
285
 
164
- export { type ApiResponse, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, ForbiddenError, type HookType, type HttpDriverConfig, type LocalDriverConfig, NotFoundError, type PageMeta, type PagedResponse, type QueryParams, type SeedDefinition, Service, type SortParams, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, field, relation, seed };
286
+ interface StorageBackend {
287
+ getAll(resource: string): Record<string, any>[];
288
+ getById(resource: string, id: string): Record<string, any> | undefined;
289
+ set(resource: string, id: string, data: Record<string, any>): void;
290
+ remove(resource: string, id: string): void;
291
+ clear(resource: string): void;
292
+ getMeta(key: string): string | null;
293
+ setMeta(key: string, value: string): void;
294
+ }
295
+ type AuthProvider = () => {
296
+ userId: string;
297
+ userName?: string;
298
+ } | null;
299
+ declare class LocalDriver implements Driver {
300
+ private storage;
301
+ private entityClasses;
302
+ private authProvider;
303
+ private _ready;
304
+ private _isReady;
305
+ constructor(config: LocalDriverConfig);
306
+ get ready(): Promise<void>;
307
+ get isReady(): boolean;
308
+ setAuthProvider(provider: AuthProvider): void;
309
+ getStorageBackend(): StorageBackend;
310
+ registerEntity(resource: string, entityClass: Function): void;
311
+ list<T>(resource: string, query: QueryParams): Promise<PagedResponse<T>>;
312
+ get<T>(resource: string, id: string): Promise<ApiResponse<T>>;
313
+ create<T>(resource: string, data: Partial<T>): Promise<ApiResponse<T>>;
314
+ update<T>(resource: string, id: string, data: Partial<T>): Promise<ApiResponse<T>>;
315
+ delete<T>(resource: string, id: string): Promise<ApiResponse<T>>;
316
+ count(resource: string, filter?: Record<string, any>): Promise<number>;
317
+ bulkCreate<T>(resource: string, data: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
318
+ bulkUpdate<T>(resource: string, updates: Array<{
319
+ id: string;
320
+ data: Partial<T>;
321
+ }>): Promise<ApiResponse<T[]>>;
322
+ bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
323
+ count: number;
324
+ }>>;
325
+ seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
326
+ getSeedVersion(): string | null;
327
+ setSeedVersion(version: string): void;
328
+ clear(resource: string): void;
329
+ }
330
+
331
+ type FilterStyle = 'django' | 'dot' | 'bracket' | 'nestjs';
332
+ interface Preset {
333
+ name: string;
334
+ response: {
335
+ single: (raw: any) => {
336
+ data: any;
337
+ };
338
+ list: (raw: any) => {
339
+ items: any[];
340
+ meta: Record<string, any>;
341
+ };
342
+ error: (raw: any) => {
343
+ error: string;
344
+ code: string;
345
+ details?: Record<string, string>;
346
+ };
347
+ };
348
+ meta: {
349
+ page: string;
350
+ size: string;
351
+ totalItems: string;
352
+ totalPages: string;
353
+ };
354
+ query: {
355
+ filterStyle: FilterStyle;
356
+ pageParam: string;
357
+ sizeParam: string;
358
+ sortParam?: string;
359
+ sortFormat: string;
360
+ pageOffset?: number;
361
+ };
362
+ auth: {
363
+ loginUrl: string;
364
+ registerUrl: string;
365
+ logoutUrl?: string;
366
+ tokenField: string;
367
+ userField: string;
368
+ headerFormat: string;
369
+ };
370
+ }
371
+ declare function definePreset(config: Preset): Preset;
372
+
373
+ declare const defaultPreset: Preset;
374
+
375
+ declare const springBootPreset: Preset;
376
+
377
+ declare const laravelPreset: Preset;
378
+
379
+ declare const djangoPreset: Preset;
380
+
381
+ declare const nestjsPreset: Preset;
382
+
383
+ declare const expressPreset: Preset;
384
+
385
+ declare function getPreset(name: string): Preset;
386
+
387
+ export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };