velocious 1.0.430 → 1.0.431
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/velocious.js +48 -0
- package/build/bin/velocious.js +39 -34
- package/build/index.js +1 -2
- package/build/src/application.js +214 -187
- package/build/src/authorization/ability.d.ts +24 -23
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +300 -252
- package/build/src/authorization/base-resource.d.ts +20 -26
- package/build/src/authorization/base-resource.d.ts.map +1 -1
- package/build/src/authorization/base-resource.js +136 -118
- package/build/src/background-jobs/client.js +47 -43
- package/build/src/background-jobs/cron-expression.js +166 -127
- package/build/src/background-jobs/forked-runner-child.js +47 -37
- package/build/src/background-jobs/job-record.js +10 -8
- package/build/src/background-jobs/job-registry.js +84 -72
- package/build/src/background-jobs/job-runner.js +81 -74
- package/build/src/background-jobs/job.js +72 -62
- package/build/src/background-jobs/json-socket.js +70 -65
- package/build/src/background-jobs/main.js +900 -841
- package/build/src/background-jobs/normalize-error.js +11 -12
- package/build/src/background-jobs/scheduler.js +247 -205
- package/build/src/background-jobs/socket-request.js +65 -60
- package/build/src/background-jobs/status-reporter.js +96 -86
- package/build/src/background-jobs/store.js +980 -862
- package/build/src/background-jobs/types.js +3 -2
- package/build/src/background-jobs/web/authorization.js +50 -38
- package/build/src/background-jobs/web/controller.js +268 -232
- package/build/src/background-jobs/web/index.js +40 -36
- package/build/src/background-jobs/web/path-matcher.js +48 -45
- package/build/src/background-jobs/web/registry.js +14 -9
- package/build/src/background-jobs/worker.js +639 -585
- package/build/src/beacon/client.js +293 -264
- package/build/src/beacon/in-process-broker.js +25 -20
- package/build/src/beacon/in-process-client.js +116 -104
- package/build/src/beacon/server.js +126 -110
- package/build/src/beacon/types.js +8 -2
- package/build/src/cli/base-command.js +57 -49
- package/build/src/cli/browser-cli.js +42 -37
- package/build/src/cli/commands/background-jobs-main.js +5 -5
- package/build/src/cli/commands/background-jobs-runner.js +5 -5
- package/build/src/cli/commands/background-jobs-worker.js +5 -5
- package/build/src/cli/commands/beacon.js +5 -5
- package/build/src/cli/commands/console.js +10 -10
- package/build/src/cli/commands/db/base-command.js +76 -71
- package/build/src/cli/commands/db/create.js +61 -53
- package/build/src/cli/commands/db/drop.js +71 -62
- package/build/src/cli/commands/db/migrate.js +15 -13
- package/build/src/cli/commands/db/reset.js +19 -16
- package/build/src/cli/commands/db/rollback.js +13 -12
- package/build/src/cli/commands/db/schema/dump.js +9 -9
- package/build/src/cli/commands/db/schema/load.js +9 -9
- package/build/src/cli/commands/db/seed.js +9 -9
- package/build/src/cli/commands/db/tenants/check.js +35 -32
- package/build/src/cli/commands/db/tenants/create.js +29 -26
- package/build/src/cli/commands/db/tenants/migrate.js +44 -40
- package/build/src/cli/commands/destroy/migration.js +5 -5
- package/build/src/cli/commands/generate/base-models.js +5 -5
- package/build/src/cli/commands/generate/frontend-models.js +9 -9
- package/build/src/cli/commands/generate/migration.js +5 -5
- package/build/src/cli/commands/generate/model.js +5 -5
- package/build/src/cli/commands/init.js +9 -7
- package/build/src/cli/commands/routes.js +6 -6
- package/build/src/cli/commands/run-script.js +9 -9
- package/build/src/cli/commands/runner.js +9 -9
- package/build/src/cli/commands/server.js +6 -6
- package/build/src/cli/commands/test.js +7 -6
- package/build/src/cli/index.js +141 -127
- package/build/src/cli/tenant-database-command-helper.js +185 -154
- package/build/src/cli/use-browser-cli.js +20 -15
- package/build/src/configuration-resolver.js +54 -47
- package/build/src/configuration-types.d.ts +21 -2
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +60 -3
- package/build/src/configuration.js +2547 -2240
- package/build/src/controller.js +407 -363
- package/build/src/current-configuration.js +12 -9
- package/build/src/current.js +75 -70
- package/build/src/database/annotations-async-hooks.js +22 -16
- package/build/src/database/annotations.js +18 -12
- package/build/src/database/drivers/base-column.js +179 -155
- package/build/src/database/drivers/base-columns-index.js +78 -69
- package/build/src/database/drivers/base-foreign-key.js +101 -89
- package/build/src/database/drivers/base-table.js +149 -124
- package/build/src/database/drivers/base.js +1489 -1306
- package/build/src/database/drivers/mssql/column.js +50 -39
- package/build/src/database/drivers/mssql/columns-index.js +3 -2
- package/build/src/database/drivers/mssql/connect-connection.js +9 -11
- package/build/src/database/drivers/mssql/foreign-key.js +9 -8
- package/build/src/database/drivers/mssql/index.js +587 -507
- package/build/src/database/drivers/mssql/options.js +75 -68
- package/build/src/database/drivers/mssql/query-parser.js +3 -2
- package/build/src/database/drivers/mssql/sql/alter-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/create-database.js +31 -24
- package/build/src/database/drivers/mssql/sql/create-index.js +2 -2
- package/build/src/database/drivers/mssql/sql/create-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/delete.js +16 -14
- package/build/src/database/drivers/mssql/sql/drop-database.js +31 -24
- package/build/src/database/drivers/mssql/sql/drop-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/insert.js +2 -2
- package/build/src/database/drivers/mssql/sql/update.js +28 -24
- package/build/src/database/drivers/mssql/sql/upsert.js +20 -18
- package/build/src/database/drivers/mssql/structure-sql.js +114 -102
- package/build/src/database/drivers/mssql/table.js +96 -81
- package/build/src/database/drivers/mysql/column.js +92 -75
- package/build/src/database/drivers/mysql/columns-index.js +19 -16
- package/build/src/database/drivers/mysql/foreign-key.js +9 -8
- package/build/src/database/drivers/mysql/index.js +457 -396
- package/build/src/database/drivers/mysql/options.js +30 -26
- package/build/src/database/drivers/mysql/query-parser.js +3 -2
- package/build/src/database/drivers/mysql/query.js +29 -26
- package/build/src/database/drivers/mysql/sql/alter-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/create-database.js +28 -23
- package/build/src/database/drivers/mysql/sql/create-index.js +3 -2
- package/build/src/database/drivers/mysql/sql/create-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/delete.js +17 -14
- package/build/src/database/drivers/mysql/sql/drop-database.js +3 -2
- package/build/src/database/drivers/mysql/sql/drop-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/insert.js +3 -2
- package/build/src/database/drivers/mysql/sql/update.js +29 -24
- package/build/src/database/drivers/mysql/sql/upsert.js +10 -8
- package/build/src/database/drivers/mysql/structure-sql.js +88 -79
- package/build/src/database/drivers/mysql/table.js +98 -83
- package/build/src/database/drivers/pgsql/column.js +72 -56
- package/build/src/database/drivers/pgsql/columns-index.js +3 -2
- package/build/src/database/drivers/pgsql/foreign-key.js +9 -8
- package/build/src/database/drivers/pgsql/index.js +438 -377
- package/build/src/database/drivers/pgsql/options.js +28 -25
- package/build/src/database/drivers/pgsql/query-parser.js +3 -2
- package/build/src/database/drivers/pgsql/sql/alter-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/create-database.js +23 -19
- package/build/src/database/drivers/pgsql/sql/create-index.js +3 -2
- package/build/src/database/drivers/pgsql/sql/create-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/delete.js +17 -14
- package/build/src/database/drivers/pgsql/sql/drop-database.js +3 -2
- package/build/src/database/drivers/pgsql/sql/drop-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/insert.js +3 -2
- package/build/src/database/drivers/pgsql/sql/update.js +29 -24
- package/build/src/database/drivers/pgsql/sql/upsert.js +11 -9
- package/build/src/database/drivers/pgsql/structure-sql.js +120 -108
- package/build/src/database/drivers/pgsql/table.js +77 -60
- package/build/src/database/drivers/sqlite/base.js +478 -405
- package/build/src/database/drivers/sqlite/column.js +69 -54
- package/build/src/database/drivers/sqlite/columns-index.js +27 -22
- package/build/src/database/drivers/sqlite/connection-sql-js.js +42 -35
- package/build/src/database/drivers/sqlite/foreign-key.js +21 -18
- package/build/src/database/drivers/sqlite/index.js +373 -330
- package/build/src/database/drivers/sqlite/index.native.js +64 -55
- package/build/src/database/drivers/sqlite/index.web.js +87 -69
- package/build/src/database/drivers/sqlite/options.js +28 -25
- package/build/src/database/drivers/sqlite/query-parser.js +3 -2
- package/build/src/database/drivers/sqlite/query.js +24 -21
- package/build/src/database/drivers/sqlite/query.native.js +25 -20
- package/build/src/database/drivers/sqlite/query.web.js +37 -30
- package/build/src/database/drivers/sqlite/sql/alter-table.js +179 -159
- package/build/src/database/drivers/sqlite/sql/create-index.js +3 -2
- package/build/src/database/drivers/sqlite/sql/create-table.js +3 -2
- package/build/src/database/drivers/sqlite/sql/delete.js +22 -17
- package/build/src/database/drivers/sqlite/sql/drop-table.js +3 -2
- package/build/src/database/drivers/sqlite/sql/insert.js +3 -2
- package/build/src/database/drivers/sqlite/sql/update.js +29 -24
- package/build/src/database/drivers/sqlite/sql/upsert.js +11 -9
- package/build/src/database/drivers/sqlite/structure-sql.js +52 -49
- package/build/src/database/drivers/sqlite/table-rebuilder.js +75 -62
- package/build/src/database/drivers/sqlite/table.js +125 -102
- package/build/src/database/drivers/structure-sql/utils.js +17 -14
- package/build/src/database/handler.js +10 -9
- package/build/src/database/initializer-from-require-context.js +87 -76
- package/build/src/database/migration/index.js +395 -332
- package/build/src/database/migrator/files-finder.js +50 -40
- package/build/src/database/migrator/types.js +30 -2
- package/build/src/database/migrator.js +526 -454
- package/build/src/database/pool/async-tracked-multi-connection.js +1147 -997
- package/build/src/database/pool/base-methods-forward.js +43 -40
- package/build/src/database/pool/base.js +343 -298
- package/build/src/database/pool/single-multi-use.js +110 -93
- package/build/src/database/query/alter-table-base.js +99 -84
- package/build/src/database/query/base.js +46 -39
- package/build/src/database/query/create-database-base.js +30 -25
- package/build/src/database/query/create-index-base.js +94 -75
- package/build/src/database/query/create-table-base.js +193 -151
- package/build/src/database/query/delete-base.js +16 -14
- package/build/src/database/query/drop-database-base.js +28 -23
- package/build/src/database/query/drop-table-base.js +53 -42
- package/build/src/database/query/from-base.js +33 -30
- package/build/src/database/query/from-plain.js +13 -11
- package/build/src/database/query/from-table.js +15 -13
- package/build/src/database/query/index.js +472 -410
- package/build/src/database/query/insert-base.js +164 -143
- package/build/src/database/query/join-base.js +40 -35
- package/build/src/database/query/join-object.js +153 -128
- package/build/src/database/query/join-plain.js +15 -13
- package/build/src/database/query/join-tracker.js +90 -76
- package/build/src/database/query/model-class-query.js +1370 -1134
- package/build/src/database/query/order-base.js +30 -27
- package/build/src/database/query/order-column.js +53 -44
- package/build/src/database/query/order-plain.js +24 -20
- package/build/src/database/query/preloader/belongs-to.js +258 -210
- package/build/src/database/query/preloader/ensure-model-class-initialized.js +9 -8
- package/build/src/database/query/preloader/has-many.js +301 -240
- package/build/src/database/query/preloader/has-one.js +117 -91
- package/build/src/database/query/preloader/selection.js +129 -117
- package/build/src/database/query/preloader.js +185 -160
- package/build/src/database/query/query-data.js +201 -157
- package/build/src/database/query/select-base.js +27 -25
- package/build/src/database/query/select-plain.js +15 -13
- package/build/src/database/query/select-table-and-column.js +25 -21
- package/build/src/database/query/update-base.js +38 -35
- package/build/src/database/query/upsert-base.js +100 -93
- package/build/src/database/query/where-base.js +35 -32
- package/build/src/database/query/where-combinator.d.ts.map +1 -1
- package/build/src/database/query/where-combinator.js +28 -26
- package/build/src/database/query/where-hash.js +68 -61
- package/build/src/database/query/where-model-class-hash.js +469 -414
- package/build/src/database/query/where-not.js +20 -18
- package/build/src/database/query/where-plain.js +17 -15
- package/build/src/database/query/with-count.js +159 -125
- package/build/src/database/query-parser/base-query-parser.js +37 -32
- package/build/src/database/query-parser/from-parser.js +45 -36
- package/build/src/database/query-parser/group-parser.js +50 -42
- package/build/src/database/query-parser/joins-parser.js +33 -28
- package/build/src/database/query-parser/limit-parser.js +70 -67
- package/build/src/database/query-parser/options.js +82 -75
- package/build/src/database/query-parser/order-parser.js +40 -36
- package/build/src/database/query-parser/select-parser.js +60 -49
- package/build/src/database/query-parser/where-parser.js +41 -36
- package/build/src/database/record/acts-as-list.js +273 -235
- package/build/src/database/record/attachments/download.js +45 -44
- package/build/src/database/record/attachments/handle.js +161 -141
- package/build/src/database/record/attachments/normalize-input.js +138 -128
- package/build/src/database/record/attachments/storage-drivers/filesystem.js +91 -77
- package/build/src/database/record/attachments/storage-drivers/native.js +121 -112
- package/build/src/database/record/attachments/storage-drivers/s3.js +208 -177
- package/build/src/database/record/attachments/store.d.ts +1 -1
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +540 -468
- package/build/src/database/record/index.d.ts +17 -15
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +3894 -3361
- package/build/src/database/record/instance-relationships/base.js +268 -234
- package/build/src/database/record/instance-relationships/belongs-to.js +73 -58
- package/build/src/database/record/instance-relationships/has-many.js +264 -225
- package/build/src/database/record/instance-relationships/has-one.js +105 -85
- package/build/src/database/record/record-not-found-error.js +2 -3
- package/build/src/database/record/relationships/base.d.ts +2 -2
- package/build/src/database/record/relationships/base.d.ts.map +1 -1
- package/build/src/database/record/relationships/base.js +167 -145
- package/build/src/database/record/relationships/belongs-to.js +51 -44
- package/build/src/database/record/relationships/has-many.js +40 -32
- package/build/src/database/record/relationships/has-one.js +40 -32
- package/build/src/database/record/state-machine.js +208 -156
- package/build/src/database/record/user-module.js +38 -32
- package/build/src/database/record/validators/base.js +24 -22
- package/build/src/database/record/validators/format.js +46 -36
- package/build/src/database/record/validators/presence.js +20 -18
- package/build/src/database/record/validators/uniqueness.js +117 -99
- package/build/src/database/table-data/index.js +231 -199
- package/build/src/database/table-data/table-column.js +382 -338
- package/build/src/database/table-data/table-foreign-key.js +66 -57
- package/build/src/database/table-data/table-index.js +36 -29
- package/build/src/database/table-data/table-reference.js +10 -10
- package/build/src/database/use-database.js +40 -32
- package/build/src/environment-handlers/base.js +544 -484
- package/build/src/environment-handlers/browser.js +294 -241
- package/build/src/environment-handlers/node/cli/commands/background-jobs-main.js +19 -16
- package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +21 -18
- package/build/src/environment-handlers/node/cli/commands/background-jobs-worker.js +29 -22
- package/build/src/environment-handlers/node/cli/commands/beacon.js +19 -16
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +15 -14
- package/build/src/environment-handlers/node/cli/commands/console.js +120 -99
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +39 -34
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +63 -57
- package/build/src/environment-handlers/node/cli/commands/db/seed.js +63 -51
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +40 -32
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +353 -298
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +844 -729
- package/build/src/environment-handlers/node/cli/commands/generate/migration.js +38 -34
- package/build/src/environment-handlers/node/cli/commands/generate/model.js +38 -34
- package/build/src/environment-handlers/node/cli/commands/init.js +61 -56
- package/build/src/environment-handlers/node/cli/commands/routes.js +59 -51
- package/build/src/environment-handlers/node/cli/commands/run-script.js +68 -54
- package/build/src/environment-handlers/node/cli/commands/runner.js +74 -56
- package/build/src/environment-handlers/node/cli/commands/server.js +106 -93
- package/build/src/environment-handlers/node/cli/commands/test.js +113 -97
- package/build/src/environment-handlers/node.js +874 -753
- package/build/src/error-logger.js +21 -22
- package/build/src/frontend-model-controller.d.ts +6 -6
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +3288 -2788
- package/build/src/frontend-model-resource/base-resource.d.ts +18 -17
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +869 -759
- package/build/src/frontend-models/base.d.ts +19 -12
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +3602 -3114
- package/build/src/frontend-models/clear-pending-debounced-callback.js +8 -7
- package/build/src/frontend-models/event-hook-models.js +21 -16
- package/build/src/frontend-models/model-registry.js +11 -9
- package/build/src/frontend-models/outgoing-event-buffer.js +17 -10
- package/build/src/frontend-models/preloader.d.ts +6 -6
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +149 -131
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +1855 -1560
- package/build/src/frontend-models/resource-config-validation.js +37 -27
- package/build/src/frontend-models/resource-definition.js +288 -234
- package/build/src/frontend-models/transport-serialization.js +266 -203
- package/build/src/frontend-models/use-created-event.js +7 -5
- package/build/src/frontend-models/use-destroyed-event.js +93 -80
- package/build/src/frontend-models/use-model-class-event.js +91 -79
- package/build/src/frontend-models/use-updated-event.js +97 -84
- package/build/src/frontend-models/websocket-channel.js +441 -381
- package/build/src/frontend-models/websocket-publishers.js +173 -140
- package/build/src/http-client/header.js +14 -13
- package/build/src/http-client/index.js +132 -116
- package/build/src/http-client/request.js +87 -71
- package/build/src/http-client/response.js +140 -122
- package/build/src/http-client/websocket-client.js +17 -15
- package/build/src/http-server/client/index.js +465 -409
- package/build/src/http-server/client/params-to-object.js +135 -124
- package/build/src/http-server/client/request-buffer/form-data-part.js +132 -111
- package/build/src/http-server/client/request-buffer/header.js +16 -15
- package/build/src/http-server/client/request-buffer/index.js +506 -446
- package/build/src/http-server/client/request-parser.js +186 -163
- package/build/src/http-server/client/request-runner.js +259 -226
- package/build/src/http-server/client/request-timing.js +151 -132
- package/build/src/http-server/client/request.js +108 -96
- package/build/src/http-server/client/response.js +235 -213
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +29 -25
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +29 -25
- package/build/src/http-server/client/uploaded-file/uploaded-file.js +33 -33
- package/build/src/http-server/client/websocket-request.js +137 -114
- package/build/src/http-server/client/websocket-session.js +1657 -1452
- package/build/src/http-server/cookie.js +236 -216
- package/build/src/http-server/development-reloader.js +221 -190
- package/build/src/http-server/index.js +525 -451
- package/build/src/http-server/remote-address.js +50 -38
- package/build/src/http-server/server-client.js +208 -181
- package/build/src/http-server/server-lock.js +167 -153
- package/build/src/http-server/websocket-channel-subscribers.js +93 -81
- package/build/src/http-server/websocket-channel.js +117 -104
- package/build/src/http-server/websocket-connection.js +104 -96
- package/build/src/http-server/websocket-event-log-store.js +404 -350
- package/build/src/http-server/websocket-events-host.js +164 -145
- package/build/src/http-server/websocket-events.js +47 -47
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +14 -13
- package/build/src/http-server/worker-handler/in-process.js +141 -123
- package/build/src/http-server/worker-handler/index.js +349 -313
- package/build/src/http-server/worker-handler/worker-script.js +5 -4
- package/build/src/http-server/worker-handler/worker-thread.js +269 -240
- package/build/src/initializer.js +36 -31
- package/build/src/jobs/mail-delivery.js +15 -13
- package/build/src/logger/base-logger.js +26 -24
- package/build/src/logger/console-logger.js +23 -21
- package/build/src/logger/file-logger.js +31 -29
- package/build/src/logger/outputs/array-output.js +42 -37
- package/build/src/logger/outputs/console-output.js +24 -20
- package/build/src/logger/outputs/file-output.js +48 -43
- package/build/src/logger/outputs/stdout-output.js +48 -39
- package/build/src/logger.js +394 -338
- package/build/src/mailer/backends/smtp.js +163 -134
- package/build/src/mailer/base.js +251 -211
- package/build/src/mailer/delivery.js +64 -56
- package/build/src/mailer/index.js +22 -4
- package/build/src/mailer.js +13 -4
- package/build/src/plugins/sqljs-wasm-route-controller.js +52 -42
- package/build/src/plugins/sqljs-wasm-route.js +38 -28
- package/build/src/record-payload-values.js +28 -25
- package/build/src/routes/app-routes.js +14 -12
- package/build/src/routes/base-route.js +130 -112
- package/build/src/routes/basic-route.js +102 -83
- package/build/src/routes/built-in/debug/controller.js +10 -10
- package/build/src/routes/built-in/errors/controller.js +5 -5
- package/build/src/routes/get-route.js +63 -50
- package/build/src/routes/hooks/frontend-model-command-route-hook.js +80 -66
- package/build/src/routes/index.js +43 -36
- package/build/src/routes/namespace-route.js +47 -38
- package/build/src/routes/plugin-routes.js +124 -107
- package/build/src/routes/post-route.js +62 -51
- package/build/src/routes/resolver.js +494 -422
- package/build/src/routes/resource-route.js +143 -124
- package/build/src/routes/root-route.js +8 -7
- package/build/src/testing/base-expect.js +14 -13
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +405 -329
- package/build/src/testing/browser-test-app.js +29 -23
- package/build/src/testing/expect-to-change.js +50 -41
- package/build/src/testing/expect-utils.js +184 -139
- package/build/src/testing/expect.js +731 -638
- package/build/src/testing/request-client.js +85 -70
- package/build/src/testing/test-files-finder.js +339 -285
- package/build/src/testing/test-filter-parser.js +155 -124
- package/build/src/testing/test-runner.js +1020 -883
- package/build/src/testing/test-suite-splitter.js +142 -114
- package/build/src/testing/test.js +256 -216
- package/build/src/utils/backtrace-cleaner-node.js +69 -62
- package/build/src/utils/backtrace-cleaner.js +216 -188
- package/build/src/utils/ensure-error.js +7 -7
- package/build/src/utils/event-emitter.js +6 -4
- package/build/src/utils/file-exists.js +10 -9
- package/build/src/utils/format-value.js +76 -67
- package/build/src/utils/model-scope.js +31 -27
- package/build/src/utils/nest-callbacks.js +13 -10
- package/build/src/utils/plain-object.js +6 -5
- package/build/src/utils/ransack.d.ts.map +1 -1
- package/build/src/utils/ransack.js +563 -449
- package/build/src/utils/rest-args-error.js +6 -5
- package/build/src/utils/singularize-model-name.js +11 -9
- package/build/src/utils/split-sql-statements.js +79 -68
- package/build/src/utils/to-import-specifier.js +30 -24
- package/build/src/utils/with-tracked-stack-async-hooks.js +74 -60
- package/build/src/utils/with-tracked-stack.js +18 -14
- package/build/src/velocious-error.js +30 -27
- package/index.js +1 -0
- package/package.json +10 -4
- package/scripts/clean-build.js +8 -0
- package/scripts/ensure-bin-executable.js +13 -0
- package/scripts/run-tests.js +37 -0
- package/scripts/test-browser.js +486 -0
- package/src/application.js +229 -0
- package/src/authorization/ability.js +329 -0
- package/src/authorization/base-resource.js +143 -0
- package/src/background-jobs/client.js +50 -0
- package/src/background-jobs/cron-expression.js +277 -0
- package/src/background-jobs/forked-runner-child.js +86 -0
- package/src/background-jobs/job-record.js +13 -0
- package/src/background-jobs/job-registry.js +92 -0
- package/src/background-jobs/job-runner.js +107 -0
- package/src/background-jobs/job.js +77 -0
- package/src/background-jobs/json-socket.js +78 -0
- package/src/background-jobs/main.js +926 -0
- package/src/background-jobs/normalize-error.js +26 -0
- package/src/background-jobs/scheduler.js +274 -0
- package/src/background-jobs/socket-request.js +68 -0
- package/src/background-jobs/status-reporter.js +101 -0
- package/src/background-jobs/store.js +994 -0
- package/src/background-jobs/types.js +70 -0
- package/src/background-jobs/web/authorization.js +89 -0
- package/src/background-jobs/web/controller.js +280 -0
- package/src/background-jobs/web/index.js +57 -0
- package/src/background-jobs/web/path-matcher.js +74 -0
- package/src/background-jobs/web/registry.js +49 -0
- package/src/background-jobs/worker.js +683 -0
- package/src/beacon/client.js +330 -0
- package/src/beacon/in-process-broker.js +71 -0
- package/src/beacon/in-process-client.js +139 -0
- package/src/beacon/server.js +148 -0
- package/src/beacon/types.js +55 -0
- package/src/cli/base-command.js +67 -0
- package/src/cli/browser-cli.js +45 -0
- package/src/cli/commands/background-jobs-main.js +7 -0
- package/src/cli/commands/background-jobs-runner.js +7 -0
- package/src/cli/commands/background-jobs-worker.js +7 -0
- package/src/cli/commands/beacon.js +7 -0
- package/src/cli/commands/console.js +12 -0
- package/src/cli/commands/db/base-command.js +82 -0
- package/src/cli/commands/db/create.js +64 -0
- package/src/cli/commands/db/drop.js +75 -0
- package/src/cli/commands/db/migrate.js +17 -0
- package/src/cli/commands/db/reset.js +22 -0
- package/src/cli/commands/db/rollback.js +15 -0
- package/src/cli/commands/db/schema/dump.js +12 -0
- package/src/cli/commands/db/schema/load.js +12 -0
- package/src/cli/commands/db/seed.js +12 -0
- package/src/cli/commands/db/tenants/check.js +38 -0
- package/src/cli/commands/db/tenants/create.js +33 -0
- package/src/cli/commands/db/tenants/migrate.js +49 -0
- package/src/cli/commands/destroy/migration.js +7 -0
- package/src/cli/commands/generate/base-models.js +7 -0
- package/src/cli/commands/generate/frontend-models.js +12 -0
- package/src/cli/commands/generate/migration.js +7 -0
- package/src/cli/commands/generate/model.js +7 -0
- package/src/cli/commands/init.js +11 -0
- package/src/cli/commands/routes.js +7 -0
- package/src/cli/commands/run-script.js +12 -0
- package/src/cli/commands/runner.js +12 -0
- package/src/cli/commands/server.js +7 -0
- package/src/cli/commands/test.js +9 -0
- package/src/cli/index.js +152 -0
- package/src/cli/tenant-database-command-helper.js +198 -0
- package/src/cli/use-browser-cli.js +30 -0
- package/src/configuration-resolver.js +65 -0
- package/src/configuration-types.js +429 -0
- package/src/configuration.js +2590 -0
- package/src/controller.js +421 -0
- package/src/current-configuration.js +31 -0
- package/src/current.js +80 -0
- package/src/database/annotations-async-hooks.js +47 -0
- package/src/database/annotations.js +40 -0
- package/src/database/drivers/base-column.js +182 -0
- package/src/database/drivers/base-columns-index.js +81 -0
- package/src/database/drivers/base-foreign-key.js +104 -0
- package/src/database/drivers/base-table.js +156 -0
- package/src/database/drivers/base.js +1609 -0
- package/src/database/drivers/mssql/column.js +74 -0
- package/src/database/drivers/mssql/columns-index.js +6 -0
- package/src/database/drivers/mssql/connect-connection.js +16 -0
- package/src/database/drivers/mssql/foreign-key.js +12 -0
- package/src/database/drivers/mssql/index.js +590 -0
- package/src/database/drivers/mssql/options.js +79 -0
- package/src/database/drivers/mssql/query-parser.js +6 -0
- package/src/database/drivers/mssql/sql/alter-table.js +4 -0
- package/src/database/drivers/mssql/sql/create-database.js +36 -0
- package/src/database/drivers/mssql/sql/create-index.js +4 -0
- package/src/database/drivers/mssql/sql/create-table.js +4 -0
- package/src/database/drivers/mssql/sql/delete.js +19 -0
- package/src/database/drivers/mssql/sql/drop-database.js +36 -0
- package/src/database/drivers/mssql/sql/drop-table.js +4 -0
- package/src/database/drivers/mssql/sql/insert.js +4 -0
- package/src/database/drivers/mssql/sql/update.js +31 -0
- package/src/database/drivers/mssql/sql/upsert.js +23 -0
- package/src/database/drivers/mssql/structure-sql.js +120 -0
- package/src/database/drivers/mssql/table.js +145 -0
- package/src/database/drivers/mysql/column.js +112 -0
- package/src/database/drivers/mysql/columns-index.js +22 -0
- package/src/database/drivers/mysql/foreign-key.js +12 -0
- package/src/database/drivers/mysql/index.js +473 -0
- package/src/database/drivers/mysql/options.js +34 -0
- package/src/database/drivers/mysql/query-parser.js +6 -0
- package/src/database/drivers/mysql/query.js +37 -0
- package/src/database/drivers/mysql/sql/alter-table.js +6 -0
- package/src/database/drivers/mysql/sql/create-database.js +39 -0
- package/src/database/drivers/mysql/sql/create-index.js +6 -0
- package/src/database/drivers/mysql/sql/create-table.js +6 -0
- package/src/database/drivers/mysql/sql/delete.js +21 -0
- package/src/database/drivers/mysql/sql/drop-database.js +6 -0
- package/src/database/drivers/mysql/sql/drop-table.js +6 -0
- package/src/database/drivers/mysql/sql/insert.js +6 -0
- package/src/database/drivers/mysql/sql/update.js +33 -0
- package/src/database/drivers/mysql/sql/upsert.js +13 -0
- package/src/database/drivers/mysql/structure-sql.js +93 -0
- package/src/database/drivers/mysql/table.js +121 -0
- package/src/database/drivers/pgsql/column.js +90 -0
- package/src/database/drivers/pgsql/columns-index.js +6 -0
- package/src/database/drivers/pgsql/foreign-key.js +12 -0
- package/src/database/drivers/pgsql/index.js +441 -0
- package/src/database/drivers/pgsql/options.js +32 -0
- package/src/database/drivers/pgsql/query-parser.js +6 -0
- package/src/database/drivers/pgsql/sql/alter-table.js +6 -0
- package/src/database/drivers/pgsql/sql/create-database.js +38 -0
- package/src/database/drivers/pgsql/sql/create-index.js +6 -0
- package/src/database/drivers/pgsql/sql/create-table.js +6 -0
- package/src/database/drivers/pgsql/sql/delete.js +21 -0
- package/src/database/drivers/pgsql/sql/drop-database.js +6 -0
- package/src/database/drivers/pgsql/sql/drop-table.js +6 -0
- package/src/database/drivers/pgsql/sql/insert.js +6 -0
- package/src/database/drivers/pgsql/sql/update.js +33 -0
- package/src/database/drivers/pgsql/sql/upsert.js +14 -0
- package/src/database/drivers/pgsql/structure-sql.js +126 -0
- package/src/database/drivers/pgsql/table.js +135 -0
- package/src/database/drivers/sqlite/base.js +509 -0
- package/src/database/drivers/sqlite/column.js +75 -0
- package/src/database/drivers/sqlite/columns-index.js +30 -0
- package/src/database/drivers/sqlite/connection-sql-js.js +46 -0
- package/src/database/drivers/sqlite/foreign-key.js +24 -0
- package/src/database/drivers/sqlite/index.js +394 -0
- package/src/database/drivers/sqlite/index.native.js +72 -0
- package/src/database/drivers/sqlite/index.web.js +99 -0
- package/src/database/drivers/sqlite/options.js +32 -0
- package/src/database/drivers/sqlite/query-parser.js +6 -0
- package/src/database/drivers/sqlite/query.js +35 -0
- package/src/database/drivers/sqlite/query.native.js +35 -0
- package/src/database/drivers/sqlite/query.web.js +49 -0
- package/src/database/drivers/sqlite/sql/alter-table.js +187 -0
- package/src/database/drivers/sqlite/sql/create-index.js +6 -0
- package/src/database/drivers/sqlite/sql/create-table.js +6 -0
- package/src/database/drivers/sqlite/sql/delete.js +26 -0
- package/src/database/drivers/sqlite/sql/drop-table.js +6 -0
- package/src/database/drivers/sqlite/sql/insert.js +6 -0
- package/src/database/drivers/sqlite/sql/update.js +33 -0
- package/src/database/drivers/sqlite/sql/upsert.js +14 -0
- package/src/database/drivers/sqlite/structure-sql.js +56 -0
- package/src/database/drivers/sqlite/table-rebuilder.js +96 -0
- package/src/database/drivers/sqlite/table.js +131 -0
- package/src/database/drivers/structure-sql/utils.js +35 -0
- package/src/database/handler.js +13 -0
- package/src/database/initializer-from-require-context.js +101 -0
- package/src/database/migration/index.js +438 -0
- package/src/database/migrator/files-finder.js +55 -0
- package/src/database/migrator/types.js +31 -0
- package/src/database/migrator.js +557 -0
- package/src/database/pool/async-tracked-multi-connection.js +1164 -0
- package/src/database/pool/base-methods-forward.js +52 -0
- package/src/database/pool/base.js +380 -0
- package/src/database/pool/single-multi-use.js +118 -0
- package/src/database/query/alter-table-base.js +104 -0
- package/src/database/query/base.js +49 -0
- package/src/database/query/create-database-base.js +42 -0
- package/src/database/query/create-index-base.js +117 -0
- package/src/database/query/create-table-base.js +205 -0
- package/src/database/query/delete-base.js +19 -0
- package/src/database/query/drop-database-base.js +38 -0
- package/src/database/query/drop-table-base.js +58 -0
- package/src/database/query/from-base.js +36 -0
- package/src/database/query/from-plain.js +16 -0
- package/src/database/query/from-table.js +18 -0
- package/src/database/query/index.js +533 -0
- package/src/database/query/insert-base.js +172 -0
- package/src/database/query/join-base.js +43 -0
- package/src/database/query/join-object.js +167 -0
- package/src/database/query/join-plain.js +18 -0
- package/src/database/query/join-tracker.js +93 -0
- package/src/database/query/model-class-query.js +1577 -0
- package/src/database/query/order-base.js +33 -0
- package/src/database/query/order-column.js +77 -0
- package/src/database/query/order-plain.js +28 -0
- package/src/database/query/preloader/belongs-to.js +267 -0
- package/src/database/query/preloader/ensure-model-class-initialized.js +18 -0
- package/src/database/query/preloader/has-many.js +316 -0
- package/src/database/query/preloader/has-one.js +123 -0
- package/src/database/query/preloader/selection.js +152 -0
- package/src/database/query/preloader.js +201 -0
- package/src/database/query/query-data.js +305 -0
- package/src/database/query/select-base.js +30 -0
- package/src/database/query/select-plain.js +18 -0
- package/src/database/query/select-table-and-column.js +28 -0
- package/src/database/query/update-base.js +41 -0
- package/src/database/query/upsert-base.js +103 -0
- package/src/database/query/where-base.js +38 -0
- package/src/database/query/where-combinator.js +31 -0
- package/src/database/query/where-hash.js +77 -0
- package/src/database/query/where-model-class-hash.js +505 -0
- package/src/database/query/where-not.js +23 -0
- package/src/database/query/where-plain.js +20 -0
- package/src/database/query/with-count.js +219 -0
- package/src/database/query-parser/base-query-parser.js +40 -0
- package/src/database/query-parser/from-parser.js +49 -0
- package/src/database/query-parser/group-parser.js +55 -0
- package/src/database/query-parser/joins-parser.js +37 -0
- package/src/database/query-parser/limit-parser.js +77 -0
- package/src/database/query-parser/options.js +94 -0
- package/src/database/query-parser/order-parser.js +45 -0
- package/src/database/query-parser/select-parser.js +67 -0
- package/src/database/query-parser/where-parser.js +46 -0
- package/src/database/record/acts-as-list.js +374 -0
- package/src/database/record/attachments/download.js +49 -0
- package/src/database/record/attachments/handle.js +188 -0
- package/src/database/record/attachments/normalize-input.js +213 -0
- package/src/database/record/attachments/storage-drivers/filesystem.js +114 -0
- package/src/database/record/attachments/storage-drivers/native.js +146 -0
- package/src/database/record/attachments/storage-drivers/s3.js +245 -0
- package/src/database/record/attachments/store.js +591 -0
- package/src/database/record/index.js +3970 -0
- package/src/database/record/instance-relationships/base.js +289 -0
- package/src/database/record/instance-relationships/belongs-to.js +84 -0
- package/src/database/record/instance-relationships/has-many.js +284 -0
- package/src/database/record/instance-relationships/has-one.js +117 -0
- package/src/database/record/record-not-found-error.js +3 -0
- package/src/database/record/relationships/base.js +195 -0
- package/src/database/record/relationships/belongs-to.js +57 -0
- package/src/database/record/relationships/has-many.js +46 -0
- package/src/database/record/relationships/has-one.js +46 -0
- package/src/database/record/state-machine.js +278 -0
- package/src/database/record/user-module.js +43 -0
- package/src/database/record/validators/base.js +27 -0
- package/src/database/record/validators/format.js +50 -0
- package/src/database/record/validators/presence.js +24 -0
- package/src/database/record/validators/uniqueness.js +124 -0
- package/src/database/table-data/index.js +241 -0
- package/src/database/table-data/table-column.js +416 -0
- package/src/database/table-data/table-foreign-key.js +69 -0
- package/src/database/table-data/table-index.js +46 -0
- package/src/database/table-data/table-reference.js +13 -0
- package/src/database/use-database.js +48 -0
- package/src/environment-handlers/base.js +561 -0
- package/src/environment-handlers/browser.js +338 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
- package/src/environment-handlers/node/cli/commands/beacon.js +21 -0
- package/src/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
- package/src/environment-handlers/node/cli/commands/console.js +149 -0
- package/src/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
- package/src/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
- package/src/environment-handlers/node/cli/commands/db/seed.js +79 -0
- package/src/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +367 -0
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
- package/src/environment-handlers/node/cli/commands/generate/migration.js +45 -0
- package/src/environment-handlers/node/cli/commands/generate/model.js +45 -0
- package/src/environment-handlers/node/cli/commands/init.js +68 -0
- package/src/environment-handlers/node/cli/commands/routes.js +63 -0
- package/src/environment-handlers/node/cli/commands/run-script.js +85 -0
- package/src/environment-handlers/node/cli/commands/runner.js +84 -0
- package/src/environment-handlers/node/cli/commands/server.js +151 -0
- package/src/environment-handlers/node/cli/commands/test.js +118 -0
- package/src/environment-handlers/node.js +887 -0
- package/src/error-logger.js +30 -0
- package/src/frontend-model-controller.js +3491 -0
- package/src/frontend-model-resource/base-resource.js +935 -0
- package/src/frontend-models/base.js +4004 -0
- package/src/frontend-models/clear-pending-debounced-callback.js +16 -0
- package/src/frontend-models/event-hook-models.js +49 -0
- package/src/frontend-models/model-registry.js +28 -0
- package/src/frontend-models/outgoing-event-buffer.js +51 -0
- package/src/frontend-models/preloader.js +169 -0
- package/src/frontend-models/query.js +2245 -0
- package/src/frontend-models/resource-config-validation.js +56 -0
- package/src/frontend-models/resource-definition.js +399 -0
- package/src/frontend-models/transport-serialization.js +369 -0
- package/src/frontend-models/use-created-event.js +21 -0
- package/src/frontend-models/use-destroyed-event.js +148 -0
- package/src/frontend-models/use-model-class-event.js +164 -0
- package/src/frontend-models/use-updated-event.js +152 -0
- package/src/frontend-models/websocket-channel.js +494 -0
- package/src/frontend-models/websocket-publishers.js +224 -0
- package/src/http-client/header.js +17 -0
- package/src/http-client/index.js +139 -0
- package/src/http-client/request.js +94 -0
- package/src/http-client/response.js +151 -0
- package/src/http-client/websocket-client.js +27 -0
- package/src/http-server/client/index.js +507 -0
- package/src/http-server/client/params-to-object.js +152 -0
- package/src/http-server/client/request-buffer/form-data-part.js +139 -0
- package/src/http-server/client/request-buffer/header.js +19 -0
- package/src/http-server/client/request-buffer/index.js +535 -0
- package/src/http-server/client/request-parser.js +195 -0
- package/src/http-server/client/request-runner.js +321 -0
- package/src/http-server/client/request-timing.js +171 -0
- package/src/http-server/client/request.js +114 -0
- package/src/http-server/client/response.js +251 -0
- package/src/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
- package/src/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
- package/src/http-server/client/uploaded-file/uploaded-file.js +36 -0
- package/src/http-server/client/websocket-request.js +147 -0
- package/src/http-server/client/websocket-session.js +1755 -0
- package/src/http-server/cookie.js +245 -0
- package/src/http-server/development-reloader.js +240 -0
- package/src/http-server/index.js +561 -0
- package/src/http-server/remote-address.js +77 -0
- package/src/http-server/server-client.js +222 -0
- package/src/http-server/server-lock.js +178 -0
- package/src/http-server/websocket-channel-subscribers.js +110 -0
- package/src/http-server/websocket-channel.js +137 -0
- package/src/http-server/websocket-connection.js +118 -0
- package/src/http-server/websocket-event-log-store.js +433 -0
- package/src/http-server/websocket-events-host.js +170 -0
- package/src/http-server/websocket-events.js +50 -0
- package/src/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
- package/src/http-server/worker-handler/in-process.js +155 -0
- package/src/http-server/worker-handler/index.js +370 -0
- package/src/http-server/worker-handler/worker-script.js +6 -0
- package/src/http-server/worker-handler/worker-thread.js +286 -0
- package/src/initializer.js +39 -0
- package/src/jobs/.gitkeep +1 -0
- package/src/jobs/mail-delivery.js +22 -0
- package/src/logger/base-logger.js +34 -0
- package/src/logger/console-logger.js +28 -0
- package/src/logger/file-logger.js +36 -0
- package/src/logger/outputs/array-output.js +50 -0
- package/src/logger/outputs/console-output.js +32 -0
- package/src/logger/outputs/file-output.js +55 -0
- package/src/logger/outputs/stdout-output.js +64 -0
- package/src/logger.js +507 -0
- package/src/mailer/backends/smtp.js +197 -0
- package/src/mailer/base.js +337 -0
- package/src/mailer/delivery.js +70 -0
- package/src/mailer/index.js +24 -0
- package/src/mailer.js +15 -0
- package/src/plugins/sqljs-wasm-route-controller.js +70 -0
- package/src/plugins/sqljs-wasm-route.js +71 -0
- package/src/record-payload-values.js +83 -0
- package/src/routes/app-routes.js +17 -0
- package/src/routes/base-route.js +133 -0
- package/src/routes/basic-route.js +109 -0
- package/src/routes/built-in/debug/controller.js +12 -0
- package/src/routes/built-in/errors/controller.js +7 -0
- package/src/routes/built-in/errors/not-found.ejs +1 -0
- package/src/routes/get-route.js +75 -0
- package/src/routes/hooks/frontend-model-command-route-hook.js +100 -0
- package/src/routes/index.js +50 -0
- package/src/routes/namespace-route.js +51 -0
- package/src/routes/plugin-routes.js +141 -0
- package/src/routes/post-route.js +74 -0
- package/src/routes/resolver.js +535 -0
- package/src/routes/resource-route.js +154 -0
- package/src/routes/root-route.js +11 -0
- package/src/templates/configuration.js +61 -0
- package/src/templates/generate-migration.js +11 -0
- package/src/templates/generate-model.js +6 -0
- package/src/templates/routes.js +11 -0
- package/src/testing/base-expect.js +17 -0
- package/src/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
- package/src/testing/browser-test-app.js +32 -0
- package/src/testing/expect-to-change.js +55 -0
- package/src/testing/expect-utils.js +269 -0
- package/src/testing/expect.js +763 -0
- package/src/testing/request-client.js +90 -0
- package/src/testing/test-files-finder.js +364 -0
- package/src/testing/test-filter-parser.js +198 -0
- package/src/testing/test-runner.js +1168 -0
- package/src/testing/test-suite-splitter.js +177 -0
- package/src/testing/test.js +370 -0
- package/src/types/external-modules.d.ts +57 -0
- package/src/utils/backtrace-cleaner-node.js +87 -0
- package/src/utils/backtrace-cleaner.js +266 -0
- package/src/utils/ensure-error.js +15 -0
- package/src/utils/event-emitter.js +8 -0
- package/src/utils/file-exists.js +18 -0
- package/src/utils/format-value.js +101 -0
- package/src/utils/model-scope.js +56 -0
- package/src/utils/nest-callbacks.js +22 -0
- package/src/utils/plain-object.js +14 -0
- package/src/utils/ransack.js +859 -0
- package/src/utils/rest-args-error.js +14 -0
- package/src/utils/singularize-model-name.js +18 -0
- package/src/utils/split-sql-statements.js +88 -0
- package/src/utils/to-import-specifier.js +53 -0
- package/src/utils/with-tracked-stack-async-hooks.js +103 -0
- package/src/utils/with-tracked-stack.js +38 -0
- package/src/velocious-error.js +34 -0
- package/tsconfig.json +16 -0
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
2
|
+
|
|
3
|
+
import * as inflection from "inflection"
|
|
4
|
+
import {isPlainObject} from "is-plain-object"
|
|
5
|
+
import {resolveFrontendModelClass} from "../frontend-models/model-registry.js"
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* RansackPredicate type.
|
|
7
9
|
* @typedef {"cont" | "end" | "eq" | "gt" | "gteq" | "in" | "lt" | "lteq" | "not_eq" | "not_in" | "null" | "start"} RansackPredicate
|
|
8
10
|
*/
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* RansackCombinator type.
|
|
11
14
|
* @typedef {"and" | "or"} RansackCombinator
|
|
12
15
|
*/
|
|
16
|
+
|
|
13
17
|
/**
|
|
14
18
|
* RansackModelClass type.
|
|
15
19
|
* @typedef {typeof import("../database/record/index.js").default | typeof import("../frontend-models/base.js").default} RansackModelClass
|
|
16
20
|
*/
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* RansackAttribute type.
|
|
19
24
|
* @typedef {object} RansackAttribute
|
|
20
25
|
* @property {string} attributeName - Resolved attribute name.
|
|
21
26
|
* @property {string[]} path - Resolved relationship path.
|
|
22
27
|
*/
|
|
28
|
+
|
|
23
29
|
/**
|
|
24
30
|
* RansackCondition type.
|
|
25
31
|
* @typedef {object} RansackCondition
|
|
@@ -28,6 +34,7 @@ import { resolveFrontendModelClass } from "../frontend-models/model-registry.js"
|
|
|
28
34
|
* @property {RansackPredicate} predicate - Parsed Ransack predicate.
|
|
29
35
|
* @property {?} value - Normalized value.
|
|
30
36
|
*/
|
|
37
|
+
|
|
31
38
|
/**
|
|
32
39
|
* RansackGroup type.
|
|
33
40
|
* @typedef {object} RansackGroup
|
|
@@ -35,30 +42,32 @@ import { resolveFrontendModelClass } from "../frontend-models/model-registry.js"
|
|
|
35
42
|
* @property {RansackCondition[]} conditions - Conditions in this group.
|
|
36
43
|
* @property {RansackGroup[]} groupings - Nested groups.
|
|
37
44
|
*/
|
|
45
|
+
|
|
38
46
|
const supportedPredicates = [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
]
|
|
47
|
+
"not_in",
|
|
48
|
+
"not_eq",
|
|
49
|
+
"gteq",
|
|
50
|
+
"lteq",
|
|
51
|
+
"start",
|
|
52
|
+
"cont",
|
|
53
|
+
"null",
|
|
54
|
+
"end",
|
|
55
|
+
"eq",
|
|
56
|
+
"gt",
|
|
57
|
+
"lt",
|
|
58
|
+
"in"
|
|
59
|
+
]
|
|
60
|
+
|
|
52
61
|
/**
|
|
53
62
|
* Runs the normalizeRansackParams helper.
|
|
54
63
|
* @param {RansackModelClass} modelClass - Model class.
|
|
55
64
|
* @param {Record<string, ?>} params - Ransack-style params hash.
|
|
56
65
|
* @returns {RansackCondition[]} - Normalized conditions.
|
|
57
66
|
*/
|
|
58
|
-
// fallow-ignore-next-line unused-export
|
|
59
67
|
export function normalizeRansackParams(modelClass, params) {
|
|
60
|
-
|
|
68
|
+
return normalizeRansackGroup(modelClass, params).conditions
|
|
61
69
|
}
|
|
70
|
+
|
|
62
71
|
/**
|
|
63
72
|
* Runs the normalizeRansackGroup helper.
|
|
64
73
|
* @param {RansackModelClass} modelClass - Model class.
|
|
@@ -66,36 +75,43 @@ export function normalizeRansackParams(modelClass, params) {
|
|
|
66
75
|
* @returns {RansackGroup} - Normalized group.
|
|
67
76
|
*/
|
|
68
77
|
export function normalizeRansackGroup(modelClass, params) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
78
|
+
if (!isPlainObject(params)) {
|
|
79
|
+
throw new Error(`ransack params must be a plain object, got: ${typeof params}`)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Normalized.
|
|
84
|
+
@type {RansackGroup} */
|
|
85
|
+
const normalized = {
|
|
86
|
+
combinator: normalizeRansackCombinator(params.m, "and"),
|
|
87
|
+
conditions: [],
|
|
88
|
+
groupings: []
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const [key, rawValue] of Object.entries(params)) {
|
|
92
|
+
if (key === "m") {
|
|
93
|
+
continue
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (key === "c") {
|
|
97
|
+
normalized.conditions.push(...normalizeAdvancedRansackConditions({modelClass, value: rawValue}))
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (key === "g") {
|
|
102
|
+
normalized.groupings.push(...normalizeAdvancedRansackGroups({modelClass, value: rawValue}))
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const condition = normalizeSimpleRansackCondition({key, modelClass, rawValue})
|
|
107
|
+
if (condition) normalized.conditions.push(condition)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return normalized
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const SKIP_RANSACK_CONDITION = Symbol("skip-ransack-condition")
|
|
114
|
+
|
|
99
115
|
/**
|
|
100
116
|
* Runs normalize simple ransack condition.
|
|
101
117
|
* @param {object} args - Options.
|
|
@@ -104,25 +120,30 @@ const SKIP_RANSACK_CONDITION = Symbol("skip-ransack-condition");
|
|
|
104
120
|
* @param {?} args.rawValue - Raw condition value.
|
|
105
121
|
* @returns {RansackCondition | null} - Normalized condition, or null when skipped.
|
|
106
122
|
*/
|
|
107
|
-
function normalizeSimpleRansackCondition({
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
function normalizeSimpleRansackCondition({key, modelClass, rawValue}) {
|
|
124
|
+
const parsedKey = parseRansackKey(key)
|
|
125
|
+
|
|
126
|
+
if (!parsedKey) {
|
|
127
|
+
throw new Error(`Unsupported ransack predicate in key: ${key}`)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const value = normalizeRansackValue({
|
|
131
|
+
predicate: parsedKey.predicate,
|
|
132
|
+
value: rawValue
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
if (value === SKIP_RANSACK_CONDITION) return null
|
|
136
|
+
|
|
137
|
+
const attributes = resolveRansackAttributes({modelClass, value: parsedKey.pathValue})
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
attributes,
|
|
141
|
+
combinator: attributes.length > 1 ? "or" : "and",
|
|
142
|
+
predicate: parsedKey.predicate,
|
|
143
|
+
value
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
126
147
|
/**
|
|
127
148
|
* Runs normalize advanced ransack conditions.
|
|
128
149
|
* @param {object} args - Options.
|
|
@@ -130,39 +151,48 @@ function normalizeSimpleRansackCondition({ key, modelClass, rawValue }) {
|
|
|
130
151
|
* @param {?} args.value - Advanced conditions collection.
|
|
131
152
|
* @returns {RansackCondition[]} - Normalized conditions.
|
|
132
153
|
*/
|
|
133
|
-
function normalizeAdvancedRansackConditions({
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
154
|
+
function normalizeAdvancedRansackConditions({modelClass, value}) {
|
|
155
|
+
/**
|
|
156
|
+
* Conditions.
|
|
157
|
+
@type {RansackCondition[]} */
|
|
158
|
+
const conditions = []
|
|
159
|
+
|
|
160
|
+
for (const entry of normalizeRansackCollection(value, "conditions")) {
|
|
161
|
+
if (!isPlainObject(entry)) {
|
|
162
|
+
throw new Error(`Ransack condition entries must be plain objects, got: ${typeof entry}`)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const predicateValue = entry.p
|
|
166
|
+
|
|
167
|
+
if (typeof predicateValue !== "string") {
|
|
168
|
+
throw new Error("Ransack condition predicate must be a string")
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!supportedPredicates.includes(predicateValue)) {
|
|
172
|
+
throw new Error(`Unsupported ransack predicate in condition: ${predicateValue}`)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const predicate = /**
|
|
176
|
+
* Narrows the runtime value to the documented type.
|
|
177
|
+
@type {RansackPredicate} */ (predicateValue)
|
|
178
|
+
const rawValue = advancedRansackConditionValue({predicate, value: entry.v})
|
|
179
|
+
const normalizedValue = normalizeRansackValue({predicate, value: rawValue})
|
|
180
|
+
|
|
181
|
+
if (normalizedValue === SKIP_RANSACK_CONDITION) continue
|
|
182
|
+
|
|
183
|
+
const attributes = resolveRansackAttributesFromAdvancedValue({modelClass, value: entry.a})
|
|
184
|
+
|
|
185
|
+
conditions.push({
|
|
186
|
+
attributes,
|
|
187
|
+
combinator: normalizeRansackCombinator(entry.m, attributes.length > 1 ? "or" : "and"),
|
|
188
|
+
predicate,
|
|
189
|
+
value: normalizedValue
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return conditions
|
|
194
|
+
}
|
|
195
|
+
|
|
166
196
|
/**
|
|
167
197
|
* Runs normalize advanced ransack groups.
|
|
168
198
|
* @param {object} args - Options.
|
|
@@ -170,19 +200,23 @@ function normalizeAdvancedRansackConditions({ modelClass, value }) {
|
|
|
170
200
|
* @param {?} args.value - Advanced groups collection.
|
|
171
201
|
* @returns {RansackGroup[]} - Normalized groups.
|
|
172
202
|
*/
|
|
173
|
-
function normalizeAdvancedRansackGroups({
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
groupings.push(normalizeRansackGroup(modelClass, entry));
|
|
203
|
+
function normalizeAdvancedRansackGroups({modelClass, value}) {
|
|
204
|
+
/**
|
|
205
|
+
* Groupings.
|
|
206
|
+
@type {RansackGroup[]} */
|
|
207
|
+
const groupings = []
|
|
208
|
+
|
|
209
|
+
for (const entry of normalizeRansackCollection(value, "groupings")) {
|
|
210
|
+
if (!isPlainObject(entry)) {
|
|
211
|
+
throw new Error(`Ransack grouping entries must be plain objects, got: ${typeof entry}`)
|
|
183
212
|
}
|
|
184
|
-
|
|
213
|
+
|
|
214
|
+
groupings.push(normalizeRansackGroup(modelClass, entry))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return groupings
|
|
185
218
|
}
|
|
219
|
+
|
|
186
220
|
/**
|
|
187
221
|
* Runs normalize ransack combinator.
|
|
188
222
|
* @param {?} value - Candidate combinator.
|
|
@@ -190,12 +224,12 @@ function normalizeAdvancedRansackGroups({ modelClass, value }) {
|
|
|
190
224
|
* @returns {RansackCombinator} - Normalized combinator.
|
|
191
225
|
*/
|
|
192
226
|
function normalizeRansackCombinator(value, defaultValue) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
throw new Error(`Invalid ransack combinator: ${String(value)}`);
|
|
227
|
+
if (value === undefined || value === null || value === "") return defaultValue
|
|
228
|
+
if (value === "and" || value === "or") return value
|
|
229
|
+
|
|
230
|
+
throw new Error(`Invalid ransack combinator: ${String(value)}`)
|
|
198
231
|
}
|
|
232
|
+
|
|
199
233
|
/**
|
|
200
234
|
* Runs normalize ransack collection.
|
|
201
235
|
* @param {?} value - Candidate collection.
|
|
@@ -203,24 +237,27 @@ function normalizeRansackCombinator(value, defaultValue) {
|
|
|
203
237
|
* @returns {Array<?>} - Collection values in stable order.
|
|
204
238
|
*/
|
|
205
239
|
function normalizeRansackCollection(value, name) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
240
|
+
if (value === undefined || value === null || value === "") return []
|
|
241
|
+
if (Array.isArray(value)) return value
|
|
242
|
+
|
|
243
|
+
if (isPlainObject(value)) {
|
|
244
|
+
return Object.keys(value)
|
|
245
|
+
.sort((left, right) => {
|
|
246
|
+
const leftNumber = Number(left)
|
|
247
|
+
const rightNumber = Number(right)
|
|
248
|
+
|
|
249
|
+
if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {
|
|
250
|
+
return leftNumber - rightNumber
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return left.localeCompare(right)
|
|
254
|
+
})
|
|
255
|
+
.map((key) => value[key])
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
throw new Error(`Ransack ${name} must be an array or object, got: ${typeof value}`)
|
|
223
259
|
}
|
|
260
|
+
|
|
224
261
|
/**
|
|
225
262
|
* Runs advanced ransack condition value.
|
|
226
263
|
* @param {object} args - Options.
|
|
@@ -228,14 +265,16 @@ function normalizeRansackCollection(value, name) {
|
|
|
228
265
|
* @param {?} args.value - Advanced condition value.
|
|
229
266
|
* @returns {?} - Value passed to predicate normalization.
|
|
230
267
|
*/
|
|
231
|
-
function advancedRansackConditionValue({
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
268
|
+
function advancedRansackConditionValue({predicate, value}) {
|
|
269
|
+
if (predicate === "in" || predicate === "not_in") return value
|
|
270
|
+
|
|
271
|
+
if (Array.isArray(value)) {
|
|
272
|
+
return value.find((entry) => entry !== undefined && entry !== null && entry !== "")
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return value
|
|
238
276
|
}
|
|
277
|
+
|
|
239
278
|
/**
|
|
240
279
|
* Runs resolve ransack attributes from advanced value.
|
|
241
280
|
* @param {object} args - Options.
|
|
@@ -243,49 +282,58 @@ function advancedRansackConditionValue({ predicate, value }) {
|
|
|
243
282
|
* @param {?} args.value - Advanced attribute value.
|
|
244
283
|
* @returns {RansackAttribute[]} - Resolved attributes.
|
|
245
284
|
*/
|
|
246
|
-
function resolveRansackAttributesFromAdvancedValue({
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
285
|
+
function resolveRansackAttributesFromAdvancedValue({modelClass, value}) {
|
|
286
|
+
const values = normalizeAdvancedAttributeValues(value)
|
|
287
|
+
/**
|
|
288
|
+
* Attributes.
|
|
289
|
+
@type {RansackAttribute[]} */
|
|
290
|
+
const attributes = []
|
|
291
|
+
|
|
292
|
+
for (const attributeValue of values) {
|
|
293
|
+
attributes.push(...resolveRansackAttributes({modelClass, value: attributeValue}))
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (attributes.length < 1) {
|
|
297
|
+
throw new Error("Ransack condition must include at least one attribute")
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return attributes
|
|
301
|
+
}
|
|
302
|
+
|
|
260
303
|
/**
|
|
261
304
|
* Runs normalize advanced attribute values.
|
|
262
305
|
* @param {?} value - Advanced attribute value.
|
|
263
306
|
* @returns {string[]} - Attribute path strings.
|
|
264
307
|
*/
|
|
265
308
|
function normalizeAdvancedAttributeValues(value) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
309
|
+
if (typeof value === "string") return [value]
|
|
310
|
+
|
|
311
|
+
if (Array.isArray(value)) {
|
|
312
|
+
return value.map((entry) => normalizeAdvancedAttributeValue(entry))
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (isPlainObject(value)) {
|
|
316
|
+
return normalizeRansackCollection(value, "attributes").map((entry) => normalizeAdvancedAttributeValue(entry))
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
throw new Error(`Ransack condition attributes must be strings, arrays, or objects, got: ${typeof value}`)
|
|
320
|
+
}
|
|
321
|
+
|
|
276
322
|
/**
|
|
277
323
|
* Runs normalize advanced attribute value.
|
|
278
324
|
* @param {?} value - Advanced attribute entry.
|
|
279
325
|
* @returns {string} - Attribute path string.
|
|
280
326
|
*/
|
|
281
327
|
function normalizeAdvancedAttributeValue(value) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
328
|
+
if (typeof value === "string") return value
|
|
329
|
+
|
|
330
|
+
if (isPlainObject(value) && typeof value.name === "string") {
|
|
331
|
+
return value.name
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
throw new Error(`Ransack condition attribute entries must be strings or {name}, got: ${typeof value}`)
|
|
288
335
|
}
|
|
336
|
+
|
|
289
337
|
/**
|
|
290
338
|
* Runs resolve ransack attributes.
|
|
291
339
|
* @param {object} args - Options.
|
|
@@ -293,20 +341,23 @@ function normalizeAdvancedAttributeValue(value) {
|
|
|
293
341
|
* @param {string} args.value - Attribute path value.
|
|
294
342
|
* @returns {RansackAttribute[]} - Resolved attributes.
|
|
295
343
|
*/
|
|
296
|
-
function resolveRansackAttributes({
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
344
|
+
function resolveRansackAttributes({modelClass, value}) {
|
|
345
|
+
return value.split("_or_").map((attributeValue) => {
|
|
346
|
+
const resolvedPath = resolveRansackPath({modelClass, value: attributeValue})
|
|
347
|
+
const targetModelClass = modelClassAtPath({modelClass, path: resolvedPath.path})
|
|
348
|
+
const attributeName = resolveAttributeName({modelClass: targetModelClass, value: resolvedPath.attributeValue})
|
|
349
|
+
|
|
350
|
+
if (!attributeName) {
|
|
351
|
+
throw new Error(`Unknown ransack attribute "${resolvedPath.attributeValue}" for ${targetModelClass.name}`)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return {
|
|
355
|
+
attributeName,
|
|
356
|
+
path: resolvedPath.path
|
|
357
|
+
}
|
|
358
|
+
})
|
|
309
359
|
}
|
|
360
|
+
|
|
310
361
|
/**
|
|
311
362
|
* Runs model class at path.
|
|
312
363
|
* @param {object} args - Options.
|
|
@@ -314,17 +365,22 @@ function resolveRansackAttributes({ modelClass, value }) {
|
|
|
314
365
|
* @param {string[]} args.path - Relationship path.
|
|
315
366
|
* @returns {RansackModelClass} - Target model class.
|
|
316
367
|
*/
|
|
317
|
-
function modelClassAtPath({
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
368
|
+
function modelClassAtPath({modelClass, path}) {
|
|
369
|
+
let currentModelClass = modelClass
|
|
370
|
+
|
|
371
|
+
for (const relationshipName of path) {
|
|
372
|
+
const relationship = relationshipEntries(currentModelClass)[relationshipName]
|
|
373
|
+
|
|
374
|
+
if (!relationship) {
|
|
375
|
+
throw new Error(`Unknown ransack relationship "${relationshipName}" for ${currentModelClass.name}`)
|
|
325
376
|
}
|
|
326
|
-
|
|
377
|
+
|
|
378
|
+
currentModelClass = relationship.targetModelClass
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return currentModelClass
|
|
327
382
|
}
|
|
383
|
+
|
|
328
384
|
/**
|
|
329
385
|
* Runs resolve ransack path.
|
|
330
386
|
* @param {object} args - Options.
|
|
@@ -332,35 +388,41 @@ function modelClassAtPath({ modelClass, path }) {
|
|
|
332
388
|
* @param {string} args.value - Remaining path value.
|
|
333
389
|
* @returns {{attributeValue: string, path: string[]}} - Resolved relationship path and remaining attribute value.
|
|
334
390
|
*/
|
|
335
|
-
function resolveRansackPath({
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
391
|
+
function resolveRansackPath({modelClass, value}) {
|
|
392
|
+
/**
|
|
393
|
+
* Path.
|
|
394
|
+
@type {string[]} */
|
|
395
|
+
const path = []
|
|
396
|
+
let currentModelClass = modelClass
|
|
397
|
+
let remainingValue = value
|
|
398
|
+
|
|
399
|
+
while (true) {
|
|
400
|
+
if (resolveAttributeName({modelClass: currentModelClass, value: remainingValue})) {
|
|
401
|
+
break
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const match = findRelationshipPrefix({
|
|
405
|
+
modelClass: currentModelClass,
|
|
406
|
+
value: remainingValue
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
if (!match) break
|
|
410
|
+
|
|
411
|
+
path.push(match.relationshipName)
|
|
412
|
+
currentModelClass = match.targetModelClass
|
|
413
|
+
remainingValue = match.remainingValue
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (remainingValue.length < 1) {
|
|
417
|
+
throw new Error(`Invalid ransack key path: ${value}`)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return {
|
|
421
|
+
attributeValue: remainingValue,
|
|
422
|
+
path
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
364
426
|
/**
|
|
365
427
|
* Runs find relationship prefix.
|
|
366
428
|
* @param {object} args - Options.
|
|
@@ -368,34 +430,37 @@ function resolveRansackPath({ modelClass, value }) {
|
|
|
368
430
|
* @param {string} args.value - Remaining value to match.
|
|
369
431
|
* @returns {{relationshipName: string, remainingValue: string, targetModelClass: RansackModelClass} | null} - Matching relationship prefix.
|
|
370
432
|
*/
|
|
371
|
-
function findRelationshipPrefix({
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
433
|
+
function findRelationshipPrefix({modelClass, value}) {
|
|
434
|
+
let bestMatch = null
|
|
435
|
+
|
|
436
|
+
for (const relationshipName of Object.keys(relationshipEntries(modelClass))) {
|
|
437
|
+
const relationship = relationshipEntries(modelClass)[relationshipName]
|
|
438
|
+
|
|
439
|
+
for (const candidate of relationshipCandidates(relationshipName)) {
|
|
440
|
+
const remainingValue = stripRelationshipCandidate(value, candidate)
|
|
441
|
+
|
|
442
|
+
if (remainingValue === null) continue
|
|
443
|
+
if (remainingValue.length < 1) continue
|
|
444
|
+
if (bestMatch && candidate.length <= bestMatch.candidateLength) continue
|
|
445
|
+
|
|
446
|
+
bestMatch = {
|
|
447
|
+
candidateLength: candidate.length,
|
|
448
|
+
relationshipName,
|
|
449
|
+
remainingValue,
|
|
450
|
+
targetModelClass: relationship.targetModelClass
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (!bestMatch) return null
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
relationshipName: bestMatch.relationshipName,
|
|
459
|
+
remainingValue: bestMatch.remainingValue,
|
|
460
|
+
targetModelClass: bestMatch.targetModelClass
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
399
464
|
/**
|
|
400
465
|
* Returns the portion of `value` after `candidate` when `candidate`
|
|
401
466
|
* sits at a relationship-path boundary, or null when there's no
|
|
@@ -412,26 +477,29 @@ function findRelationshipPrefix({ modelClass, value }) {
|
|
|
412
477
|
* @returns {string | null} - Remainder after the candidate, or null.
|
|
413
478
|
*/
|
|
414
479
|
function stripRelationshipCandidate(value, candidate) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
480
|
+
if (value.startsWith(`${candidate}_`)) {
|
|
481
|
+
return value.slice(candidate.length + 1)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (value.length <= candidate.length) return null
|
|
485
|
+
if (!value.startsWith(candidate)) return null
|
|
486
|
+
|
|
487
|
+
const nextChar = value.charAt(candidate.length)
|
|
488
|
+
|
|
489
|
+
if (nextChar < "A" || nextChar > "Z") return null
|
|
490
|
+
|
|
491
|
+
return nextChar.toLowerCase() + value.slice(candidate.length + 1)
|
|
492
|
+
}
|
|
493
|
+
|
|
427
494
|
/**
|
|
428
495
|
* Runs relationship candidates.
|
|
429
496
|
* @param {string} relationshipName - Relationship name.
|
|
430
497
|
* @returns {string[]} - Candidate tokens for matching.
|
|
431
498
|
*/
|
|
432
499
|
function relationshipCandidates(relationshipName) {
|
|
433
|
-
|
|
500
|
+
return uniqunize([relationshipName, inflection.underscore(relationshipName)])
|
|
434
501
|
}
|
|
502
|
+
|
|
435
503
|
/**
|
|
436
504
|
* Runs resolve attribute name.
|
|
437
505
|
* @param {object} args - Options.
|
|
@@ -439,123 +507,139 @@ function relationshipCandidates(relationshipName) {
|
|
|
439
507
|
* @param {string} args.value - Attribute candidate.
|
|
440
508
|
* @returns {string | undefined} - Resolved attribute name.
|
|
441
509
|
*/
|
|
442
|
-
function resolveAttributeName({
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
510
|
+
function resolveAttributeName({modelClass, value}) {
|
|
511
|
+
for (const [attributeName, columnName] of Object.entries(attributeEntries(modelClass))) {
|
|
512
|
+
if (matchesAttributeValue({attributeName, columnName, value})) {
|
|
513
|
+
return attributeName
|
|
447
514
|
}
|
|
448
|
-
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return undefined
|
|
449
518
|
}
|
|
519
|
+
|
|
450
520
|
/**
|
|
451
521
|
* Runs relationship entries.
|
|
452
522
|
* @param {RansackModelClass} modelClass - Model class.
|
|
453
523
|
* @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
|
|
454
524
|
*/
|
|
455
525
|
function relationshipEntries(modelClass) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
526
|
+
if (typeof /**
|
|
527
|
+
* Narrows the runtime value to the documented type.
|
|
528
|
+
@type {?} */ (modelClass).getRelationshipsMap === "function") {
|
|
529
|
+
return backendRelationshipEntries(modelClass)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (typeof /**
|
|
533
|
+
* Narrows the runtime value to the documented type.
|
|
534
|
+
@type {?} */ (modelClass).relationshipDefinitions === "function" &&
|
|
535
|
+
typeof /**
|
|
536
|
+
* Narrows the runtime value to the documented type.
|
|
537
|
+
@type {?} */ (modelClass).relationshipModelClasses === "function") {
|
|
538
|
+
return frontendRelationshipEntries(modelClass)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return {}
|
|
542
|
+
}
|
|
543
|
+
|
|
471
544
|
/**
|
|
472
545
|
* Runs backend relationship entries.
|
|
473
546
|
* @param {RansackModelClass} modelClass - Backend model class.
|
|
474
547
|
* @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
|
|
475
548
|
*/
|
|
476
549
|
function backendRelationshipEntries(modelClass) {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
550
|
+
/**
|
|
551
|
+
* Entries.
|
|
552
|
+
@type {Record<string, {targetModelClass: RansackModelClass}>} */
|
|
553
|
+
const entries = {}
|
|
554
|
+
const relationshipsMap = /**
|
|
555
|
+
* Narrows the runtime value to the documented type.
|
|
556
|
+
@type {?} */ (modelClass).getRelationshipsMap()
|
|
557
|
+
|
|
558
|
+
for (const relationshipName of Object.keys(relationshipsMap)) {
|
|
559
|
+
const relationship = relationshipsMap[relationshipName]
|
|
560
|
+
|
|
561
|
+
if (typeof relationship.isPolymorphic === "function" && relationship.isPolymorphic()) continue
|
|
562
|
+
|
|
563
|
+
const targetModelClass = relationship.getTargetModelClass()
|
|
564
|
+
|
|
565
|
+
if (!targetModelClass) continue
|
|
566
|
+
|
|
567
|
+
entries[relationshipName] = {targetModelClass}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return entries
|
|
571
|
+
}
|
|
572
|
+
|
|
495
573
|
/**
|
|
496
574
|
* Runs frontend relationship entries.
|
|
497
575
|
* @param {RansackModelClass} modelClass - Frontend model class.
|
|
498
576
|
* @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
|
|
499
577
|
*/
|
|
500
578
|
function frontendRelationshipEntries(modelClass) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
579
|
+
/**
|
|
580
|
+
* Entries.
|
|
581
|
+
@type {Record<string, {targetModelClass: RansackModelClass}>} */
|
|
582
|
+
const entries = {}
|
|
583
|
+
const definitions = /**
|
|
584
|
+
* Narrows the runtime value to the documented type.
|
|
585
|
+
@type {?} */ (modelClass).relationshipDefinitions()
|
|
586
|
+
const relationshipModelClasses = /**
|
|
587
|
+
* Narrows the runtime value to the documented type.
|
|
588
|
+
@type {?} */ (modelClass).relationshipModelClasses()
|
|
589
|
+
|
|
590
|
+
for (const relationshipName of Object.keys(definitions)) {
|
|
591
|
+
const targetModelClass = resolveFrontendModelClass(relationshipModelClasses[relationshipName])
|
|
592
|
+
|
|
593
|
+
if (!targetModelClass) continue
|
|
594
|
+
|
|
595
|
+
entries[relationshipName] = {targetModelClass}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return entries
|
|
599
|
+
}
|
|
600
|
+
|
|
519
601
|
/**
|
|
520
602
|
* Runs attribute entries.
|
|
521
603
|
* @param {RansackModelClass} modelClass - Model class.
|
|
522
604
|
* @returns {Record<string, string>} - Attribute-to-column entries keyed by attribute name.
|
|
523
605
|
*/
|
|
524
606
|
function attributeEntries(modelClass) {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
607
|
+
if (typeof /**
|
|
608
|
+
* Narrows the runtime value to the documented type.
|
|
609
|
+
@type {?} */ (modelClass).getAttributeNameToColumnNameMap === "function") {
|
|
610
|
+
return /** Narrows the runtime value to the documented type. @type {Record<string, string>} */ ((/**
|
|
611
|
+
* Narrows the runtime value to the documented type.
|
|
612
|
+
@type {?} */ (modelClass).getAttributeNameToColumnNameMap()))
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const resourceConfig = typeof /**
|
|
616
|
+
* Narrows the runtime value to the documented type.
|
|
617
|
+
@type {?} */ (modelClass).resourceConfig === "function"
|
|
618
|
+
? /**
|
|
619
|
+
* Narrows the runtime value to the documented type.
|
|
620
|
+
@type {?} */ (modelClass).resourceConfig()
|
|
621
|
+
: {}
|
|
622
|
+
const attributes = resourceConfig.attributes
|
|
623
|
+
/**
|
|
624
|
+
* Entries.
|
|
625
|
+
@type {Record<string, string>} */
|
|
626
|
+
const entries = {}
|
|
627
|
+
|
|
628
|
+
if (Array.isArray(attributes)) {
|
|
629
|
+
for (const attributeName of attributes) {
|
|
630
|
+
if (typeof attributeName !== "string") continue
|
|
631
|
+
|
|
632
|
+
entries[attributeName] = attributeName
|
|
633
|
+
}
|
|
634
|
+
} else if (isPlainObject(attributes)) {
|
|
635
|
+
for (const attributeName of Object.keys(attributes)) {
|
|
636
|
+
entries[attributeName] = attributeName
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return entries
|
|
641
|
+
}
|
|
642
|
+
|
|
559
643
|
/**
|
|
560
644
|
* Runs matches attribute value.
|
|
561
645
|
* @param {object} args - Options.
|
|
@@ -564,61 +648,72 @@ function attributeEntries(modelClass) {
|
|
|
564
648
|
* @param {string} args.value - Candidate value.
|
|
565
649
|
* @returns {boolean} - Whether the candidate resolves to the attribute.
|
|
566
650
|
*/
|
|
567
|
-
function matchesAttributeValue({
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
651
|
+
function matchesAttributeValue({attributeName, columnName, value}) {
|
|
652
|
+
return uniqunize([
|
|
653
|
+
attributeName,
|
|
654
|
+
columnName,
|
|
655
|
+
inflection.underscore(attributeName),
|
|
656
|
+
inflection.underscore(columnName)
|
|
657
|
+
]).includes(value)
|
|
574
658
|
}
|
|
659
|
+
|
|
575
660
|
/**
|
|
576
661
|
* Runs parse ransack key.
|
|
577
662
|
* @param {string} key - Ransack key.
|
|
578
663
|
* @returns {{pathValue: string, predicate: RansackPredicate} | null} - Parsed key.
|
|
579
664
|
*/
|
|
580
665
|
function parseRansackKey(key) {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
666
|
+
for (const predicate of supportedPredicates) {
|
|
667
|
+
const suffix = `_${predicate}`
|
|
668
|
+
if (!key.endsWith(suffix)) continue
|
|
669
|
+
|
|
670
|
+
const pathValue = key.slice(0, key.length - suffix.length)
|
|
671
|
+
|
|
672
|
+
if (pathValue.length < 1) {
|
|
673
|
+
throw new Error(`Invalid ransack key: ${key}`)
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
return {
|
|
677
|
+
pathValue,
|
|
678
|
+
predicate: /**
|
|
679
|
+
* Narrows the runtime value to the documented type.
|
|
680
|
+
@type {RansackPredicate} */ (predicate)
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
for (const predicate of supportedPredicates) {
|
|
685
|
+
const camelSuffix = snakeToCamelSuffix(predicate)
|
|
686
|
+
|
|
687
|
+
if (!key.endsWith(camelSuffix)) continue
|
|
688
|
+
|
|
689
|
+
const pathValue = key.slice(0, key.length - camelSuffix.length)
|
|
690
|
+
|
|
691
|
+
if (pathValue.length < 1) {
|
|
692
|
+
throw new Error(`Invalid ransack key: ${key}`)
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return {
|
|
696
|
+
pathValue,
|
|
697
|
+
predicate: /**
|
|
698
|
+
* Narrows the runtime value to the documented type.
|
|
699
|
+
@type {RansackPredicate} */ (predicate)
|
|
610
700
|
}
|
|
611
|
-
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return null
|
|
612
704
|
}
|
|
705
|
+
|
|
613
706
|
/**
|
|
614
707
|
* Runs snake to camel suffix.
|
|
615
708
|
* @param {string} value - Snake-case predicate.
|
|
616
709
|
* @returns {string} - CamelCase predicate suffix used in ransack keys.
|
|
617
710
|
*/
|
|
618
711
|
function snakeToCamelSuffix(value) {
|
|
619
|
-
|
|
620
|
-
|
|
712
|
+
const segments = value.split("_")
|
|
713
|
+
|
|
714
|
+
return segments.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("")
|
|
621
715
|
}
|
|
716
|
+
|
|
622
717
|
/**
|
|
623
718
|
* Runs normalize ransack value.
|
|
624
719
|
* @param {object} args - Options.
|
|
@@ -626,87 +721,99 @@ function snakeToCamelSuffix(value) {
|
|
|
626
721
|
* @param {?} args.value - Raw value.
|
|
627
722
|
* @returns {?} - Normalized value.
|
|
628
723
|
*/
|
|
629
|
-
function normalizeRansackValue({
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
724
|
+
function normalizeRansackValue({predicate, value}) {
|
|
725
|
+
if (predicate === "null") {
|
|
726
|
+
return normalizeRansackNullValue(value)
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if (predicate === "in" || predicate === "not_in") {
|
|
730
|
+
return normalizeRansackListValue(value)
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (ransackValueIsBlank(value)) return SKIP_RANSACK_CONDITION
|
|
734
|
+
|
|
735
|
+
return value
|
|
736
|
+
}
|
|
737
|
+
|
|
640
738
|
/**
|
|
641
739
|
* Runs normalize ransack null value.
|
|
642
740
|
* @param {?} value - Candidate null predicate value.
|
|
643
741
|
* @returns {boolean | typeof SKIP_RANSACK_CONDITION} - Normalized value.
|
|
644
742
|
*/
|
|
645
743
|
function normalizeRansackNullValue(value) {
|
|
646
|
-
|
|
647
|
-
|
|
744
|
+
const booleanValue = normalizeRansackBoolean(value)
|
|
745
|
+
|
|
746
|
+
return booleanValue === null ? SKIP_RANSACK_CONDITION : booleanValue
|
|
648
747
|
}
|
|
748
|
+
|
|
649
749
|
/**
|
|
650
750
|
* Runs normalize ransack list value.
|
|
651
751
|
* @param {?} value - Candidate list predicate value.
|
|
652
752
|
* @returns {Array<?> | typeof SKIP_RANSACK_CONDITION} - Normalized value.
|
|
653
753
|
*/
|
|
654
754
|
function normalizeRansackListValue(value) {
|
|
655
|
-
|
|
656
|
-
|
|
755
|
+
const normalizedArray = normalizeRansackArray(value)
|
|
756
|
+
|
|
757
|
+
return normalizedArray.length < 1 ? SKIP_RANSACK_CONDITION : normalizedArray
|
|
657
758
|
}
|
|
759
|
+
|
|
658
760
|
/**
|
|
659
761
|
* Ransack true values.
|
|
660
762
|
@type {Set<?>} */
|
|
661
|
-
const ransackTrueValues = new Set([true, 1, "1", "true"])
|
|
763
|
+
const ransackTrueValues = new Set([true, 1, "1", "true"])
|
|
662
764
|
/**
|
|
663
765
|
* Ransack false values.
|
|
664
766
|
@type {Set<?>} */
|
|
665
|
-
const ransackFalseValues = new Set([false, 0, "0", "false"])
|
|
767
|
+
const ransackFalseValues = new Set([false, 0, "0", "false"])
|
|
768
|
+
|
|
666
769
|
/**
|
|
667
770
|
* Runs normalize ransack boolean.
|
|
668
771
|
* @param {?} value - Candidate boolean.
|
|
669
772
|
* @returns {boolean | null} - Normalized boolean or null when blank.
|
|
670
773
|
*/
|
|
671
774
|
function normalizeRansackBoolean(value) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
return null;
|
|
678
|
-
throw new Error(`Invalid ransack boolean value: ${String(value)}`);
|
|
775
|
+
if (ransackTrueValues.has(value)) return true
|
|
776
|
+
if (ransackFalseValues.has(value)) return false
|
|
777
|
+
if (ransackValueIsBlank(value)) return null
|
|
778
|
+
|
|
779
|
+
throw new Error(`Invalid ransack boolean value: ${String(value)}`)
|
|
679
780
|
}
|
|
781
|
+
|
|
680
782
|
/**
|
|
681
783
|
* Runs ransack value is blank.
|
|
682
784
|
* @param {?} value - Candidate value.
|
|
683
785
|
* @returns {boolean} - Whether value should be ignored as blank.
|
|
684
786
|
*/
|
|
685
787
|
function ransackValueIsBlank(value) {
|
|
686
|
-
|
|
788
|
+
return value === undefined || value === null || value === ""
|
|
687
789
|
}
|
|
790
|
+
|
|
688
791
|
/**
|
|
689
792
|
* Runs normalize ransack array.
|
|
690
793
|
* @param {?} value - Candidate array-ish value.
|
|
691
794
|
* @returns {Array<?>} - Normalized array values.
|
|
692
795
|
*/
|
|
693
796
|
function normalizeRansackArray(value) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
797
|
+
if (Array.isArray(value)) {
|
|
798
|
+
return value.filter((entry) => entry !== undefined && entry !== null && entry !== "")
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (typeof value === "string") {
|
|
802
|
+
return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0)
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
if (value === undefined || value === null || value === "") return []
|
|
806
|
+
|
|
807
|
+
return [value]
|
|
808
|
+
}
|
|
809
|
+
|
|
704
810
|
/**
|
|
705
811
|
* RansackSort type.
|
|
706
812
|
* @typedef {object} RansackSort
|
|
707
813
|
* @property {string} attribute - Resolved attribute name.
|
|
708
814
|
* @property {"asc" | "desc"} direction - Sort direction.
|
|
709
815
|
*/
|
|
816
|
+
|
|
710
817
|
/**
|
|
711
818
|
* Parses and validates a ransack `s` sort string against model attributes.
|
|
712
819
|
* @param {RansackModelClass} modelClass - Model class for attribute validation.
|
|
@@ -714,32 +821,39 @@ function normalizeRansackArray(value) {
|
|
|
714
821
|
* @returns {RansackSort[]} - Validated sort definitions.
|
|
715
822
|
*/
|
|
716
823
|
export function parseRansackSort(modelClass, sortString) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
824
|
+
const segments = sortString.split(",").map((segment) => segment.trim()).filter((segment) => segment.length > 0)
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Sorts.
|
|
828
|
+
@type {RansackSort[]} */
|
|
829
|
+
const sorts = []
|
|
830
|
+
|
|
831
|
+
for (const segment of segments) {
|
|
832
|
+
const parts = segment.split(/\s+/)
|
|
833
|
+
const columnCandidate = parts[0]
|
|
834
|
+
const directionCandidate = parts.length > 1 ? parts[1].toLowerCase() : "asc"
|
|
835
|
+
|
|
836
|
+
if (directionCandidate !== "asc" && directionCandidate !== "desc") {
|
|
837
|
+
throw new Error(`Invalid ransack sort direction "${directionCandidate}" in: ${segment}`)
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
const resolvedAttribute = resolveAttributeName({modelClass, value: columnCandidate})
|
|
841
|
+
|
|
842
|
+
if (!resolvedAttribute) {
|
|
843
|
+
throw new Error(`Unknown ransack sort attribute "${columnCandidate}" for ${modelClass.name}`)
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
sorts.push({attribute: resolvedAttribute, direction: directionCandidate})
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
return sorts
|
|
850
|
+
}
|
|
851
|
+
|
|
737
852
|
/**
|
|
738
853
|
* Runs uniqunize.
|
|
739
854
|
* @param {string[]} values - Input values.
|
|
740
855
|
* @returns {string[]} - Unique values in original order.
|
|
741
856
|
*/
|
|
742
857
|
function uniqunize(values) {
|
|
743
|
-
|
|
858
|
+
return Array.from(new Set(values))
|
|
744
859
|
}
|
|
745
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuc2Fjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9yYW5zYWNrLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQTtBQUN4QyxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDN0MsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sc0NBQXNDLENBQUE7QUFFOUU7OztHQUdHO0FBRUg7OztHQUdHO0FBRUg7OztHQUdHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7OztHQU9HO0FBRUg7Ozs7OztHQU1HO0FBRUgsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixRQUFRO0lBQ1IsUUFBUTtJQUNSLE1BQU07SUFDTixNQUFNO0lBQ04sT0FBTztJQUNQLE1BQU07SUFDTixNQUFNO0lBQ04sS0FBSztJQUNMLElBQUk7SUFDSixJQUFJO0lBQ0osSUFBSTtJQUNKLElBQUk7Q0FDTCxDQUFBO0FBRUQ7Ozs7O0dBS0c7QUFDSCx3Q0FBd0M7QUFDeEMsTUFBTSxVQUFVLHNCQUFzQixDQUFDLFVBQVUsRUFBRSxNQUFNO0lBQ3ZELE9BQU8scUJBQXFCLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLFVBQVUsQ0FBQTtBQUM3RCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsVUFBVSxFQUFFLE1BQU07SUFDdEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0NBQStDLE9BQU8sTUFBTSxFQUFFLENBQUMsQ0FBQTtJQUNqRixDQUFDO0lBRUQ7OzZCQUV5QjtJQUN6QixNQUFNLFVBQVUsR0FBRztRQUNqQixVQUFVLEVBQUUsMEJBQTBCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUM7UUFDdkQsVUFBVSxFQUFF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TUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsa0JBQWtCLFNBQVMsT0FBTyxFQUFFLENBQUMsQ0FBQTtRQUMxRixDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQyxFQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFDLENBQUMsQ0FBQTtRQUVwRixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxlQUFlLFNBQVMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7UUFDL0YsQ0FBQztRQUVELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBQyxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFDLENBQUMsQ0FBQTtJQUMzRSxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsU0FBUyxDQUFDLE1BQU07SUFDdkIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDcEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgKiBhcyBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCJcbmltcG9ydCB7aXNQbGFpbk9iamVjdH0gZnJvbSBcImlzLXBsYWluLW9iamVjdFwiXG5pbXBvcnQge3Jlc29sdmVGcm9udGVuZE1vZGVsQ2xhc3N9IGZyb20gXCIuLi9mcm9udGVuZC1tb2RlbHMvbW9kZWwtcmVnaXN0cnkuanNcIlxuXG4vKipcbiAqIFJhbnNhY2tQcmVkaWNhdGUgdHlwZS5cbiAqIEB0eXBlZGVmIHtcImNvbnRcIiB8IFwiZW5kXCIgfCBcImVxXCIgfCBcImd0XCIgfCBcImd0ZXFcIiB8IFwiaW5cIiB8IFwibHRcIiB8IFwibHRlcVwiIHwgXCJub3RfZXFcIiB8IFwibm90X2luXCIgfCBcIm51bGxcIiB8IFwic3RhcnRcIn0gUmFuc2Fja1ByZWRpY2F0ZVxuICovXG5cbi8qKlxuICogUmFuc2Fja0NvbWJpbmF0b3IgdHlwZS5cbiAqIEB0eXBlZGVmIHtcImFuZFwiIHwgXCJvclwifSBSYW5zYWNrQ29tYmluYXRvclxuICovXG5cbi8qKlxuICogUmFuc2Fja01vZGVsQ2xhc3MgdHlwZS5cbiAqIEB0eXBlZGVmIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCB0eXBlb2YgaW1wb3J0KFwiLi4vZnJvbnRlbmQtbW9kZWxzL2Jhc2UuanNcIikuZGVmYXVsdH0gUmFuc2Fja01vZGVsQ2xhc3NcbiAqL1xuXG4vKipcbiAqIFJhbnNhY2tBdHRyaWJ1dGUgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFJhbnNhY2tBdHRyaWJ1dGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gUmVzb2x2ZWQgYXR0cmlidXRlIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBwYXRoIC0gUmVzb2x2ZWQgcmVsYXRpb25zaGlwIHBhdGguXG4gKi9cblxuLyoqXG4gKiBSYW5zYWNrQ29uZGl0aW9uIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBSYW5zYWNrQ29uZGl0aW9uXG4gKiBAcHJvcGVydHkge1JhbnNhY2tBdHRyaWJ1dGVbXX0gYXR0cmlidXRlcyAtIFJlc29sdmVkIGF0dHJpYnV0ZXMgdG8gdGVzdC5cbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja0NvbWJpbmF0b3J9IGNvbWJpbmF0b3IgLSBIb3cgbXVsdGlwbGUgYXR0cmlidXRlcyBhcmUgY29tYmluZWQuXG4gKiBAcHJvcGVydHkge1JhbnNhY2tQcmVkaWNhdGV9IHByZWRpY2F0ZSAtIFBhcnNlZCBSYW5zYWNrIHByZWRpY2F0ZS5cbiAqIEBwcm9wZXJ0eSB7P30gdmFsdWUgLSBOb3JtYWxpemVkIHZhbHVlLlxuICovXG5cbi8qKlxuICogUmFuc2Fja0dyb3VwIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBSYW5zYWNrR3JvdXBcbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja0NvbWJpbmF0b3J9IGNvbWJpbmF0b3IgLSBIb3cgZW50cmllcyBpbnNpZGUgdGhpcyBncm91cCBhcmUgY29tYmluZWQuXG4gKiBAcHJvcGVydHkge1JhbnNhY2tDb25kaXRpb25bXX0gY29uZGl0aW9ucyAtIENvbmRpdGlvbnMgaW4gdGhpcyBncm91cC5cbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja0dyb3VwW119IGdyb3VwaW5ncyAtIE5lc3RlZCBncm91cHMuXG4gKi9cblxuY29uc3Qgc3VwcG9ydGVkUHJlZGljYXRlcyA9IFtcbiAgXCJub3RfaW5cIixcbiAgXCJub3RfZXFcIixcbiAgXCJndGVxXCIsXG4gIFwibHRlcVwiLFxuICBcInN0YXJ0XCIsXG4gIFwiY29udFwiLFxuICBcIm51bGxcIixcbiAgXCJlbmRcIixcbiAgXCJlcVwiLFxuICBcImd0XCIsXG4gIFwibHRcIixcbiAgXCJpblwiXG5dXG5cbi8qKlxuICogUnVucyB0aGUgbm9ybWFsaXplUmFuc2Fja1BhcmFtcyBoZWxwZXIuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSYW5zYWNrLXN0eWxlIHBhcmFtcyBoYXNoLlxuICogQHJldHVybnMge1JhbnNhY2tDb25kaXRpb25bXX0gLSBOb3JtYWxpemVkIGNvbmRpdGlvbnMuXG4gKi9cbi8vIGZhbGxvdy1pZ25vcmUtbmV4dC1saW5lIHVudXNlZC1leHBvcnRcbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrUGFyYW1zKG1vZGVsQ2xhc3MsIHBhcmFtcykge1xuICByZXR1cm4gbm9ybWFsaXplUmFuc2Fja0dyb3VwKG1vZGVsQ2xhc3MsIHBhcmFtcykuY29uZGl0aW9uc1xufVxuXG4vKipcbiAqIFJ1bnMgdGhlIG5vcm1hbGl6ZVJhbnNhY2tHcm91cCBoZWxwZXIuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSYW5zYWNrLXN0eWxlIHBhcmFtcyBoYXNoLlxuICogQHJldHVybnMge1JhbnNhY2tHcm91cH0gLSBOb3JtYWxpemVkIGdyb3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUmFuc2Fja0dyb3VwKG1vZGVsQ2xhc3MsIHBhcmFtcykge1xuICBpZiAoIWlzUGxhaW5PYmplY3QocGFyYW1zKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgcmFuc2FjayBwYXJhbXMgbXVzdCBiZSBhIHBsYWluIG9iamVjdCwgZ290OiAke3R5cGVvZiBwYXJhbXN9YClcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVkLlxuICAgIEB0eXBlIHtSYW5zYWNrR3JvdXB9ICovXG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSB7XG4gICAgY29tYmluYXRvcjogbm9ybWFsaXplUmFuc2Fja0NvbWJpbmF0b3IocGFyYW1zLm0sIFwiYW5kXCIpLFxuICAgIGNvbmRpdGlvbnM6IFtdLFxuICAgIGdyb3VwaW5nczogW11cbiAgfVxuXG4gIGZvciAoY29uc3QgW2tleSwgcmF3VmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHBhcmFtcykpIHtcbiAgICBpZiAoa2V5ID09PSBcIm1cIikge1xuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoa2V5ID09PSBcImNcIikge1xuICAgICAgbm9ybWFsaXplZC5jb25kaXRpb25zLnB1c2goLi4ubm9ybWFsaXplQWR2YW5jZWRSYW5zYWNrQ29uZGl0aW9ucyh7bW9kZWxDbGFzcywgdmFsdWU6IHJhd1ZhbHVlfSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChrZXkgPT09IFwiZ1wiKSB7XG4gICAgICBub3JtYWxpemVkLmdyb3VwaW5ncy5wdXNoKC4uLm5vcm1hbGl6ZUFkdmFuY2VkUmFuc2Fja0dyb3Vwcyh7bW9kZWxDbGFzcywgdmFsdWU6IHJhd1ZhbHVlfSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IGNvbmRpdGlvbiA9IG5vcm1hbGl6ZVNpbXBsZVJhbnNhY2tDb25kaXRpb24oe2tleSwgbW9kZWxDbGFzcywgcmF3VmFsdWV9KVxuICAgIGlmIChjb25kaXRpb24pIG5vcm1hbGl6ZWQuY29uZGl0aW9ucy5wdXNoKGNvbmRpdGlvbilcbiAgfVxuXG4gIHJldHVybiBub3JtYWxpemVkXG59XG5cbmNvbnN0IFNLSVBfUkFOU0FDS19DT05ESVRJT04gPSBTeW1ib2woXCJza2lwLXJhbnNhY2stY29uZGl0aW9uXCIpXG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgc2ltcGxlIHJhbnNhY2sgY29uZGl0aW9uLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3Mua2V5IC0gU2ltcGxlIFJhbnNhY2sga2V5LlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0gez99IGFyZ3MucmF3VmFsdWUgLSBSYXcgY29uZGl0aW9uIHZhbHVlLlxuICogQHJldHVybnMge1JhbnNhY2tDb25kaXRpb24gfCBudWxsfSAtIE5vcm1hbGl6ZWQgY29uZGl0aW9uLCBvciBudWxsIHdoZW4gc2tpcHBlZC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplU2ltcGxlUmFuc2Fja0NvbmRpdGlvbih7a2V5LCBtb2RlbENsYXNzLCByYXdWYWx1ZX0pIHtcbiAgY29uc3QgcGFyc2VkS2V5ID0gcGFyc2VSYW5zYWNrS2V5KGtleSlcblxuICBpZiAoIXBhcnNlZEtleSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcmFuc2FjayBwcmVkaWNhdGUgaW4ga2V5OiAke2tleX1gKVxuICB9XG5cbiAgY29uc3QgdmFsdWUgPSBub3JtYWxpemVSYW5zYWNrVmFsdWUoe1xuICAgIHByZWRpY2F0ZTogcGFyc2VkS2V5LnByZWRpY2F0ZSxcbiAgICB2YWx1ZTogcmF3VmFsdWVcbiAgfSlcblxuICBpZiAodmFsdWUgPT09IFNLSVBfUkFOU0FDS19DT05ESVRJT04pIHJldHVybiBudWxsXG5cbiAgY29uc3QgYXR0cmlidXRlcyA9IHJlc29sdmVSYW5zYWNrQXR0cmlidXRlcyh7bW9kZWxDbGFzcywgdmFsdWU6IHBhcnNlZEtleS5wYXRoVmFsdWV9KVxuXG4gIHJldHVybiB7XG4gICAgYXR0cmlidXRlcyxcbiAgICBjb21iaW5hdG9yOiBhdHRyaWJ1dGVzLmxlbmd0aCA+IDEgPyBcIm9yXCIgOiBcImFuZFwiLFxuICAgIHByZWRpY2F0ZTogcGFyc2VkS2V5LnByZWRpY2F0ZSxcbiAgICB2YWx1ZVxuICB9XG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgYWR2YW5jZWQgcmFuc2FjayBjb25kaXRpb25zLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBBZHZhbmNlZCBjb25kaXRpb25zIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7UmFuc2Fja0NvbmRpdGlvbltdfSAtIE5vcm1hbGl6ZWQgY29uZGl0aW9ucy5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQWR2YW5jZWRSYW5zYWNrQ29uZGl0aW9ucyh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIC8qKlxuICAgKiBDb25kaXRpb25zLlxuICAgIEB0eXBlIHtSYW5zYWNrQ29uZGl0aW9uW119ICovXG4gIGNvbnN0IGNvbmRpdGlvbnMgPSBbXVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygbm9ybWFsaXplUmFuc2Fja0NvbGxlY3Rpb24odmFsdWUsIFwiY29uZGl0aW9uc1wiKSkge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChlbnRyeSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmFuc2FjayBjb25kaXRpb24gZW50cmllcyBtdXN0IGJlIHBsYWluIG9iamVjdHMsIGdvdDogJHt0eXBlb2YgZW50cnl9YClcbiAgICB9XG5cbiAgICBjb25zdCBwcmVkaWNhdGVWYWx1ZSA9IGVudHJ5LnBcblxuICAgIGlmICh0eXBlb2YgcHJlZGljYXRlVmFsdWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJhbnNhY2sgY29uZGl0aW9uIHByZWRpY2F0ZSBtdXN0IGJlIGEgc3RyaW5nXCIpXG4gICAgfVxuXG4gICAgaWYgKCFzdXBwb3J0ZWRQcmVkaWNhdGVzLmluY2x1ZGVzKHByZWRpY2F0ZVZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCByYW5zYWNrIHByZWRpY2F0ZSBpbiBjb25kaXRpb246ICR7cHJlZGljYXRlVmFsdWV9YClcbiAgICB9XG5cbiAgICBjb25zdCBwcmVkaWNhdGUgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmFuc2Fja1ByZWRpY2F0ZX0gKi8gKHByZWRpY2F0ZVZhbHVlKVxuICAgIGNvbnN0IHJhd1ZhbHVlID0gYWR2YW5jZWRSYW5zYWNrQ29uZGl0aW9uVmFsdWUoe3ByZWRpY2F0ZSwgdmFsdWU6IGVudHJ5LnZ9KVxuICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IG5vcm1hbGl6ZVJhbnNhY2tWYWx1ZSh7cHJlZGljYXRlLCB2YWx1ZTogcmF3VmFsdWV9KVxuXG4gICAgaWYgKG5vcm1hbGl6ZWRWYWx1ZSA9PT0gU0tJUF9SQU5TQUNLX0NPTkRJVElPTikgY29udGludWVcblxuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSByZXNvbHZlUmFuc2Fja0F0dHJpYnV0ZXNGcm9tQWR2YW5jZWRWYWx1ZSh7bW9kZWxDbGFzcywgdmFsdWU6IGVudHJ5LmF9KVxuXG4gICAgY29uZGl0aW9ucy5wdXNoKHtcbiAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICBjb21iaW5hdG9yOiBub3JtYWxpemVSYW5zYWNrQ29tYmluYXRvcihlbnRyeS5tLCBhdHRyaWJ1dGVzLmxlbmd0aCA+IDEgPyBcIm9yXCIgOiBcImFuZFwiKSxcbiAgICAgIHByZWRpY2F0ZSxcbiAgICAgIHZhbHVlOiBub3JtYWxpemVkVmFsdWVcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGNvbmRpdGlvbnNcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBhZHZhbmNlZCByYW5zYWNrIGdyb3Vwcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICogQHBhcmFtIHs/fSBhcmdzLnZhbHVlIC0gQWR2YW5jZWQgZ3JvdXBzIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7UmFuc2Fja0dyb3VwW119IC0gTm9ybWFsaXplZCBncm91cHMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUFkdmFuY2VkUmFuc2Fja0dyb3Vwcyh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIC8qKlxuICAgKiBHcm91cGluZ3MuXG4gICAgQHR5cGUge1JhbnNhY2tHcm91cFtdfSAqL1xuICBjb25zdCBncm91cGluZ3MgPSBbXVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygbm9ybWFsaXplUmFuc2Fja0NvbGxlY3Rpb24odmFsdWUsIFwiZ3JvdXBpbmdzXCIpKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KGVudHJ5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSYW5zYWNrIGdyb3VwaW5nIGVudHJpZXMgbXVzdCBiZSBwbGFpbiBvYmplY3RzLCBnb3Q6ICR7dHlwZW9mIGVudHJ5fWApXG4gICAgfVxuXG4gICAgZ3JvdXBpbmdzLnB1c2gobm9ybWFsaXplUmFuc2Fja0dyb3VwKG1vZGVsQ2xhc3MsIGVudHJ5KSlcbiAgfVxuXG4gIHJldHVybiBncm91cGluZ3Ncbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSByYW5zYWNrIGNvbWJpbmF0b3IuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQ2FuZGlkYXRlIGNvbWJpbmF0b3IuXG4gKiBAcGFyYW0ge1JhbnNhY2tDb21iaW5hdG9yfSBkZWZhdWx0VmFsdWUgLSBEZWZhdWx0IGNvbWJpbmF0b3IuXG4gKiBAcmV0dXJucyB7UmFuc2Fja0NvbWJpbmF0b3J9IC0gTm9ybWFsaXplZCBjb21iaW5hdG9yLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrQ29tYmluYXRvcih2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSBcIlwiKSByZXR1cm4gZGVmYXVsdFZhbHVlXG4gIGlmICh2YWx1ZSA9PT0gXCJhbmRcIiB8fCB2YWx1ZSA9PT0gXCJvclwiKSByZXR1cm4gdmFsdWVcblxuICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmFuc2FjayBjb21iaW5hdG9yOiAke1N0cmluZyh2YWx1ZSl9YClcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSByYW5zYWNrIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQ2FuZGlkYXRlIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIENvbGxlY3Rpb24gbmFtZSBmb3IgZXJyb3JzLlxuICogQHJldHVybnMge0FycmF5PD8+fSAtIENvbGxlY3Rpb24gdmFsdWVzIGluIHN0YWJsZSBvcmRlci5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUmFuc2Fja0NvbGxlY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHJldHVybiBbXVxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh2YWx1ZSlcbiAgICAgIC5zb3J0KChsZWZ0LCByaWdodCkgPT4ge1xuICAgICAgICBjb25zdCBsZWZ0TnVtYmVyID0gTnVtYmVyKGxlZnQpXG4gICAgICAgIGNvbnN0IHJpZ2h0TnVtYmVyID0gTnVtYmVyKHJpZ2h0KVxuXG4gICAgICAgIGlmIChOdW1iZXIuaXNGaW5pdGUobGVmdE51bWJlcikgJiYgTnVtYmVyLmlzRmluaXRlKHJpZ2h0TnVtYmVyKSkge1xuICAgICAgICAgIHJldHVybiBsZWZ0TnVtYmVyIC0gcmlnaHROdW1iZXJcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBsZWZ0LmxvY2FsZUNvbXBhcmUocmlnaHQpXG4gICAgICB9KVxuICAgICAgLm1hcCgoa2V5KSA9PiB2YWx1ZVtrZXldKVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBSYW5zYWNrICR7bmFtZX0gbXVzdCBiZSBhbiBhcnJheSBvciBvYmplY3QsIGdvdDogJHt0eXBlb2YgdmFsdWV9YClcbn1cblxuLyoqXG4gKiBSdW5zIGFkdmFuY2VkIHJhbnNhY2sgY29uZGl0aW9uIHZhbHVlLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrUHJlZGljYXRlfSBhcmdzLnByZWRpY2F0ZSAtIFBhcnNlZCBwcmVkaWNhdGUuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBBZHZhbmNlZCBjb25kaXRpb24gdmFsdWUuXG4gKiBAcmV0dXJucyB7P30gLSBWYWx1ZSBwYXNzZWQgdG8gcHJlZGljYXRlIG5vcm1hbGl6YXRpb24uXG4gKi9cbmZ1bmN0aW9uIGFkdmFuY2VkUmFuc2Fja0NvbmRpdGlvblZhbHVlKHtwcmVkaWNhdGUsIHZhbHVlfSkge1xuICBpZiAocHJlZGljYXRlID09PSBcImluXCIgfHwgcHJlZGljYXRlID09PSBcIm5vdF9pblwiKSByZXR1cm4gdmFsdWVcblxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUuZmluZCgoZW50cnkpID0+IGVudHJ5ICE9PSB1bmRlZmluZWQgJiYgZW50cnkgIT09IG51bGwgJiYgZW50cnkgIT09IFwiXCIpXG4gIH1cblxuICByZXR1cm4gdmFsdWVcbn1cblxuLyoqXG4gKiBSdW5zIHJlc29sdmUgcmFuc2FjayBhdHRyaWJ1dGVzIGZyb20gYWR2YW5jZWQgdmFsdWUuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7P30gYXJncy52YWx1ZSAtIEFkdmFuY2VkIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHtSYW5zYWNrQXR0cmlidXRlW119IC0gUmVzb2x2ZWQgYXR0cmlidXRlcy5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVJhbnNhY2tBdHRyaWJ1dGVzRnJvbUFkdmFuY2VkVmFsdWUoe21vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICBjb25zdCB2YWx1ZXMgPSBub3JtYWxpemVBZHZhbmNlZEF0dHJpYnV0ZVZhbHVlcyh2YWx1ZSlcbiAgLyoqXG4gICAqIEF0dHJpYnV0ZXMuXG4gICAgQHR5cGUge1JhbnNhY2tBdHRyaWJ1dGVbXX0gKi9cbiAgY29uc3QgYXR0cmlidXRlcyA9IFtdXG5cbiAgZm9yIChjb25zdCBhdHRyaWJ1dGVWYWx1ZSBvZiB2YWx1ZXMpIHtcbiAgICBhdHRyaWJ1dGVzLnB1c2goLi4ucmVzb2x2ZVJhbnNhY2tBdHRyaWJ1dGVzKHttb2RlbENsYXNzLCB2YWx1ZTogYXR0cmlidXRlVmFsdWV9KSlcbiAgfVxuXG4gIGlmIChhdHRyaWJ1dGVzLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJSYW5zYWNrIGNvbmRpdGlvbiBtdXN0IGluY2x1ZGUgYXQgbGVhc3Qgb25lIGF0dHJpYnV0ZVwiKVxuICB9XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXNcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBhZHZhbmNlZCBhdHRyaWJ1dGUgdmFsdWVzLlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIEFkdmFuY2VkIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBBdHRyaWJ1dGUgcGF0aCBzdHJpbmdzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVBZHZhbmNlZEF0dHJpYnV0ZVZhbHVlcyh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSByZXR1cm4gW3ZhbHVlXVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5tYXAoKGVudHJ5KSA9PiBub3JtYWxpemVBZHZhbmNlZEF0dHJpYnV0ZVZhbHVlKGVudHJ5KSlcbiAgfVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiBub3JtYWxpemVSYW5zYWNrQ29sbGVjdGlvbih2YWx1ZSwgXCJhdHRyaWJ1dGVzXCIpLm1hcCgoZW50cnkpID0+IG5vcm1hbGl6ZUFkdmFuY2VkQXR0cmlidXRlVmFsdWUoZW50cnkpKVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBSYW5zYWNrIGNvbmRpdGlvbiBhdHRyaWJ1dGVzIG11c3QgYmUgc3RyaW5ncywgYXJyYXlzLCBvciBvYmplY3RzLCBnb3Q6ICR7dHlwZW9mIHZhbHVlfWApXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgYWR2YW5jZWQgYXR0cmlidXRlIHZhbHVlLlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIEFkdmFuY2VkIGF0dHJpYnV0ZSBlbnRyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQXR0cmlidXRlIHBhdGggc3RyaW5nLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVBZHZhbmNlZEF0dHJpYnV0ZVZhbHVlKHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiB2YWx1ZVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSAmJiB0eXBlb2YgdmFsdWUubmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB2YWx1ZS5uYW1lXG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYFJhbnNhY2sgY29uZGl0aW9uIGF0dHJpYnV0ZSBlbnRyaWVzIG11c3QgYmUgc3RyaW5ncyBvciB7bmFtZX0sIGdvdDogJHt0eXBlb2YgdmFsdWV9YClcbn1cblxuLyoqXG4gKiBSdW5zIHJlc29sdmUgcmFuc2FjayBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncy52YWx1ZSAtIEF0dHJpYnV0ZSBwYXRoIHZhbHVlLlxuICogQHJldHVybnMge1JhbnNhY2tBdHRyaWJ1dGVbXX0gLSBSZXNvbHZlZCBhdHRyaWJ1dGVzLlxuICovXG5mdW5jdGlvbiByZXNvbHZlUmFuc2Fja0F0dHJpYnV0ZXMoe21vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoXCJfb3JfXCIpLm1hcCgoYXR0cmlidXRlVmFsdWUpID0+IHtcbiAgICBjb25zdCByZXNvbHZlZFBhdGggPSByZXNvbHZlUmFuc2Fja1BhdGgoe21vZGVsQ2xhc3MsIHZhbHVlOiBhdHRyaWJ1dGVWYWx1ZX0pXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IG1vZGVsQ2xhc3NBdFBhdGgoe21vZGVsQ2xhc3MsIHBhdGg6IHJlc29sdmVkUGF0aC5wYXRofSlcbiAgICBjb25zdCBhdHRyaWJ1dGVOYW1lID0gcmVzb2x2ZUF0dHJpYnV0ZU5hbWUoe21vZGVsQ2xhc3M6IHRhcmdldE1vZGVsQ2xhc3MsIHZhbHVlOiByZXNvbHZlZFBhdGguYXR0cmlidXRlVmFsdWV9KVxuXG4gICAgaWYgKCFhdHRyaWJ1dGVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcmFuc2FjayBhdHRyaWJ1dGUgXCIke3Jlc29sdmVkUGF0aC5hdHRyaWJ1dGVWYWx1ZX1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXR0cmlidXRlTmFtZSxcbiAgICAgIHBhdGg6IHJlc29sdmVkUGF0aC5wYXRoXG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIFJ1bnMgbW9kZWwgY2xhc3MgYXQgcGF0aC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IGFyZ3MubW9kZWxDbGFzcyAtIFJvb3QgbW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtSYW5zYWNrTW9kZWxDbGFzc30gLSBUYXJnZXQgbW9kZWwgY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIG1vZGVsQ2xhc3NBdFBhdGgoe21vZGVsQ2xhc3MsIHBhdGh9KSB7XG4gIGxldCBjdXJyZW50TW9kZWxDbGFzcyA9IG1vZGVsQ2xhc3NcblxuICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgb2YgcGF0aCkge1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcEVudHJpZXMoY3VycmVudE1vZGVsQ2xhc3MpW3JlbGF0aW9uc2hpcE5hbWVdXG5cbiAgICBpZiAoIXJlbGF0aW9uc2hpcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHJhbnNhY2sgcmVsYXRpb25zaGlwIFwiJHtyZWxhdGlvbnNoaXBOYW1lfVwiIGZvciAke2N1cnJlbnRNb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICBjdXJyZW50TW9kZWxDbGFzcyA9IHJlbGF0aW9uc2hpcC50YXJnZXRNb2RlbENsYXNzXG4gIH1cblxuICByZXR1cm4gY3VycmVudE1vZGVsQ2xhc3Ncbn1cblxuLyoqXG4gKiBSdW5zIHJlc29sdmUgcmFuc2FjayBwYXRoLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gQ3VycmVudCBtb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnZhbHVlIC0gUmVtYWluaW5nIHBhdGggdmFsdWUuXG4gKiBAcmV0dXJucyB7e2F0dHJpYnV0ZVZhbHVlOiBzdHJpbmcsIHBhdGg6IHN0cmluZ1tdfX0gLSBSZXNvbHZlZCByZWxhdGlvbnNoaXAgcGF0aCBhbmQgcmVtYWluaW5nIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVJhbnNhY2tQYXRoKHttb2RlbENsYXNzLCB2YWx1ZX0pIHtcbiAgLyoqXG4gICAqIFBhdGguXG4gICAgQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCBwYXRoID0gW11cbiAgbGV0IGN1cnJlbnRNb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuICBsZXQgcmVtYWluaW5nVmFsdWUgPSB2YWx1ZVxuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKHJlc29sdmVBdHRyaWJ1dGVOYW1lKHttb2RlbENsYXNzOiBjdXJyZW50TW9kZWxDbGFzcywgdmFsdWU6IHJlbWFpbmluZ1ZhbHVlfSkpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuXG4gICAgY29uc3QgbWF0Y2ggPSBmaW5kUmVsYXRpb25zaGlwUHJlZml4KHtcbiAgICAgIG1vZGVsQ2xhc3M6IGN1cnJlbnRNb2RlbENsYXNzLFxuICAgICAgdmFsdWU6IHJlbWFpbmluZ1ZhbHVlXG4gICAgfSlcblxuICAgIGlmICghbWF0Y2gpIGJyZWFrXG5cbiAgICBwYXRoLnB1c2gobWF0Y2gucmVsYXRpb25zaGlwTmFtZSlcbiAgICBjdXJyZW50TW9kZWxDbGFzcyA9IG1hdGNoLnRhcmdldE1vZGVsQ2xhc3NcbiAgICByZW1haW5pbmdWYWx1ZSA9IG1hdGNoLnJlbWFpbmluZ1ZhbHVlXG4gIH1cblxuICBpZiAocmVtYWluaW5nVmFsdWUubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIGtleSBwYXRoOiAke3ZhbHVlfWApXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGF0dHJpYnV0ZVZhbHVlOiByZW1haW5pbmdWYWx1ZSxcbiAgICBwYXRoXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIGZpbmQgcmVsYXRpb25zaGlwIHByZWZpeC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IGFyZ3MubW9kZWxDbGFzcyAtIEN1cnJlbnQgbW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncy52YWx1ZSAtIFJlbWFpbmluZyB2YWx1ZSB0byBtYXRjaC5cbiAqIEByZXR1cm5zIHt7cmVsYXRpb25zaGlwTmFtZTogc3RyaW5nLCByZW1haW5pbmdWYWx1ZTogc3RyaW5nLCB0YXJnZXRNb2RlbENsYXNzOiBSYW5zYWNrTW9kZWxDbGFzc30gfCBudWxsfSAtIE1hdGNoaW5nIHJlbGF0aW9uc2hpcCBwcmVmaXguXG4gKi9cbmZ1bmN0aW9uIGZpbmRSZWxhdGlvbnNoaXBQcmVmaXgoe21vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICBsZXQgYmVzdE1hdGNoID0gbnVsbFxuXG4gIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBPYmplY3Qua2V5cyhyZWxhdGlvbnNoaXBFbnRyaWVzKG1vZGVsQ2xhc3MpKSkge1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcylbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHJlbGF0aW9uc2hpcENhbmRpZGF0ZXMocmVsYXRpb25zaGlwTmFtZSkpIHtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1ZhbHVlID0gc3RyaXBSZWxhdGlvbnNoaXBDYW5kaWRhdGUodmFsdWUsIGNhbmRpZGF0ZSlcblxuICAgICAgaWYgKHJlbWFpbmluZ1ZhbHVlID09PSBudWxsKSBjb250aW51ZVxuICAgICAgaWYgKHJlbWFpbmluZ1ZhbHVlLmxlbmd0aCA8IDEpIGNvbnRpbnVlXG4gICAgICBpZiAoYmVzdE1hdGNoICYmIGNhbmRpZGF0ZS5sZW5ndGggPD0gYmVzdE1hdGNoLmNhbmRpZGF0ZUxlbmd0aCkgY29udGludWVcblxuICAgICAgYmVzdE1hdGNoID0ge1xuICAgICAgICBjYW5kaWRhdGVMZW5ndGg6IGNhbmRpZGF0ZS5sZW5ndGgsXG4gICAgICAgIHJlbGF0aW9uc2hpcE5hbWUsXG4gICAgICAgIHJlbWFpbmluZ1ZhbHVlLFxuICAgICAgICB0YXJnZXRNb2RlbENsYXNzOiByZWxhdGlvbnNoaXAudGFyZ2V0TW9kZWxDbGFzc1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICghYmVzdE1hdGNoKSByZXR1cm4gbnVsbFxuXG4gIHJldHVybiB7XG4gICAgcmVsYXRpb25zaGlwTmFtZTogYmVzdE1hdGNoLnJlbGF0aW9uc2hpcE5hbWUsXG4gICAgcmVtYWluaW5nVmFsdWU6IGJlc3RNYXRjaC5yZW1haW5pbmdWYWx1ZSxcbiAgICB0YXJnZXRNb2RlbENsYXNzOiBiZXN0TWF0Y2gudGFyZ2V0TW9kZWxDbGFzc1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcG9ydGlvbiBvZiBgdmFsdWVgIGFmdGVyIGBjYW5kaWRhdGVgIHdoZW4gYGNhbmRpZGF0ZWBcbiAqIHNpdHMgYXQgYSByZWxhdGlvbnNoaXAtcGF0aCBib3VuZGFyeSwgb3IgbnVsbCB3aGVuIHRoZXJlJ3Mgbm9cbiAqIGJvdW5kYXJ5IG1hdGNoLiBUd28gYm91bmRhcnkgZm9ybXMgYXJlIGFjY2VwdGVkOlxuICogLSBzbmFrZTogYDxjYW5kaWRhdGU+X2AgZm9sbG93ZWQgYnkgdGhlIHJlc3Qgb2YgdGhlIHBhdGggKGUuZy5cbiAqICAgYHRhc2tfcHJvamVjdF9pZGAgYWdhaW5zdCBjYW5kaWRhdGUgYHRhc2tgIHJldHVybnMgYHByb2plY3RfaWRgKS5cbiAqIC0gY2FtZWw6IGA8Y2FuZGlkYXRlPmAgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYW4gdXBwZXJjYXNlIGxldHRlcixcbiAqICAgd2hpY2ggbWFya3MgYSBuZXcgd29yZCBpbiBjYW1lbENhc2UgKGUuZy4gYHRhc2tQcm9qZWN0SWRgIGFnYWluc3RcbiAqICAgY2FuZGlkYXRlIGB0YXNrYCByZXR1cm5zIGBwcm9qZWN0SWRgIHdpdGggdGhlIGxlYWRpbmcgYFBgXG4gKiAgIGxvd2VyY2FzZWQgc28gdGhlIHJlbWFpbmRlciBzdGF5cyBpbiBjYWxsZXItZm9ybSBmb3IgdGhlIG5leHRcbiAqICAgYXR0cmlidXRlIC8gcmVsYXRpb25zaGlwIG1hdGNoKS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFJlbWFpbmluZyByYW5zYWNrIHBhdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gY2FuZGlkYXRlIC0gUmVsYXRpb25zaGlwIG5hbWUgY2FuZGlkYXRlLlxuICogQHJldHVybnMge3N0cmluZyB8IG51bGx9IC0gUmVtYWluZGVyIGFmdGVyIHRoZSBjYW5kaWRhdGUsIG9yIG51bGwuXG4gKi9cbmZ1bmN0aW9uIHN0cmlwUmVsYXRpb25zaGlwQ2FuZGlkYXRlKHZhbHVlLCBjYW5kaWRhdGUpIHtcbiAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoYCR7Y2FuZGlkYXRlfV9gKSkge1xuICAgIHJldHVybiB2YWx1ZS5zbGljZShjYW5kaWRhdGUubGVuZ3RoICsgMSlcbiAgfVxuXG4gIGlmICh2YWx1ZS5sZW5ndGggPD0gY2FuZGlkYXRlLmxlbmd0aCkgcmV0dXJuIG51bGxcbiAgaWYgKCF2YWx1ZS5zdGFydHNXaXRoKGNhbmRpZGF0ZSkpIHJldHVybiBudWxsXG5cbiAgY29uc3QgbmV4dENoYXIgPSB2YWx1ZS5jaGFyQXQoY2FuZGlkYXRlLmxlbmd0aClcblxuICBpZiAobmV4dENoYXIgPCBcIkFcIiB8fCBuZXh0Q2hhciA+IFwiWlwiKSByZXR1cm4gbnVsbFxuXG4gIHJldHVybiBuZXh0Q2hhci50b0xvd2VyQ2FzZSgpICsgdmFsdWUuc2xpY2UoY2FuZGlkYXRlLmxlbmd0aCArIDEpXG59XG5cbi8qKlxuICogUnVucyByZWxhdGlvbnNoaXAgY2FuZGlkYXRlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZWxhdGlvbnNoaXBOYW1lIC0gUmVsYXRpb25zaGlwIG5hbWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nW119IC0gQ2FuZGlkYXRlIHRva2VucyBmb3IgbWF0Y2hpbmcuXG4gKi9cbmZ1bmN0aW9uIHJlbGF0aW9uc2hpcENhbmRpZGF0ZXMocmVsYXRpb25zaGlwTmFtZSkge1xuICByZXR1cm4gdW5pcXVuaXplKFtyZWxhdGlvbnNoaXBOYW1lLCBpbmZsZWN0aW9uLnVuZGVyc2NvcmUocmVsYXRpb25zaGlwTmFtZSldKVxufVxuXG4vKipcbiAqIFJ1bnMgcmVzb2x2ZSBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudmFsdWUgLSBBdHRyaWJ1dGUgY2FuZGlkYXRlLlxuICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXNvbHZlZCBhdHRyaWJ1dGUgbmFtZS5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZUF0dHJpYnV0ZU5hbWUoe21vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCBjb2x1bW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVFbnRyaWVzKG1vZGVsQ2xhc3MpKSkge1xuICAgIGlmIChtYXRjaGVzQXR0cmlidXRlVmFsdWUoe2F0dHJpYnV0ZU5hbWUsIGNvbHVtbk5hbWUsIHZhbHVlfSkpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVOYW1lXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIFJ1bnMgcmVsYXRpb25zaGlwIGVudHJpZXMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywge3RhcmdldE1vZGVsQ2xhc3M6IFJhbnNhY2tNb2RlbENsYXNzfT59IC0gUmVsYXRpb25zaGlwIGVudHJpZXMga2V5ZWQgYnkgbmFtZS5cbiAqL1xuZnVuY3Rpb24gcmVsYXRpb25zaGlwRW50cmllcyhtb2RlbENsYXNzKSB7XG4gIGlmICh0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5nZXRSZWxhdGlvbnNoaXBzTWFwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICByZXR1cm4gYmFja2VuZFJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcylcbiAgfVxuXG4gIGlmICh0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZWxhdGlvbnNoaXBEZWZpbml0aW9ucyA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgdHlwZW9mIC8qKlxuICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZWxhdGlvbnNoaXBNb2RlbENsYXNzZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJldHVybiBmcm9udGVuZFJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcylcbiAgfVxuXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIFJ1bnMgYmFja2VuZCByZWxhdGlvbnNoaXAgZW50cmllcy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IG1vZGVsQ2xhc3MgLSBCYWNrZW5kIG1vZGVsIGNsYXNzLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHt0YXJnZXRNb2RlbENsYXNzOiBSYW5zYWNrTW9kZWxDbGFzc30+fSAtIFJlbGF0aW9uc2hpcCBlbnRyaWVzIGtleWVkIGJ5IG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGJhY2tlbmRSZWxhdGlvbnNoaXBFbnRyaWVzKG1vZGVsQ2xhc3MpIHtcbiAgLyoqXG4gICAqIEVudHJpZXMuXG4gICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIHt0YXJnZXRNb2RlbENsYXNzOiBSYW5zYWNrTW9kZWxDbGFzc30+fSAqL1xuICBjb25zdCBlbnRyaWVzID0ge31cbiAgY29uc3QgcmVsYXRpb25zaGlwc01hcCA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLmdldFJlbGF0aW9uc2hpcHNNYXAoKVxuXG4gIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBPYmplY3Qua2V5cyhyZWxhdGlvbnNoaXBzTWFwKSkge1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcHNNYXBbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgIGlmICh0eXBlb2YgcmVsYXRpb25zaGlwLmlzUG9seW1vcnBoaWMgPT09IFwiZnVuY3Rpb25cIiAmJiByZWxhdGlvbnNoaXAuaXNQb2x5bW9ycGhpYygpKSBjb250aW51ZVxuXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHJlbGF0aW9uc2hpcC5nZXRUYXJnZXRNb2RlbENsYXNzKClcblxuICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcykgY29udGludWVcblxuICAgIGVudHJpZXNbcmVsYXRpb25zaGlwTmFtZV0gPSB7dGFyZ2V0TW9kZWxDbGFzc31cbiAgfVxuXG4gIHJldHVybiBlbnRyaWVzXG59XG5cbi8qKlxuICogUnVucyBmcm9udGVuZCByZWxhdGlvbnNoaXAgZW50cmllcy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IG1vZGVsQ2xhc3MgLSBGcm9udGVuZCBtb2RlbCBjbGFzcy5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB7dGFyZ2V0TW9kZWxDbGFzczogUmFuc2Fja01vZGVsQ2xhc3N9Pn0gLSBSZWxhdGlvbnNoaXAgZW50cmllcyBrZXllZCBieSBuYW1lLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZFJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcykge1xuICAvKipcbiAgICogRW50cmllcy5cbiAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywge3RhcmdldE1vZGVsQ2xhc3M6IFJhbnNhY2tNb2RlbENsYXNzfT59ICovXG4gIGNvbnN0IGVudHJpZXMgPSB7fVxuICBjb25zdCBkZWZpbml0aW9ucyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAobW9kZWxDbGFzcykucmVsYXRpb25zaGlwRGVmaW5pdGlvbnMoKVxuICBjb25zdCByZWxhdGlvbnNoaXBNb2RlbENsYXNzZXMgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAobW9kZWxDbGFzcykucmVsYXRpb25zaGlwTW9kZWxDbGFzc2VzKClcblxuICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgb2YgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpKSB7XG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHJlc29sdmVGcm9udGVuZE1vZGVsQ2xhc3MocmVsYXRpb25zaGlwTW9kZWxDbGFzc2VzW3JlbGF0aW9uc2hpcE5hbWVdKVxuXG4gICAgaWYgKCF0YXJnZXRNb2RlbENsYXNzKSBjb250aW51ZVxuXG4gICAgZW50cmllc1tyZWxhdGlvbnNoaXBOYW1lXSA9IHt0YXJnZXRNb2RlbENsYXNzfVxuICB9XG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuLyoqXG4gKiBSdW5zIGF0dHJpYnV0ZSBlbnRyaWVzLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZz59IC0gQXR0cmlidXRlLXRvLWNvbHVtbiBlbnRyaWVzIGtleWVkIGJ5IGF0dHJpYnV0ZSBuYW1lLlxuICovXG5mdW5jdGlvbiBhdHRyaWJ1dGVFbnRyaWVzKG1vZGVsQ2xhc3MpIHtcbiAgaWYgKHR5cGVvZiAvKipcbiAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLmdldEF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVNYXAgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJldHVybiAvKiogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLiBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gKi8gKCgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAobW9kZWxDbGFzcykuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCgpKSlcbiAgfVxuXG4gIGNvbnN0IHJlc291cmNlQ29uZmlnID0gdHlwZW9mIC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZXNvdXJjZUNvbmZpZyA9PT0gXCJmdW5jdGlvblwiXG4gICAgPyAvKipcbiAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZXNvdXJjZUNvbmZpZygpXG4gICAgOiB7fVxuICBjb25zdCBhdHRyaWJ1dGVzID0gcmVzb3VyY2VDb25maWcuYXR0cmlidXRlc1xuICAvKipcbiAgICogRW50cmllcy5cbiAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gKi9cbiAgY29uc3QgZW50cmllcyA9IHt9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRlcykpIHtcbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgYXR0cmlidXRlcykge1xuICAgICAgaWYgKHR5cGVvZiBhdHRyaWJ1dGVOYW1lICE9PSBcInN0cmluZ1wiKSBjb250aW51ZVxuXG4gICAgICBlbnRyaWVzW2F0dHJpYnV0ZU5hbWVdID0gYXR0cmlidXRlTmFtZVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KGF0dHJpYnV0ZXMpKSB7XG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGVOYW1lIG9mIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpKSB7XG4gICAgICBlbnRyaWVzW2F0dHJpYnV0ZU5hbWVdID0gYXR0cmlidXRlTmFtZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbnRyaWVzXG59XG5cbi8qKlxuICogUnVucyBtYXRjaGVzIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmF0dHJpYnV0ZU5hbWUgLSBBdHRyaWJ1dGUgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbHVtbk5hbWUgLSBDb2x1bW4gbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnZhbHVlIC0gQ2FuZGlkYXRlIHZhbHVlLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY2FuZGlkYXRlIHJlc29sdmVzIHRvIHRoZSBhdHRyaWJ1dGUuXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNBdHRyaWJ1dGVWYWx1ZSh7YXR0cmlidXRlTmFtZSwgY29sdW1uTmFtZSwgdmFsdWV9KSB7XG4gIHJldHVybiB1bmlxdW5pemUoW1xuICAgIGF0dHJpYnV0ZU5hbWUsXG4gICAgY29sdW1uTmFtZSxcbiAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoYXR0cmlidXRlTmFtZSksXG4gICAgaW5mbGVjdGlvbi51bmRlcnNjb3JlKGNvbHVtbk5hbWUpXG4gIF0pLmluY2x1ZGVzKHZhbHVlKVxufVxuXG4vKipcbiAqIFJ1bnMgcGFyc2UgcmFuc2FjayBrZXkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gUmFuc2FjayBrZXkuXG4gKiBAcmV0dXJucyB7e3BhdGhWYWx1ZTogc3RyaW5nLCBwcmVkaWNhdGU6IFJhbnNhY2tQcmVkaWNhdGV9IHwgbnVsbH0gLSBQYXJzZWQga2V5LlxuICovXG5mdW5jdGlvbiBwYXJzZVJhbnNhY2tLZXkoa2V5KSB7XG4gIGZvciAoY29uc3QgcHJlZGljYXRlIG9mIHN1cHBvcnRlZFByZWRpY2F0ZXMpIHtcbiAgICBjb25zdCBzdWZmaXggPSBgXyR7cHJlZGljYXRlfWBcbiAgICBpZiAoIWtleS5lbmRzV2l0aChzdWZmaXgpKSBjb250aW51ZVxuXG4gICAgY29uc3QgcGF0aFZhbHVlID0ga2V5LnNsaWNlKDAsIGtleS5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKVxuXG4gICAgaWYgKHBhdGhWYWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmFuc2FjayBrZXk6ICR7a2V5fWApXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGhWYWx1ZSxcbiAgICAgIHByZWRpY2F0ZTogLyoqXG4gICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmFuc2Fja1ByZWRpY2F0ZX0gKi8gKHByZWRpY2F0ZSlcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IHByZWRpY2F0ZSBvZiBzdXBwb3J0ZWRQcmVkaWNhdGVzKSB7XG4gICAgY29uc3QgY2FtZWxTdWZmaXggPSBzbmFrZVRvQ2FtZWxTdWZmaXgocHJlZGljYXRlKVxuXG4gICAgaWYgKCFrZXkuZW5kc1dpdGgoY2FtZWxTdWZmaXgpKSBjb250aW51ZVxuXG4gICAgY29uc3QgcGF0aFZhbHVlID0ga2V5LnNsaWNlKDAsIGtleS5sZW5ndGggLSBjYW1lbFN1ZmZpeC5sZW5ndGgpXG5cbiAgICBpZiAocGF0aFZhbHVlLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIGtleTogJHtrZXl9YClcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGF0aFZhbHVlLFxuICAgICAgcHJlZGljYXRlOiAvKipcbiAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSYW5zYWNrUHJlZGljYXRlfSAqLyAocHJlZGljYXRlKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cbi8qKlxuICogUnVucyBzbmFrZSB0byBjYW1lbCBzdWZmaXguXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBTbmFrZS1jYXNlIHByZWRpY2F0ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQ2FtZWxDYXNlIHByZWRpY2F0ZSBzdWZmaXggdXNlZCBpbiByYW5zYWNrIGtleXMuXG4gKi9cbmZ1bmN0aW9uIHNuYWtlVG9DYW1lbFN1ZmZpeCh2YWx1ZSkge1xuICBjb25zdCBzZWdtZW50cyA9IHZhbHVlLnNwbGl0KFwiX1wiKVxuXG4gIHJldHVybiBzZWdtZW50cy5tYXAoKHNlZ21lbnQpID0+IHNlZ21lbnQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzZWdtZW50LnNsaWNlKDEpKS5qb2luKFwiXCIpXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgcmFuc2FjayB2YWx1ZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja1ByZWRpY2F0ZX0gYXJncy5wcmVkaWNhdGUgLSBQYXJzZWQgcHJlZGljYXRlLlxuICogQHBhcmFtIHs/fSBhcmdzLnZhbHVlIC0gUmF3IHZhbHVlLlxuICogQHJldHVybnMgez99IC0gTm9ybWFsaXplZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUmFuc2Fja1ZhbHVlKHtwcmVkaWNhdGUsIHZhbHVlfSkge1xuICBpZiAocHJlZGljYXRlID09PSBcIm51bGxcIikge1xuICAgIHJldHVybiBub3JtYWxpemVSYW5zYWNrTnVsbFZhbHVlKHZhbHVlKVxuICB9XG5cbiAgaWYgKHByZWRpY2F0ZSA9PT0gXCJpblwiIHx8IHByZWRpY2F0ZSA9PT0gXCJub3RfaW5cIikge1xuICAgIHJldHVybiBub3JtYWxpemVSYW5zYWNrTGlzdFZhbHVlKHZhbHVlKVxuICB9XG5cbiAgaWYgKHJhbnNhY2tWYWx1ZUlzQmxhbmsodmFsdWUpKSByZXR1cm4gU0tJUF9SQU5TQUNLX0NPTkRJVElPTlxuXG4gIHJldHVybiB2YWx1ZVxufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHJhbnNhY2sgbnVsbCB2YWx1ZS5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgbnVsbCBwcmVkaWNhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbiB8IHR5cGVvZiBTS0lQX1JBTlNBQ0tfQ09ORElUSU9OfSAtIE5vcm1hbGl6ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbnNhY2tOdWxsVmFsdWUodmFsdWUpIHtcbiAgY29uc3QgYm9vbGVhblZhbHVlID0gbm9ybWFsaXplUmFuc2Fja0Jvb2xlYW4odmFsdWUpXG5cbiAgcmV0dXJuIGJvb2xlYW5WYWx1ZSA9PT0gbnVsbCA/IFNLSVBfUkFOU0FDS19DT05ESVRJT04gOiBib29sZWFuVmFsdWVcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSByYW5zYWNrIGxpc3QgdmFsdWUuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQ2FuZGlkYXRlIGxpc3QgcHJlZGljYXRlIHZhbHVlLlxuICogQHJldHVybnMge0FycmF5PD8+IHwgdHlwZW9mIFNLSVBfUkFOU0FDS19DT05ESVRJT059IC0gTm9ybWFsaXplZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUmFuc2Fja0xpc3RWYWx1ZSh2YWx1ZSkge1xuICBjb25zdCBub3JtYWxpemVkQXJyYXkgPSBub3JtYWxpemVSYW5zYWNrQXJyYXkodmFsdWUpXG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRBcnJheS5sZW5ndGggPCAxID8gU0tJUF9SQU5TQUNLX0NPTkRJVElPTiA6IG5vcm1hbGl6ZWRBcnJheVxufVxuXG4vKipcbiAqIFJhbnNhY2sgdHJ1ZSB2YWx1ZXMuXG4gIEB0eXBlIHtTZXQ8Pz59ICovXG5jb25zdCByYW5zYWNrVHJ1ZVZhbHVlcyA9IG5ldyBTZXQoW3RydWUsIDEsIFwiMVwiLCBcInRydWVcIl0pXG4vKipcbiAqIFJhbnNhY2sgZmFsc2UgdmFsdWVzLlxuICBAdHlwZSB7U2V0PD8+fSAqL1xuY29uc3QgcmFuc2Fja0ZhbHNlVmFsdWVzID0gbmV3IFNldChbZmFsc2UsIDAsIFwiMFwiLCBcImZhbHNlXCJdKVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHJhbnNhY2sgYm9vbGVhbi5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgYm9vbGVhbi5cbiAqIEByZXR1cm5zIHtib29sZWFuIHwgbnVsbH0gLSBOb3JtYWxpemVkIGJvb2xlYW4gb3IgbnVsbCB3aGVuIGJsYW5rLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrQm9vbGVhbih2YWx1ZSkge1xuICBpZiAocmFuc2Fja1RydWVWYWx1ZXMuaGFzKHZhbHVlKSkgcmV0dXJuIHRydWVcbiAgaWYgKHJhbnNhY2tGYWxzZVZhbHVlcy5oYXModmFsdWUpKSByZXR1cm4gZmFsc2VcbiAgaWYgKHJhbnNhY2tWYWx1ZUlzQmxhbmsodmFsdWUpKSByZXR1cm4gbnVsbFxuXG4gIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIGJvb2xlYW4gdmFsdWU6ICR7U3RyaW5nKHZhbHVlKX1gKVxufVxuXG4vKipcbiAqIFJ1bnMgcmFuc2FjayB2YWx1ZSBpcyBibGFuay5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHZhbHVlIHNob3VsZCBiZSBpZ25vcmVkIGFzIGJsYW5rLlxuICovXG5mdW5jdGlvbiByYW5zYWNrVmFsdWVJc0JsYW5rKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSBcIlwiXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgcmFuc2FjayBhcnJheS5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgYXJyYXktaXNoIHZhbHVlLlxuICogQHJldHVybnMge0FycmF5PD8+fSAtIE5vcm1hbGl6ZWQgYXJyYXkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrQXJyYXkodmFsdWUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLmZpbHRlcigoZW50cnkpID0+IGVudHJ5ICE9PSB1bmRlZmluZWQgJiYgZW50cnkgIT09IG51bGwgJiYgZW50cnkgIT09IFwiXCIpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIHZhbHVlLnNwbGl0KFwiLFwiKS5tYXAoKGVudHJ5KSA9PiBlbnRyeS50cmltKCkpLmZpbHRlcigoZW50cnkpID0+IGVudHJ5Lmxlbmd0aCA+IDApXG4gIH1cblxuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikgcmV0dXJuIFtdXG5cbiAgcmV0dXJuIFt2YWx1ZV1cbn1cblxuLyoqXG4gKiBSYW5zYWNrU29ydCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gUmFuc2Fja1NvcnRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhdHRyaWJ1dGUgLSBSZXNvbHZlZCBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7XCJhc2NcIiB8IFwiZGVzY1wifSBkaXJlY3Rpb24gLSBTb3J0IGRpcmVjdGlvbi5cbiAqL1xuXG4vKipcbiAqIFBhcnNlcyBhbmQgdmFsaWRhdGVzIGEgcmFuc2FjayBgc2Agc29ydCBzdHJpbmcgYWdhaW5zdCBtb2RlbCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzIGZvciBhdHRyaWJ1dGUgdmFsaWRhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3J0U3RyaW5nIC0gUmFuc2FjayBzb3J0IHN0cmluZyAoZS5nLiwgXCJuYW1lIGFzY1wiIG9yIFwibmFtZSBhc2MsIGNyZWF0ZWRBdCBkZXNjXCIpLlxuICogQHJldHVybnMge1JhbnNhY2tTb3J0W119IC0gVmFsaWRhdGVkIHNvcnQgZGVmaW5pdGlvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJhbnNhY2tTb3J0KG1vZGVsQ2xhc3MsIHNvcnRTdHJpbmcpIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBzb3J0U3RyaW5nLnNwbGl0KFwiLFwiKS5tYXAoKHNlZ21lbnQpID0+IHNlZ21lbnQudHJpbSgpKS5maWx0ZXIoKHNlZ21lbnQpID0+IHNlZ21lbnQubGVuZ3RoID4gMClcblxuICAvKipcbiAgICogU29ydHMuXG4gICAgQHR5cGUge1JhbnNhY2tTb3J0W119ICovXG4gIGNvbnN0IHNvcnRzID0gW11cblxuICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHNlZ21lbnQuc3BsaXQoL1xccysvKVxuICAgIGNvbnN0IGNvbHVtbkNhbmRpZGF0ZSA9IHBhcnRzWzBdXG4gICAgY29uc3QgZGlyZWN0aW9uQ2FuZGlkYXRlID0gcGFydHMubGVuZ3RoID4gMSA/IHBhcnRzWzFdLnRvTG93ZXJDYXNlKCkgOiBcImFzY1wiXG5cbiAgICBpZiAoZGlyZWN0aW9uQ2FuZGlkYXRlICE9PSBcImFzY1wiICYmIGRpcmVjdGlvbkNhbmRpZGF0ZSAhPT0gXCJkZXNjXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIHNvcnQgZGlyZWN0aW9uIFwiJHtkaXJlY3Rpb25DYW5kaWRhdGV9XCIgaW46ICR7c2VnbWVudH1gKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc29sdmVkQXR0cmlidXRlID0gcmVzb2x2ZUF0dHJpYnV0ZU5hbWUoe21vZGVsQ2xhc3MsIHZhbHVlOiBjb2x1bW5DYW5kaWRhdGV9KVxuXG4gICAgaWYgKCFyZXNvbHZlZEF0dHJpYnV0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHJhbnNhY2sgc29ydCBhdHRyaWJ1dGUgXCIke2NvbHVtbkNhbmRpZGF0ZX1cIiBmb3IgJHttb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICBzb3J0cy5wdXNoKHthdHRyaWJ1dGU6IHJlc29sdmVkQXR0cmlidXRlLCBkaXJlY3Rpb246IGRpcmVjdGlvbkNhbmRpZGF0ZX0pXG4gIH1cblxuICByZXR1cm4gc29ydHNcbn1cblxuLyoqXG4gKiBSdW5zIHVuaXF1bml6ZS5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHZhbHVlcyAtIElucHV0IHZhbHVlcy5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBVbmlxdWUgdmFsdWVzIGluIG9yaWdpbmFsIG9yZGVyLlxuICovXG5mdW5jdGlvbiB1bmlxdW5pemUodmFsdWVzKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzKSlcbn1cbiJdfQ==
|