@decaf-ts/for-typeorm 0.0.6

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 (109) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +93 -0
  3. package/dist/for-typeorm.cjs +2553 -0
  4. package/dist/for-typeorm.esm.cjs +2538 -0
  5. package/lib/TypeORMAdapter.cjs +1129 -0
  6. package/lib/TypeORMAdapter.d.ts +221 -0
  7. package/lib/TypeORMDispatch.cjs +134 -0
  8. package/lib/TypeORMDispatch.d.ts +87 -0
  9. package/lib/TypeORMEventSubscriber.cjs +96 -0
  10. package/lib/TypeORMEventSubscriber.d.ts +56 -0
  11. package/lib/TypeORMRepository.cjs +209 -0
  12. package/lib/TypeORMRepository.d.ts +125 -0
  13. package/lib/constants.cjs +43 -0
  14. package/lib/constants.d.ts +39 -0
  15. package/lib/errors.cjs +28 -0
  16. package/lib/errors.d.ts +21 -0
  17. package/lib/esm/TypeORMAdapter.d.ts +221 -0
  18. package/lib/esm/TypeORMAdapter.js +1124 -0
  19. package/lib/esm/TypeORMDispatch.d.ts +87 -0
  20. package/lib/esm/TypeORMDispatch.js +130 -0
  21. package/lib/esm/TypeORMEventSubscriber.d.ts +56 -0
  22. package/lib/esm/TypeORMEventSubscriber.js +93 -0
  23. package/lib/esm/TypeORMRepository.d.ts +125 -0
  24. package/lib/esm/TypeORMRepository.js +206 -0
  25. package/lib/esm/constants.d.ts +39 -0
  26. package/lib/esm/constants.js +40 -0
  27. package/lib/esm/errors.d.ts +21 -0
  28. package/lib/esm/errors.js +24 -0
  29. package/lib/esm/index.d.ts +22 -0
  30. package/lib/esm/index.js +25 -0
  31. package/lib/esm/indexes/generator.d.ts +50 -0
  32. package/lib/esm/indexes/generator.js +95 -0
  33. package/lib/esm/indexes/index.d.ts +1 -0
  34. package/lib/esm/indexes/index.js +2 -0
  35. package/lib/esm/overrides/Column.d.ts +74 -0
  36. package/lib/esm/overrides/Column.js +70 -0
  37. package/lib/esm/overrides/CreateDateColumn.d.ts +2 -0
  38. package/lib/esm/overrides/CreateDateColumn.js +9 -0
  39. package/lib/esm/overrides/Entity.d.ts +11 -0
  40. package/lib/esm/overrides/Entity.js +28 -0
  41. package/lib/esm/overrides/PrimaryColumn.d.ts +20 -0
  42. package/lib/esm/overrides/PrimaryColumn.js +53 -0
  43. package/lib/esm/overrides/PrimaryGeneratedColumn.d.ts +24 -0
  44. package/lib/esm/overrides/PrimaryGeneratedColumn.js +51 -0
  45. package/lib/esm/overrides/UpdateDateColumn.d.ts +2 -0
  46. package/lib/esm/overrides/UpdateDateColumn.js +9 -0
  47. package/lib/esm/overrides/utils.d.ts +2 -0
  48. package/lib/esm/overrides/utils.js +29 -0
  49. package/lib/esm/query/Paginator.d.ts +86 -0
  50. package/lib/esm/query/Paginator.js +124 -0
  51. package/lib/esm/query/Statement.d.ts +131 -0
  52. package/lib/esm/query/Statement.js +242 -0
  53. package/lib/esm/query/constants.d.ts +52 -0
  54. package/lib/esm/query/constants.js +74 -0
  55. package/lib/esm/query/index.d.ts +4 -0
  56. package/lib/esm/query/index.js +5 -0
  57. package/lib/esm/query/translate.d.ts +34 -0
  58. package/lib/esm/query/translate.js +42 -0
  59. package/lib/esm/raw/postgres.d.ts +36 -0
  60. package/lib/esm/raw/postgres.js +2 -0
  61. package/lib/esm/sequences/Sequence.d.ts +67 -0
  62. package/lib/esm/sequences/Sequence.js +117 -0
  63. package/lib/esm/sequences/index.d.ts +1 -0
  64. package/lib/esm/sequences/index.js +2 -0
  65. package/lib/esm/types.d.ts +67 -0
  66. package/lib/esm/types.js +28 -0
  67. package/lib/esm/utils.d.ts +16 -0
  68. package/lib/esm/utils.js +29 -0
  69. package/lib/index.cjs +42 -0
  70. package/lib/index.d.ts +22 -0
  71. package/lib/indexes/generator.cjs +98 -0
  72. package/lib/indexes/generator.d.ts +50 -0
  73. package/lib/indexes/index.cjs +18 -0
  74. package/lib/indexes/index.d.ts +1 -0
  75. package/lib/overrides/Column.cjs +73 -0
  76. package/lib/overrides/Column.d.ts +74 -0
  77. package/lib/overrides/CreateDateColumn.cjs +12 -0
  78. package/lib/overrides/CreateDateColumn.d.ts +2 -0
  79. package/lib/overrides/Entity.cjs +31 -0
  80. package/lib/overrides/Entity.d.ts +11 -0
  81. package/lib/overrides/PrimaryColumn.cjs +56 -0
  82. package/lib/overrides/PrimaryColumn.d.ts +20 -0
  83. package/lib/overrides/PrimaryGeneratedColumn.cjs +54 -0
  84. package/lib/overrides/PrimaryGeneratedColumn.d.ts +24 -0
  85. package/lib/overrides/UpdateDateColumn.cjs +12 -0
  86. package/lib/overrides/UpdateDateColumn.d.ts +2 -0
  87. package/lib/overrides/utils.cjs +32 -0
  88. package/lib/overrides/utils.d.ts +2 -0
  89. package/lib/query/Paginator.cjs +128 -0
  90. package/lib/query/Paginator.d.ts +86 -0
  91. package/lib/query/Statement.cjs +246 -0
  92. package/lib/query/Statement.d.ts +131 -0
  93. package/lib/query/constants.cjs +77 -0
  94. package/lib/query/constants.d.ts +52 -0
  95. package/lib/query/index.cjs +21 -0
  96. package/lib/query/index.d.ts +4 -0
  97. package/lib/query/translate.cjs +45 -0
  98. package/lib/query/translate.d.ts +34 -0
  99. package/lib/raw/postgres.cjs +3 -0
  100. package/lib/raw/postgres.d.ts +36 -0
  101. package/lib/sequences/Sequence.cjs +121 -0
  102. package/lib/sequences/Sequence.d.ts +67 -0
  103. package/lib/sequences/index.cjs +18 -0
  104. package/lib/sequences/index.d.ts +1 -0
  105. package/lib/types.cjs +31 -0
  106. package/lib/types.d.ts +67 -0
  107. package/lib/utils.cjs +32 -0
  108. package/lib/utils.d.ts +16 -0
  109. package/package.json +128 -0
@@ -0,0 +1,24 @@
1
+ import { PrimaryGeneratedColumnNumericOptions } from "typeorm/decorator/options/PrimaryGeneratedColumnNumericOptions";
2
+ import { PrimaryGeneratedColumnUUIDOptions } from "typeorm/decorator/options/PrimaryGeneratedColumnUUIDOptions";
3
+ import { PrimaryGeneratedColumnIdentityOptions } from "typeorm/decorator/options/PrimaryGeneratedColumnIdentityOptions";
4
+ /**
5
+ * Column decorator is used to mark a specific class property as a table column.
6
+ */
7
+ export declare function PrimaryGeneratedColumn(): PropertyDecorator;
8
+ /**
9
+ * Column decorator is used to mark a specific class property as a table column.
10
+ */
11
+ export declare function PrimaryGeneratedColumn(options: PrimaryGeneratedColumnNumericOptions): PropertyDecorator;
12
+ /**
13
+ * Column decorator is used to mark a specific class property as a table column.
14
+ */
15
+ export declare function PrimaryGeneratedColumn(strategy: "increment", options?: PrimaryGeneratedColumnNumericOptions): PropertyDecorator;
16
+ /**
17
+ * Column decorator is used to mark a specific class property as a table column.
18
+ */
19
+ export declare function PrimaryGeneratedColumn(strategy: "uuid", options?: PrimaryGeneratedColumnUUIDOptions): PropertyDecorator;
20
+ /**
21
+ * Column decorator is used to mark a specific class property as a table column.
22
+ */
23
+ export declare function PrimaryGeneratedColumn(strategy: "rowid", options?: PrimaryGeneratedColumnUUIDOptions): PropertyDecorator;
24
+ export declare function PrimaryGeneratedColumn(strategy: "identity", options?: PrimaryGeneratedColumnIdentityOptions): PropertyDecorator;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateDateColumn = UpdateDateColumn;
4
+ const typeorm_1 = require("typeorm");
5
+ const utils_1 = require("./utils.cjs");
6
+ function UpdateDateColumn(options) {
7
+ return function (object, propertyName) {
8
+ const columns = (0, typeorm_1.getMetadataArgsStorage)().columns;
9
+ (0, utils_1.aggregateOrNewColumn)(object.constructor, propertyName, columns, options || {}, "updateDate");
10
+ };
11
+ }
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXBkYXRlRGF0ZUNvbHVtbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vdmVycmlkZXMvVXBkYXRlRGF0ZUNvbHVtbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdBLDRDQVdDO0FBZEQscUNBQWdFO0FBQ2hFLHVDQUErQztBQUUvQyxTQUFnQixnQkFBZ0IsQ0FBQyxPQUF1QjtJQUN0RCxPQUFPLFVBQVUsTUFBVyxFQUFFLFlBQWlCO1FBQzdDLE1BQU0sT0FBTyxHQUFHLElBQUEsZ0NBQXNCLEdBQUUsQ0FBQyxPQUFPLENBQUM7UUFDakQsSUFBQSw0QkFBb0IsRUFDbEIsTUFBTSxDQUFDLFdBQVcsRUFDbEIsWUFBWSxFQUNaLE9BQU8sRUFDUCxPQUFPLElBQUksRUFBRSxFQUNiLFlBQVksQ0FDYixDQUFDO0lBQ0osQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbHVtbk9wdGlvbnMsIGdldE1ldGFkYXRhQXJnc1N0b3JhZ2UgfSBmcm9tIFwidHlwZW9ybVwiO1xuaW1wb3J0IHsgYWdncmVnYXRlT3JOZXdDb2x1bW4gfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gVXBkYXRlRGF0ZUNvbHVtbihvcHRpb25zPzogQ29sdW1uT3B0aW9ucyk6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3Q6IGFueSwgcHJvcGVydHlOYW1lOiBhbnkpIHtcbiAgICBjb25zdCBjb2x1bW5zID0gZ2V0TWV0YWRhdGFBcmdzU3RvcmFnZSgpLmNvbHVtbnM7XG4gICAgYWdncmVnYXRlT3JOZXdDb2x1bW4oXG4gICAgICBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBwcm9wZXJ0eU5hbWUsXG4gICAgICBjb2x1bW5zLFxuICAgICAgb3B0aW9ucyB8fCB7fSxcbiAgICAgIFwidXBkYXRlRGF0ZVwiXG4gICAgKTtcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ import { ColumnOptions } from "typeorm";
2
+ export declare function UpdateDateColumn(options?: ColumnOptions): PropertyDecorator;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aggregateOrNewColumn = aggregateOrNewColumn;
4
+ function aggregateOrNewColumn(target, property, columns, options = {}, mode = "regular") {
5
+ const cols = columns.filter((c) => c.target === target && c.propertyName === property);
6
+ if (cols.length > 1)
7
+ throw new Error(`Multiple columns for ${property} found for given target: ${columns.map((c) => c.propertyName).join(", ")}`);
8
+ if (cols.length === 0) {
9
+ columns.push({
10
+ target: target,
11
+ propertyName: property,
12
+ mode: mode,
13
+ options: options,
14
+ });
15
+ return;
16
+ }
17
+ const column = cols[0];
18
+ Object.defineProperty(column, "options", {
19
+ value: { ...column.options, ...options },
20
+ writable: true,
21
+ enumerable: true,
22
+ configurable: true,
23
+ });
24
+ if (mode !== "regular")
25
+ Object.defineProperty(column, "mode", {
26
+ value: mode,
27
+ writable: true,
28
+ enumerable: true,
29
+ configurable: true,
30
+ });
31
+ }
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3ZlcnJpZGVzL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsb0RBMENDO0FBMUNELFNBQWdCLG9CQUFvQixDQUNsQyxNQUFXLEVBQ1gsUUFBZ0IsRUFDaEIsT0FBNkIsRUFDN0IsVUFBZSxFQUFFLEVBQ2pCLE9BQWUsU0FBUztJQUV4QixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUN6QixDQUFDLENBQXFCLEVBQUUsRUFBRSxDQUN4QixDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsWUFBWSxLQUFLLFFBQVEsQ0FDckQsQ0FBQztJQUVGLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQ2Isd0JBQXdCLFFBQVEsNEJBQTRCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDNUcsQ0FBQztJQUVKLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ1gsTUFBTSxFQUFFLE1BQU07WUFDZCxZQUFZLEVBQUUsUUFBUTtZQUN0QixJQUFJLEVBQUUsSUFBSTtZQUNWLE9BQU8sRUFBRSxPQUFPO1NBQ0ssQ0FBQyxDQUFDO1FBQ3pCLE9BQU87SUFDVCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZCLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRTtRQUN2QyxLQUFLLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUU7UUFDeEMsUUFBUSxFQUFFLElBQUk7UUFDZCxVQUFVLEVBQUUsSUFBSTtRQUNoQixZQUFZLEVBQUUsSUFBSTtLQUNuQixDQUFDLENBQUM7SUFFSCxJQUFJLElBQUksS0FBSyxTQUFTO1FBQ3BCLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRTtZQUNwQyxLQUFLLEVBQUUsSUFBSTtZQUNYLFFBQVEsRUFBRSxJQUFJO1lBQ2QsVUFBVSxFQUFFLElBQUk7WUFDaEIsWUFBWSxFQUFFLElBQUk7U0FDbkIsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbHVtbk1ldGFkYXRhQXJncyB9IGZyb20gXCJ0eXBlb3JtL21ldGFkYXRhLWFyZ3MvQ29sdW1uTWV0YWRhdGFBcmdzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhZ2dyZWdhdGVPck5ld0NvbHVtbihcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5OiBzdHJpbmcsXG4gIGNvbHVtbnM6IENvbHVtbk1ldGFkYXRhQXJnc1tdLFxuICBvcHRpb25zOiBhbnkgPSB7fSxcbiAgbW9kZTogc3RyaW5nID0gXCJyZWd1bGFyXCJcbikge1xuICBjb25zdCBjb2xzID0gY29sdW1ucy5maWx0ZXIoXG4gICAgKGM6IENvbHVtbk1ldGFkYXRhQXJncykgPT5cbiAgICAgIGMudGFyZ2V0ID09PSB0YXJnZXQgJiYgYy5wcm9wZXJ0eU5hbWUgPT09IHByb3BlcnR5XG4gICk7XG5cbiAgaWYgKGNvbHMubGVuZ3RoID4gMSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTXVsdGlwbGUgY29sdW1ucyBmb3IgJHtwcm9wZXJ0eX0gZm91bmQgZm9yIGdpdmVuIHRhcmdldDogJHtjb2x1bW5zLm1hcCgoYykgPT4gYy5wcm9wZXJ0eU5hbWUpLmpvaW4oXCIsIFwiKX1gXG4gICAgKTtcblxuICBpZiAoY29scy5sZW5ndGggPT09IDApIHtcbiAgICBjb2x1bW5zLnB1c2goe1xuICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICBwcm9wZXJ0eU5hbWU6IHByb3BlcnR5LFxuICAgICAgbW9kZTogbW9kZSxcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgfSBhcyBDb2x1bW5NZXRhZGF0YUFyZ3MpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNvbHVtbiA9IGNvbHNbMF07XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb2x1bW4sIFwib3B0aW9uc1wiLCB7XG4gICAgdmFsdWU6IHsgLi4uY29sdW1uLm9wdGlvbnMsIC4uLm9wdGlvbnMgfSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgfSk7XG5cbiAgaWYgKG1vZGUgIT09IFwicmVndWxhclwiKVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb2x1bW4sIFwibW9kZVwiLCB7XG4gICAgICB2YWx1ZTogbW9kZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB9KTtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ import { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
2
+ export declare function aggregateOrNewColumn(target: any, property: string, columns: ColumnMetadataArgs[], options?: any, mode?: string): void;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TypeORMPaginator = void 0;
4
+ const core_1 = require("@decaf-ts/core");
5
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
6
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
7
+ /**
8
+ * @description Paginator for TypeORM query results.
9
+ * @summary Implements pagination for TypeORM-built queries using take/skip for efficient navigation through result sets.
10
+ * @template M The model type that extends Model.
11
+ * @template R The result type.
12
+ * @param {TypeORMAdapter} adapter The TypeORM adapter.
13
+ * @param {TypeORMQuery} query The query container to paginate.
14
+ * @param {number} size The page size.
15
+ * @param {Constructor<M>} clazz The model constructor.
16
+ * @class TypeORMPaginator
17
+ * @example
18
+ * // Example of using TypeORMPaginator
19
+ * const paginator = new TypeORMPaginator(adapter, { query: qb }, 10, User);
20
+ * const page1 = await paginator.page(1);
21
+ * const page2 = await paginator.page(2);
22
+ */
23
+ class TypeORMPaginator extends core_1.Paginator {
24
+ /**
25
+ * @description Gets the total number of pages
26
+ * @summary Returns the total number of pages based on the record count and page size
27
+ * @return {number} The total number of pages
28
+ */
29
+ get total() {
30
+ return this._totalPages;
31
+ }
32
+ /**
33
+ * @description Gets the total record count
34
+ * @summary Returns the total number of records matching the query
35
+ * @return {number} The total record count
36
+ */
37
+ get count() {
38
+ return this._recordCount;
39
+ }
40
+ get repo() {
41
+ if (!this.__repo) {
42
+ this.__repo = this.adapter.dataSource.getRepository(this.clazz[decorator_validation_1.ModelKeys.ANCHOR]);
43
+ }
44
+ return this.__repo;
45
+ }
46
+ /**
47
+ * @description Creates a new TypeORMPaginator instance.
48
+ * @summary Initializes a paginator for TypeORM query results.
49
+ * @param {TypeORMAdapter} adapter The TypeORM adapter.
50
+ * @param {TypeORMQuery} query The TypeORM query container to paginate.
51
+ * @param {number} size The page size.
52
+ * @param {Constructor<M>} clazz The model constructor.
53
+ */
54
+ constructor(adapter, query, size, clazz) {
55
+ super(adapter, query, size, clazz);
56
+ }
57
+ /**
58
+ * @description Prepares a query for pagination
59
+ * @summary Modifies the raw query to include pagination parameters
60
+ * @param {TypeORMQuery} rawStatement - The original PostgreSQL query
61
+ * @return {TypeORMQuery} The prepared query with pagination parameters
62
+ */
63
+ prepare(rawStatement) {
64
+ const query = { ...rawStatement };
65
+ return query;
66
+ }
67
+ /**
68
+ * @description Retrieves a specific page of results.
69
+ * @summary Executes the query with pagination and processes the results.
70
+ * @param {number} [page=1] The page number to retrieve.
71
+ * @return {Promise<R[]>} A promise that resolves to an array of results.
72
+ * @throws {PagingError} If trying to access an invalid page or if no class is defined.
73
+ * @mermaid
74
+ * sequenceDiagram
75
+ * participant Client
76
+ * participant Paginator as TypeORMPaginator
77
+ * participant Adapter
78
+ * participant DB as Database
79
+ *
80
+ * Client->>Paginator: page(pageNumber)
81
+ * Note over Paginator: Prepare options (skip/take)
82
+ *
83
+ * alt First time or need count
84
+ * Paginator->>Adapter: Get count
85
+ * Adapter->>DB: Execute COUNT
86
+ * DB-->>Adapter: count
87
+ * Adapter-->>Paginator: count
88
+ * Paginator->>Paginator: Calculate total pages
89
+ * end
90
+ *
91
+ * Paginator->>Adapter: Execute query
92
+ * Adapter->>DB: findAndCount(options)
93
+ * DB-->>Adapter: rows, count
94
+ * Adapter-->>Paginator: rows, count
95
+ *
96
+ * Paginator->>Paginator: Map rows to models
97
+ * Paginator-->>Client: results
98
+ */
99
+ async page(page = 1) {
100
+ const statement = { ...this.statement };
101
+ // Get total count if not already calculated
102
+ if (!this._recordCount || !this._totalPages) {
103
+ this._totalPages = this._recordCount = 0;
104
+ }
105
+ const opts = Object.assign(statement, {
106
+ skip: (this.current || 0) * this.size,
107
+ take: this.size,
108
+ });
109
+ // this.validatePage(page);
110
+ const result = await this.repo.findAndCount(opts);
111
+ this._recordCount = result[1];
112
+ this._totalPages = Math.ceil(this._recordCount / this.size);
113
+ if (!this.clazz)
114
+ throw new core_1.PagingError("No statement target defined");
115
+ const pkDef = (0, db_decorators_1.findPrimaryKey)(new this.clazz());
116
+ const rows = result[0] || [];
117
+ const results =
118
+ // statement.columns && statement.columns.length
119
+ // ? rows // has columns means it's not full model
120
+ rows.map((row) => {
121
+ return this.adapter.revert(row, this.clazz, pkDef.id, row[pkDef.id]);
122
+ });
123
+ this._currentPage = page;
124
+ return results;
125
+ }
126
+ }
127
+ exports.TypeORMPaginator = TypeORMPaginator;
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFnaW5hdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3F1ZXJ5L1BhZ2luYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBd0Q7QUFFeEQseUVBQStFO0FBRy9FLDJEQUF5RDtBQUV6RDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFhLGdCQUFxQyxTQUFRLGdCQUl6RDtJQUNDOzs7O09BSUc7SUFDSCxJQUFhLEtBQUs7UUFDaEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBYSxLQUFLO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBSUQsSUFBYyxJQUFJO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBSSxJQUFJLENBQUMsT0FBMEIsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUNyRSxJQUFJLENBQUMsS0FBSyxDQUFDLGdDQUFTLENBQUMsTUFBaUMsQ0FBQyxDQUN4RCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFlBQ0UsT0FBdUIsRUFDdkIsS0FBbUIsRUFDbkIsSUFBWSxFQUNaLEtBQXFCO1FBRXJCLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxPQUFPLENBQUMsWUFBMEI7UUFDMUMsTUFBTSxLQUFLLEdBQWlCLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztRQUNoRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQStCRztJQUVILEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBZSxDQUFDO1FBQ3pCLE1BQU0sU0FBUyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFeEMsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUF1QixNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtZQUN4RCxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJO1lBQ3JDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtTQUNoQixDQUFDLENBQUM7UUFFSCwyQkFBMkI7UUFFM0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLGtCQUFXLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUV0RSxNQUFNLEtBQUssR0FBRyxJQUFBLDhCQUFjLEVBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMvQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRTdCLE1BQU0sT0FBTztRQUNYLGdEQUFnRDtRQUNoRCxvREFBb0Q7UUFDcEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO1lBQ3BCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixPQUFPLE9BQXlCLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBbElELDRDQWtJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhZ2luYXRvciwgUGFnaW5nRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IFR5cGVPUk1RdWVyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsLCBNb2RlbEtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBUeXBlT1JNQWRhcHRlciB9IGZyb20gXCIuLi9UeXBlT1JNQWRhcHRlclwiO1xuaW1wb3J0IHsgRmluZE1hbnlPcHRpb25zLCBSZXBvc2l0b3J5IGFzIFJlcG8gfSBmcm9tIFwidHlwZW9ybVwiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXkgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGFnaW5hdG9yIGZvciBUeXBlT1JNIHF1ZXJ5IHJlc3VsdHMuXG4gKiBAc3VtbWFyeSBJbXBsZW1lbnRzIHBhZ2luYXRpb24gZm9yIFR5cGVPUk0tYnVpbHQgcXVlcmllcyB1c2luZyB0YWtlL3NraXAgZm9yIGVmZmljaWVudCBuYXZpZ2F0aW9uIHRocm91Z2ggcmVzdWx0IHNldHMuXG4gKiBAdGVtcGxhdGUgTSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWwuXG4gKiBAdGVtcGxhdGUgUiBUaGUgcmVzdWx0IHR5cGUuXG4gKiBAcGFyYW0ge1R5cGVPUk1BZGFwdGVyfSBhZGFwdGVyIFRoZSBUeXBlT1JNIGFkYXB0ZXIuXG4gKiBAcGFyYW0ge1R5cGVPUk1RdWVyeX0gcXVlcnkgVGhlIHF1ZXJ5IGNvbnRhaW5lciB0byBwYWdpbmF0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFRoZSBwYWdlIHNpemUuXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiBUaGUgbW9kZWwgY29uc3RydWN0b3IuXG4gKiBAY2xhc3MgVHlwZU9STVBhZ2luYXRvclxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgb2YgdXNpbmcgVHlwZU9STVBhZ2luYXRvclxuICogY29uc3QgcGFnaW5hdG9yID0gbmV3IFR5cGVPUk1QYWdpbmF0b3IoYWRhcHRlciwgeyBxdWVyeTogcWIgfSwgMTAsIFVzZXIpO1xuICogY29uc3QgcGFnZTEgPSBhd2FpdCBwYWdpbmF0b3IucGFnZSgxKTtcbiAqIGNvbnN0IHBhZ2UyID0gYXdhaXQgcGFnaW5hdG9yLnBhZ2UoMik7XG4gKi9cbmV4cG9ydCBjbGFzcyBUeXBlT1JNUGFnaW5hdG9yPE0gZXh0ZW5kcyBNb2RlbCwgUj4gZXh0ZW5kcyBQYWdpbmF0b3I8XG4gIE0sXG4gIFIsXG4gIFR5cGVPUk1RdWVyeVxuPiB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBwYWdlcyBiYXNlZCBvbiB0aGUgcmVjb3JkIGNvdW50IGFuZCBwYWdlIHNpemVcbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzXG4gICAqL1xuICBvdmVycmlkZSBnZXQgdG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdG90YWxQYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgdG90YWwgcmVjb3JkIGNvdW50XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiByZWNvcmRzIG1hdGNoaW5nIHRoZSBxdWVyeVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB0b3RhbCByZWNvcmQgY291bnRcbiAgICovXG4gIG92ZXJyaWRlIGdldCBjb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9yZWNvcmRDb3VudDtcbiAgfVxuXG4gIHByaXZhdGUgX19yZXBvPzogUmVwbzxhbnk+O1xuXG4gIHByb3RlY3RlZCBnZXQgcmVwbygpIHtcbiAgICBpZiAoIXRoaXMuX19yZXBvKSB7XG4gICAgICB0aGlzLl9fcmVwbyA9ICh0aGlzLmFkYXB0ZXIgYXMgVHlwZU9STUFkYXB0ZXIpLmRhdGFTb3VyY2UuZ2V0UmVwb3NpdG9yeShcbiAgICAgICAgdGhpcy5jbGF6eltNb2RlbEtleXMuQU5DSE9SIGFzIGtleW9mIHR5cGVvZiB0aGlzLmNsYXp6XVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX19yZXBvO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IFR5cGVPUk1QYWdpbmF0b3IgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIGEgcGFnaW5hdG9yIGZvciBUeXBlT1JNIHF1ZXJ5IHJlc3VsdHMuXG4gICAqIEBwYXJhbSB7VHlwZU9STUFkYXB0ZXJ9IGFkYXB0ZXIgVGhlIFR5cGVPUk0gYWRhcHRlci5cbiAgICogQHBhcmFtIHtUeXBlT1JNUXVlcnl9IHF1ZXJ5IFRoZSBUeXBlT1JNIHF1ZXJ5IGNvbnRhaW5lciB0byBwYWdpbmF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgVGhlIHBhZ2Ugc2l6ZS5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gY2xhenogVGhlIG1vZGVsIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgYWRhcHRlcjogVHlwZU9STUFkYXB0ZXIsXG4gICAgcXVlcnk6IFR5cGVPUk1RdWVyeSxcbiAgICBzaXplOiBudW1iZXIsXG4gICAgY2xheno6IENvbnN0cnVjdG9yPE0+XG4gICkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIHF1ZXJ5LCBzaXplLCBjbGF6eik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGEgcXVlcnkgZm9yIHBhZ2luYXRpb25cbiAgICogQHN1bW1hcnkgTW9kaWZpZXMgdGhlIHJhdyBxdWVyeSB0byBpbmNsdWRlIHBhZ2luYXRpb24gcGFyYW1ldGVyc1xuICAgKiBAcGFyYW0ge1R5cGVPUk1RdWVyeX0gcmF3U3RhdGVtZW50IC0gVGhlIG9yaWdpbmFsIFBvc3RncmVTUUwgcXVlcnlcbiAgICogQHJldHVybiB7VHlwZU9STVF1ZXJ5fSBUaGUgcHJlcGFyZWQgcXVlcnkgd2l0aCBwYWdpbmF0aW9uIHBhcmFtZXRlcnNcbiAgICovXG4gIHByb3RlY3RlZCBwcmVwYXJlKHJhd1N0YXRlbWVudDogVHlwZU9STVF1ZXJ5KTogVHlwZU9STVF1ZXJ5IHtcbiAgICBjb25zdCBxdWVyeTogVHlwZU9STVF1ZXJ5ID0geyAuLi5yYXdTdGF0ZW1lbnQgfTtcbiAgICByZXR1cm4gcXVlcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHNwZWNpZmljIHBhZ2Ugb2YgcmVzdWx0cy5cbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMgdGhlIHF1ZXJ5IHdpdGggcGFnaW5hdGlvbiBhbmQgcHJvY2Vzc2VzIHRoZSByZXN1bHRzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW3BhZ2U9MV0gVGhlIHBhZ2UgbnVtYmVyIHRvIHJldHJpZXZlLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJbXT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIHJlc3VsdHMuXG4gICAqIEB0aHJvd3Mge1BhZ2luZ0Vycm9yfSBJZiB0cnlpbmcgdG8gYWNjZXNzIGFuIGludmFsaWQgcGFnZSBvciBpZiBubyBjbGFzcyBpcyBkZWZpbmVkLlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQYWdpbmF0b3IgYXMgVHlwZU9STVBhZ2luYXRvclxuICAgKiAgIHBhcnRpY2lwYW50IEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBEQiBhcyBEYXRhYmFzZVxuICAgKlxuICAgKiAgIENsaWVudC0+PlBhZ2luYXRvcjogcGFnZShwYWdlTnVtYmVyKVxuICAgKiAgIE5vdGUgb3ZlciBQYWdpbmF0b3I6IFByZXBhcmUgb3B0aW9ucyAoc2tpcC90YWtlKVxuICAgKlxuICAgKiAgIGFsdCBGaXJzdCB0aW1lIG9yIG5lZWQgY291bnRcbiAgICogICAgIFBhZ2luYXRvci0+PkFkYXB0ZXI6IEdldCBjb3VudFxuICAgKiAgICAgQWRhcHRlci0+PkRCOiBFeGVjdXRlIENPVU5UXG4gICAqICAgICBEQi0tPj5BZGFwdGVyOiBjb3VudFxuICAgKiAgICAgQWRhcHRlci0tPj5QYWdpbmF0b3I6IGNvdW50XG4gICAqICAgICBQYWdpbmF0b3ItPj5QYWdpbmF0b3I6IENhbGN1bGF0ZSB0b3RhbCBwYWdlc1xuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIFBhZ2luYXRvci0+PkFkYXB0ZXI6IEV4ZWN1dGUgcXVlcnlcbiAgICogICBBZGFwdGVyLT4+REI6IGZpbmRBbmRDb3VudChvcHRpb25zKVxuICAgKiAgIERCLS0+PkFkYXB0ZXI6IHJvd3MsIGNvdW50XG4gICAqICAgQWRhcHRlci0tPj5QYWdpbmF0b3I6IHJvd3MsIGNvdW50XG4gICAqXG4gICAqICAgUGFnaW5hdG9yLT4+UGFnaW5hdG9yOiBNYXAgcm93cyB0byBtb2RlbHNcbiAgICogICBQYWdpbmF0b3ItLT4+Q2xpZW50OiByZXN1bHRzXG4gICAqL1xuXG4gIGFzeW5jIHBhZ2UocGFnZTogbnVtYmVyID0gMSk6IFByb21pc2U8UltdPiB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0geyAuLi50aGlzLnN0YXRlbWVudCB9O1xuXG4gICAgLy8gR2V0IHRvdGFsIGNvdW50IGlmIG5vdCBhbHJlYWR5IGNhbGN1bGF0ZWRcbiAgICBpZiAoIXRoaXMuX3JlY29yZENvdW50IHx8ICF0aGlzLl90b3RhbFBhZ2VzKSB7XG4gICAgICB0aGlzLl90b3RhbFBhZ2VzID0gdGhpcy5fcmVjb3JkQ291bnQgPSAwO1xuICAgIH1cblxuICAgIGNvbnN0IG9wdHM6IEZpbmRNYW55T3B0aW9uczxNPiA9IE9iamVjdC5hc3NpZ24oc3RhdGVtZW50LCB7XG4gICAgICBza2lwOiAodGhpcy5jdXJyZW50IHx8IDApICogdGhpcy5zaXplLFxuICAgICAgdGFrZTogdGhpcy5zaXplLFxuICAgIH0pO1xuXG4gICAgLy8gdGhpcy52YWxpZGF0ZVBhZ2UocGFnZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJlcG8uZmluZEFuZENvdW50KG9wdHMpO1xuXG4gICAgdGhpcy5fcmVjb3JkQ291bnQgPSByZXN1bHRbMV07XG4gICAgdGhpcy5fdG90YWxQYWdlcyA9IE1hdGguY2VpbCh0aGlzLl9yZWNvcmRDb3VudCAvIHRoaXMuc2l6ZSk7XG5cbiAgICBpZiAoIXRoaXMuY2xhenopIHRocm93IG5ldyBQYWdpbmdFcnJvcihcIk5vIHN0YXRlbWVudCB0YXJnZXQgZGVmaW5lZFwiKTtcblxuICAgIGNvbnN0IHBrRGVmID0gZmluZFByaW1hcnlLZXkobmV3IHRoaXMuY2xhenooKSk7XG4gICAgY29uc3Qgcm93cyA9IHJlc3VsdFswXSB8fCBbXTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPVxuICAgICAgLy8gc3RhdGVtZW50LmNvbHVtbnMgJiYgc3RhdGVtZW50LmNvbHVtbnMubGVuZ3RoXG4gICAgICAvLyAgID8gcm93cyAvLyBoYXMgY29sdW1ucyBtZWFucyBpdCdzIG5vdCBmdWxsIG1vZGVsXG4gICAgICByb3dzLm1hcCgocm93OiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQocm93LCB0aGlzLmNsYXp6LCBwa0RlZi5pZCwgcm93W3BrRGVmLmlkXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMuX2N1cnJlbnRQYWdlID0gcGFnZTtcbiAgICByZXR1cm4gcmVzdWx0cyBhcyB1bmtub3duIGFzIFJbXTtcbiAgfVxufVxuIl19
@@ -0,0 +1,86 @@
1
+ import { Paginator } from "@decaf-ts/core";
2
+ import { TypeORMQuery } from "../types";
3
+ import { Constructor, Model } from "@decaf-ts/decorator-validation";
4
+ import { TypeORMAdapter } from "../TypeORMAdapter";
5
+ import { Repository as Repo } from "typeorm";
6
+ /**
7
+ * @description Paginator for TypeORM query results.
8
+ * @summary Implements pagination for TypeORM-built queries using take/skip for efficient navigation through result sets.
9
+ * @template M The model type that extends Model.
10
+ * @template R The result type.
11
+ * @param {TypeORMAdapter} adapter The TypeORM adapter.
12
+ * @param {TypeORMQuery} query The query container to paginate.
13
+ * @param {number} size The page size.
14
+ * @param {Constructor<M>} clazz The model constructor.
15
+ * @class TypeORMPaginator
16
+ * @example
17
+ * // Example of using TypeORMPaginator
18
+ * const paginator = new TypeORMPaginator(adapter, { query: qb }, 10, User);
19
+ * const page1 = await paginator.page(1);
20
+ * const page2 = await paginator.page(2);
21
+ */
22
+ export declare class TypeORMPaginator<M extends Model, R> extends Paginator<M, R, TypeORMQuery> {
23
+ /**
24
+ * @description Gets the total number of pages
25
+ * @summary Returns the total number of pages based on the record count and page size
26
+ * @return {number} The total number of pages
27
+ */
28
+ get total(): number;
29
+ /**
30
+ * @description Gets the total record count
31
+ * @summary Returns the total number of records matching the query
32
+ * @return {number} The total record count
33
+ */
34
+ get count(): number;
35
+ private __repo?;
36
+ protected get repo(): Repo<any>;
37
+ /**
38
+ * @description Creates a new TypeORMPaginator instance.
39
+ * @summary Initializes a paginator for TypeORM query results.
40
+ * @param {TypeORMAdapter} adapter The TypeORM adapter.
41
+ * @param {TypeORMQuery} query The TypeORM query container to paginate.
42
+ * @param {number} size The page size.
43
+ * @param {Constructor<M>} clazz The model constructor.
44
+ */
45
+ constructor(adapter: TypeORMAdapter, query: TypeORMQuery, size: number, clazz: Constructor<M>);
46
+ /**
47
+ * @description Prepares a query for pagination
48
+ * @summary Modifies the raw query to include pagination parameters
49
+ * @param {TypeORMQuery} rawStatement - The original PostgreSQL query
50
+ * @return {TypeORMQuery} The prepared query with pagination parameters
51
+ */
52
+ protected prepare(rawStatement: TypeORMQuery): TypeORMQuery;
53
+ /**
54
+ * @description Retrieves a specific page of results.
55
+ * @summary Executes the query with pagination and processes the results.
56
+ * @param {number} [page=1] The page number to retrieve.
57
+ * @return {Promise<R[]>} A promise that resolves to an array of results.
58
+ * @throws {PagingError} If trying to access an invalid page or if no class is defined.
59
+ * @mermaid
60
+ * sequenceDiagram
61
+ * participant Client
62
+ * participant Paginator as TypeORMPaginator
63
+ * participant Adapter
64
+ * participant DB as Database
65
+ *
66
+ * Client->>Paginator: page(pageNumber)
67
+ * Note over Paginator: Prepare options (skip/take)
68
+ *
69
+ * alt First time or need count
70
+ * Paginator->>Adapter: Get count
71
+ * Adapter->>DB: Execute COUNT
72
+ * DB-->>Adapter: count
73
+ * Adapter-->>Paginator: count
74
+ * Paginator->>Paginator: Calculate total pages
75
+ * end
76
+ *
77
+ * Paginator->>Adapter: Execute query
78
+ * Adapter->>DB: findAndCount(options)
79
+ * DB-->>Adapter: rows, count
80
+ * Adapter-->>Paginator: rows, count
81
+ *
82
+ * Paginator->>Paginator: Map rows to models
83
+ * Paginator-->>Client: results
84
+ */
85
+ page(page?: number): Promise<R[]>;
86
+ }
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TypeORMStatement = void 0;
4
+ const core_1 = require("@decaf-ts/core");
5
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
6
+ const translate_1 = require("./translate.cjs");
7
+ const constants_1 = require("./constants.cjs");
8
+ const Paginator_1 = require("./Paginator.cjs");
9
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
10
+ /**
11
+ * @description Statement builder for TypeORM-backed queries.
12
+ * @summary Provides a fluent interface for building SQL queries via TypeORM's SelectQueryBuilder with type safety and Decaf.ts abstractions.
13
+ * @template M The model type that extends Model.
14
+ * @template R The result type returned from execution.
15
+ * @param {TypeORMAdapter} adapter The TypeORM adapter.
16
+ * @class TypeORMStatement
17
+ * @example
18
+ * // Example using TypeORMStatement
19
+ * const statement = new TypeORMStatement<User, User[]>(adapter);
20
+ * const users = await statement
21
+ * .from(User)
22
+ * .where(Condition.attribute<User>('age').gt(18))
23
+ * .orderBy('lastName', 'asc')
24
+ * .limit(10)
25
+ * .execute();
26
+ */
27
+ class TypeORMStatement extends core_1.Statement {
28
+ constructor(adapter) {
29
+ super(adapter);
30
+ }
31
+ /**
32
+ * @description Builds a TypeORM SelectQueryBuilder from the statement.
33
+ * @summary Converts the statement's conditions, selectors, and options into a TypeORM-backed query object.
34
+ * @return {TypeORMQuery} The built TypeORM query container.
35
+ * @throws {Error} If there are invalid query conditions.
36
+ * @mermaid
37
+ * sequenceDiagram
38
+ * participant Statement
39
+ * participant Repository
40
+ * participant parseCondition
41
+ *
42
+ * Statement->>Statement: build()
43
+ * Note over Statement: Initialize query
44
+ * Statement->>Repository: Get table name
45
+ * Repository-->>Statement: Return table name
46
+ * Statement->>Statement: Create base query
47
+ *
48
+ * alt Has selectSelector
49
+ * Statement->>Statement: Add columns to query
50
+ * end
51
+ *
52
+ * alt Has whereCondition
53
+ * Statement->>Statement: Create combined condition with table
54
+ * Statement->>parseCondition: Parse condition
55
+ * parseCondition-->>Statement: Return parsed conditions
56
+ * Statement->>Statement: Add conditions to query
57
+ * end
58
+ *
59
+ * alt Has orderBySelector
60
+ * Statement->>Statement: Add orderBy to query
61
+ * end
62
+ *
63
+ * alt Has limitSelector
64
+ * Statement->>Statement: Set limit
65
+ * else
66
+ * Statement->>Statement: Use default limit
67
+ * end
68
+ *
69
+ * alt Has offsetSelector
70
+ * Statement->>Statement: Set offset
71
+ * end
72
+ *
73
+ * Statement-->>Statement: Return query
74
+ */
75
+ build() {
76
+ const log = this.log.for(this.build);
77
+ const tableName = core_1.Repository.table(this.fromSelector);
78
+ const m = new this.fromSelector();
79
+ const q = {
80
+ query: this.adapter.dataSource
81
+ .getRepository(this.fromSelector[decorator_validation_1.ModelKeys.ANCHOR])
82
+ .createQueryBuilder(tableName),
83
+ };
84
+ if (this.selectSelector)
85
+ q.query = q.query.select(this.selectSelector.map((s) => `${tableName}.${s}`));
86
+ else
87
+ q.query = q.query.select();
88
+ //
89
+ // q.query = (q.query as SelectQueryBuilder<any>).from(
90
+ // this.fromSelector[ModelKeys.ANCHOR as keyof typeof this.fromSelector],
91
+ // tableName
92
+ // );
93
+ if (this.whereCondition)
94
+ q.query = this.parseCondition(this.whereCondition, tableName, q.query).query;
95
+ let orderByArgs;
96
+ if (!this.orderBySelector)
97
+ orderByArgs = [
98
+ `${tableName}.${(0, db_decorators_1.findPrimaryKey)(m).id}`,
99
+ core_1.OrderDirection.ASC.toUpperCase(),
100
+ ];
101
+ else
102
+ orderByArgs = [
103
+ `${tableName}.${this.orderBySelector[0]}`,
104
+ this.orderBySelector[1].toUpperCase(),
105
+ ];
106
+ q.query = q.query.orderBy(...orderByArgs);
107
+ if (this.limitSelector) {
108
+ q.query = q.query.limit(this.limitSelector);
109
+ }
110
+ else {
111
+ log.debug(`No limit selector defined. Using default limit of ${constants_1.TypeORMQueryLimit}`);
112
+ q.query = q.query.limit(constants_1.TypeORMQueryLimit);
113
+ }
114
+ // Add offset
115
+ if (this.offsetSelector)
116
+ q.query = q.query.skip(this.offsetSelector);
117
+ return q;
118
+ }
119
+ /**
120
+ * @description Creates a paginator for the statement.
121
+ * @summary Builds the query and returns a TypeORMPaginator for paginated results.
122
+ * @template R The result type.
123
+ * @param {number} size The page size.
124
+ * @return {Promise<Paginator<M, R, TypeORMQuery>>} A promise that resolves to a paginator.
125
+ * @throws {InternalError} If there's an error building the query.
126
+ */
127
+ async paginate(size) {
128
+ try {
129
+ const query = this.build();
130
+ const transformedQuery = {};
131
+ const a = query.query;
132
+ if (this.whereCondition)
133
+ transformedQuery.where = this.parseConditionForPagination(this.whereCondition, core_1.Repository.table(this.fromSelector));
134
+ if (this.orderBySelector)
135
+ transformedQuery.order = {
136
+ [this.orderBySelector[0]]: this.orderBySelector[1].toString(),
137
+ };
138
+ return new Paginator_1.TypeORMPaginator(this.adapter, transformedQuery, size, this.fromSelector);
139
+ }
140
+ catch (e) {
141
+ throw new db_decorators_1.InternalError(e);
142
+ }
143
+ }
144
+ /**
145
+ * @description Processes a record.
146
+ * @summary Converts a raw result row to a model instance using the adapter.
147
+ * @param {any} r The raw record.
148
+ * @param {keyof M} pkAttr The primary key attribute of the model.
149
+ * @param {"Number" | "BigInt" | undefined} sequenceType The type of the sequence.
150
+ * @return {any} The processed record.
151
+ */
152
+ processRecord(r, pkAttr) {
153
+ if (typeof r[pkAttr] !== "undefined") {
154
+ return this.adapter.revert(r, this.fromSelector, pkAttr, r[pkAttr]);
155
+ }
156
+ return r;
157
+ }
158
+ /**
159
+ * @description Executes a raw TypeORM query builder.
160
+ * @summary Sends the built SelectQueryBuilder to the database via TypeORM and returns the results.
161
+ * @template R The result type.
162
+ * @param {TypeORMQuery} rawInput The query container to execute.
163
+ * @return {Promise<R>} A promise that resolves to the query results.
164
+ */
165
+ async raw(rawInput) {
166
+ const log = this.log.for(this.raw);
167
+ log.debug(`Executing raw query: ${rawInput.query.getSql()}`);
168
+ return (await rawInput.query.getMany());
169
+ }
170
+ parseConditionForPagination(condition, tableName, counter = 0, conditionalOp) {
171
+ throw new db_decorators_1.InternalError("Not implemented");
172
+ }
173
+ /**
174
+ * @description Parses a condition into PostgreSQL conditions
175
+ * @summary Converts a Condition object into PostgreSQL condition structures
176
+ * @param {Condition<M>} condition - The condition to parse
177
+ * @param {string} [tableName] - the positional index of the arguments
178
+ * @return {TypeORMQuery} The PostgresSQL condition
179
+ * @mermaid
180
+ * sequenceDiagram
181
+ * participant Statement
182
+ * participant translateOperators
183
+ * participant parseCondition
184
+ *
185
+ * Statement->>Statement: parseCondition(condition)
186
+ *
187
+ * Note over Statement: Extract condition parts
188
+ *
189
+ * alt Simple comparison operator
190
+ * Statement->>translateOperators: translateOperators(operator)
191
+ * translateOperators-->>Statement: Return PostgreSQL operator
192
+ * Statement->>Statement: Create condition with column, operator, and value
193
+ * else NOT operator
194
+ * Statement->>Statement: parseCondition(attr1)
195
+ * Statement->>Statement: Add NOT to conditions
196
+ * else AND/OR operator
197
+ * Statement->>Statement: parseCondition(attr1)
198
+ * Statement->>Statement: parseCondition(comparison)
199
+ * Statement->>Statement: Combine conditions with AND/OR
200
+ * end
201
+ *
202
+ * Statement-->>Statement: Return conditions array
203
+ */
204
+ parseCondition(condition, tableName, qb, counter = 0, conditionalOp) {
205
+ const { attr1, operator, comparison } = condition;
206
+ function parse() {
207
+ const sqlOperator = (0, translate_1.translateOperators)(operator);
208
+ const attrRef = `${attr1}${counter}`;
209
+ const queryStr = `${tableName}.${attr1} ${sqlOperator} :${attrRef}`;
210
+ const values = {
211
+ [attrRef]: comparison,
212
+ };
213
+ switch (conditionalOp) {
214
+ case core_1.GroupOperator.AND:
215
+ return {
216
+ query: qb.andWhere(queryStr, values),
217
+ };
218
+ case core_1.GroupOperator.OR:
219
+ return {
220
+ query: qb.orWhere(queryStr, values),
221
+ };
222
+ case core_1.Operator.NOT:
223
+ throw new Error("NOT operator not implemented");
224
+ default:
225
+ return {
226
+ query: qb.where(queryStr, values),
227
+ };
228
+ }
229
+ }
230
+ if ([core_1.GroupOperator.AND, core_1.GroupOperator.OR, core_1.Operator.NOT].indexOf(operator) === -1) {
231
+ return parse();
232
+ }
233
+ // For NOT operator
234
+ else if (operator === core_1.Operator.NOT) {
235
+ throw new Error("NOT operator not implemented");
236
+ }
237
+ // For AND/OR operators
238
+ else {
239
+ qb = this.parseCondition(attr1, tableName, qb, ++counter)
240
+ .query;
241
+ return this.parseCondition(comparison, tableName, qb, ++counter, operator);
242
+ }
243
+ }
244
+ }
245
+ exports.TypeORMStatement = TypeORMStatement;
246
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhdGVtZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3F1ZXJ5L1N0YXRlbWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FRd0I7QUFDeEIseUVBQWtFO0FBQ2xFLCtDQUFpRDtBQUNqRCwrQ0FBZ0Q7QUFDaEQsK0NBQStDO0FBQy9DLDJEQUF3RTtBQU94RTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQWEsZ0JBQXFDLFNBQVEsZ0JBSXpEO0lBR0MsWUFBWSxPQUF1QjtRQUNqQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMkNHO0lBQ08sS0FBSztRQUNiLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxNQUFNLFNBQVMsR0FBRyxpQkFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbEMsTUFBTSxDQUFDLEdBQTJDO1lBQ2hELEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVU7aUJBQzNCLGFBQWEsQ0FDWixJQUFJLENBQUMsWUFBWSxDQUFDLGdDQUFTLENBQUMsTUFBd0MsQ0FBQyxDQUN0RTtpQkFDQSxrQkFBa0IsQ0FBQyxTQUFTLENBQTBCO1NBQzFELENBQUM7UUFFRixJQUFJLElBQUksQ0FBQyxjQUFjO1lBQ3JCLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQ3RCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLFNBQVMsSUFBSSxDQUFXLEVBQUUsQ0FB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SSxDQUFDLGNBQWMsQ0FBQyxLQUFxQixFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUM7aUJBQ3RFLEtBQXlDLENBQUM7WUFDN0MsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUN4QixVQUFVLEVBQ1YsU0FBUyxFQUNULEVBQUUsRUFDRixFQUFFLE9BQU8sRUFDVCxRQUFRLENBQ1QsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUE1UkQsNENBNFJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29uZGl0aW9uLFxuICBHcm91cE9wZXJhdG9yLFxuICBPcGVyYXRvcixcbiAgT3JkZXJEaXJlY3Rpb24sXG4gIFBhZ2luYXRvcixcbiAgUmVwb3NpdG9yeSxcbiAgU3RhdGVtZW50LFxufSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsLCBNb2RlbEtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyB0cmFuc2xhdGVPcGVyYXRvcnMgfSBmcm9tIFwiLi90cmFuc2xhdGVcIjtcbmltcG9ydCB7IFR5cGVPUk1RdWVyeUxpbWl0IH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBUeXBlT1JNUGFnaW5hdG9yIH0gZnJvbSBcIi4vUGFnaW5hdG9yXCI7XG5pbXBvcnQgeyBmaW5kUHJpbWFyeUtleSwgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVHlwZU9STVF1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBUeXBlT1JNQWRhcHRlciB9IGZyb20gXCIuLi9UeXBlT1JNQWRhcHRlclwiO1xuaW1wb3J0IHsgRmluZE1hbnlPcHRpb25zLCBTZWxlY3RRdWVyeUJ1aWxkZXIgfSBmcm9tIFwidHlwZW9ybVwiO1xuaW1wb3J0IHsgRmluZE9wdGlvbnNXaGVyZSB9IGZyb20gXCJ0eXBlb3JtL2ZpbmQtb3B0aW9ucy9GaW5kT3B0aW9uc1doZXJlXCI7XG5pbXBvcnQgeyBGaW5kT3B0aW9uc09yZGVyIH0gZnJvbSBcInR5cGVvcm0vZmluZC1vcHRpb25zL0ZpbmRPcHRpb25zT3JkZXJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3RhdGVtZW50IGJ1aWxkZXIgZm9yIFR5cGVPUk0tYmFja2VkIHF1ZXJpZXMuXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIGZsdWVudCBpbnRlcmZhY2UgZm9yIGJ1aWxkaW5nIFNRTCBxdWVyaWVzIHZpYSBUeXBlT1JNJ3MgU2VsZWN0UXVlcnlCdWlsZGVyIHdpdGggdHlwZSBzYWZldHkgYW5kIERlY2FmLnRzIGFic3RyYWN0aW9ucy5cbiAqIEB0ZW1wbGF0ZSBNIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAqIEB0ZW1wbGF0ZSBSIFRoZSByZXN1bHQgdHlwZSByZXR1cm5lZCBmcm9tIGV4ZWN1dGlvbi5cbiAqIEBwYXJhbSB7VHlwZU9STUFkYXB0ZXJ9IGFkYXB0ZXIgVGhlIFR5cGVPUk0gYWRhcHRlci5cbiAqIEBjbGFzcyBUeXBlT1JNU3RhdGVtZW50XG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSB1c2luZyBUeXBlT1JNU3RhdGVtZW50XG4gKiBjb25zdCBzdGF0ZW1lbnQgPSBuZXcgVHlwZU9STVN0YXRlbWVudDxVc2VyLCBVc2VyW10+KGFkYXB0ZXIpO1xuICogY29uc3QgdXNlcnMgPSBhd2FpdCBzdGF0ZW1lbnRcbiAqICAgLmZyb20oVXNlcilcbiAqICAgLndoZXJlKENvbmRpdGlvbi5hdHRyaWJ1dGU8VXNlcj4oJ2FnZScpLmd0KDE4KSlcbiAqICAgLm9yZGVyQnkoJ2xhc3ROYW1lJywgJ2FzYycpXG4gKiAgIC5saW1pdCgxMClcbiAqICAgLmV4ZWN1dGUoKTtcbiAqL1xuZXhwb3J0IGNsYXNzIFR5cGVPUk1TdGF0ZW1lbnQ8TSBleHRlbmRzIE1vZGVsLCBSPiBleHRlbmRzIFN0YXRlbWVudDxcbiAgVHlwZU9STVF1ZXJ5PE0+LFxuICBNLFxuICBSXG4+IHtcbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFkYXB0ZXIhOiBUeXBlT1JNQWRhcHRlcjtcblxuICBjb25zdHJ1Y3RvcihhZGFwdGVyOiBUeXBlT1JNQWRhcHRlcikge1xuICAgIHN1cGVyKGFkYXB0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCdWlsZHMgYSBUeXBlT1JNIFNlbGVjdFF1ZXJ5QnVpbGRlciBmcm9tIHRoZSBzdGF0ZW1lbnQuXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIHRoZSBzdGF0ZW1lbnQncyBjb25kaXRpb25zLCBzZWxlY3RvcnMsIGFuZCBvcHRpb25zIGludG8gYSBUeXBlT1JNLWJhY2tlZCBxdWVyeSBvYmplY3QuXG4gICAqIEByZXR1cm4ge1R5cGVPUk1RdWVyeX0gVGhlIGJ1aWx0IFR5cGVPUk0gcXVlcnkgY29udGFpbmVyLlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgYXJlIGludmFsaWQgcXVlcnkgY29uZGl0aW9ucy5cbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgU3RhdGVtZW50XG4gICAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICAgKiAgIHBhcnRpY2lwYW50IHBhcnNlQ29uZGl0aW9uXG4gICAqXG4gICAqICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBidWlsZCgpXG4gICAqICAgTm90ZSBvdmVyIFN0YXRlbWVudDogSW5pdGlhbGl6ZSBxdWVyeVxuICAgKiAgIFN0YXRlbWVudC0+PlJlcG9zaXRvcnk6IEdldCB0YWJsZSBuYW1lXG4gICAqICAgUmVwb3NpdG9yeS0tPj5TdGF0ZW1lbnQ6IFJldHVybiB0YWJsZSBuYW1lXG4gICAqICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBDcmVhdGUgYmFzZSBxdWVyeVxuICAgKlxuICAgKiAgIGFsdCBIYXMgc2VsZWN0U2VsZWN0b3JcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogQWRkIGNvbHVtbnMgdG8gcXVlcnlcbiAgICogICBlbmRcbiAgICpcbiAgICogICBhbHQgSGFzIHdoZXJlQ29uZGl0aW9uXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IENyZWF0ZSBjb21iaW5lZCBjb25kaXRpb24gd2l0aCB0YWJsZVxuICAgKiAgICAgU3RhdGVtZW50LT4+cGFyc2VDb25kaXRpb246IFBhcnNlIGNvbmRpdGlvblxuICAgKiAgICAgcGFyc2VDb25kaXRpb24tLT4+U3RhdGVtZW50OiBSZXR1cm4gcGFyc2VkIGNvbmRpdGlvbnNcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogQWRkIGNvbmRpdGlvbnMgdG8gcXVlcnlcbiAgICogICBlbmRcbiAgICpcbiAgICogICBhbHQgSGFzIG9yZGVyQnlTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBBZGQgb3JkZXJCeSB0byBxdWVyeVxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIGFsdCBIYXMgbGltaXRTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBTZXQgbGltaXRcbiAgICogICBlbHNlXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IFVzZSBkZWZhdWx0IGxpbWl0XG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgYWx0IEhhcyBvZmZzZXRTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBTZXQgb2Zmc2V0XG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgU3RhdGVtZW50LS0+PlN0YXRlbWVudDogUmV0dXJuIHF1ZXJ5XG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGQoKTogVHlwZU9STVF1ZXJ5PE0+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5idWlsZCk7XG4gICAgY29uc3QgdGFibGVOYW1lID0gUmVwb3NpdG9yeS50YWJsZSh0aGlzLmZyb21TZWxlY3Rvcik7XG4gICAgY29uc3QgbSA9IG5ldyB0aGlzLmZyb21TZWxlY3RvcigpO1xuXG4gICAgY29uc3QgcTogVHlwZU9STVF1ZXJ5PE0sIFNlbGVjdFF1ZXJ5QnVpbGRlcjxNPj4gPSB7XG4gICAgICBxdWVyeTogdGhpcy5hZGFwdGVyLmRhdGFTb3VyY2VcbiAgICAgICAgLmdldFJlcG9zaXRvcnkoXG4gICAgICAgICAgdGhpcy5mcm9tU2VsZWN0b3JbTW9kZWxLZXlzLkFOQ0hPUiBhcyBrZXlvZiB0eXBlb2YgdGhpcy5mcm9tU2VsZWN0b3JdXG4gICAgICAgIClcbiAgICAgICAgLmNyZWF0ZVF1ZXJ5QnVpbGRlcih0YWJsZU5hbWUpIGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxNPixcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuc2VsZWN0U2VsZWN0b3IpXG4gICAgICBxLnF1ZXJ5ID0gcS5xdWVyeS5zZWxlY3QoXG4gICAgICAgIHRoaXMuc2VsZWN0U2VsZWN0b3IubWFwKChzKSA9PiBgJHt0YWJsZU5hbWV9LiR7cyBhcyBzdHJpbmd9YClcbiAgICAgICk7XG4gICAgZWxzZSBxLnF1ZXJ5ID0gcS5xdWVyeS5zZWxlY3QoKTtcbiAgICAvL1xuICAgIC8vIHEucXVlcnkgPSAocS5xdWVyeSBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8YW55PikuZnJvbShcbiAgICAvLyAgIHRoaXMuZnJvbVNlbGVjdG9yW01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIHRoaXMuZnJvbVNlbGVjdG9yXSxcbiAgICAvLyAgIHRhYmxlTmFtZVxuICAgIC8vICk7XG5cbiAgICBpZiAodGhpcy53aGVyZUNvbmRpdGlvbilcbiAgICAgIHEucXVlcnkgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKFxuICAgICAgICB0aGlzLndoZXJlQ29uZGl0aW9uLFxuICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgIHEucXVlcnkgYXMgU2VsZWN0UXVlcnlCdWlsZGVyPGFueT5cbiAgICAgICkucXVlcnkgYXMgdW5rbm93biBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8TT47XG5cbiAgICBsZXQgb3JkZXJCeUFyZ3M6IFtzdHJpbmcsIFwiREVTQ1wiIHwgXCJBU0NcIl07XG4gICAgaWYgKCF0aGlzLm9yZGVyQnlTZWxlY3RvcilcbiAgICAgIG9yZGVyQnlBcmdzID0gW1xuICAgICAgICBgJHt0YWJsZU5hbWV9LiR7ZmluZFByaW1hcnlLZXkobSkuaWQgYXMgc3RyaW5nfWAsXG4gICAgICAgIE9yZGVyRGlyZWN0aW9uLkFTQy50b1VwcGVyQ2FzZSgpIGFzIFwiQVNDXCIsXG4gICAgICBdO1xuICAgIGVsc2VcbiAgICAgIG9yZGVyQnlBcmdzID0gW1xuICAgICAgICBgJHt0YWJsZU5hbWV9LiR7dGhpcy5vcmRlckJ5U2VsZWN0b3JbMF0gYXMgc3RyaW5nfWAsXG4gICAgICAgIHRoaXMub3JkZXJCeVNlbGVjdG9yWzFdLnRvVXBwZXJDYXNlKCkgYXMgXCJERVNDXCIgfCBcIkFTQ1wiLFxuICAgICAgXTtcblxuICAgIHEucXVlcnkgPSAocS5xdWVyeSBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8YW55Pikub3JkZXJCeSguLi5vcmRlckJ5QXJncyk7XG4gICAgaWYgKHRoaXMubGltaXRTZWxlY3Rvcikge1xuICAgICAgcS5xdWVyeSA9IChxLnF1ZXJ5IGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxhbnk+KS5saW1pdCh0aGlzLmxpbWl0U2VsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuZGVidWcoXG4gICAgICAgIGBObyBsaW1pdCBzZWxlY3RvciBkZWZpbmVkLiBVc2luZyBkZWZhdWx0IGxpbWl0IG9mICR7VHlwZU9STVF1ZXJ5TGltaXR9YFxuICAgICAgKTtcbiAgICAgIHEucXVlcnkgPSAocS5xdWVyeSBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8YW55PikubGltaXQoVHlwZU9STVF1ZXJ5TGltaXQpO1xuICAgIH1cblxuICAgIC8vIEFkZCBvZmZzZXRcbiAgICBpZiAodGhpcy5vZmZzZXRTZWxlY3RvcilcbiAgICAgIHEucXVlcnkgPSAocS5xdWVyeSBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8YW55Pikuc2tpcCh0aGlzLm9mZnNldFNlbGVjdG9yKTtcblxuICAgIHJldHVybiBxIGFzIGFueTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHBhZ2luYXRvciBmb3IgdGhlIHN0YXRlbWVudC5cbiAgICogQHN1bW1hcnkgQnVpbGRzIHRoZSBxdWVyeSBhbmQgcmV0dXJucyBhIFR5cGVPUk1QYWdpbmF0b3IgZm9yIHBhZ2luYXRlZCByZXN1bHRzLlxuICAgKiBAdGVtcGxhdGUgUiBUaGUgcmVzdWx0IHR5cGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFRoZSBwYWdlIHNpemUuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UGFnaW5hdG9yPE0sIFIsIFR5cGVPUk1RdWVyeT4+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHBhZ2luYXRvci5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgdGhlcmUncyBhbiBlcnJvciBidWlsZGluZyB0aGUgcXVlcnkuXG4gICAqL1xuICBhc3luYyBwYWdpbmF0ZTxSPihzaXplOiBudW1iZXIpOiBQcm9taXNlPFBhZ2luYXRvcjxNLCBSLCBUeXBlT1JNUXVlcnk+PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBUeXBlT1JNUXVlcnkgPSB0aGlzLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFF1ZXJ5OiBGaW5kTWFueU9wdGlvbnM8TT4gPSB7fTtcbiAgICAgIGNvbnN0IGEgPSBxdWVyeS5xdWVyeSBhcyB1bmtub3duIGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxNPjtcbiAgICAgIGlmICh0aGlzLndoZXJlQ29uZGl0aW9uKVxuICAgICAgICB0cmFuc2Zvcm1lZFF1ZXJ5LndoZXJlID0gdGhpcy5wYXJzZUNvbmRpdGlvbkZvclBhZ2luYXRpb24oXG4gICAgICAgICAgdGhpcy53aGVyZUNvbmRpdGlvbixcbiAgICAgICAgICBSZXBvc2l0b3J5LnRhYmxlKHRoaXMuZnJvbVNlbGVjdG9yKVxuICAgICAgICApO1xuXG4gICAgICBpZiAodGhpcy5vcmRlckJ5U2VsZWN0b3IpXG4gICAgICAgIHRyYW5zZm9ybWVkUXVlcnkub3JkZXIgPSB7XG4gICAgICAgICAgW3RoaXMub3JkZXJCeVNlbGVjdG9yWzBdXTogdGhpcy5vcmRlckJ5U2VsZWN0b3JbMV0udG9TdHJpbmcoKSxcbiAgICAgICAgfSBhcyBhbnk7XG5cbiAgICAgIHJldHVybiBuZXcgVHlwZU9STVBhZ2luYXRvcihcbiAgICAgICAgdGhpcy5hZGFwdGVyIGFzIGFueSxcbiAgICAgICAgdHJhbnNmb3JtZWRRdWVyeSBhcyBhbnksXG4gICAgICAgIHNpemUsXG4gICAgICAgIHRoaXMuZnJvbVNlbGVjdG9yXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm9jZXNzZXMgYSByZWNvcmQuXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIGEgcmF3IHJlc3VsdCByb3cgdG8gYSBtb2RlbCBpbnN0YW5jZSB1c2luZyB0aGUgYWRhcHRlci5cbiAgICogQHBhcmFtIHthbnl9IHIgVGhlIHJhdyByZWNvcmQuXG4gICAqIEBwYXJhbSB7a2V5b2YgTX0gcGtBdHRyIFRoZSBwcmltYXJ5IGtleSBhdHRyaWJ1dGUgb2YgdGhlIG1vZGVsLlxuICAgKiBAcGFyYW0ge1wiTnVtYmVyXCIgfCBcIkJpZ0ludFwiIHwgdW5kZWZpbmVkfSBzZXF1ZW5jZVR5cGUgVGhlIHR5cGUgb2YgdGhlIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJuIHthbnl9IFRoZSBwcm9jZXNzZWQgcmVjb3JkLlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzUmVjb3JkKHI6IGFueSwgcGtBdHRyOiBrZXlvZiBNKSB7XG4gICAgaWYgKHR5cGVvZiByW3BrQXR0cl0gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuZnJvbVNlbGVjdG9yLCBwa0F0dHIsIHJbcGtBdHRyXSk7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyBhIHJhdyBUeXBlT1JNIHF1ZXJ5IGJ1aWxkZXIuXG4gICAqIEBzdW1tYXJ5IFNlbmRzIHRoZSBidWlsdCBTZWxlY3RRdWVyeUJ1aWxkZXIgdG8gdGhlIGRhdGFiYXNlIHZpYSBUeXBlT1JNIGFuZCByZXR1cm5zIHRoZSByZXN1bHRzLlxuICAgKiBAdGVtcGxhdGUgUiBUaGUgcmVzdWx0IHR5cGUuXG4gICAqIEBwYXJhbSB7VHlwZU9STVF1ZXJ5fSByYXdJbnB1dCBUaGUgcXVlcnkgY29udGFpbmVyIHRvIGV4ZWN1dGUuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Uj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBxdWVyeSByZXN1bHRzLlxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgcmF3PFI+KHJhd0lucHV0OiBUeXBlT1JNUXVlcnk8TT4pOiBQcm9taXNlPFI+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5yYXcpO1xuICAgIGxvZy5kZWJ1ZyhcbiAgICAgIGBFeGVjdXRpbmcgcmF3IHF1ZXJ5OiAkeyhyYXdJbnB1dC5xdWVyeSBhcyB1bmtub3duIGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxNPikuZ2V0U3FsKCl9YFxuICAgICk7XG4gICAgcmV0dXJuIChhd2FpdCAoXG4gICAgICByYXdJbnB1dC5xdWVyeSBhcyB1bmtub3duIGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxNPlxuICAgICkuZ2V0TWFueSgpKSBhcyBSO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlQ29uZGl0aW9uRm9yUGFnaW5hdGlvbihcbiAgICBjb25kaXRpb246IENvbmRpdGlvbjxNPixcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBjb3VudGVyID0gMCxcbiAgICBjb25kaXRpb25hbE9wPzogR3JvdXBPcGVyYXRvciB8IE9wZXJhdG9yXG4gICk6IEZpbmRPcHRpb25zV2hlcmU8TT5bXSB8IEZpbmRPcHRpb25zV2hlcmU8TT4ge1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQYXJzZXMgYSBjb25kaXRpb24gaW50byBQb3N0Z3JlU1FMIGNvbmRpdGlvbnNcbiAgICogQHN1bW1hcnkgQ29udmVydHMgYSBDb25kaXRpb24gb2JqZWN0IGludG8gUG9zdGdyZVNRTCBjb25kaXRpb24gc3RydWN0dXJlc1xuICAgKiBAcGFyYW0ge0NvbmRpdGlvbjxNPn0gY29uZGl0aW9uIC0gVGhlIGNvbmRpdGlvbiB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhYmxlTmFtZV0gLSB0aGUgcG9zaXRpb25hbCBpbmRleCBvZiB0aGUgYXJndW1lbnRzXG4gICAqIEByZXR1cm4ge1R5cGVPUk1RdWVyeX0gVGhlIFBvc3RncmVzU1FMIGNvbmRpdGlvblxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBTdGF0ZW1lbnRcbiAgICogICBwYXJ0aWNpcGFudCB0cmFuc2xhdGVPcGVyYXRvcnNcbiAgICogICBwYXJ0aWNpcGFudCBwYXJzZUNvbmRpdGlvblxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogcGFyc2VDb25kaXRpb24oY29uZGl0aW9uKVxuICAgKlxuICAgKiAgIE5vdGUgb3ZlciBTdGF0ZW1lbnQ6IEV4dHJhY3QgY29uZGl0aW9uIHBhcnRzXG4gICAqXG4gICAqICAgYWx0IFNpbXBsZSBjb21wYXJpc29uIG9wZXJhdG9yXG4gICAqICAgICBTdGF0ZW1lbnQtPj50cmFuc2xhdGVPcGVyYXRvcnM6IHRyYW5zbGF0ZU9wZXJhdG9ycyhvcGVyYXRvcilcbiAgICogICAgIHRyYW5zbGF0ZU9wZXJhdG9ycy0tPj5TdGF0ZW1lbnQ6IFJldHVybiBQb3N0Z3JlU1FMIG9wZXJhdG9yXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IENyZWF0ZSBjb25kaXRpb24gd2l0aCBjb2x1bW4sIG9wZXJhdG9yLCBhbmQgdmFsdWVcbiAgICogICBlbHNlIE5PVCBvcGVyYXRvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBwYXJzZUNvbmRpdGlvbihhdHRyMSlcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogQWRkIE5PVCB0byBjb25kaXRpb25zXG4gICAqICAgZWxzZSBBTkQvT1Igb3BlcmF0b3JcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogcGFyc2VDb25kaXRpb24oYXR0cjEpXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IHBhcnNlQ29uZGl0aW9uKGNvbXBhcmlzb24pXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IENvbWJpbmUgY29uZGl0aW9ucyB3aXRoIEFORC9PUlxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0tPj5TdGF0ZW1lbnQ6IFJldHVybiBjb25kaXRpb25zIGFycmF5XG4gICAqL1xuICBwcm90ZWN0ZWQgcGFyc2VDb25kaXRpb24oXG4gICAgY29uZGl0aW9uOiBDb25kaXRpb248TT4sXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgcWI6IFNlbGVjdFF1ZXJ5QnVpbGRlcjxhbnk+LFxuICAgIGNvdW50ZXIgPSAwLFxuICAgIGNvbmRpdGlvbmFsT3A/OiBHcm91cE9wZXJhdG9yIHwgT3BlcmF0b3JcbiAgKTogVHlwZU9STVF1ZXJ5PE0+IHtcbiAgICBjb25zdCB7IGF0dHIxLCBvcGVyYXRvciwgY29tcGFyaXNvbiB9ID0gY29uZGl0aW9uIGFzIHVua25vd24gYXMge1xuICAgICAgYXR0cjE6IHN0cmluZyB8IENvbmRpdGlvbjxNPjtcbiAgICAgIG9wZXJhdG9yOiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3I7XG4gICAgICBjb21wYXJpc29uOiBhbnk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHBhcnNlKCk6IFR5cGVPUk1RdWVyeTxNPiB7XG4gICAgICBjb25zdCBzcWxPcGVyYXRvciA9IHRyYW5zbGF0ZU9wZXJhdG9ycyhvcGVyYXRvcik7XG4gICAgICBjb25zdCBhdHRyUmVmID0gYCR7YXR0cjF9JHtjb3VudGVyfWA7XG4gICAgICBjb25zdCBxdWVyeVN0ciA9IGAke3RhYmxlTmFtZX0uJHthdHRyMX0gJHtzcWxPcGVyYXRvcn0gOiR7YXR0clJlZn1gO1xuICAgICAgY29uc3QgdmFsdWVzID0ge1xuICAgICAgICBbYXR0clJlZl06IGNvbXBhcmlzb24sXG4gICAgICB9O1xuICAgICAgc3dpdGNoIChjb25kaXRpb25hbE9wKSB7XG4gICAgICAgIGNhc2UgR3JvdXBPcGVyYXRvci5BTkQ6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHF1ZXJ5OiBxYi5hbmRXaGVyZShxdWVyeVN0ciwgdmFsdWVzKSBhcyBhbnksXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSBHcm91cE9wZXJhdG9yLk9SOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBxdWVyeTogcWIub3JXaGVyZShxdWVyeVN0ciwgdmFsdWVzKSBhcyBhbnksXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSBPcGVyYXRvci5OT1Q6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9UIG9wZXJhdG9yIG5vdCBpbXBsZW1lbnRlZFwiKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcXVlcnk6IHFiLndoZXJlKHF1ZXJ5U3RyLCB2YWx1ZXMpIGFzIGFueSxcbiAgICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChcbiAgICAgIFtHcm91cE9wZXJhdG9yLkFORCwgR3JvdXBPcGVyYXRvci5PUiwgT3BlcmF0b3IuTk9UXS5pbmRleE9mKFxuICAgICAgICBvcGVyYXRvciBhcyBHcm91cE9wZXJhdG9yXG4gICAgICApID09PSAtMVxuICAgICkge1xuICAgICAgcmV0dXJuIHBhcnNlKCk7XG4gICAgfVxuICAgIC8vIEZvciBOT1Qgb3BlcmF0b3JcbiAgICBlbHNlIGlmIChvcGVyYXRvciA9PT0gT3BlcmF0b3IuTk9UKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOT1Qgb3BlcmF0b3Igbm90IGltcGxlbWVudGVkXCIpO1xuICAgIH1cbiAgICAvLyBGb3IgQU5EL09SIG9wZXJhdG9yc1xuICAgIGVsc2Uge1xuICAgICAgcWIgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKGF0dHIxIGFzIENvbmRpdGlvbjxNPiwgdGFibGVOYW1lLCBxYiwgKytjb3VudGVyKVxuICAgICAgICAucXVlcnkgYXMgdW5rbm93biBhcyBTZWxlY3RRdWVyeUJ1aWxkZXI8TT47XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZUNvbmRpdGlvbihcbiAgICAgICAgY29tcGFyaXNvbixcbiAgICAgICAgdGFibGVOYW1lLFxuICAgICAgICBxYixcbiAgICAgICAgKytjb3VudGVyLFxuICAgICAgICBvcGVyYXRvclxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==