wabe 0.5.3 → 0.5.5

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="https://wabe.dev"><img src="https://www.wabe.dev/logo.png" alt="Wabe logo" height=170></a>
2
+ <a href="https://wabe.dev"><img src="https://www.wabe.dev/logo.webp" alt="Wabe logo" height=170></a>
3
3
  </p>
4
4
  <h1 align="center">Wabe</h1>
5
5
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## What is Wabe?
11
11
 
12
- Wabe is an open-source backend that allows you to create your own fully customizable backend in just a few minutes. It handles database access, automatic GraphQL API generation, authentication with various methods (classic or OAuth), permissions, security, and more for you.
12
+ Wabe is an open-source backend that allows you to create your own fully customizable backend in just a few minutes. It handles database access, automatic GraphQL API generation, authentication with various methods (classic or OAuth), permissions, security, payment, emails, and more for you.
13
13
 
14
14
  ## Install
15
15
 
@@ -52,6 +52,8 @@ await run();
52
52
  - **Database**: A powerful, scalable database to store and manage you data.
53
53
  - **GraphQL API**: A flexible and powerful GraphQL API (following GraphQL Relay standard) to interact with your data.
54
54
  - **Hooks**: Powerful hooks system to execute custom actions before or after database requests.
55
+ - **Email**: Send emails with your favorite provider with very simple integration.
56
+ - **Payment**: Accept payments with Stripe or create your own payment provider adapter.
55
57
 
56
58
  ## Contributing
57
59
 
package/dist/index.d.ts CHANGED
@@ -60,7 +60,8 @@ export type Scalars = {
60
60
  };
61
61
  };
62
62
  declare enum AuthenticationProvider {
63
- Google = "Google"
63
+ Google = "google",
64
+ EmailPassword = "emailPassword"
64
65
  }
65
66
  declare enum SecondaryFactor {
66
67
  EmailOtp = "EmailOTP"
@@ -250,6 +251,34 @@ export type PaymentAclObjectRolesAcl = {
250
251
  read: Scalars["Boolean"]["output"];
251
252
  write: Scalars["Boolean"]["output"];
252
253
  };
254
+ export type _InternalConfig = {
255
+ __typename?: "_InternalConfig";
256
+ id: Scalars["ID"]["output"];
257
+ configKey: Scalars["String"]["output"];
258
+ configValue: Scalars["String"]["output"];
259
+ description?: Maybe<Scalars["String"]["output"]>;
260
+ acl?: Maybe<_InternalConfigAclObject>;
261
+ createdAt?: Maybe<Scalars["Date"]["output"]>;
262
+ updatedAt?: Maybe<Scalars["Date"]["output"]>;
263
+ search?: Maybe<Array<Maybe<Scalars["String"]["output"]>>>;
264
+ };
265
+ export type _InternalConfigAclObject = {
266
+ __typename?: "_InternalConfigACLObject";
267
+ users?: Maybe<Array<Maybe<_InternalConfigAclObjectUsersAcl>>>;
268
+ roles?: Maybe<Array<Maybe<_InternalConfigAclObjectRolesAcl>>>;
269
+ };
270
+ export type _InternalConfigAclObjectUsersAcl = {
271
+ __typename?: "_InternalConfigACLObjectUsersACL";
272
+ userId: Scalars["String"]["output"];
273
+ read: Scalars["Boolean"]["output"];
274
+ write: Scalars["Boolean"]["output"];
275
+ };
276
+ export type _InternalConfigAclObjectRolesAcl = {
277
+ __typename?: "_InternalConfigACLObjectRolesACL";
278
+ roleId: Scalars["String"]["output"];
279
+ read: Scalars["Boolean"]["output"];
280
+ write: Scalars["Boolean"]["output"];
281
+ };
253
282
  export type SignInWithInput = {
254
283
  authentication?: InputMaybe<SignInWithAuthenticationInput>;
255
284
  };
@@ -298,11 +327,12 @@ export type WabeSchemaTypes = {
298
327
  _Session: _Session;
299
328
  Role: Role;
300
329
  Payment: Payment;
330
+ _InternalConfig: _InternalConfig;
301
331
  };
302
332
  export interface WabeContext<T extends WabeTypes> {
303
333
  response?: WobeResponse;
304
334
  user?: User | null;
305
- sessionId?: string;
335
+ sessionId?: string | null;
306
336
  isRoot: boolean;
307
337
  wabe: Wabe<T>;
308
338
  }
@@ -328,7 +358,7 @@ export interface AdapterOptions {
328
358
  databaseUrl: string;
329
359
  databaseName: string;
330
360
  }
331
- export type MutationData<T extends keyof WabeTypes["types"]> = Record<keyof WabeTypes["types"][T], any>;
361
+ export type MutationData<T extends keyof WabeTypes["types"], K extends keyof WabeTypes["types"][T]> = Record<K, any>;
332
362
  export interface CountOptions<T extends keyof WabeTypes["types"], K extends keyof WabeTypes["types"][T]> {
333
363
  className: T;
334
364
  where?: WhereType<T, K>;
@@ -354,13 +384,13 @@ export interface GetObjectsOptions<T extends keyof WabeTypes["types"], K extends
354
384
  }
355
385
  export interface CreateObjectOptions<T extends keyof WabeTypes["types"], K extends keyof WabeTypes["types"][T], W extends keyof WabeTypes["types"][T]> {
356
386
  className: T;
357
- data: MutationData<W>;
387
+ data: MutationData<T, W>;
358
388
  fields: Array<K | "*">;
359
389
  context: WabeContext<any>;
360
390
  }
361
391
  export interface CreateObjectsOptions<T extends keyof WabeTypes["types"], K extends keyof WabeTypes["types"][T], W extends keyof WabeTypes["types"][T], X extends keyof WabeTypes["types"][T]> {
362
392
  className: T;
363
- data: Array<MutationData<W>>;
393
+ data: Array<MutationData<T, W>>;
364
394
  fields: Array<K | "*">;
365
395
  offset?: number;
366
396
  first?: number;
@@ -371,7 +401,7 @@ export interface UpdateObjectOptions<T extends keyof WabeTypes["types"], K exten
371
401
  className: T;
372
402
  id: string;
373
403
  where?: WhereType<T, W>;
374
- data: MutationData<W>;
404
+ data: MutationData<T, W>;
375
405
  fields: Array<K | "*">;
376
406
  context: WabeContext<any>;
377
407
  }
@@ -379,7 +409,7 @@ export interface UpdateObjectsOptions<T extends keyof WabeTypes["types"], K exte
379
409
  className: T;
380
410
  where: WhereType<T, W>;
381
411
  order?: OrderType<T, X>;
382
- data: MutationData<W>;
412
+ data: MutationData<T, W>;
383
413
  fields: Array<K | "*">;
384
414
  offset?: number;
385
415
  first?: number;
@@ -500,9 +530,9 @@ export declare class DatabaseController<T extends WabeTypes> {
500
530
  getObject<U extends keyof T["types"], K extends keyof T["types"][U]>({ fields, className, context, skipHooks, id, where, }: GetObjectOptions<U, K>): Promise<OutputType<U, K>>;
501
531
  getObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ className, fields, context, where, skipHooks, first, offset, order, }: GetObjectsOptions<U, K, W, X>): Promise<OutputType<U, K>[]>;
502
532
  createObject<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U]>({ className, context, data, fields }: CreateObjectOptions<U, K, W>): Promise<OutputType<U, K>>;
503
- createObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ data, fields, className, context, first, offset, order, }: CreateObjectsOptions<U, K, W, X>): Promise<OutputType<U, K>[]>;
533
+ createObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ data, fields, className, context, first, offset, order, }: CreateObjectsOptions<U, K, W, X>): Promise<OutputType<any, K>[]>;
504
534
  updateObject<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U]>({ id, className, context, data, fields }: UpdateObjectOptions<U, K, W>): Promise<OutputType<keyof T["types"], K>>;
505
- updateObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ className, where, context, fields, data, first, offset, order, }: UpdateObjectsOptions<U, K, W, X>): Promise<OutputType<U, K>[]>;
535
+ updateObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ className, where, context, fields, data, first, offset, order, }: UpdateObjectsOptions<U, K, W, X>): Promise<OutputType<any, K>[]>;
506
536
  deleteObject<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U]>({ context, className, id, fields }: DeleteObjectOptions<U, K, W>): Promise<OutputType<U, K>>;
507
537
  deleteObjects<U extends keyof T["types"], K extends keyof T["types"][U], W extends keyof T["types"][U], X extends keyof T["types"][U]>({ className, context, fields, where, first, offset, order, }: DeleteObjectsOptions<U, K, W, X>): Promise<OutputType<U, K>[]>;
508
538
  }
@@ -514,6 +544,75 @@ export interface DatabaseConfig {
514
544
  url: string;
515
545
  name: string;
516
546
  }
547
+ export declare enum OperationType {
548
+ AfterCreate = "afterCreate",
549
+ AfterUpdate = "afterUpdate",
550
+ AfterDelete = "afterDelete",
551
+ AfterRead = "afterRead",
552
+ BeforeCreate = "beforeCreate",
553
+ BeforeUpdate = "beforeUpdate",
554
+ BeforeDelete = "beforeDelete",
555
+ BeforeRead = "beforeRead"
556
+ }
557
+ export type Hook<T extends WabeTypes, K extends keyof WabeTypes["types"]> = {
558
+ operationType: OperationType;
559
+ className?: K;
560
+ priority: number;
561
+ callback: (hookObject: HookObject<T, K>) => Promise<void> | void;
562
+ };
563
+ export declare const _findHooksByPriority: <T extends unknown>({ className, operationType, priority, config, }: {
564
+ operationType: OperationType;
565
+ className: T;
566
+ priority: number;
567
+ config: WabeConfig<any>;
568
+ }) => Promise<Hook<any, any>[]>;
569
+ export declare const initializeHook: <T extends unknown>({ className, newData, context, }: {
570
+ className: T;
571
+ newData?: MutationData<any, any> | undefined;
572
+ context: WabeContext<any>;
573
+ }) => {
574
+ runOnSingleObject: ({ operationType, id, object: inputObject, }: {
575
+ operationType: OperationType;
576
+ id?: string | undefined;
577
+ object?: OutputType<any, any> | undefined;
578
+ }) => Promise<{
579
+ object: undefined;
580
+ newData: {};
581
+ } | {
582
+ object: OutputType<any, any>;
583
+ newData: MutationData<T, keyof WabeSchemaTypes[T]>;
584
+ }>;
585
+ runOnMultipleObjects: ({ operationType, where, objects: inputObjects, }: {
586
+ operationType: OperationType;
587
+ where?: WhereType<any, any> | undefined;
588
+ objects?: OutputType<any, any>[] | undefined;
589
+ }) => Promise<{
590
+ objects: never[];
591
+ newData: MutationData<any, any>[];
592
+ } | {
593
+ objects: OutputType<any, any>[];
594
+ newData: Awaited<MutationData<T, keyof WabeSchemaTypes[T]>>[];
595
+ }>;
596
+ };
597
+ export declare const getDefaultHooks: () => Hook<any, any>[];
598
+ declare class HookObject<T extends WabeTypes, K extends keyof WabeTypes["types"]> {
599
+ className: K;
600
+ private newData;
601
+ private operationType;
602
+ context: WabeContext<T>;
603
+ object: Partial<Record<keyof T["types"][K], any>>;
604
+ constructor({ newData, className, operationType, context, object, }: {
605
+ className: K;
606
+ newData?: MutationData<K, keyof T["types"][K]>;
607
+ operationType: OperationType;
608
+ context: WabeContext<T>;
609
+ object: Partial<Record<keyof T["types"][K], any>>;
610
+ });
611
+ getUser(): User | null | undefined;
612
+ isFieldUpdate(field: keyof T["types"][K]): boolean | undefined;
613
+ upsertNewData(field: keyof T["types"][K], value: any): void;
614
+ getNewData(): MutationData<K, keyof T["types"][K]>;
615
+ }
517
616
  export type WabePrimaryTypes = "String" | "Int" | "Float" | "Boolean" | "Email" | "Date" | "File";
518
617
  export type WabeCustomTypes = "Array" | "Object";
519
618
  export type WabeRelationTypes = "Pointer" | "Relation";
@@ -623,7 +722,34 @@ export interface PermissionProperties {
623
722
  */
624
723
  authorizedRoles?: Array<string>;
625
724
  }
626
- export type ClassPermissions = Partial<Record<PermissionsOperations, PermissionProperties>>;
725
+ /**
726
+ * ACL properties
727
+ * Automatically create ACL object before insert of the object in the database
728
+ * Allow you to specify which user can read or write the object
729
+ * You can specify "self" to allow only the user that created the object to read or write it
730
+ * You can specify "all" to allow all users to read or write the object
731
+ * For some custom use cases, you can specify a callback function that will be called before
732
+ * inserting the object in the database.
733
+ * Authorized roles is more restristive that at the class level. You can have a role access on all the class
734
+ * except one object.
735
+ * If the array of authorized users is empty, no user is authorized
736
+ * If the array of authorized users is undefined, everyone is authorized
737
+ */
738
+ export type ACLProperties = {
739
+ authorizedUsers: {
740
+ read: Array<"self">;
741
+ write: Array<"self">;
742
+ };
743
+ authorizedRoles: {
744
+ read: Array<string>;
745
+ write: Array<string>;
746
+ };
747
+ } | {
748
+ callback?: (hookObject: HookObject<any, any>) => void | Promise<void>;
749
+ };
750
+ export type ClassPermissions = Partial<Record<PermissionsOperations, PermissionProperties> & {
751
+ acl: ACLProperties;
752
+ }>;
627
753
  export type SearchableFields = Array<string>;
628
754
  export type ClassIndexes = Array<{
629
755
  field: string;
@@ -666,6 +792,7 @@ export declare class Schema<T extends WabeTypes> {
666
792
  sessionClass(): ClassInterface<T>;
667
793
  paymentClass(): ClassInterface<T>;
668
794
  roleClass(): ClassInterface<T>;
795
+ internalConfigClass(): ClassInterface<T>;
669
796
  userClass(): ClassInterface<T>;
670
797
  defaultFields(): SchemaFields<T>;
671
798
  mergeClass(newClass: ClassInterface<T>[]): ClassInterface<T>[];
@@ -683,6 +810,9 @@ export type AuthenticationEventsOptions<T> = {
683
810
  input: T;
684
811
  context: WabeContext<any>;
685
812
  };
813
+ export type AuthenticationEventsOptionsWithUserId<T> = AuthenticationEventsOptions<T> & {
814
+ userId: string;
815
+ };
686
816
  export type ProviderInterface<T = any> = {
687
817
  onSignIn: (options: AuthenticationEventsOptions<T>) => Promise<{
688
818
  user: Partial<User>;
@@ -696,6 +826,9 @@ export type ProviderInterface<T = any> = {
696
826
  onSignUp: (options: AuthenticationEventsOptions<T>) => Promise<{
697
827
  authenticationDataToSave: any;
698
828
  }>;
829
+ onUpdateAuthenticationData?: (options: AuthenticationEventsOptionsWithUserId<T>) => Promise<{
830
+ authenticationDataToSave: any;
831
+ }>;
699
832
  };
700
833
  export type SecondaryProviderInterface<T = any> = {
701
834
  onSendChallenge: () => Promise<void>;
@@ -742,80 +875,14 @@ export interface Provider {
742
875
  refreshToken(options: refreshTokenOptions): Promise<void>;
743
876
  }
744
877
  declare enum AuthenticationProvider$1 {
745
- Google = "Google"
878
+ Google = "google",
879
+ EmailPassword = "emailPassword"
746
880
  }
747
881
  export interface WabeRoute {
748
882
  method: "GET" | "POST" | "PUT" | "DELETE";
749
883
  path: string;
750
884
  handler: WobeHandler<WobeCustomContext<any>>;
751
885
  }
752
- declare class HookObject<T extends WabeTypes, K = keyof T["types"]> {
753
- className: string;
754
- private newData;
755
- private operationType;
756
- context: WabeContext<T>;
757
- object: Record<keyof WabeTypes["types"][T], any>;
758
- constructor({ newData, className, operationType, context, object, }: {
759
- className: K;
760
- newData?: MutationData<T>;
761
- operationType: OperationType;
762
- context: WabeContext<T>;
763
- object: Record<keyof WabeTypes["types"][T], any>;
764
- });
765
- getUser(): User | null | undefined;
766
- isFieldUpdate(field: keyof WabeTypes["types"][T]): boolean | undefined;
767
- upsertNewData(field: keyof WabeTypes["types"][T], value: any): void;
768
- getNewData(): MutationData<T>;
769
- }
770
- export declare enum OperationType {
771
- AfterCreate = "AfterCreate",
772
- AfterUpdate = "afterUpdate",
773
- AfterDelete = "afterDelete",
774
- AfterRead = "afterRead",
775
- BeforeCreate = "beforeInsert",
776
- BeforeUpdate = "beforeUpdate",
777
- BeforeDelete = "beforeDelete",
778
- BeforeRead = "beforeRead"
779
- }
780
- export type Hook<T extends WabeTypes> = {
781
- operationType: OperationType;
782
- className?: T;
783
- priority: number;
784
- callback: (hookObject: HookObject<T>) => Promise<void> | void;
785
- };
786
- export type TypedNewData<T extends keyof WabeTypes["types"]> = Record<keyof WabeTypes["types"][T], any>;
787
- export declare const _findHooksByPriority: <T extends unknown>({ className, operationType, priority, config, }: {
788
- operationType: OperationType;
789
- className: T;
790
- priority: number;
791
- config: WabeConfig<any>;
792
- }) => Promise<Hook<any>[]>;
793
- export declare const initializeHook: <T extends unknown>({ className, newData, context, }: {
794
- className: T;
795
- newData?: TypedNewData<any> | undefined;
796
- context: WabeContext<any>;
797
- }) => {
798
- runOnSingleObject: ({ operationType, id, object: inputObject, }: {
799
- operationType: OperationType;
800
- id?: string | undefined;
801
- object?: OutputType<any, any> | undefined;
802
- }) => Promise<{
803
- object: undefined;
804
- newData: {};
805
- } | {
806
- object: OutputType<any, any>;
807
- newData: MutationData<any>;
808
- }>;
809
- runOnMultipleObjects: ({ operationType, where, objects: inputObjects, }: {
810
- operationType: OperationType;
811
- where?: WhereType<any, any> | undefined;
812
- objects?: OutputType<any, any>[] | undefined;
813
- }) => Promise<{
814
- objects: OutputType<any, any>[];
815
- newData: MutationData<any>[];
816
- }>;
817
- };
818
- export declare const getDefaultHooks: () => Hook<any>[];
819
886
  export type DevWabeTypes = {
820
887
  types: WabeSchemaTypes;
821
888
  scalars: WabeSchemaScalars;
@@ -838,6 +905,7 @@ export type WabeFileAdapter = (file: File) => Promise<string>;
838
905
  export interface FileConfig {
839
906
  adapter: WabeFileAdapter;
840
907
  }
908
+ export type Templates = "sendOTPCode";
841
909
  export interface EmailSendOptions {
842
910
  from: string;
843
911
  to: Array<string>;
@@ -854,8 +922,19 @@ export interface EmailAdapter {
854
922
  */
855
923
  send(options: EmailSendOptions): Promise<string>;
856
924
  }
925
+ /**
926
+ * Configuration for the email in Wabe
927
+ * @property adapter The adapter to use to send emails
928
+ * @property mainEmail The email to use as sender for emails sent by Wabe
929
+ * @property templates The html templates to use for a specific email. If not provided, Wabe will use the default templates
930
+ */
857
931
  export interface EmailConfig {
858
932
  adapter: EmailAdapter;
933
+ mainEmail?: string;
934
+ htmlTemplates?: Record<Templates, (payload: any) => string>;
935
+ }
936
+ export declare class EmailDevAdapter implements EmailAdapter {
937
+ send(): Promise<string>;
859
938
  }
860
939
  declare class EmailController implements EmailAdapter {
861
940
  adapter: EmailAdapter;
@@ -1062,7 +1141,7 @@ export interface WabeConfig<T extends WabeTypes> {
1062
1141
  authentication?: AuthenticationConfig<T>;
1063
1142
  routes?: WabeRoute[];
1064
1143
  rootKey: string;
1065
- hooks?: Hook<any>[];
1144
+ hooks?: Hook<T, any>[];
1066
1145
  email?: EmailConfig;
1067
1146
  payment?: PaymentConfig;
1068
1147
  file?: FileConfig;