taon 19.0.65 → 19.0.67

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.
Files changed (97) hide show
  1. package/README.md +160 -160
  2. package/bin/start.js +281 -281
  3. package/bin/taon +6 -6
  4. package/bin/taon-debug +5 -5
  5. package/bin/taon-debug-brk +5 -5
  6. package/browser/README.md +24 -24
  7. package/browser/fesm2022/taon.mjs +288 -81
  8. package/browser/fesm2022/taon.mjs.map +1 -1
  9. package/browser/lib/base-classes/base-class.d.ts +8 -1
  10. package/browser/lib/base-classes/base-controller.d.ts +56 -4
  11. package/browser/lib/base-classes/base-crud-controller.d.ts +5 -4
  12. package/browser/lib/base-classes/base-repository.d.ts +3 -0
  13. package/browser/lib/config/method-config.d.ts +1 -0
  14. package/browser/lib/decorators/http/http-decorators.d.ts +2 -1
  15. package/browser/lib/decorators/http/http-methods-decorators.d.ts +35 -4
  16. package/browser/lib/decorators/http/http-params-decorators.d.ts +3 -0
  17. package/browser/lib/endpoint-context.d.ts +3 -0
  18. package/browser/lib/get-response-value.d.ts +1 -1
  19. package/browser/lib/helpers/taon-helpers.d.ts +1 -0
  20. package/browser/lib/index.d.ts +4 -0
  21. package/browser/lib/models.d.ts +4 -10
  22. package/browser/lib/realtime/realtime-client.d.ts +18 -14
  23. package/browser/lib/realtime/realtime-server.d.ts +28 -3
  24. package/browser/lib/realtime/realtime.models.d.ts +15 -2
  25. package/browser/package.json +1 -1
  26. package/icon-menu-taon.svg +15 -15
  27. package/lib/base-classes/base-class.d.ts +8 -1
  28. package/lib/base-classes/base-class.js +20 -2
  29. package/lib/base-classes/base-class.js.map +1 -1
  30. package/lib/base-classes/base-controller.d.ts +57 -5
  31. package/lib/base-classes/base-controller.js +83 -12
  32. package/lib/base-classes/base-controller.js.map +1 -1
  33. package/lib/base-classes/base-crud-controller.d.ts +5 -4
  34. package/lib/base-classes/base-crud-controller.js +29 -17
  35. package/lib/base-classes/base-crud-controller.js.map +1 -1
  36. package/lib/base-classes/base-repository.d.ts +3 -0
  37. package/lib/base-classes/base-repository.js +3 -0
  38. package/lib/base-classes/base-repository.js.map +1 -1
  39. package/lib/build-info._auto-generated_.d.ts +1 -1
  40. package/lib/build-info._auto-generated_.js +1 -1
  41. package/lib/config/method-config.d.ts +1 -0
  42. package/lib/config/method-config.js.map +1 -1
  43. package/lib/decorators/http/http-decorators.d.ts +2 -1
  44. package/lib/decorators/http/http-decorators.js +2 -1
  45. package/lib/decorators/http/http-decorators.js.map +1 -1
  46. package/lib/decorators/http/http-methods-decorators.d.ts +35 -4
  47. package/lib/decorators/http/http-methods-decorators.js +34 -1
  48. package/lib/decorators/http/http-methods-decorators.js.map +1 -1
  49. package/lib/decorators/http/http-params-decorators.d.ts +3 -0
  50. package/lib/decorators/http/http-params-decorators.js +3 -0
  51. package/lib/decorators/http/http-params-decorators.js.map +1 -1
  52. package/lib/endpoint-context.d.ts +3 -0
  53. package/lib/endpoint-context.js +152 -122
  54. package/lib/endpoint-context.js.map +1 -1
  55. package/lib/get-response-value.d.ts +1 -1
  56. package/lib/get-response-value.js +0 -4
  57. package/lib/get-response-value.js.map +1 -1
  58. package/lib/helpers/taon-helpers.d.ts +1 -0
  59. package/lib/helpers/taon-helpers.js +6 -0
  60. package/lib/helpers/taon-helpers.js.map +1 -1
  61. package/lib/index.d.ts +4 -0
  62. package/lib/index.js +8 -2
  63. package/lib/index.js.map +1 -1
  64. package/lib/models.d.ts +4 -10
  65. package/lib/models.js +5 -23
  66. package/lib/models.js.map +1 -1
  67. package/lib/realtime/realtime-client.d.ts +18 -14
  68. package/lib/realtime/realtime-client.js +33 -25
  69. package/lib/realtime/realtime-client.js.map +1 -1
  70. package/lib/realtime/realtime-server.d.ts +28 -3
  71. package/lib/realtime/realtime-server.js +28 -2
  72. package/lib/realtime/realtime-server.js.map +1 -1
  73. package/lib/realtime/realtime.models.d.ts +15 -2
  74. package/lib/ui/index.js +2 -2
  75. package/lib/ui/taon-admin-mode-configuration/index.js +2 -2
  76. package/package.json +1 -1
  77. package/scss/global.scss +9 -12
  78. package/websql/README.md +24 -24
  79. package/websql/fesm2022/taon.mjs +289 -83
  80. package/websql/fesm2022/taon.mjs.map +1 -1
  81. package/websql/lib/base-classes/base-class.d.ts +8 -1
  82. package/websql/lib/base-classes/base-controller.d.ts +56 -4
  83. package/websql/lib/base-classes/base-crud-controller.d.ts +5 -4
  84. package/websql/lib/base-classes/base-repository.d.ts +3 -0
  85. package/websql/lib/config/method-config.d.ts +1 -0
  86. package/websql/lib/decorators/http/http-decorators.d.ts +2 -1
  87. package/websql/lib/decorators/http/http-methods-decorators.d.ts +35 -4
  88. package/websql/lib/decorators/http/http-params-decorators.d.ts +3 -0
  89. package/websql/lib/endpoint-context.d.ts +3 -0
  90. package/websql/lib/get-response-value.d.ts +1 -1
  91. package/websql/lib/helpers/taon-helpers.d.ts +1 -0
  92. package/websql/lib/index.d.ts +4 -0
  93. package/websql/lib/models.d.ts +4 -10
  94. package/websql/lib/realtime/realtime-client.d.ts +18 -14
  95. package/websql/lib/realtime/realtime-server.d.ts +28 -3
  96. package/websql/lib/realtime/realtime.models.d.ts +15 -2
  97. package/websql/package.json +1 -1
@@ -5,5 +5,12 @@ export declare class BaseClass<CloneT extends BaseClass = any> {
5
5
  * taon after class instance creation
6
6
  */
7
7
  _(): Promise<void>;
8
- clone(override?: Partial<CloneT>): CloneT;
8
+ /**
9
+ *
10
+ * @param overrideObjOrFn if object is provided it will override values in cloned object,
11
+ * if function is provided it will be called with old cloned values and should return
12
+ * object with values to override
13
+ * @returns cloned instance of the class
14
+ */
15
+ clone(overrideObjOrFn?: Partial<CloneT> | ((oldValues: Partial<CloneT>) => Partial<CloneT>)): CloneT;
9
16
  }
@@ -1,4 +1,5 @@
1
1
  // @ts-nocheck
2
+ import { RestErrorResponseWrapper, HttpResponseError } from 'ng2-rest/browser';
2
3
  import type { ContextsEndpointStorage } from '../endpoint-context-storage';
3
4
  import type { Models } from '../models';
4
5
  import { BaseInjector } from './base-injector';
@@ -13,7 +14,7 @@ export interface MulterFileUploadResponse {
13
14
  size: number;
14
15
  mimetype: string;
15
16
  }
16
- export declare class BaseController<T = any> extends BaseInjector {
17
+ export declare class BaseController<UPLOAD_FILE_QUERY_PARAMS = {}> extends BaseInjector {
17
18
  /**
18
19
  * Hook that is called when taon app is inited
19
20
  * (all contexts are created and inited)
@@ -21,11 +22,62 @@ export declare class BaseController<T = any> extends BaseInjector {
21
22
  afterAllCtxInited(options: {
22
23
  ctxStorage: ContextsEndpointStorage;
23
24
  }): Promise<void>;
24
- uploadFormDataToServer(formData: FormData): Models.Http.Response<MulterFileUploadResponse[]>;
25
+ uploadFormDataToServer(formData: FormData, queryParams?: UPLOAD_FILE_QUERY_PARAMS): Models.Http.Response<MulterFileUploadResponse[]>;
25
26
  /**
26
27
  * Hook after file is uploaded
27
28
  * through `uploadFormDataToServer` or `uploadLocalFileToServer`
28
29
  */
29
- protected afterFileUploadAction(file: MulterFileUploadResponse): void | Promise<void>;
30
- uploadLocalFileToServer(absFilePath: string, options?: Pick<Models.Http.Rest.Ng2RestAxiosRequestConfig, 'onUploadProgress'>): Promise<MulterFileUploadResponse[]>;
30
+ protected afterFileUploadAction(file?: MulterFileUploadResponse, queryParams?: UPLOAD_FILE_QUERY_PARAMS): void | Promise<void>;
31
+ uploadLocalFileToServer(absFilePath: string, options?: Pick<Models.Http.Rest.Ng2RestAxiosRequestConfig, 'onUploadProgress'>, queryParams?: UPLOAD_FILE_QUERY_PARAMS): Promise<MulterFileUploadResponse[]>;
32
+ /**
33
+ * Easy way to wait for status change with http (1s default) pooling.
34
+ *
35
+ * example (in sub class):
36
+ * ```ts
37
+ async check() {
38
+ await this.waitForProperStatusChange({
39
+ request: () => this.uploadFormDataToServer(void 0, void 0).request(),
40
+ statusCheck: resp => resp.body.json[0].ok,
41
+ });
42
+ }
43
+ * ```
44
+ */
45
+ _waitForProperStatusChange<T>(options: {
46
+ actionName: string;
47
+ /**
48
+ * Request for pooling
49
+ */
50
+ request: (opt?: {
51
+ /**
52
+ * optional index number to identify request in logs
53
+ * (starts from 0 and increments by 1 on each try)
54
+ */
55
+ reqIndexNum?: number;
56
+ httpErrorsCount?: number;
57
+ }) => ReturnType<Models.Http.Response<T>['request']>;
58
+ poolingInterval?: number;
59
+ /**
60
+ * default infinite tries
61
+ */
62
+ maxTries?: number;
63
+ /**
64
+ * default infiniti allowed http errors
65
+ */
66
+ allowedHttpErrors?: number;
67
+ /**
68
+ * condition to be met
69
+ */
70
+ statusCheck?: (response: Awaited<ReturnType<typeof options.request>>) => boolean;
71
+ /**
72
+ * if return true.. loop will continue
73
+ * if false .. will exit the loop
74
+ */
75
+ loopRequestsOnBackendError?: (opt: {
76
+ unknownError: Error;
77
+ unknownHttpError: HttpResponseError<any>;
78
+ taonError: HttpResponseError<RestErrorResponseWrapper>;
79
+ reqIndexNum?: number;
80
+ httpErrorsCount?: number;
81
+ }) => boolean | Promise<boolean>;
82
+ }): Promise<void>;
31
83
  }
@@ -5,10 +5,10 @@ import { BaseRepository } from './base-repository';
5
5
  /**
6
6
  * Please override property entityClassFn with entity class.
7
7
  */
8
- export declare abstract class BaseCrudController<Entity> extends BaseController {
8
+ export declare abstract class BaseCrudController<Entity, UPLOAD_FILE_QUERY_PARAMS = {}> extends BaseController<UPLOAD_FILE_QUERY_PARAMS> {
9
9
  protected db: BaseRepository<Entity>;
10
10
  /**
11
- * Please provide entity as class propery entityClassFn:
11
+ * Please provide entity as class property entityClassFn:
12
12
  * @returns class function
13
13
  *
14
14
  */
@@ -21,8 +21,9 @@ export declare abstract class BaseCrudController<Entity> extends BaseController
21
21
  updateById(id: number | string, item: Entity): Models.Http.Response<Entity>;
22
22
  patchById(id: number | string, item: Entity): Models.Http.Response<Entity>;
23
23
  bulkUpdate(items: Entity[]): Models.Http.Response<Entity[]>;
24
- deleteById(id: number): Models.Http.Response<Entity>;
24
+ deleteById(id: number | string): Models.Http.Response<Entity>;
25
25
  bulkDelete(ids: (number | string)[]): Models.Http.Response<(number | string | Entity)[]>;
26
- create(item: Entity): Models.Http.Response<Entity>;
26
+ clearTable(): Models.Http.Response<void>;
27
+ save(item: Entity): Models.Http.Response<Entity>;
27
28
  bulkCreate(items: Entity): Models.Http.Response<Entity[]>;
28
29
  }
@@ -61,6 +61,9 @@ export declare abstract class BaseRepository<Entity extends {
61
61
  bulkSave(items: Entity[], options?: SaveOptions & {
62
62
  reload: false;
63
63
  }): Promise<Entity[]>;
64
+ /**
65
+ * @deprecated use bulkSave instead
66
+ */
64
67
  bulkCreate(items: Entity[], options?: SaveOptions & {
65
68
  reload: false;
66
69
  }): Promise<Entity[]>;
@@ -17,6 +17,7 @@ export declare class MethodConfig implements Pick<TaonHttpDecoratorOptions, 'pat
17
17
  * override default axiso response type
18
18
  */
19
19
  responseType?: any;
20
+ overrideExpressSendAsHtml?: boolean;
20
21
  path: string;
21
22
  descriptor: PropertyDescriptor;
22
23
  type: CoreModels.HttpMethod;
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
+ import { Models } from 'ng2-rest/browser';
2
3
  import * as methods from './http-methods-decorators';
3
4
  import * as params from './http-params-decorators';
4
- import { Models } from 'ng2-rest/browser';
5
5
  export declare namespace Http {
6
6
  export import GET = methods.GET;
7
7
  export import POST = methods.POST;
@@ -9,6 +9,7 @@ export declare namespace Http {
9
9
  export import DELETE = methods.DELETE;
10
10
  export import PATCH = methods.PATCH;
11
11
  export import HEAD = methods.HEAD;
12
+ export import HTML = methods.HTML;
12
13
  export import Response = Models.HttpResponse;
13
14
  namespace Param {
14
15
  export import Query = params.Query;
@@ -18,21 +18,52 @@ export type TaonMiddlewareFunction = (options: {
18
18
  export interface TaonHttpDecoratorOptions {
19
19
  /**
20
20
  * @deprecated don't use in production - keep stuff encapsulated
21
- * path is global in express app
22
- * ! BE CAREFUL ! global path IS NOT GLOBAL inside dockerized app
23
- * (/api/contextName is automatically added to global path in docker)
21
+ * normally path is generated from method name and its params
24
22
  */
25
23
  path?: string;
26
24
  /**
27
- * ! BE CAREFULL
28
25
  * If true, the path will be global
26
+ *
27
+ * ! BE CAREFUL ! global path IS NOT GLOBAL inside dockerized app
28
+ * (/api/contextName is automatically added to global path in docker)
29
+ *
30
+ * @deprecated don't use in production - keep stuff encapsulated
29
31
  */
30
32
  pathIsGlobal?: boolean;
31
33
  overrideContentType?: CoreModels.ContentType;
32
34
  overrideResponseType?: ModelsNg2Rest.ResponseTypeAxios;
35
+ /**
36
+ * Express will send response as HTML string with proper headers
37
+ */
38
+ overrideExpressSendAsHtml?: boolean;
33
39
  middlewares?: TaonMiddlewareFunction;
34
40
  }
35
41
  export declare function GET(pathOrOptions?: string | TaonHttpDecoratorOptions, pathIsGlobal?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
42
+ /**
43
+ * Method for sending html website from text
44
+ * Example
45
+ *
46
+ * ```ts
47
+ * ...
48
+ * // in your taon controller
49
+ * ..Taon.Http.HTML()
50
+ * sendHtmlDummyWebsite(): Taon.ResponseHtml {
51
+ * return `
52
+ <html>
53
+ <head>
54
+ <title>Dummy website</title>
55
+ </head>
56
+ <body>
57
+ <h1>This is dummy website</h1>
58
+ <p>Served as HTML string from Taon controller method</p>
59
+ </body>
60
+ </html>
61
+ * `; *
62
+ * }
63
+ * ...
64
+ * ```
65
+ */
66
+ export declare function HTML(pathOrOptions?: Pick<TaonHttpDecoratorOptions, 'path' | 'pathIsGlobal'>): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
36
67
  export declare function HEAD(pathOrOptions?: string | TaonHttpDecoratorOptions, pathIsGlobal?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
37
68
  export declare function POST(pathOrOptions?: string | TaonHttpDecoratorOptions, pathIsGlobal?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
38
69
  export declare function PUT(pathOrOptions?: string | TaonHttpDecoratorOptions, pathIsGlobal?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
@@ -1,4 +1,7 @@
1
1
  // @ts-nocheck
2
+ /**
3
+ * @deprecated use Taon.Http.Param.Path (is more safe and cleaner)
4
+ */
2
5
  export declare function Path(name: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
3
6
  export declare function Query(name?: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
4
7
  export declare function Cookie(name: string, expireInSecond?: number): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
@@ -1,6 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import type { Server } from 'http';
3
3
  import type { NgZone } from '@angular/core';
4
+ import * as express from 'express';
4
5
  import type { Application } from 'express';
5
6
  import { DataSource } from 'taon-typeorm/browser';
6
7
  import type { BaseInjector } from './base-classes/base-injector';
@@ -66,6 +67,7 @@ export declare class EndpointContext {
66
67
  get logHttp(): boolean;
67
68
  get logRealtime(): boolean;
68
69
  get logFramework(): boolean;
70
+ get logRoutes(): boolean;
69
71
  get logDb(): boolean;
70
72
  get logMigrations(): boolean;
71
73
  /**
@@ -185,6 +187,7 @@ export declare class EndpointContext {
185
187
  private initCustomBackendMiddlewares;
186
188
  private initBackendMiddlewares;
187
189
  private initServer;
190
+ protected sendError(res: express.Response, error: unknown, req: express.Request, expressPath: string): void;
188
191
  /**
189
192
  * client can be browser or nodejs (when remote host)
190
193
  */
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
- import { Models } from './models';
3
2
  import { Response as ExpressResponse, Request as ExpressRequest } from 'express';
3
+ import { Models } from './models';
4
4
  export declare const getResponseValue: <T>(response: Models.Http.Response<T>, options?: {
5
5
  req: ExpressRequest;
6
6
  res: ExpressResponse;
@@ -4,6 +4,7 @@ import { MethodConfig } from '../config/method-config';
4
4
  export declare namespace TaonHelpers {
5
5
  const fillUpTo: (s: string, nCharacters: number) => string;
6
6
  const isGoodPath: (p: string) => boolean;
7
+ const firstStringOrElemFromArray: (stringOrArrayOfString: string[] | string) => string;
7
8
  const tryTransformParam: (param: any) => any;
8
9
  const getExpressPath: (c: ControllerConfig, pathOrClassConfig: Partial<MethodConfig>) => string;
9
10
  const defaultType: (value: any) => {};
@@ -1,6 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import 'reflect-metadata';
3
3
  import { NgZone } from '@angular/core';
4
+ import { RestErrorResponseWrapper } from 'ng2-rest/browser';
4
5
  import * as base from './base-classes/base';
5
6
  import * as controllerDecorator from './decorators/classes/controller-decorator';
6
7
  import * as entityDecorator from './decorators/classes/entity-decorator';
@@ -23,6 +24,7 @@ export { BaseProvider } from './base-classes/base-provider';
23
24
  export { BaseEntity } from './base-classes/base-entity';
24
25
  export { BaseContext } from './base-classes/base-context';
25
26
  export { BaseMigration } from './base-classes/base-migration';
27
+ export { BaseClass } from './base-classes/base-class';
26
28
  export { TaonAdditionalMiddlewareMethodInfo } from './base-classes/base-middleware';
27
29
  export { createContext, TaonContext } from './create-context';
28
30
  export { inject } from './inject';
@@ -34,6 +36,8 @@ export { ContextsEndpointStorage } from './endpoint-context-storage';
34
36
  export { ClassHelpers } from './helpers/class-helpers';
35
37
  export type { TaonClientMiddlewareInterceptOptions, TaonServerMiddlewareInterceptOptions, } from 'ng2-rest/browser';
36
38
  export declare namespace Taon {
39
+ const error: (opt: Pick<RestErrorResponseWrapper, "message" | "status" | "details" | "code">) => void;
40
+ type ResponseHtml = models.Models.Http.Response<string>;
37
41
  export import Response = models.Models.Http.Response;
38
42
  export import Http = http.Http;
39
43
  export import Base = base.Base;
@@ -1,8 +1,10 @@
1
1
  // @ts-nocheck
2
2
  import { Response as ExpressResponse, Request as ExpressRequest } from 'express';
3
- import { Models as ModelsNg2Rest } from 'ng2-rest/browser';
3
+ import { Models as ModelsNg2Rest, RestResponseWrapper } from 'ng2-rest/browser';
4
4
  import { CoreModels } from 'tnp-core/browser';
5
5
  import type { EndpointContext } from './endpoint-context';
6
+ export declare class TaonRestResponseWrapper extends RestResponseWrapper {
7
+ }
6
8
  export declare namespace Models {
7
9
  type FrameworkMode = 'backend-frontend(tcp+udp)' | 'remote-backend(tcp+udp)' | 'backend-frontend(ipc-electron)' | 'backend-frontend(websql-electron)' | 'backend-frontend(websql)';
8
10
  enum ClassType {
@@ -82,6 +84,7 @@ export declare namespace Models {
82
84
  framework?: boolean;
83
85
  db?: boolean;
84
86
  migrations?: boolean;
87
+ routes?: boolean;
85
88
  };
86
89
  interface ContextOptions<CONTEXTS, CONTROLLERS, ENTITIES, REPOSITORIES, PROVIDERS, SUBSCRIBERS, MIGRATIONS, MIDDLEWARES> {
87
90
  appId?: string;
@@ -230,15 +233,6 @@ export declare namespace Models {
230
233
  (req?: ExpressRequest, res?: ExpressResponse): Promise<SyncResponse<T> | SyncResponseFunc<T>>;
231
234
  }
232
235
  type Response<T = string> = AsyncResponse<T> & ClientAction<T>;
233
- class Errors {
234
- message: string;
235
- private code;
236
- toString: () => string;
237
- private constructor();
238
- private static create;
239
- static entityNotFound(entity?: Function): Errors;
240
- static custom(message: string, code?: ModelsNg2Rest.HttpCode): Errors;
241
- }
242
236
  }
243
237
  interface StartParams {
244
238
  port: number;
@@ -1,33 +1,37 @@
1
1
  // @ts-nocheck
2
2
  import { Observable } from 'rxjs';
3
- import type { BaseEntity } from '../base-classes/base-entity';
4
3
  import { RealtimeCore } from './realtime-core';
5
4
  import { RealtimeModels } from './realtime.models';
5
+ /**
6
+ * Client for realtime communication
7
+ * you can listen to:
8
+ * - entity changes (any property in table changed)
9
+ * - entity custom property changes (specific property changed)
10
+ * - entity table changes (new instance added, instance removed)
11
+ * - custom events
12
+ */
6
13
  export declare class RealtimeClient {
7
14
  private core;
8
15
  private subsManagers;
9
16
  constructor(core: RealtimeCore);
10
17
  private init;
11
18
  /**
19
+ * Usage:
20
+ * myContext.realtimeClient.listenChangesEntity(myEntityInstance);
21
+ *
22
+ *
12
23
  * Changes trigger on backend needs to be done manually.. example code:
13
24
  *
14
- * ...
15
- * Context.Realtime.Server.TrigggerEntityChanges(myEntityInstance);
25
+ * myContext.realtimeServer.triggerEntityChanges(myEntityInstance);
16
26
  * ...
17
27
  */
18
- listenChangesEntity(entityClassFn: Function, idOrUniqValue: any, options: RealtimeModels.ChangeOption): Observable<unknown>;
19
- listenChangesEntityTable(entityClassFn: Function): Observable<unknown>;
28
+ listenChangesEntity<RESULT = any>(entityClassFnOrObj: Function | object, options?: RealtimeModels.ChangeOption): Observable<RESULT>;
20
29
  /**
21
- * Changes trigger on backend needs to be done manually.. example code:
22
- *
23
- * ...
24
- * Context.Realtime.Server.TrigggerEntityChanges(myEntityInstance);
25
- * // or
26
- * Context.Realtime.Server.TrigggerEntityPropertyChanges(myEntityInstance,{ property: 'geolocationX' });
27
- * ...
30
+ * Listen changes entity table
31
+ * Example: for pagination, lists update ...
28
32
  */
29
- listenChangesEntityObj<T extends BaseEntity>(entity: T, options?: RealtimeModels.ChangeOption): Observable<unknown>;
30
- listenChangesCustomEvent(customEvent: string): Observable<unknown>;
33
+ listenChangesEntityTable<RESULT = any>(entityClassFn: Function): Observable<RESULT>;
34
+ listenChangesCustomEvent<RESULT = any>(customEvent: string): Observable<RESULT>;
31
35
  /**
32
36
  * Trigger custom event on backend
33
37
  * @param customEvent global event name
@@ -1,14 +1,39 @@
1
1
  // @ts-nocheck
2
2
  import { Observable } from 'rxjs';
3
- import type { BaseEntity } from '../base-classes/base-entity';
4
3
  import { RealtimeCore } from './realtime-core';
4
+ /**
5
+ * Server for realtime communication
6
+ * you can trigger:
7
+ * - entity changes (any property in table changed)
8
+ * - entity custom property changes (specific property changed)
9
+ * - entity table changes (new instance added, instance removed)
10
+ * - custom events
11
+ *
12
+ * and also listen to:
13
+ * - custom events from yourself
14
+ */
5
15
  export declare class RealtimeServer {
6
16
  private core;
7
17
  constructor(core: RealtimeCore);
8
18
  private init;
9
19
  private triggerChanges;
10
- triggerEntityChanges(entityObjOrClass: Function, idToTrigger?: number | string): void;
11
- triggerEntityPropertyChanges<ENTITY extends BaseEntity>(entityObjOrClass: new (...args: any[]) => ENTITY, property: keyof ENTITY | (keyof ENTITY)[], idToTrigger?: number | string): void;
20
+ triggerEntityChanges(entityObjOrClass: Function | object,
21
+ /**
22
+ * value of unique key property of entity instance
23
+ * (this value is not needed if entityObjOrClass is instance of entity)
24
+ */
25
+ idToTrigger?: number | string): void;
26
+ triggerEntityPropertyChanges(entityObjOrClass: Function | object,
27
+ /**
28
+ * property name or array of property names that changed
29
+ * for entity instance
30
+ */
31
+ property: string | string[],
32
+ /**
33
+ * value of unique key property of entity instance
34
+ * (this value is not needed if entityObjOrClass is instance of entity)
35
+ */
36
+ idToTrigger?: number | string): void;
12
37
  triggerEntityTableChanges(entityClassOrInstance: Function | object): void;
13
38
  triggerCustomEvent(customEvent: string, dataToPush: any): void;
14
39
  /**
@@ -7,9 +7,22 @@ export declare namespace RealtimeModels {
7
7
  roomName: string;
8
8
  property: string;
9
9
  };
10
- type ChangeOption = {
10
+ interface ChangeOption {
11
+ /**
12
+ * Specify property name to listen changes on that property only;
13
+ */
11
14
  property?: string;
15
+ /**
16
+ * Override custom event name to listen
17
+ */
12
18
  customEvent?: string;
13
- };
19
+ /**
20
+ * Value from entity object.
21
+ * Key for this value is usually id or unique key
22
+ * property defined in entity decorator.
23
+ * TODO @LAST IMPLEMENT unique key support
24
+ */
25
+ idOrUniqValue?: any;
26
+ }
14
27
  type EventHandler = (...args: any[]) => void;
15
28
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taon/browser",
3
- "version": "19.0.65",
3
+ "version": "19.0.67",
4
4
  "module": "fesm2022/taon.mjs",
5
5
  "typings": "index.d.ts",
6
6
  "exports": {
@@ -1,15 +1,15 @@
1
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg
3
- viewBox="0 0 23.432 23.432004"
4
- version="1.1"
5
- id="svg1"
6
- width="23.431999"
7
- height="23.432003"
8
- xmlns="http://www.w3.org/2000/svg"
9
- xmlns:svg="http://www.w3.org/2000/svg">
10
- <defs
11
- id="defs1" />
12
- <path
13
- id="path1"
14
- d="m 11.521484,1.265625 c -0.953032,1.5597622 -1.9887223,3.0593334 -3.1074215,4.5 C 6.9495642,4.7476223 5.485983,3.7308932 4.0214844,2.7128906 3.8829075,2.6603831 3.738968,2.6414114 3.5917969,2.6582031 2.7651252,6.7213623 1.8733597,10.758159 0.9140625,14.767578 v 0.75 c 1.6097872,1.096932 3.2239518,2.188127 4.8417969,3.273438 v 0.08008 h 0.1171875 c 1.806633,1.211497 3.6188659,2.414261 5.4355471,3.611328 0.07144,0.07147 0.14145,0.143364 0.21289,0.214844 h 0.429688 c 3.432812,-2.431526 6.897745,-4.824781 10.394531,-7.179688 V 14.552734 C 21.353633,10.612741 20.406845,6.6479161 19.505859,2.6582031 19.42892,2.5563391 19.339974,2.5393307 19.238281,2.6054688 17.782054,3.6890192 16.286176,4.7048374 14.75,5.6523438 a 3.4715793,3.1345327 0 0 0 -0.01758,-0.00195 C 13.814421,4.161603 12.851221,2.7003542 11.84375,1.265625 Z M 4.1855469,8.9433594 H 10.810547 V 10.048828 H 8.34375 V 15.46875 H 6.6601562 V 10.048828 H 4.1855469 Z m 7.7285151,0 h 1.638672 l 3.41211,4.3574216 V 8.9433594 h 1.564453 V 15.46875 h -1.689453 l -3.361328,-4.253906 v 4.253906 h -1.564454 z" />
15
- </svg>
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ viewBox="0 0 23.432 23.432004"
4
+ version="1.1"
5
+ id="svg1"
6
+ width="23.431999"
7
+ height="23.432003"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ xmlns:svg="http://www.w3.org/2000/svg">
10
+ <defs
11
+ id="defs1" />
12
+ <path
13
+ id="path1"
14
+ d="m 11.521484,1.265625 c -0.953032,1.5597622 -1.9887223,3.0593334 -3.1074215,4.5 C 6.9495642,4.7476223 5.485983,3.7308932 4.0214844,2.7128906 3.8829075,2.6603831 3.738968,2.6414114 3.5917969,2.6582031 2.7651252,6.7213623 1.8733597,10.758159 0.9140625,14.767578 v 0.75 c 1.6097872,1.096932 3.2239518,2.188127 4.8417969,3.273438 v 0.08008 h 0.1171875 c 1.806633,1.211497 3.6188659,2.414261 5.4355471,3.611328 0.07144,0.07147 0.14145,0.143364 0.21289,0.214844 h 0.429688 c 3.432812,-2.431526 6.897745,-4.824781 10.394531,-7.179688 V 14.552734 C 21.353633,10.612741 20.406845,6.6479161 19.505859,2.6582031 19.42892,2.5563391 19.339974,2.5393307 19.238281,2.6054688 17.782054,3.6890192 16.286176,4.7048374 14.75,5.6523438 a 3.4715793,3.1345327 0 0 0 -0.01758,-0.00195 C 13.814421,4.161603 12.851221,2.7003542 11.84375,1.265625 Z M 4.1855469,8.9433594 H 10.810547 V 10.048828 H 8.34375 V 15.46875 H 6.6601562 V 10.048828 H 4.1855469 Z m 7.7285151,0 h 1.638672 l 3.41211,4.3574216 V 8.9433594 h 1.564453 V 15.46875 h -1.689453 l -3.361328,-4.253906 v 4.253906 h -1.564454 z" />
15
+ </svg>
@@ -4,5 +4,12 @@ export declare class BaseClass<CloneT extends BaseClass = any> {
4
4
  * taon after class instance creation
5
5
  */
6
6
  _(): Promise<void>;
7
- clone(override?: Partial<CloneT>): CloneT;
7
+ /**
8
+ *
9
+ * @param overrideObjOrFn if object is provided it will override values in cloned object,
10
+ * if function is provided it will be called with old cloned values and should return
11
+ * object with values to override
12
+ * @returns cloned instance of the class
13
+ */
14
+ clone(overrideObjOrFn?: Partial<CloneT> | ((oldValues: Partial<CloneT>) => Partial<CloneT>)): CloneT;
8
15
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseClass = void 0;
4
+ const lib_1 = require("tnp-core/lib");
4
5
  const class_helpers_1 = require("../helpers/class-helpers");
5
6
  const clone_obj_1 = require("../helpers/clone-obj");
6
7
  //#endregion
@@ -13,9 +14,26 @@ class BaseClass {
13
14
  async _() { }
14
15
  //#endregion
15
16
  //#region clone
16
- clone(override) {
17
+ /**
18
+ *
19
+ * @param overrideObjOrFn if object is provided it will override values in cloned object,
20
+ * if function is provided it will be called with old cloned values and should return
21
+ * object with values to override
22
+ * @returns cloned instance of the class
23
+ */
24
+ clone(overrideObjOrFn) {
25
+ if (lib_1._.isString(overrideObjOrFn)) {
26
+ console.log(overrideObjOrFn);
27
+ throw new Error('String is not supported as .clone() method argument');
28
+ }
17
29
  const classFn = class_helpers_1.ClassHelpers.getClassFnFromObject(this);
18
- return (0, clone_obj_1.cloneObj)(override, classFn);
30
+ if (lib_1._.isFunction(overrideObjOrFn)) {
31
+ // console.log('clone with fn');
32
+ const oldValues = (lib_1._.cloneDeep(this) || {});
33
+ return (0, clone_obj_1.cloneObj)(overrideObjOrFn(oldValues), classFn);
34
+ }
35
+ // console.log('clone normal');
36
+ return (0, clone_obj_1.cloneObj)(overrideObjOrFn, classFn);
19
37
  }
20
38
  }
21
39
  exports.BaseClass = BaseClass;
@@ -1 +1 @@
1
- {"version":3,"file":"base-class.js","sourceRoot":"","sources":[""],"names":[],"mappings":";;;AAIA,4DAAwD;AACxD,oDAAgD;AAEhD,YAAY;AAEZ,MAAa,SAAS;IACpB,mCAAmC;IACnC;;;OAGG;IACH,KAAK,CAAC,CAAC,KAAmB,CAAC;IAC3B,YAAY;IAEZ,eAAe;IACR,KAAK,CAAC,QAA0B;QACrC,MAAM,OAAO,GAAG,4BAAY,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxD,OAAO,IAAA,oBAAQ,EAAS,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;CAEF;AAfD,8BAeC"}
1
+ {"version":3,"file":"base-class.js","sourceRoot":"","sources":[""],"names":[],"mappings":";;;AAEA,sCAAiC;AAEjC,4DAAwD;AACxD,oDAAgD;AAEhD,YAAY;AAEZ,MAAa,SAAS;IACpB,mCAAmC;IACnC;;;OAGG;IACH,KAAK,CAAC,CAAC,KAAmB,CAAC;IAC3B,YAAY;IAEZ,eAAe;IACf;;;;;;OAMG;IACI,KAAK,CACV,eAEqD;QAErD,IAAG,OAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,OAAO,GAAG,4BAAY,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,OAAC,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAClC,gCAAgC;YAChC,MAAM,SAAS,GAAG,CAAC,OAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAA2B,CAAC;YACtE,OAAO,IAAA,oBAAQ,EAAS,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;QACD,+BAA+B;QAC/B,OAAO,IAAA,oBAAQ,EAAS,eAAsB,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;CAEF;AApCD,8BAoCC"}
@@ -1,4 +1,5 @@
1
1
  import * as FormData from 'form-data';
2
+ import { RestErrorResponseWrapper, HttpResponseError } from 'ng2-rest';
2
3
  import type { ContextsEndpointStorage } from '../endpoint-context-storage';
3
4
  import type { Models } from '../models';
4
5
  import { BaseInjector } from './base-injector';
@@ -13,7 +14,7 @@ export interface MulterFileUploadResponse {
13
14
  size: number;
14
15
  mimetype: string;
15
16
  }
16
- export declare class BaseController<T = any> extends BaseInjector {
17
+ export declare class BaseController<UPLOAD_FILE_QUERY_PARAMS = {}> extends BaseInjector {
17
18
  /**
18
19
  * Hook that is called when taon app is inited
19
20
  * (all contexts are created and inited)
@@ -21,11 +22,62 @@ export declare class BaseController<T = any> extends BaseInjector {
21
22
  afterAllCtxInited(options: {
22
23
  ctxStorage: ContextsEndpointStorage;
23
24
  }): Promise<void>;
24
- uploadFormDataToServer(formData: FormData): Models.Http.Response<MulterFileUploadResponse[]>;
25
+ uploadFormDataToServer(formData: FormData, queryParams?: UPLOAD_FILE_QUERY_PARAMS): Models.Http.Response<MulterFileUploadResponse[]>;
25
26
  /**
26
27
  * Hook after file is uploaded
27
28
  * through `uploadFormDataToServer` or `uploadLocalFileToServer`
28
29
  */
29
- protected afterFileUploadAction(file: MulterFileUploadResponse): void | Promise<void>;
30
- uploadLocalFileToServer(absFilePath: string, options?: Pick<Models.Http.Rest.Ng2RestAxiosRequestConfig, 'onUploadProgress'>): Promise<MulterFileUploadResponse[]>;
31
- }
30
+ protected afterFileUploadAction(file?: MulterFileUploadResponse, queryParams?: UPLOAD_FILE_QUERY_PARAMS): void | Promise<void>;
31
+ uploadLocalFileToServer(absFilePath: string, options?: Pick<Models.Http.Rest.Ng2RestAxiosRequestConfig, 'onUploadProgress'>, queryParams?: UPLOAD_FILE_QUERY_PARAMS): Promise<MulterFileUploadResponse[]>;
32
+ /**
33
+ * Easy way to wait for status change with http (1s default) pooling.
34
+ *
35
+ * example (in sub class):
36
+ * ```ts
37
+ async check() {
38
+ await this.waitForProperStatusChange({
39
+ request: () => this.uploadFormDataToServer(void 0, void 0).request(),
40
+ statusCheck: resp => resp.body.json[0].ok,
41
+ });
42
+ }
43
+ * ```
44
+ */
45
+ _waitForProperStatusChange<T>(options: {
46
+ actionName: string;
47
+ /**
48
+ * Request for pooling
49
+ */
50
+ request: (opt?: {
51
+ /**
52
+ * optional index number to identify request in logs
53
+ * (starts from 0 and increments by 1 on each try)
54
+ */
55
+ reqIndexNum?: number;
56
+ httpErrorsCount?: number;
57
+ }) => ReturnType<Models.Http.Response<T>['request']>;
58
+ poolingInterval?: number;
59
+ /**
60
+ * default infinite tries
61
+ */
62
+ maxTries?: number;
63
+ /**
64
+ * default infiniti allowed http errors
65
+ */
66
+ allowedHttpErrors?: number;
67
+ /**
68
+ * condition to be met
69
+ */
70
+ statusCheck?: (response: Awaited<ReturnType<typeof options.request>>) => boolean;
71
+ /**
72
+ * if return true.. loop will continue
73
+ * if false .. will exit the loop
74
+ */
75
+ loopRequestsOnBackendError?: (opt: {
76
+ unknownError: Error;
77
+ unknownHttpError: HttpResponseError<any>;
78
+ taonError: HttpResponseError<RestErrorResponseWrapper>;
79
+ reqIndexNum?: number;
80
+ httpErrorsCount?: number;
81
+ }) => boolean | Promise<boolean>;
82
+ }): Promise<void>;
83
+ }