@uql/core 1.0.12 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +254 -0
- package/LICENSE.md +2 -2
- package/dist/browser/http/bus.d.ts +3 -0
- package/dist/browser/http/bus.js +14 -0
- package/dist/browser/http/http.d.ts +6 -0
- package/dist/browser/http/http.js +45 -0
- package/dist/browser/http/index.d.ts +2 -0
- package/dist/browser/http/index.js +3 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +5 -0
- package/dist/browser/options.d.ts +4 -0
- package/dist/browser/options.js +14 -0
- package/dist/browser/querier/genericClientRepository.d.ts +17 -0
- package/dist/browser/querier/genericClientRepository.js +39 -0
- package/dist/browser/querier/httpQuerier.d.ts +20 -0
- package/dist/browser/querier/httpQuerier.js +71 -0
- package/dist/browser/querier/index.d.ts +3 -0
- package/dist/browser/querier/index.js +4 -0
- package/dist/browser/querier/querier.util.d.ts +2 -0
- package/dist/browser/querier/querier.util.js +17 -0
- package/dist/browser/type/clientQuerier.d.ts +16 -0
- package/dist/browser/type/clientQuerier.js +2 -0
- package/dist/browser/type/clientQuerierPool.d.ts +4 -0
- package/dist/browser/type/clientQuerierPool.js +2 -0
- package/dist/browser/type/clientRepository.d.ts +13 -0
- package/dist/browser/type/clientRepository.js +2 -0
- package/dist/browser/type/index.d.ts +4 -0
- package/dist/browser/type/index.js +5 -0
- package/dist/browser/type/request.d.ts +28 -0
- package/dist/browser/type/request.js +2 -0
- package/dist/browser/uql-browser.min.js +2150 -0
- package/dist/browser/uql-browser.min.js.map +1 -0
- package/dist/dialect/abstractDialect.d.ts +16 -0
- package/dist/dialect/abstractDialect.js +28 -0
- package/dist/dialect/abstractSqlDialect.d.ts +47 -0
- package/dist/dialect/abstractSqlDialect.js +650 -0
- package/dist/dialect/index.d.ts +3 -0
- package/dist/dialect/index.js +4 -0
- package/dist/dialect/queryContext.d.ts +48 -0
- package/dist/dialect/queryContext.js +65 -0
- package/{entity → dist/entity}/decorator/definition.d.ts +3 -3
- package/dist/entity/decorator/definition.js +214 -0
- package/{entity → dist/entity}/decorator/entity.d.ts +1 -1
- package/dist/entity/decorator/entity.js +7 -0
- package/{entity → dist/entity}/decorator/field.d.ts +1 -1
- package/dist/entity/decorator/field.js +8 -0
- package/{entity → dist/entity}/decorator/id.d.ts +1 -1
- package/dist/entity/decorator/id.js +8 -0
- package/dist/entity/decorator/index.d.ts +5 -0
- package/dist/entity/decorator/index.js +6 -0
- package/{entity → dist/entity}/decorator/relation.d.ts +1 -1
- package/dist/entity/decorator/relation.js +20 -0
- package/dist/entity/index.d.ts +1 -0
- package/dist/entity/index.js +2 -0
- package/dist/express/index.d.ts +2 -0
- package/dist/express/index.js +3 -0
- package/dist/express/querierMiddleware.d.ts +26 -0
- package/dist/express/querierMiddleware.js +190 -0
- package/dist/express/query.util.d.ts +2 -0
- package/dist/express/query.util.js +19 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/maria/index.d.ts +3 -0
- package/dist/maria/index.js +4 -0
- package/dist/maria/mariaDialect.d.ts +8 -0
- package/dist/maria/mariaDialect.js +38 -0
- package/dist/maria/mariaQuerierPool.test.d.ts +5 -0
- package/dist/maria/mariaQuerierPool.test.js +19 -0
- package/dist/maria/mariadbQuerier.d.ts +17 -0
- package/dist/maria/mariadbQuerier.js +39 -0
- package/dist/maria/mariadbQuerier.test.d.ts +4 -0
- package/dist/maria/mariadbQuerier.test.js +19 -0
- package/dist/maria/mariadbQuerierPool.d.ts +10 -0
- package/dist/maria/mariadbQuerierPool.js +17 -0
- package/dist/migrate/cli.d.ts +2 -0
- package/dist/migrate/cli.js +254 -0
- package/dist/migrate/generator/index.d.ts +4 -0
- package/dist/migrate/generator/index.js +5 -0
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +12 -0
- package/dist/migrate/generator/mongoSchemaGenerator.js +100 -0
- package/dist/migrate/generator/mysqlSchemaGenerator.d.ts +14 -0
- package/dist/migrate/generator/mysqlSchemaGenerator.js +81 -0
- package/dist/migrate/generator/postgresSchemaGenerator.d.ts +18 -0
- package/dist/migrate/generator/postgresSchemaGenerator.js +111 -0
- package/dist/migrate/generator/sqliteSchemaGenerator.d.ts +14 -0
- package/dist/migrate/generator/sqliteSchemaGenerator.js +68 -0
- package/dist/migrate/index.d.ts +12 -0
- package/dist/migrate/index.js +17 -0
- package/dist/migrate/introspection/index.d.ts +4 -0
- package/dist/migrate/introspection/index.js +5 -0
- package/dist/migrate/introspection/mongoIntrospector.d.ts +8 -0
- package/dist/migrate/introspection/mongoIntrospector.js +46 -0
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +25 -0
- package/dist/migrate/introspection/mysqlIntrospector.js +220 -0
- package/dist/migrate/introspection/postgresIntrospector.d.ts +21 -0
- package/dist/migrate/introspection/postgresIntrospector.js +269 -0
- package/dist/migrate/introspection/sqliteIntrospector.d.ts +23 -0
- package/dist/migrate/introspection/sqliteIntrospector.js +212 -0
- package/dist/migrate/migrator-mongo.test.d.ts +1 -0
- package/dist/migrate/migrator-mongo.test.js +54 -0
- package/dist/migrate/migrator.d.ts +133 -0
- package/dist/migrate/migrator.js +600 -0
- package/dist/migrate/migrator.test.d.ts +1 -0
- package/dist/migrate/migrator.test.js +106 -0
- package/dist/migrate/schemaGenerator.d.ts +78 -0
- package/dist/migrate/schemaGenerator.js +363 -0
- package/dist/migrate/storage/databaseStorage.d.ts +24 -0
- package/dist/migrate/storage/databaseStorage.js +77 -0
- package/dist/migrate/storage/index.d.ts +2 -0
- package/dist/migrate/storage/index.js +3 -0
- package/dist/migrate/storage/jsonStorage.d.ts +15 -0
- package/dist/migrate/storage/jsonStorage.js +51 -0
- package/dist/migrate/type.d.ts +1 -0
- package/dist/migrate/type.js +2 -0
- package/dist/mongo/index.d.ts +3 -0
- package/dist/mongo/index.js +4 -0
- package/dist/mongo/mongoDialect.d.ts +34 -0
- package/dist/mongo/mongoDialect.js +163 -0
- package/dist/mongo/mongodbQuerier.d.ts +28 -0
- package/dist/mongo/mongodbQuerier.js +204 -0
- package/dist/mongo/mongodbQuerier.test.d.ts +1 -0
- package/dist/mongo/mongodbQuerier.test.js +36 -0
- package/dist/mongo/mongodbQuerierPool.d.ts +10 -0
- package/dist/mongo/mongodbQuerierPool.js +20 -0
- package/dist/mongo/mongodbQuerierPool.test.d.ts +1 -0
- package/dist/mongo/mongodbQuerierPool.test.js +21 -0
- package/dist/mysql/index.d.ts +3 -0
- package/dist/mysql/index.js +4 -0
- package/dist/mysql/mysql2Querier.d.ts +17 -0
- package/dist/mysql/mysql2Querier.js +43 -0
- package/dist/mysql/mysql2Querier.test.d.ts +4 -0
- package/dist/mysql/mysql2Querier.test.js +16 -0
- package/dist/mysql/mysql2QuerierPool.d.ts +10 -0
- package/dist/mysql/mysql2QuerierPool.js +17 -0
- package/dist/mysql/mysql2QuerierPool.test.d.ts +5 -0
- package/dist/mysql/mysql2QuerierPool.test.js +16 -0
- package/dist/mysql/mysqlDialect.d.ts +5 -0
- package/dist/mysql/mysqlDialect.js +15 -0
- package/dist/namingStrategy/defaultNamingStrategy.d.ts +9 -0
- package/dist/namingStrategy/defaultNamingStrategy.js +15 -0
- package/dist/namingStrategy/index.d.ts +2 -0
- package/dist/namingStrategy/index.js +3 -0
- package/dist/namingStrategy/snakeCaseNamingStrategy.d.ts +8 -0
- package/dist/namingStrategy/snakeCaseNamingStrategy.js +14 -0
- package/{options.d.ts → dist/options.d.ts} +1 -1
- package/dist/options.js +14 -0
- package/dist/package.json +131 -0
- package/dist/postgres/index.d.ts +3 -0
- package/dist/postgres/index.js +4 -0
- package/dist/postgres/pgQuerier.d.ts +17 -0
- package/dist/postgres/pgQuerier.js +39 -0
- package/dist/postgres/pgQuerier.test.d.ts +4 -0
- package/dist/postgres/pgQuerier.test.js +20 -0
- package/dist/postgres/pgQuerierPool.d.ts +10 -0
- package/dist/postgres/pgQuerierPool.js +17 -0
- package/dist/postgres/pgQuerierPool.test.d.ts +5 -0
- package/dist/postgres/pgQuerierPool.test.js +23 -0
- package/dist/postgres/postgresDialect.d.ts +13 -0
- package/dist/postgres/postgresDialect.js +110 -0
- package/dist/querier/abstractQuerier-test.d.ts +45 -0
- package/dist/querier/abstractQuerier-test.js +461 -0
- package/dist/querier/abstractQuerier.d.ts +50 -0
- package/dist/querier/abstractQuerier.js +278 -0
- package/dist/querier/abstractQuerierPool-test.d.ts +9 -0
- package/dist/querier/abstractQuerierPool-test.js +18 -0
- package/dist/querier/abstractQuerierPool.d.ts +14 -0
- package/dist/querier/abstractQuerierPool.js +9 -0
- package/dist/querier/abstractSqlQuerier-test.d.ts +9 -0
- package/dist/querier/abstractSqlQuerier-test.js +16 -0
- package/dist/querier/abstractSqlQuerier.d.ts +28 -0
- package/dist/querier/abstractSqlQuerier.js +133 -0
- package/dist/querier/decorator/index.d.ts +3 -0
- package/dist/querier/decorator/index.js +4 -0
- package/dist/querier/decorator/injectQuerier.d.ts +3 -0
- package/dist/querier/decorator/injectQuerier.js +33 -0
- package/dist/querier/decorator/serialized.d.ts +6 -0
- package/dist/querier/decorator/serialized.js +14 -0
- package/{querier → dist/querier}/decorator/transactional.d.ts +1 -1
- package/dist/querier/decorator/transactional.js +48 -0
- package/dist/querier/index.d.ts +4 -0
- package/dist/querier/index.js +5 -0
- package/dist/repository/genericRepository.d.ts +20 -0
- package/dist/repository/genericRepository.js +51 -0
- package/dist/repository/index.d.ts +1 -0
- package/dist/repository/index.js +2 -0
- package/dist/sqlite/index.d.ts +3 -0
- package/dist/sqlite/index.js +4 -0
- package/dist/sqlite/sqliteDialect.d.ts +10 -0
- package/dist/sqlite/sqliteDialect.js +48 -0
- package/dist/sqlite/sqliteQuerier.d.ts +15 -0
- package/dist/sqlite/sqliteQuerier.js +33 -0
- package/dist/sqlite/sqliteQuerier.test.d.ts +5 -0
- package/dist/sqlite/sqliteQuerier.test.js +19 -0
- package/dist/sqlite/sqliteQuerierPool.d.ts +14 -0
- package/dist/sqlite/sqliteQuerierPool.js +34 -0
- package/dist/sqlite/sqliteQuerierPool.test.d.ts +5 -0
- package/dist/sqlite/sqliteQuerierPool.test.js +10 -0
- package/dist/test/entityMock.d.ts +164 -0
- package/dist/test/entityMock.js +554 -0
- package/dist/test/index.d.ts +3 -0
- package/dist/test/index.js +4 -0
- package/dist/test/it.util.d.ts +4 -0
- package/dist/test/it.util.js +55 -0
- package/dist/test/spec.util.d.ts +14 -0
- package/dist/test/spec.util.js +50 -0
- package/{type → dist/type}/entity.d.ts +97 -4
- package/dist/type/entity.js +5 -0
- package/dist/type/index.d.ts +9 -0
- package/dist/type/index.js +10 -0
- package/dist/type/migration.d.ts +213 -0
- package/dist/type/migration.js +2 -0
- package/dist/type/namingStrategy.d.ts +17 -0
- package/dist/type/namingStrategy.js +2 -0
- package/dist/type/querier.d.ts +96 -0
- package/dist/type/querier.js +11 -0
- package/{type → dist/type}/querierPool.d.ts +7 -3
- package/dist/type/querierPool.js +2 -0
- package/{type → dist/type}/query.d.ts +170 -108
- package/dist/type/query.js +9 -0
- package/{type → dist/type}/repository.d.ts +42 -35
- package/dist/type/repository.js +2 -0
- package/{type → dist/type}/universalQuerier.d.ts +50 -28
- package/dist/type/universalQuerier.js +2 -0
- package/dist/type/utility.d.ts +13 -0
- package/dist/type/utility.js +2 -0
- package/dist/util/dialect.util.d.ts +12 -0
- package/dist/util/dialect.util.js +93 -0
- package/dist/util/index.d.ts +5 -0
- package/dist/util/index.js +6 -0
- package/dist/util/object.util.d.ts +7 -0
- package/dist/util/object.util.js +19 -0
- package/dist/util/raw.d.ts +8 -0
- package/dist/util/raw.js +11 -0
- package/dist/util/sql.util.d.ts +13 -0
- package/dist/util/sql.util.js +78 -0
- package/{util → dist/util}/string.util.d.ts +1 -0
- package/dist/util/string.util.js +34 -0
- package/package.json +85 -17
- package/src/@types/index.d.ts +1 -0
- package/src/@types/jest.d.ts +6 -0
- package/src/browser/http/bus.spec.ts +22 -0
- package/src/browser/http/bus.ts +17 -0
- package/src/browser/http/http.spec.ts +70 -0
- package/src/browser/http/http.ts +55 -0
- package/src/browser/http/index.ts +2 -0
- package/src/browser/index.ts +4 -0
- package/src/browser/options.spec.ts +37 -0
- package/src/browser/options.ts +18 -0
- package/src/browser/querier/genericClientRepository.spec.ts +105 -0
- package/src/browser/querier/genericClientRepository.ts +49 -0
- package/src/browser/querier/httpQuerier.ts +82 -0
- package/src/browser/querier/index.ts +3 -0
- package/src/browser/querier/querier.util.spec.ts +35 -0
- package/src/browser/querier/querier.util.ts +18 -0
- package/src/browser/type/clientQuerier.ts +45 -0
- package/src/browser/type/clientQuerierPool.ts +5 -0
- package/src/browser/type/clientRepository.ts +22 -0
- package/src/browser/type/index.ts +4 -0
- package/src/browser/type/request.ts +25 -0
- package/src/dialect/abstractDialect.ts +28 -0
- package/src/dialect/abstractSqlDialect-spec.ts +1309 -0
- package/src/dialect/abstractSqlDialect.ts +805 -0
- package/src/dialect/index.ts +3 -0
- package/src/dialect/namingStrategy.spec.ts +52 -0
- package/src/dialect/queryContext.ts +69 -0
- package/src/entity/decorator/definition.spec.ts +736 -0
- package/src/entity/decorator/definition.ts +265 -0
- package/src/entity/decorator/entity.ts +8 -0
- package/src/entity/decorator/field.ts +9 -0
- package/src/entity/decorator/id.ts +9 -0
- package/src/entity/decorator/index.ts +5 -0
- package/src/entity/decorator/relation.spec.ts +41 -0
- package/src/entity/decorator/relation.ts +34 -0
- package/src/entity/index.ts +1 -0
- package/src/express/@types/express.d.ts +8 -0
- package/src/express/@types/index.d.ts +1 -0
- package/src/express/index.ts +2 -0
- package/src/express/querierMiddleware.ts +217 -0
- package/src/express/query.util.spec.ts +40 -0
- package/src/express/query.util.ts +21 -0
- package/src/index.ts +9 -0
- package/src/maria/index.ts +3 -0
- package/src/maria/mariaDialect.spec.ts +207 -0
- package/src/maria/mariaDialect.ts +42 -0
- package/src/maria/mariaQuerierPool.test.ts +23 -0
- package/src/maria/mariadbQuerier.test.ts +23 -0
- package/src/maria/mariadbQuerier.ts +45 -0
- package/src/maria/mariadbQuerierPool.ts +21 -0
- package/src/migrate/cli.ts +301 -0
- package/src/migrate/generator/index.ts +4 -0
- package/src/migrate/generator/mongoSchemaGenerator.spec.ts +112 -0
- package/src/migrate/generator/mongoSchemaGenerator.ts +115 -0
- package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +34 -0
- package/src/migrate/generator/mysqlSchemaGenerator.ts +92 -0
- package/src/migrate/generator/postgresSchemaGenerator.spec.ts +44 -0
- package/src/migrate/generator/postgresSchemaGenerator.ts +127 -0
- package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +33 -0
- package/src/migrate/generator/sqliteSchemaGenerator.ts +81 -0
- package/src/migrate/index.ts +41 -0
- package/src/migrate/introspection/index.ts +4 -0
- package/src/migrate/introspection/mongoIntrospector.spec.ts +75 -0
- package/src/migrate/introspection/mongoIntrospector.ts +47 -0
- package/src/migrate/introspection/mysqlIntrospector.spec.ts +113 -0
- package/src/migrate/introspection/mysqlIntrospector.ts +278 -0
- package/src/migrate/introspection/postgresIntrospector.spec.ts +112 -0
- package/src/migrate/introspection/postgresIntrospector.ts +329 -0
- package/src/migrate/introspection/sqliteIntrospector.spec.ts +112 -0
- package/src/migrate/introspection/sqliteIntrospector.ts +296 -0
- package/src/migrate/migrator-mongo.test.ts +54 -0
- package/src/migrate/migrator.spec.ts +255 -0
- package/src/migrate/migrator.test.ts +94 -0
- package/src/migrate/migrator.ts +719 -0
- package/src/migrate/namingStrategy.spec.ts +22 -0
- package/src/migrate/schemaGenerator-advanced.spec.ts +138 -0
- package/src/migrate/schemaGenerator.spec.ts +190 -0
- package/src/migrate/schemaGenerator.ts +478 -0
- package/src/migrate/storage/databaseStorage.spec.ts +69 -0
- package/src/migrate/storage/databaseStorage.ts +100 -0
- package/src/migrate/storage/index.ts +2 -0
- package/src/migrate/storage/jsonStorage.ts +58 -0
- package/src/migrate/type.ts +1 -0
- package/src/mongo/index.ts +3 -0
- package/src/mongo/mongoDialect.spec.ts +251 -0
- package/src/mongo/mongoDialect.ts +238 -0
- package/src/mongo/mongodbQuerier.test.ts +45 -0
- package/src/mongo/mongodbQuerier.ts +256 -0
- package/src/mongo/mongodbQuerierPool.test.ts +25 -0
- package/src/mongo/mongodbQuerierPool.ts +24 -0
- package/src/mysql/index.ts +3 -0
- package/src/mysql/mysql2Querier.test.ts +20 -0
- package/src/mysql/mysql2Querier.ts +49 -0
- package/src/mysql/mysql2QuerierPool.test.ts +20 -0
- package/src/mysql/mysql2QuerierPool.ts +21 -0
- package/src/mysql/mysqlDialect.spec.ts +20 -0
- package/src/mysql/mysqlDialect.ts +16 -0
- package/src/namingStrategy/defaultNamingStrategy.ts +18 -0
- package/src/namingStrategy/index.spec.ts +36 -0
- package/src/namingStrategy/index.ts +2 -0
- package/src/namingStrategy/snakeCaseNamingStrategy.ts +15 -0
- package/src/options.spec.ts +41 -0
- package/src/options.ts +18 -0
- package/src/postgres/index.ts +3 -0
- package/src/postgres/manual-types.d.ts +4 -0
- package/src/postgres/pgQuerier.test.ts +25 -0
- package/src/postgres/pgQuerier.ts +45 -0
- package/src/postgres/pgQuerierPool.test.ts +28 -0
- package/src/postgres/pgQuerierPool.ts +21 -0
- package/src/postgres/postgresDialect.spec.ts +428 -0
- package/src/postgres/postgresDialect.ts +144 -0
- package/src/querier/abstractQuerier-test.ts +584 -0
- package/src/querier/abstractQuerier.ts +353 -0
- package/src/querier/abstractQuerierPool-test.ts +20 -0
- package/src/querier/abstractQuerierPool.ts +18 -0
- package/src/querier/abstractSqlQuerier-spec.ts +979 -0
- package/src/querier/abstractSqlQuerier-test.ts +21 -0
- package/src/querier/abstractSqlQuerier.ts +138 -0
- package/src/querier/decorator/index.ts +3 -0
- package/src/querier/decorator/injectQuerier.spec.ts +74 -0
- package/src/querier/decorator/injectQuerier.ts +45 -0
- package/src/querier/decorator/serialized.spec.ts +98 -0
- package/src/querier/decorator/serialized.ts +13 -0
- package/src/querier/decorator/transactional.spec.ts +240 -0
- package/src/querier/decorator/transactional.ts +56 -0
- package/src/querier/index.ts +4 -0
- package/src/repository/genericRepository.spec.ts +111 -0
- package/src/repository/genericRepository.ts +74 -0
- package/src/repository/index.ts +1 -0
- package/src/sqlite/index.ts +3 -0
- package/src/sqlite/manual-types.d.ts +4 -0
- package/src/sqlite/sqliteDialect.spec.ts +155 -0
- package/src/sqlite/sqliteDialect.ts +76 -0
- package/src/sqlite/sqliteQuerier.spec.ts +36 -0
- package/src/sqlite/sqliteQuerier.test.ts +21 -0
- package/src/sqlite/sqliteQuerier.ts +37 -0
- package/src/sqlite/sqliteQuerierPool.test.ts +12 -0
- package/src/sqlite/sqliteQuerierPool.ts +38 -0
- package/src/test/entityMock.ts +375 -0
- package/src/test/index.ts +3 -0
- package/src/test/it.util.ts +69 -0
- package/src/test/spec.util.ts +57 -0
- package/src/type/entity.ts +218 -0
- package/src/type/index.ts +9 -0
- package/src/type/migration.ts +241 -0
- package/src/type/namingStrategy.ts +17 -0
- package/src/type/querier.ts +143 -0
- package/src/type/querierPool.ts +26 -0
- package/src/type/query.ts +506 -0
- package/src/type/repository.ts +142 -0
- package/src/type/universalQuerier.ts +133 -0
- package/src/type/utility.ts +21 -0
- package/src/util/dialect.util-extra.spec.ts +96 -0
- package/src/util/dialect.util.spec.ts +23 -0
- package/src/util/dialect.util.ts +134 -0
- package/src/util/index.ts +5 -0
- package/src/util/object.util.spec.ts +29 -0
- package/src/util/object.util.ts +27 -0
- package/src/util/raw.ts +11 -0
- package/src/util/sql.util-extra.spec.ts +17 -0
- package/src/util/sql.util.spec.ts +208 -0
- package/src/util/sql.util.ts +104 -0
- package/src/util/string.util.spec.ts +46 -0
- package/src/util/string.util.ts +35 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +8 -0
- package/README.md +0 -177
- package/dialect/abstractSqlDialect.d.ts +0 -30
- package/dialect/abstractSqlDialect.js +0 -365
- package/dialect/index.d.ts +0 -4
- package/dialect/index.js +0 -8
- package/dialect/mysqlDialect.d.ts +0 -6
- package/dialect/mysqlDialect.js +0 -21
- package/dialect/postgresDialect.d.ts +0 -8
- package/dialect/postgresDialect.js +0 -44
- package/dialect/sqliteDialect.d.ts +0 -4
- package/dialect/sqliteDialect.js +0 -11
- package/entity/decorator/definition.js +0 -223
- package/entity/decorator/entity.js +0 -11
- package/entity/decorator/field.js +0 -12
- package/entity/decorator/id.js +0 -12
- package/entity/decorator/index.d.ts +0 -5
- package/entity/decorator/index.js +0 -12
- package/entity/decorator/relation.js +0 -27
- package/entity/index.d.ts +0 -1
- package/entity/index.js +0 -5
- package/index.d.ts +0 -1
- package/index.js +0 -5
- package/options.js +0 -20
- package/querier/abstractQuerier.d.ts +0 -30
- package/querier/abstractQuerier.js +0 -230
- package/querier/abstractSqlQuerier.d.ts +0 -27
- package/querier/abstractSqlQuerier.js +0 -88
- package/querier/decorator/index.d.ts +0 -2
- package/querier/decorator/index.js +0 -6
- package/querier/decorator/injectQuerier.d.ts +0 -3
- package/querier/decorator/injectQuerier.js +0 -39
- package/querier/decorator/transactional.js +0 -52
- package/querier/index.d.ts +0 -3
- package/querier/index.js +0 -7
- package/repository/genericRepository.d.ts +0 -19
- package/repository/genericRepository.js +0 -52
- package/repository/index.d.ts +0 -1
- package/repository/index.js +0 -5
- package/type/entity.js +0 -5
- package/type/index.d.ts +0 -7
- package/type/index.js +0 -11
- package/type/querier.d.ts +0 -53
- package/type/querier.js +0 -3
- package/type/querierPool.js +0 -3
- package/type/query.js +0 -13
- package/type/repository.js +0 -3
- package/type/universalQuerier.js +0 -3
- package/type/utility.d.ts +0 -12
- package/type/utility.js +0 -3
- package/util/dialect.util.d.ts +0 -17
- package/util/dialect.util.js +0 -114
- package/util/index.d.ts +0 -5
- package/util/index.js +0 -9
- package/util/object.util.d.ts +0 -3
- package/util/object.util.js +0 -22
- package/util/raw.d.ts +0 -2
- package/util/raw.js +0 -9
- package/util/sql.util.d.ts +0 -2
- package/util/sql.util.js +0 -55
- package/util/string.util.js +0 -20
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { basename, extname, join } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { getEntities, getMeta } from '../entity/index.js';
|
|
5
|
+
import { isSqlQuerier } from '../type/index.js';
|
|
6
|
+
import { MariadbSchemaGenerator, MongoSchemaGenerator, MysqlSchemaGenerator, PostgresSchemaGenerator, SqliteSchemaGenerator, } from './generator/index.js';
|
|
7
|
+
import { MariadbSchemaIntrospector, MongoSchemaIntrospector, MysqlSchemaIntrospector, PostgresSchemaIntrospector, SqliteSchemaIntrospector, } from './introspection/index.js';
|
|
8
|
+
import { DatabaseMigrationStorage } from './storage/databaseStorage.js';
|
|
9
|
+
/**
|
|
10
|
+
* Main class for managing database migrations
|
|
11
|
+
*/
|
|
12
|
+
export class Migrator {
|
|
13
|
+
querierPool;
|
|
14
|
+
storage;
|
|
15
|
+
migrationsPath;
|
|
16
|
+
logger;
|
|
17
|
+
entities;
|
|
18
|
+
dialect;
|
|
19
|
+
schemaGenerator;
|
|
20
|
+
schemaIntrospector;
|
|
21
|
+
constructor(querierPool, options = {}) {
|
|
22
|
+
this.querierPool = querierPool;
|
|
23
|
+
this.dialect = options.dialect ?? querierPool.dialect ?? 'postgres';
|
|
24
|
+
this.storage =
|
|
25
|
+
options.storage ??
|
|
26
|
+
new DatabaseMigrationStorage(querierPool, {
|
|
27
|
+
tableName: options.tableName,
|
|
28
|
+
});
|
|
29
|
+
this.migrationsPath = options.migrationsPath ?? './migrations';
|
|
30
|
+
this.logger = options.logger ?? (() => { });
|
|
31
|
+
this.entities = options.entities ?? [];
|
|
32
|
+
this.schemaIntrospector = this.createIntrospector();
|
|
33
|
+
this.schemaGenerator = options.schemaGenerator ?? this.createGenerator(options.namingStrategy);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Set the schema generator for DDL operations
|
|
37
|
+
*/
|
|
38
|
+
setSchemaGenerator(generator) {
|
|
39
|
+
this.schemaGenerator = generator;
|
|
40
|
+
}
|
|
41
|
+
createIntrospector() {
|
|
42
|
+
switch (this.dialect) {
|
|
43
|
+
case 'postgres':
|
|
44
|
+
return new PostgresSchemaIntrospector(this.querierPool);
|
|
45
|
+
case 'mysql':
|
|
46
|
+
return new MysqlSchemaIntrospector(this.querierPool);
|
|
47
|
+
case 'mariadb':
|
|
48
|
+
return new MariadbSchemaIntrospector(this.querierPool);
|
|
49
|
+
case 'sqlite':
|
|
50
|
+
return new SqliteSchemaIntrospector(this.querierPool);
|
|
51
|
+
case 'mongodb':
|
|
52
|
+
return new MongoSchemaIntrospector(this.querierPool);
|
|
53
|
+
default:
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
createGenerator(namingStrategy) {
|
|
58
|
+
switch (this.dialect) {
|
|
59
|
+
case 'postgres':
|
|
60
|
+
return new PostgresSchemaGenerator(namingStrategy);
|
|
61
|
+
case 'mysql':
|
|
62
|
+
return new MysqlSchemaGenerator(namingStrategy);
|
|
63
|
+
case 'mariadb':
|
|
64
|
+
return new MariadbSchemaGenerator(namingStrategy);
|
|
65
|
+
case 'sqlite':
|
|
66
|
+
return new SqliteSchemaGenerator(namingStrategy);
|
|
67
|
+
case 'mongodb':
|
|
68
|
+
return new MongoSchemaGenerator(namingStrategy);
|
|
69
|
+
default:
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the SQL dialect
|
|
75
|
+
*/
|
|
76
|
+
getDialect() {
|
|
77
|
+
return this.dialect;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get all discovered migrations from the migrations directory
|
|
81
|
+
*/
|
|
82
|
+
async getMigrations() {
|
|
83
|
+
const files = await this.getMigrationFiles();
|
|
84
|
+
const migrations = [];
|
|
85
|
+
for (const file of files) {
|
|
86
|
+
const migration = await this.loadMigration(file);
|
|
87
|
+
if (migration) {
|
|
88
|
+
migrations.push(migration);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Sort by name (which typically includes timestamp)
|
|
92
|
+
return migrations.sort((a, b) => a.name.localeCompare(b.name));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get list of pending migrations (not yet executed)
|
|
96
|
+
*/
|
|
97
|
+
async pending() {
|
|
98
|
+
const [migrations, executed] = await Promise.all([this.getMigrations(), this.storage.executed()]);
|
|
99
|
+
const executedSet = new Set(executed);
|
|
100
|
+
return migrations.filter((m) => !executedSet.has(m.name));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get list of executed migrations
|
|
104
|
+
*/
|
|
105
|
+
async executed() {
|
|
106
|
+
return this.storage.executed();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Run all pending migrations
|
|
110
|
+
*/
|
|
111
|
+
async up(options = {}) {
|
|
112
|
+
const pendingMigrations = await this.pending();
|
|
113
|
+
const results = [];
|
|
114
|
+
let migrationsToRun = pendingMigrations;
|
|
115
|
+
if (options.to) {
|
|
116
|
+
const toIndex = migrationsToRun.findIndex((m) => m.name === options.to);
|
|
117
|
+
if (toIndex === -1) {
|
|
118
|
+
throw new Error(`Migration '${options.to}' not found`);
|
|
119
|
+
}
|
|
120
|
+
migrationsToRun = migrationsToRun.slice(0, toIndex + 1);
|
|
121
|
+
}
|
|
122
|
+
if (options.step !== undefined) {
|
|
123
|
+
migrationsToRun = migrationsToRun.slice(0, options.step);
|
|
124
|
+
}
|
|
125
|
+
for (const migration of migrationsToRun) {
|
|
126
|
+
const result = await this.runMigration(migration, 'up');
|
|
127
|
+
results.push(result);
|
|
128
|
+
if (!result.success) {
|
|
129
|
+
break; // Stop on first failure
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return results;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Rollback migrations
|
|
136
|
+
*/
|
|
137
|
+
async down(options = {}) {
|
|
138
|
+
const [migrations, executed] = await Promise.all([this.getMigrations(), this.storage.executed()]);
|
|
139
|
+
const executedSet = new Set(executed);
|
|
140
|
+
const executedMigrations = migrations.filter((m) => executedSet.has(m.name)).reverse(); // Rollback in reverse order
|
|
141
|
+
const results = [];
|
|
142
|
+
let migrationsToRun = executedMigrations;
|
|
143
|
+
if (options.to) {
|
|
144
|
+
const toIndex = migrationsToRun.findIndex((m) => m.name === options.to);
|
|
145
|
+
if (toIndex === -1) {
|
|
146
|
+
throw new Error(`Migration '${options.to}' not found`);
|
|
147
|
+
}
|
|
148
|
+
migrationsToRun = migrationsToRun.slice(0, toIndex + 1);
|
|
149
|
+
}
|
|
150
|
+
if (options.step !== undefined) {
|
|
151
|
+
migrationsToRun = migrationsToRun.slice(0, options.step);
|
|
152
|
+
}
|
|
153
|
+
for (const migration of migrationsToRun) {
|
|
154
|
+
const result = await this.runMigration(migration, 'down');
|
|
155
|
+
results.push(result);
|
|
156
|
+
if (!result.success) {
|
|
157
|
+
break; // Stop on first failure
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return results;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Run a single migration within a transaction
|
|
164
|
+
*/
|
|
165
|
+
async runMigration(migration, direction) {
|
|
166
|
+
const startTime = Date.now();
|
|
167
|
+
const querier = await this.querierPool.getQuerier();
|
|
168
|
+
if (!isSqlQuerier(querier)) {
|
|
169
|
+
await querier.release();
|
|
170
|
+
throw new Error('Migrator requires a SQL-based querier');
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
this.logger(`${direction === 'up' ? 'Running' : 'Reverting'} migration: ${migration.name}`);
|
|
174
|
+
await querier.beginTransaction();
|
|
175
|
+
if (direction === 'up') {
|
|
176
|
+
await migration.up(querier);
|
|
177
|
+
// Log within the same transaction
|
|
178
|
+
await this.storage.logWithQuerier(querier, migration.name);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
await migration.down(querier);
|
|
182
|
+
// Unlog within the same transaction
|
|
183
|
+
await this.storage.unlogWithQuerier(querier, migration.name);
|
|
184
|
+
}
|
|
185
|
+
await querier.commitTransaction();
|
|
186
|
+
const duration = Date.now() - startTime;
|
|
187
|
+
this.logger(`Migration ${migration.name} ${direction === 'up' ? 'applied' : 'reverted'} in ${duration}ms`);
|
|
188
|
+
return {
|
|
189
|
+
name: migration.name,
|
|
190
|
+
direction,
|
|
191
|
+
duration,
|
|
192
|
+
success: true,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
await querier.rollbackTransaction();
|
|
197
|
+
const duration = Date.now() - startTime;
|
|
198
|
+
this.logger(`Migration ${migration.name} failed: ${error.message}`);
|
|
199
|
+
return {
|
|
200
|
+
name: migration.name,
|
|
201
|
+
direction,
|
|
202
|
+
duration,
|
|
203
|
+
success: false,
|
|
204
|
+
error: error,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
await querier.release();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Generate a new migration file
|
|
213
|
+
*/
|
|
214
|
+
async generate(name) {
|
|
215
|
+
const timestamp = this.getTimestamp();
|
|
216
|
+
const fileName = `${timestamp}_${this.slugify(name)}.ts`;
|
|
217
|
+
const filePath = join(this.migrationsPath, fileName);
|
|
218
|
+
const content = this.generateMigrationContent(name);
|
|
219
|
+
const { writeFile, mkdir } = await import('node:fs/promises');
|
|
220
|
+
await mkdir(this.migrationsPath, { recursive: true });
|
|
221
|
+
await writeFile(filePath, content, 'utf-8');
|
|
222
|
+
this.logger(`Created migration: ${filePath}`);
|
|
223
|
+
return filePath;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Generate a migration based on entity schema differences
|
|
227
|
+
*/
|
|
228
|
+
async generateFromEntities(name) {
|
|
229
|
+
if (!this.schemaGenerator) {
|
|
230
|
+
throw new Error('Schema generator not set. Call setSchemaGenerator() first.');
|
|
231
|
+
}
|
|
232
|
+
const diffs = await this.getDiffs();
|
|
233
|
+
const upStatements = [];
|
|
234
|
+
const downStatements = [];
|
|
235
|
+
for (const diff of diffs) {
|
|
236
|
+
if (diff.type === 'create') {
|
|
237
|
+
const entity = this.findEntityForTable(diff.tableName);
|
|
238
|
+
if (entity) {
|
|
239
|
+
upStatements.push(this.schemaGenerator.generateCreateTable(entity));
|
|
240
|
+
downStatements.push(this.schemaGenerator.generateDropTable(entity));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else if (diff.type === 'alter') {
|
|
244
|
+
const alterStatements = this.schemaGenerator.generateAlterTable(diff);
|
|
245
|
+
upStatements.push(...alterStatements);
|
|
246
|
+
const alterDownStatements = this.schemaGenerator.generateAlterTableDown(diff);
|
|
247
|
+
downStatements.push(...alterDownStatements);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (upStatements.length === 0) {
|
|
251
|
+
this.logger('No schema changes detected.');
|
|
252
|
+
return '';
|
|
253
|
+
}
|
|
254
|
+
const timestamp = this.getTimestamp();
|
|
255
|
+
const fileName = `${timestamp}_${this.slugify(name)}.ts`;
|
|
256
|
+
const filePath = join(this.migrationsPath, fileName);
|
|
257
|
+
const content = this.generateMigrationContentWithStatements(name, upStatements, downStatements.reverse());
|
|
258
|
+
const { writeFile, mkdir } = await import('node:fs/promises');
|
|
259
|
+
await mkdir(this.migrationsPath, { recursive: true });
|
|
260
|
+
await writeFile(filePath, content, 'utf-8');
|
|
261
|
+
this.logger(`Created migration from entities: ${filePath}`);
|
|
262
|
+
return filePath;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get all schema differences between entities and database
|
|
266
|
+
*/
|
|
267
|
+
async getDiffs() {
|
|
268
|
+
if (!this.schemaGenerator || !this.schemaIntrospector) {
|
|
269
|
+
throw new Error('Schema generator and introspector must be set');
|
|
270
|
+
}
|
|
271
|
+
const entities = this.entities.length > 0 ? this.entities : getEntities();
|
|
272
|
+
const diffs = [];
|
|
273
|
+
for (const entity of entities) {
|
|
274
|
+
const meta = getMeta(entity);
|
|
275
|
+
const tableName = this.schemaGenerator.resolveTableName(entity, meta);
|
|
276
|
+
const currentSchema = await this.schemaIntrospector.getTableSchema(tableName);
|
|
277
|
+
const diff = this.schemaGenerator.diffSchema(entity, currentSchema);
|
|
278
|
+
if (diff) {
|
|
279
|
+
diffs.push(diff);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return diffs;
|
|
283
|
+
}
|
|
284
|
+
findEntityForTable(tableName) {
|
|
285
|
+
const entities = this.entities.length > 0 ? this.entities : getEntities();
|
|
286
|
+
for (const entity of entities) {
|
|
287
|
+
const meta = getMeta(entity);
|
|
288
|
+
const name = this.schemaGenerator.resolveTableName(entity, meta);
|
|
289
|
+
if (name === tableName) {
|
|
290
|
+
return entity;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Sync schema directly (for development only - not for production!)
|
|
297
|
+
*/
|
|
298
|
+
async sync(options = {}) {
|
|
299
|
+
if (options.force) {
|
|
300
|
+
return this.syncForce();
|
|
301
|
+
}
|
|
302
|
+
return this.autoSync({ safe: true });
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Drops and recreates all tables (Development only!)
|
|
306
|
+
*/
|
|
307
|
+
async syncForce() {
|
|
308
|
+
if (!this.schemaGenerator) {
|
|
309
|
+
throw new Error('Schema generator not set. Call setSchemaGenerator() first.');
|
|
310
|
+
}
|
|
311
|
+
const entities = this.entities.length > 0 ? this.entities : getEntities();
|
|
312
|
+
const querier = await this.querierPool.getQuerier();
|
|
313
|
+
if (!isSqlQuerier(querier)) {
|
|
314
|
+
await querier.release();
|
|
315
|
+
throw new Error('Migrator requires a SQL-based querier');
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
await querier.beginTransaction();
|
|
319
|
+
// Drop all tables first (in reverse order for foreign keys)
|
|
320
|
+
for (const entity of [...entities].reverse()) {
|
|
321
|
+
const dropSql = this.schemaGenerator.generateDropTable(entity);
|
|
322
|
+
this.logger(`Executing: ${dropSql}`);
|
|
323
|
+
await querier.run(dropSql);
|
|
324
|
+
}
|
|
325
|
+
// Create all tables
|
|
326
|
+
for (const entity of entities) {
|
|
327
|
+
const createSql = this.schemaGenerator.generateCreateTable(entity);
|
|
328
|
+
this.logger(`Executing: ${createSql}`);
|
|
329
|
+
await querier.run(createSql);
|
|
330
|
+
}
|
|
331
|
+
await querier.commitTransaction();
|
|
332
|
+
this.logger('Schema sync (force) completed');
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
await querier.rollbackTransaction();
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
finally {
|
|
339
|
+
await querier.release();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Safely synchronizes the schema by only adding missing tables and columns.
|
|
344
|
+
*/
|
|
345
|
+
async autoSync(options = {}) {
|
|
346
|
+
if (!this.schemaGenerator || !this.schemaIntrospector) {
|
|
347
|
+
throw new Error('Schema generator and introspector must be set');
|
|
348
|
+
}
|
|
349
|
+
const diffs = await this.getDiffs();
|
|
350
|
+
const statements = [];
|
|
351
|
+
for (const diff of diffs) {
|
|
352
|
+
if (diff.type === 'create') {
|
|
353
|
+
const entity = this.findEntityForTable(diff.tableName);
|
|
354
|
+
if (entity) {
|
|
355
|
+
statements.push(this.schemaGenerator.generateCreateTable(entity));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else if (diff.type === 'alter') {
|
|
359
|
+
const filteredDiff = this.filterDiff(diff, options);
|
|
360
|
+
const alterStatements = this.schemaGenerator.generateAlterTable(filteredDiff);
|
|
361
|
+
statements.push(...alterStatements);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (statements.length === 0) {
|
|
365
|
+
if (options.logging)
|
|
366
|
+
this.logger('Schema is already in sync.');
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
await this.executeSyncStatements(statements, options);
|
|
370
|
+
}
|
|
371
|
+
filterDiff(diff, options) {
|
|
372
|
+
const filteredDiff = { ...diff };
|
|
373
|
+
if (options.safe !== false) {
|
|
374
|
+
// In safe mode, we only allow additions
|
|
375
|
+
delete filteredDiff.columnsToDrop;
|
|
376
|
+
delete filteredDiff.indexesToDrop;
|
|
377
|
+
delete filteredDiff.foreignKeysToDrop;
|
|
378
|
+
}
|
|
379
|
+
if (!options.drop) {
|
|
380
|
+
delete filteredDiff.columnsToDrop;
|
|
381
|
+
}
|
|
382
|
+
return filteredDiff;
|
|
383
|
+
}
|
|
384
|
+
async executeSyncStatements(statements, options) {
|
|
385
|
+
const querier = await this.querierPool.getQuerier();
|
|
386
|
+
try {
|
|
387
|
+
if (this.dialect === 'mongodb') {
|
|
388
|
+
await this.executeMongoSyncStatements(statements, options, querier);
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
await this.executeSqlSyncStatements(statements, options, querier);
|
|
392
|
+
}
|
|
393
|
+
if (options.logging)
|
|
394
|
+
this.logger('Schema synchronization completed');
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
if (this.dialect !== 'mongodb' && isSqlQuerier(querier)) {
|
|
398
|
+
await querier.rollbackTransaction();
|
|
399
|
+
}
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
402
|
+
finally {
|
|
403
|
+
await querier.release();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
async executeMongoSyncStatements(statements, options, querier) {
|
|
407
|
+
const db = querier.db;
|
|
408
|
+
for (const stmt of statements) {
|
|
409
|
+
const cmd = JSON.parse(stmt);
|
|
410
|
+
if (options.logging)
|
|
411
|
+
this.logger(`Executing MongoDB: ${stmt}`);
|
|
412
|
+
const collectionName = cmd.name || cmd.collection;
|
|
413
|
+
if (!collectionName) {
|
|
414
|
+
throw new Error(`MongoDB command missing collection name: ${stmt}`);
|
|
415
|
+
}
|
|
416
|
+
const collection = db.collection(collectionName);
|
|
417
|
+
if (cmd.action === 'createCollection') {
|
|
418
|
+
await db.createCollection(cmd.name);
|
|
419
|
+
if (cmd.indexes?.length) {
|
|
420
|
+
for (const idx of cmd.indexes) {
|
|
421
|
+
const key = Object.fromEntries(idx.columns.map((c) => [c, 1]));
|
|
422
|
+
await collection.createIndex(key, { unique: idx.unique, name: idx.name });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
else if (cmd.action === 'dropCollection') {
|
|
427
|
+
await collection.drop();
|
|
428
|
+
}
|
|
429
|
+
else if (cmd.action === 'createIndex') {
|
|
430
|
+
await collection.createIndex(cmd.key, cmd.options);
|
|
431
|
+
}
|
|
432
|
+
else if (cmd.action === 'dropIndex') {
|
|
433
|
+
await collection.dropIndex(cmd.name);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
async executeSqlSyncStatements(statements, options, querier) {
|
|
438
|
+
if (!isSqlQuerier(querier)) {
|
|
439
|
+
throw new Error('Migrator requires a SQL-based querier for this dialect');
|
|
440
|
+
}
|
|
441
|
+
await querier.beginTransaction();
|
|
442
|
+
for (const sql of statements) {
|
|
443
|
+
if (options.logging)
|
|
444
|
+
this.logger(`Executing: ${sql}`);
|
|
445
|
+
await querier.run(sql);
|
|
446
|
+
}
|
|
447
|
+
await querier.commitTransaction();
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Get migration status
|
|
451
|
+
*/
|
|
452
|
+
async status() {
|
|
453
|
+
const [pending, executed] = await Promise.all([this.pending().then((m) => m.map((x) => x.name)), this.executed()]);
|
|
454
|
+
return { pending, executed };
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get migration files from the migrations directory
|
|
458
|
+
*/
|
|
459
|
+
async getMigrationFiles() {
|
|
460
|
+
try {
|
|
461
|
+
const files = await readdir(this.migrationsPath);
|
|
462
|
+
return files
|
|
463
|
+
.filter((f) => /\.(ts|js|mjs)$/.test(f))
|
|
464
|
+
.filter((f) => !f.endsWith('.d.ts'))
|
|
465
|
+
.sort();
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
if (error.code === 'ENOENT') {
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Load a migration from a file
|
|
476
|
+
*/
|
|
477
|
+
async loadMigration(fileName) {
|
|
478
|
+
const filePath = join(this.migrationsPath, fileName);
|
|
479
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
480
|
+
try {
|
|
481
|
+
const module = await import(fileUrl);
|
|
482
|
+
const migration = module.default ?? module;
|
|
483
|
+
if (this.isMigration(migration)) {
|
|
484
|
+
return {
|
|
485
|
+
name: this.getMigrationName(fileName),
|
|
486
|
+
up: migration.up.bind(migration),
|
|
487
|
+
down: migration.down.bind(migration),
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
this.logger(`Warning: ${fileName} is not a valid migration`);
|
|
491
|
+
return undefined;
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
this.logger(`Error loading migration ${fileName}: ${error.message}`);
|
|
495
|
+
return undefined;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Check if an object is a valid migration
|
|
500
|
+
*/
|
|
501
|
+
isMigration(obj) {
|
|
502
|
+
return (typeof obj === 'object' &&
|
|
503
|
+
obj !== undefined &&
|
|
504
|
+
obj !== null &&
|
|
505
|
+
typeof obj.up === 'function' &&
|
|
506
|
+
typeof obj.down === 'function');
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Extract migration name from filename
|
|
510
|
+
*/
|
|
511
|
+
getMigrationName(fileName) {
|
|
512
|
+
return basename(fileName, extname(fileName));
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Generate timestamp string for migration names
|
|
516
|
+
*/
|
|
517
|
+
getTimestamp() {
|
|
518
|
+
const now = new Date();
|
|
519
|
+
return [
|
|
520
|
+
now.getFullYear(),
|
|
521
|
+
String(now.getMonth() + 1).padStart(2, '0'),
|
|
522
|
+
String(now.getDate()).padStart(2, '0'),
|
|
523
|
+
String(now.getHours()).padStart(2, '0'),
|
|
524
|
+
String(now.getMinutes()).padStart(2, '0'),
|
|
525
|
+
String(now.getSeconds()).padStart(2, '0'),
|
|
526
|
+
].join('');
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Convert a string to a slug for filenames
|
|
530
|
+
*/
|
|
531
|
+
slugify(text) {
|
|
532
|
+
return text
|
|
533
|
+
.toLowerCase()
|
|
534
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
535
|
+
.replace(/^_+|_+$/g, '');
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Generate migration file content
|
|
539
|
+
*/
|
|
540
|
+
generateMigrationContent(name) {
|
|
541
|
+
return /*ts*/ `import type { SqlQuerier } from '@uql/migrate';
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Migration: ${name}
|
|
545
|
+
* Created: ${new Date().toISOString()}
|
|
546
|
+
*/
|
|
547
|
+
export default {
|
|
548
|
+
async up(querier: SqlQuerier): Promise<void> {
|
|
549
|
+
// Add your migration logic here
|
|
550
|
+
// Example:
|
|
551
|
+
// await querier.run(\`
|
|
552
|
+
// CREATE TABLE "users" (
|
|
553
|
+
// "id" SERIAL PRIMARY KEY,
|
|
554
|
+
// "name" VARCHAR(255) NOT NULL,
|
|
555
|
+
// "email" VARCHAR(255) UNIQUE NOT NULL,
|
|
556
|
+
// "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
557
|
+
// )
|
|
558
|
+
// \`);
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
async down(querier: SqlQuerier): Promise<void> {
|
|
562
|
+
// Add your rollback logic here
|
|
563
|
+
// Example:
|
|
564
|
+
// await querier.run(\`DROP TABLE IF EXISTS "users"\`);
|
|
565
|
+
},
|
|
566
|
+
};
|
|
567
|
+
`;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Generate migration file content with SQL statements
|
|
571
|
+
*/
|
|
572
|
+
generateMigrationContentWithStatements(name, upStatements, downStatements) {
|
|
573
|
+
const upSql = upStatements.map((s) => /*ts*/ ` await querier.run(\`${s}\`);`).join('\n');
|
|
574
|
+
const downSql = downStatements.map((s) => /*ts*/ ` await querier.run(\`${s}\`);`).join('\n');
|
|
575
|
+
return /*ts*/ `import type { SqlQuerier } from '@uql/migrate';
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Migration: ${name}
|
|
579
|
+
* Created: ${new Date().toISOString()}
|
|
580
|
+
* Generated from entity definitions
|
|
581
|
+
*/
|
|
582
|
+
export default {
|
|
583
|
+
async up(querier: SqlQuerier): Promise<void> {
|
|
584
|
+
${upSql}
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
async down(querier: SqlQuerier): Promise<void> {
|
|
588
|
+
${downSql}
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
`;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Helper function to define a migration with proper typing
|
|
596
|
+
*/
|
|
597
|
+
export function defineMigration(migration) {
|
|
598
|
+
return migration;
|
|
599
|
+
}
|
|
600
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlncmF0ZS9taWdyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQWlCMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIscUJBQXFCLEdBQ3RCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUNMLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsdUJBQXVCLEVBQ3ZCLDBCQUEwQixFQUMxQix3QkFBd0IsR0FDekIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUV4RTs7R0FFRztBQUNILE1BQU0sT0FBTyxRQUFRO0lBVUE7SUFURixPQUFPLENBQW1CO0lBQzFCLGNBQWMsQ0FBUztJQUN2QixNQUFNLENBQTRCO0lBQ2xDLFFBQVEsQ0FBa0I7SUFDMUIsT0FBTyxDQUFVO0lBQzFCLGVBQWUsQ0FBbUI7SUFDbkMsa0JBQWtCLENBQXNCO0lBRS9DLFlBQ21CLFdBQXdCLEVBQ3pDLFVBQTJCLEVBQUU7UUFEWixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUd6QyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksV0FBVyxDQUFDLE9BQU8sSUFBSSxVQUFVLENBQUM7UUFDcEUsSUFB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QUFFLENBQUMsV0FBVyxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBc0JyQyxDQUFDO0lBQ0EsQ0FBQztJQUVEOztPQUVHO0lBQ0ssc0NBQXNDLENBQzVDLElBQVksRUFDWixZQUFzQixFQUN0QixjQUF3QjtRQUV4QixNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVGLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEcsT0FBTyxNQUFNLENBQUM7OztnQkFHRixJQUFJO2NBQ04sSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7Ozs7O0VBS3BDLEtBQUs7Ozs7RUFJTCxPQUFPOzs7Q0FHUixDQUFDO0lBQ0EsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLFNBQThCO0lBQzVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkZGlyIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBiYXNlbmFtZSwgZXh0bmFtZSwgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSAnbm9kZTp1cmwnO1xuaW1wb3J0IHsgZ2V0RW50aXRpZXMsIGdldE1ldGEgfSBmcm9tICcuLi9lbnRpdHkvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1xuICBEaWFsZWN0LFxuICBNaWdyYXRpb24sXG4gIE1pZ3JhdGlvbkRlZmluaXRpb24sXG4gIE1pZ3JhdGlvblJlc3VsdCxcbiAgTWlncmF0aW9uU3RvcmFnZSxcbiAgTWlncmF0b3JPcHRpb25zLFxuICBNb25nb1F1ZXJpZXIsXG4gIE5hbWluZ1N0cmF0ZWd5LFxuICBRdWVyaWVyLFxuICBRdWVyaWVyUG9vbCxcbiAgU2NoZW1hRGlmZixcbiAgU2NoZW1hR2VuZXJhdG9yLFxuICBTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIFR5cGUsXG59IGZyb20gJy4uL3R5cGUvaW5kZXguanMnO1xuaW1wb3J0IHsgaXNTcWxRdWVyaWVyIH0gZnJvbSAnLi4vdHlwZS9pbmRleC5qcyc7XG5pbXBvcnQge1xuICBNYXJpYWRiU2NoZW1hR2VuZXJhdG9yLFxuICBNb25nb1NjaGVtYUdlbmVyYXRvcixcbiAgTXlzcWxTY2hlbWFHZW5lcmF0b3IsXG4gIFBvc3RncmVzU2NoZW1hR2VuZXJhdG9yLFxuICBTcWxpdGVTY2hlbWFHZW5lcmF0b3IsXG59IGZyb20gJy4vZ2VuZXJhdG9yL2luZGV4LmpzJztcbmltcG9ydCB7XG4gIE1hcmlhZGJTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIE1vbmdvU2NoZW1hSW50cm9zcGVjdG9yLFxuICBNeXNxbFNjaGVtYUludHJvc3BlY3RvcixcbiAgUG9zdGdyZXNTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIFNxbGl0ZVNjaGVtYUludHJvc3BlY3Rvcixcbn0gZnJvbSAnLi9pbnRyb3NwZWN0aW9uL2luZGV4LmpzJztcbmltcG9ydCB7IERhdGFiYXNlTWlncmF0aW9uU3RvcmFnZSB9IGZyb20gJy4vc3RvcmFnZS9kYXRhYmFzZVN0b3JhZ2UuanMnO1xuXG4vKipcbiAqIE1haW4gY2xhc3MgZm9yIG1hbmFnaW5nIGRhdGFiYXNlIG1pZ3JhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZ3JhdG9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlOiBNaWdyYXRpb25TdG9yYWdlO1xuICBwcml2YXRlIHJlYWRvbmx5IG1pZ3JhdGlvbnNQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICBwcml2YXRlIHJlYWRvbmx5IGVudGl0aWVzOiBUeXBlPHVua25vd24+W107XG4gIHByaXZhdGUgcmVhZG9ubHkgZGlhbGVjdDogRGlhbGVjdDtcbiAgcHJpdmF0ZSBzY2hlbWFHZW5lcmF0b3I/OiBTY2hlbWFHZW5lcmF0b3I7XG4gIHB1YmxpYyBzY2hlbWFJbnRyb3NwZWN0b3I/OiBTY2hlbWFJbnRyb3NwZWN0b3I7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBxdWVyaWVyUG9vbDogUXVlcmllclBvb2wsXG4gICAgb3B0aW9uczogTWlncmF0b3JPcHRpb25zID0ge30sXG4gICkge1xuICAgIHRoaXMuZGlhbGVjdCA9IG9wdGlvbnMuZGlhbGVjdCA/PyBxdWVyaWVyUG9vbC5kaWFsZWN0ID8/ICdwb3N0Z3Jlcyc7XG4gICAgdGhpcy5zdG9yYWdlID1cbiAgICAgIG9wdGlvbnMuc3RvcmFnZSA/P1xuICAgICAgbmV3IERhdGFiYXNlTWlncmF0aW9uU3RvcmFnZShxdWVyaWVyUG9vbCwge1xuICAgICAgICB0YWJsZU5hbWU6IG9wdGlvbnMudGFibGVOYW1lLFxuICAgICAgfSk7XG4gICAgdGhpcy5taWdyYXRpb25zUGF0aCA9IG9wdGlvbnMubWlncmF0aW9uc1BhdGggPz8gJy4vbWlncmF0aW9ucyc7XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRpb25zLmxvZ2dlciA/PyAoKCkgPT4ge30pO1xuICAgIHRoaXMuZW50aXRpZXMgPSBvcHRpb25zLmVudGl0aWVzID8/IFtdO1xuICAgIHRoaXMuc2NoZW1hSW50cm9zcGVjdG9yID0gdGhpcy5jcmVhdGVJbnRyb3NwZWN0b3IoKTtcbiAgICB0aGlzLnNjaGVtYUdlbmVyYXRvciA9IG9wdGlvbnMuc2NoZW1hR2VuZXJhdG9yID8/IHRoaXMuY3JlYXRlR2VuZXJhdG9yKG9wdGlvbnMubmFtaW5nU3RyYXRlZ3kpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgc2NoZW1hIGdlbmVyYXRvciBmb3IgRERMIG9wZXJhdGlvbnNcbiAgICovXG4gIHNldFNjaGVtYUdlbmVyYXRvcihnZW5lcmF0b3I6IFNjaGVtYUdlbmVyYXRvcik6IHZvaWQge1xuICAgIHRoaXMuc2NoZW1hR2VuZXJhdG9yID0gZ2VuZXJhdG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVJbnRyb3NwZWN0b3IoKTogU2NoZW1hSW50cm9zcGVjdG9yIHwgdW5kZWZpbmVkIHtcbiAgICBzd2l0Y2ggKHRoaXMuZGlhbGVjdCkge1xuICAgICAgY2FzZSAncG9zdGdyZXMnOlxuICAgICAgICByZXR1cm4gbmV3IFBvc3RncmVzU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbXlzcWwnOlxuICAgICAgICByZXR1cm4gbmV3IE15c3FsU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbWFyaWFkYic6XG4gICAgICAgIHJldHVybiBuZXcgTWFyaWFkYlNjaGVtYUludHJvc3BlY3Rvcih0aGlzLnF1ZXJpZXJQb29sKTtcbiAgICAgIGNhc2UgJ3NxbGl0ZSc6XG4gICAgICAgIHJldHVybiBuZXcgU3FsaXRlU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbW9uZ29kYic6XG4gICAgICAgIHJldHVybiBuZXcgTW9uZ29TY2hlbWFJbnRyb3NwZWN0b3IodGhpcy5xdWVyaWVyUG9vbCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJhdG9yKG5hbWluZ1N0cmF0ZWd5PzogTmFtaW5nU3RyYXRlZ3kpOiBTY2hlbWFHZW5lcmF0b3IgfCB1bmRlZmluZWQge1xuICAgIHN3aXRjaCAodGhpcy5kaWFsZWN0KSB7XG4gICAgICBjYXNlICdwb3N0Z3Jlcyc6XG4gICAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnbXlzcWwnOlxuICAgICAgICByZXR1cm4gbmV3IE15c3FsU2NoZW1hR2VuZXJhdG9yKG5hbWluZ1N0cmF0ZWd5KTtcbiAgICAgIGNhc2UgJ21hcmlhZGInOlxuICAgICAgICByZXR1cm4gbmV3IE1hcmlhZGJTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnc3FsaXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBTcWxpdGVTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnbW9uZ29kYic6XG4gICAgICAgIHJldHVybiBuZXcgTW9uZ29TY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBTUUwgZGlhbGVjdFxuICAgKi9cbiAgZ2V0RGlhbGVjdCgpOiBEaWFsZWN0IHtcbiAgICByZXR1cm4gdGhpcy5kaWFsZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgZGlzY292ZXJlZCBtaWdyYXRpb25zIGZyb20gdGhlIG1pZ3JhdGlvbnMgZGlyZWN0b3J5XG4gICAqL1xuICBhc3luYyBnZXRNaWdyYXRpb25zKCk6IFByb21pc2U8TWlncmF0aW9uW10+IHtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHRoaXMuZ2V0TWlncmF0aW9uRmlsZXMoKTtcbiAgICBjb25zdCBtaWdyYXRpb25zOiBNaWdyYXRpb25bXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBtaWdyYXRpb24gPSBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb24oZmlsZSk7XG4gICAgICBpZiAobWlncmF0aW9uKSB7XG4gICAgICAgIG1pZ3JhdGlvbnMucHVzaChtaWdyYXRpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNvcnQgYnkgbmFtZSAod2hpY2ggdHlwaWNhbGx5IGluY2x1ZGVzIHRpbWVzdGFtcClcbiAgICByZXR1cm4gbWlncmF0aW9ucy5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxpc3Qgb2YgcGVuZGluZyBtaWdyYXRpb25zIChub3QgeWV0IGV4ZWN1dGVkKVxuICAgKi9cbiAgYXN5bmMgcGVuZGluZygpOiBQcm9taXNlPE1pZ3JhdGlvbltdPiB7XG4gICAgY29uc3QgW21pZ3JhdGlvbnMsIGV4ZWN1dGVkXSA9IGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLmdldE1pZ3JhdGlvbnMoKSwgdGhpcy5zdG9yYWdlLmV4ZWN1dGVkKCldKTtcblxuICAgIGNvbnN0IGV4ZWN1dGVkU2V0ID0gbmV3IFNldChleGVjdXRlZCk7XG4gICAgcmV0dXJuIG1pZ3JhdGlvbnMuZmlsdGVyKChtOiBhbnkpID0+ICFleGVjdXRlZFNldC5oYXMobS5uYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxpc3Qgb2YgZXhlY3V0ZWQgbWlncmF0aW9uc1xuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZWQoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZXhlY3V0ZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYWxsIHBlbmRpbmcgbWlncmF0aW9uc1xuICAgKi9cbiAgYXN5bmMgdXAob3B0aW9uczogeyB0bz86IHN0cmluZzsgc3RlcD86IG51bWJlciB9ID0ge30pOiBQcm9taXNlPE1pZ3JhdGlvblJlc3VsdFtdPiB7XG4gICAgY29uc3QgcGVuZGluZ01pZ3JhdGlvbnMgPSBhd2FpdCB0aGlzLnBlbmRpbmcoKTtcbiAgICBjb25zdCByZXN1bHRzOiBNaWdyYXRpb25SZXN1bHRbXSA9IFtdO1xuXG4gICAgbGV0IG1pZ3JhdGlvbnNUb1J1biA9IHBlbmRpbmdNaWdyYXRpb25zO1xuXG4gICAgaWYgKG9wdGlvbnMudG8pIHtcbiAgICAgIGNvbnN0IHRvSW5kZXggPSBtaWdyYXRpb25zVG9SdW4uZmluZEluZGV4KChtOiBhbnkpID0+IG0ubmFtZSA9PT0gb3B0aW9ucy50byk7XG4gICAgICBpZiAodG9JbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gJyR7b3B0aW9ucy50b30nIG5vdCBmb3VuZGApO1xuICAgICAgfVxuICAgICAgbWlncmF0aW9uc1RvUnVuID0gbWlncmF0aW9uc1RvUnVuLnNsaWNlKDAsIHRvSW5kZXggKyAxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zdGVwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pZ3JhdGlvbnNUb1J1biA9IG1pZ3JhdGlvbnNUb1J1bi5zbGljZSgwLCBvcHRpb25zLnN0ZXApO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIG1pZ3JhdGlvbnNUb1J1bikge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ydW5NaWdyYXRpb24obWlncmF0aW9uLCAndXAnKTtcbiAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGJyZWFrOyAvLyBTdG9wIG9uIGZpcnN0IGZhaWx1cmVcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsYmFjayBtaWdyYXRpb25zXG4gICAqL1xuICBhc3luYyBkb3duKG9wdGlvbnM6IHsgdG8/OiBzdHJpbmc7IHN0ZXA/OiBudW1iZXIgfSA9IHt9KTogUHJvbWlzZTxNaWdyYXRpb25SZXN1bHRbXT4ge1xuICAgIGNvbnN0IFttaWdyYXRpb25zLCBleGVjdXRlZF0gPSBhd2FpdCBQcm9taXNlLmFsbChbdGhpcy5nZXRNaWdyYXRpb25zKCksIHRoaXMuc3RvcmFnZS5leGVjdXRlZCgpXSk7XG5cbiAgICBjb25zdCBleGVjdXRlZFNldCA9IG5ldyBTZXQoZXhlY3V0ZWQpO1xuICAgIGNvbnN0IGV4ZWN1dGVkTWlncmF0aW9ucyA9IG1pZ3JhdGlvbnMuZmlsdGVyKChtOiBhbnkpID0+IGV4ZWN1dGVkU2V0LmhhcyhtLm5hbWUpKS5yZXZlcnNlKCk7IC8vIFJvbGxiYWNrIGluIHJldmVyc2Ugb3JkZXJcblxuICAgIGNvbnN0IHJlc3VsdHM6IE1pZ3JhdGlvblJlc3VsdFtdID0gW107XG4gICAgbGV0IG1pZ3JhdGlvbnNUb1J1biA9IGV4ZWN1dGVkTWlncmF0aW9ucztcblxuICAgIGlmIChvcHRpb25zLnRvKSB7XG4gICAgICBjb25zdCB0b0luZGV4ID0gbWlncmF0aW9uc1RvUnVuLmZpbmRJbmRleCgobTogYW55KSA9PiBtLm5hbWUgPT09IG9wdGlvbnMudG8pO1xuICAgICAgaWYgKHRvSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICcke29wdGlvbnMudG99JyBub3QgZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIG1pZ3JhdGlvbnNUb1J1biA9IG1pZ3JhdGlvbnNUb1J1bi5zbGljZSgwLCB0b0luZGV4ICsgMSk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3RlcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaWdyYXRpb25zVG9SdW4gPSBtaWdyYXRpb25zVG9SdW4uc2xpY2UoMCwgb3B0aW9ucy5zdGVwKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBtaWdyYXRpb25zVG9SdW4pIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucnVuTWlncmF0aW9uKG1pZ3JhdGlvbiwgJ2Rvd24nKTtcbiAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGJyZWFrOyAvLyBTdG9wIG9uIGZpcnN0IGZhaWx1cmVcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYSBzaW5nbGUgbWlncmF0aW9uIHdpdGhpbiBhIHRyYW5zYWN0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bk1pZ3JhdGlvbihtaWdyYXRpb246IE1pZ3JhdGlvbiwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogUHJvbWlzZTxNaWdyYXRpb25SZXN1bHQ+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcblxuICAgIGlmICghaXNTcWxRdWVyaWVyKHF1ZXJpZXIpKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllcicpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZ2dlcihgJHtkaXJlY3Rpb24gPT09ICd1cCcgPyAnUnVubmluZycgOiAnUmV2ZXJ0aW5nJ30gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5uYW1lfWApO1xuXG4gICAgICBhd2FpdCBxdWVyaWVyLmJlZ2luVHJhbnNhY3Rpb24oKTtcblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3VwJykge1xuICAgICAgICBhd2FpdCBtaWdyYXRpb24udXAocXVlcmllcik7XG4gICAgICAgIC8vIExvZyB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb25cbiAgICAgICAgYXdhaXQgdGhpcy5zdG9yYWdlLmxvZ1dpdGhRdWVyaWVyKHF1ZXJpZXIsIG1pZ3JhdGlvbi5uYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IG1pZ3JhdGlvbi5kb3duKHF1ZXJpZXIpO1xuICAgICAgICAvLyBVbmxvZyB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb25cbiAgICAgICAgYXdhaXQgdGhpcy5zdG9yYWdlLnVubG9nV2l0aFF1ZXJpZXIocXVlcmllciwgbWlncmF0aW9uLm5hbWUpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBxdWVyaWVyLmNvbW1pdFRyYW5zYWN0aW9uKCk7XG5cbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIHRoaXMubG9nZ2VyKGBNaWdyYXRpb24gJHttaWdyYXRpb24ubmFtZX0gJHtkaXJlY3Rpb24gPT09ICd1cCcgPyAnYXBwbGllZCcgOiAncmV2ZXJ0ZWQnfSBpbiAke2R1cmF0aW9ufW1zYCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IG1pZ3JhdGlvbi5uYW1lLFxuICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgcXVlcmllci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XG5cbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIHRoaXMubG9nZ2VyKGBNaWdyYXRpb24gJHttaWdyYXRpb24ubmFtZX0gZmFpbGVkOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogbWlncmF0aW9uLm5hbWUsXG4gICAgICAgIGRpcmVjdGlvbixcbiAgICAgICAgZHVyYXRpb24sXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgYXMgRXJyb3IsXG4gICAgICB9O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSBuZXcgbWlncmF0aW9uIGZpbGVcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gdGhpcy5nZXRUaW1lc3RhbXAoKTtcbiAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RpbWVzdGFtcH1fJHt0aGlzLnNsdWdpZnkobmFtZSl9LnRzYDtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4odGhpcy5taWdyYXRpb25zUGF0aCwgZmlsZU5hbWUpO1xuXG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2VuZXJhdGVNaWdyYXRpb25Db250ZW50KG5hbWUpO1xuXG4gICAgY29uc3QgeyB3cml0ZUZpbGUsIG1rZGlyIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6ZnMvcHJvbWlzZXMnKTtcbiAgICBhd2FpdCBta2Rpcih0aGlzLm1pZ3JhdGlvbnNQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIGNvbnRlbnQsICd1dGYtOCcpO1xuXG4gICAgdGhpcy5sb2dnZXIoYENyZWF0ZWQgbWlncmF0aW9uOiAke2ZpbGVQYXRofWApO1xuICAgIHJldHVybiBmaWxlUGF0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIG1pZ3JhdGlvbiBiYXNlZCBvbiBlbnRpdHkgc2NoZW1hIGRpZmZlcmVuY2VzXG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZUZyb21FbnRpdGllcyhuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGlmICghdGhpcy5zY2hlbWFHZW5lcmF0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NoZW1hIGdlbmVyYXRvciBub3Qgc2V0LiBDYWxsIHNldFNjaGVtYUdlbmVyYXRvcigpIGZpcnN0LicpO1xuICAgIH1cblxuICAgIGNvbnN0IGRpZmZzID0gYXdhaXQgdGhpcy5nZXREaWZmcygpO1xuICAgIGNvbnN0IHVwU3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBkb3duU3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGlmZiBvZiBkaWZmcykge1xuICAgICAgaWYgKGRpZmYudHlwZSA9PT0gJ2NyZWF0ZScpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5maW5kRW50aXR5Rm9yVGFibGUoZGlmZi50YWJsZU5hbWUpO1xuICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgdXBTdGF0ZW1lbnRzLnB1c2godGhpcy5zY2hlbWFHZW5lcmF0b3IuZ2VuZXJhdGVDcmVhdGVUYWJsZShlbnRpdHkpKTtcbiAgICAgICAgICBkb3duU3RhdGVtZW50cy5wdXNoKHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlRHJvcFRhYmxlKGVudGl0eSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpZmYudHlwZSA9PT0gJ2FsdGVyJykge1xuICAgICAgICBjb25zdCBhbHRlclN0YXRlbWVudHMgPSB0aGlzLnNjaGVtYUdlbmVyYXRvci5nZW5lcmF0ZUFsdGVyVGFibGUoZGlmZik7XG4gICAgICAgIHVwU3RhdGVtZW50cy5wdXNoKC4uLmFsdGVyU3RhdGVtZW50cyk7XG5cbiAgICAgICAgY29uc3QgYWx0ZXJEb3duU3RhdGVtZW50cyA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQWx0ZXJUYWJsZURvd24oZGlmZik7XG4gICAgICAgIGRvd25TdGF0ZW1lbnRzLnB1c2goLi4uYWx0ZXJEb3duU3RhdGVtZW50cyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHVwU3RhdGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMubG9nZ2VyKCdObyBzY2hlbWEgY2hhbmdlcyBkZXRlY3RlZC4nKTtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lc3RhbXAgPSB0aGlzLmdldFRpbWVzdGFtcCgpO1xuICAgIGNvbnN0IGZpbGVOYW1lID0gYCR7dGltZXN0YW1wfV8ke3RoaXMuc2x1Z2lmeShuYW1lKX0udHNgO1xuICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbih0aGlzLm1pZ3JhdGlvbnNQYXRoLCBmaWxlTmFtZSk7XG5cbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5nZW5lcmF0ZU1pZ3JhdGlvbkNvbnRlbnRXaXRoU3RhdGVtZW50cyhuYW1lLCB1cFN0YXRlbWVudHMsIGRvd25TdGF0ZW1lbnRzLnJldmVyc2UoKSk7XG5cbiAgICBjb25zdCB7IHdyaXRlRmlsZSwgbWtkaXIgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpmcy9wcm9taXNlcycpO1xuICAgIGF3YWl0IG1rZGlyKHRoaXMubWlncmF0aW9uc1BhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGF3YWl0IHdyaXRlRmlsZShmaWxlUGF0aCwgY29udGVudCwgJ3V0Zi04Jyk7XG5cbiAgICB0aGlzLmxvZ2dlcihgQ3JlYXRlZCBtaWdyYXRpb24gZnJvbSBlbnRpdGllczogJHtmaWxlUGF0aH1gKTtcbiAgICByZXR1cm4gZmlsZVBhdGg7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBzY2hlbWEgZGlmZmVyZW5jZXMgYmV0d2VlbiBlbnRpdGllcyBhbmQgZGF0YWJhc2VcbiAgICovXG4gIGFzeW5jIGdldERpZmZzKCk6IFByb21pc2U8U2NoZW1hRGlmZltdPiB7XG4gICAgaWYgKCF0aGlzLnNjaGVtYUdlbmVyYXRvciB8fCAhdGhpcy5zY2hlbWFJbnRyb3NwZWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NoZW1hIGdlbmVyYXRvciBhbmQgaW50cm9zcGVjdG9yIG11c3QgYmUgc2V0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzLmxlbmd0aCA+IDAgPyB0aGlzLmVudGl0aWVzIDogZ2V0RW50aXRpZXMoKTtcbiAgICBjb25zdCBkaWZmczogU2NoZW1hRGlmZltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgY29uc3QgbWV0YSA9IGdldE1ldGEoZW50aXR5KTtcbiAgICAgIGNvbnN0IHRhYmxlTmFtZSA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLnJlc29sdmVUYWJsZU5hbWUoZW50aXR5LCBtZXRhKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTY2hlbWEgPSBhd2FpdCB0aGlzLnNjaGVtYUludHJvc3BlY3Rvci5nZXRUYWJsZVNjaGVtYSh0YWJsZU5hbWUpO1xuICAgICAgY29uc3QgZGlmZiA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmRpZmZTY2hlbWEoZW50aXR5LCBjdXJyZW50U2NoZW1hKTtcbiAgICAgIGlmIChkaWZmKSB7XG4gICAgICAgIGRpZmZzLnB1c2goZGlmZik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRpZmZzO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRW50aXR5Rm9yVGFibGUodGFibGVOYW1lOiBzdHJpbmcpOiBUeXBlPHVua25vd24+IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMubGVuZ3RoID4gMCA/IHRoaXMuZW50aXRpZXMgOiBnZXRFbnRpdGllcygpO1xuICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICBjb25zdCBtZXRhID0gZ2V0TWV0YShlbnRpdHkpO1xuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLnJlc29sdmVUYWJsZU5hbWUoZW50aXR5LCBtZXRhKTtcbiAgICAgIGlmIChuYW1lID09PSB0YWJsZU5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jIHNjaGVtYSBkaXJlY3RseSAoZm9yIGRldmVsb3BtZW50IG9ubHkgLSBub3QgZm9yIHByb2R1Y3Rpb24hKVxuICAgKi9cbiAgYXN5bmMgc3luYyhvcHRpb25zOiB7IGZvcmNlPzogYm9vbGVhbiB9ID0ge30pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAob3B0aW9ucy5mb3JjZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc3luY0ZvcmNlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmF1dG9TeW5jKHsgc2FmZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wcyBhbmQgcmVjcmVhdGVzIGFsbCB0YWJsZXMgKERldmVsb3BtZW50IG9ubHkhKVxuICAgKi9cbiAgcHVibGljIGFzeW5jIHN5bmNGb3JjZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuc2NoZW1hR2VuZXJhdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjaGVtYSBnZW5lcmF0b3Igbm90IHNldC4gQ2FsbCBzZXRTY2hlbWFHZW5lcmF0b3IoKSBmaXJzdC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMubGVuZ3RoID4gMCA/IHRoaXMuZW50aXRpZXMgOiBnZXRFbnRpdGllcygpO1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcblxuICAgIGlmICghaXNTcWxRdWVyaWVyKHF1ZXJpZXIpKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllcicpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLmJlZ2luVHJhbnNhY3Rpb24oKTtcblxuICAgICAgLy8gRHJvcCBhbGwgdGFibGVzIGZpcnN0IChpbiByZXZlcnNlIG9yZGVyIGZvciBmb3JlaWduIGtleXMpXG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBbLi4uZW50aXRpZXNdLnJldmVyc2UoKSkge1xuICAgICAgICBjb25zdCBkcm9wU3FsID0gdGhpcy5zY2hlbWFHZW5lcmF0b3IuZ2VuZXJhdGVEcm9wVGFibGUoZW50aXR5KTtcbiAgICAgICAgdGhpcy5sb2dnZXIoYEV4ZWN1dGluZzogJHtkcm9wU3FsfWApO1xuICAgICAgICBhd2FpdCBxdWVyaWVyLnJ1bihkcm9wU3FsKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ3JlYXRlIGFsbCB0YWJsZXNcbiAgICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNxbCA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQ3JlYXRlVGFibGUoZW50aXR5KTtcbiAgICAgICAgdGhpcy5sb2dnZXIoYEV4ZWN1dGluZzogJHtjcmVhdGVTcWx9YCk7XG4gICAgICAgIGF3YWl0IHF1ZXJpZXIucnVuKGNyZWF0ZVNxbCk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHF1ZXJpZXIuY29tbWl0VHJhbnNhY3Rpb24oKTtcbiAgICAgIHRoaXMubG9nZ2VyKCdTY2hlbWEgc3luYyAoZm9yY2UpIGNvbXBsZXRlZCcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2FmZWx5IHN5bmNocm9uaXplcyB0aGUgc2NoZW1hIGJ5IG9ubHkgYWRkaW5nIG1pc3NpbmcgdGFibGVzIGFuZCBjb2x1bW5zLlxuICAgKi9cbiAgYXN5bmMgYXV0b1N5bmMob3B0aW9uczogeyBzYWZlPzogYm9vbGVhbjsgZHJvcD86IGJvb2xlYW47IGxvZ2dpbmc/OiBib29sZWFuIH0gPSB7fSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5zY2hlbWFHZW5lcmF0b3IgfHwgIXRoaXMuc2NoZW1hSW50cm9zcGVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjaGVtYSBnZW5lcmF0b3IgYW5kIGludHJvc3BlY3RvciBtdXN0IGJlIHNldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGRpZmZzID0gYXdhaXQgdGhpcy5nZXREaWZmcygpO1xuICAgIGNvbnN0IHN0YXRlbWVudHM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGRpZmYgb2YgZGlmZnMpIHtcbiAgICAgIGlmIChkaWZmLnR5cGUgPT09ICdjcmVhdGUnKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZmluZEVudGl0eUZvclRhYmxlKGRpZmYudGFibGVOYW1lKTtcbiAgICAgICAgaWYgKGVudGl0eSkge1xuICAgICAgICAgIHN0YXRlbWVudHMucHVzaCh0aGlzLnNjaGVtYUdlbmVyYXRvci5nZW5lcmF0ZUNyZWF0ZVRhYmxlKGVudGl0eSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpZmYudHlwZSA9PT0gJ2FsdGVyJykge1xuICAgICAgICBjb25zdCBmaWx0ZXJlZERpZmYgPSB0aGlzLmZpbHRlckRpZmYoZGlmZiwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGFsdGVyU3RhdGVtZW50cyA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQWx0ZXJUYWJsZShmaWx0ZXJlZERpZmYpO1xuICAgICAgICBzdGF0ZW1lbnRzLnB1c2goLi4uYWx0ZXJTdGF0ZW1lbnRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcHRpb25zLmxvZ2dpbmcpIHRoaXMubG9nZ2VyKCdTY2hlbWEgaXMgYWxyZWFkeSBpbiBzeW5jLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZXhlY3V0ZVN5bmNTdGF0ZW1lbnRzKHN0YXRlbWVudHMsIG9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWx0ZXJEaWZmKGRpZmY6IFNjaGVtYURpZmYsIG9wdGlvbnM6IHsgc2FmZT86IGJvb2xlYW47IGRyb3A/OiBib29sZWFuIH0pOiBTY2hlbWFEaWZmIHtcbiAgICBjb25zdCBmaWx0ZXJlZERpZmYgPSB7IC4uLmRpZmYgfSBhcyB7IC1yZWFkb25seSBbSyBpbiBrZXlvZiBTY2hlbWFEaWZmXTogU2NoZW1hRGlmZltLXSB9O1xuICAgIGlmIChvcHRpb25zLnNhZmUgIT09IGZhbHNlKSB7XG4gICAgICAvLyBJbiBzYWZlIG1vZGUsIHdlIG9ubHkgYWxsb3cgYWRkaXRpb25zXG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmNvbHVtbnNUb0Ryb3A7XG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmluZGV4ZXNUb0Ryb3A7XG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmZvcmVpZ25LZXlzVG9Ecm9wO1xuICAgIH1cbiAgICBpZiAoIW9wdGlvbnMuZHJvcCkge1xuICAgICAgZGVsZXRlIGZpbHRlcmVkRGlmZi5jb2x1bW5zVG9Ecm9wO1xuICAgIH1cbiAgICByZXR1cm4gZmlsdGVyZWREaWZmO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlU3luY1N0YXRlbWVudHMoc3RhdGVtZW50czogc3RyaW5nW10sIG9wdGlvbnM6IHsgbG9nZ2luZz86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZGlhbGVjdCA9PT0gJ21vbmdvZGInKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZU1vbmdvU3luY1N0YXRlbWVudHMoc3RhdGVtZW50cywgb3B0aW9ucywgcXVlcmllciBhcyBNb25nb1F1ZXJpZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlU3FsU3luY1N0YXRlbWVudHMoc3RhdGVtZW50cywgb3B0aW9ucywgcXVlcmllcik7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5sb2dnaW5nKSB0aGlzLmxvZ2dlcignU2NoZW1hIHN5bmNocm9uaXphdGlvbiBjb21wbGV0ZWQnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKHRoaXMuZGlhbGVjdCAhPT0gJ21vbmdvZGInICYmIGlzU3FsUXVlcmllcihxdWVyaWVyKSkge1xuICAgICAgICBhd2FpdCBxdWVyaWVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVNb25nb1N5bmNTdGF0ZW1lbnRzKFxuICAgIHN0YXRlbWVudHM6IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM6IHsgbG9nZ2luZz86IGJvb2xlYW4gfSxcbiAgICBxdWVyaWVyOiBNb25nb1F1ZXJpZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRiID0gcXVlcmllci5kYjtcbiAgICBmb3IgKGNvbnN0IHN0bXQgb2Ygc3RhdGVtZW50cykge1xuICAgICAgY29uc3QgY21kID0gSlNPTi5wYXJzZShzdG10KSBhcyB7XG4gICAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgICBuYW1lPzogc3RyaW5nO1xuICAgICAgICBjb2xsZWN0aW9uPzogc3RyaW5nO1xuICAgICAgICBpbmRleGVzPzogeyBuYW1lOiBzdHJpbmc7IGNvbHVtbnM6IHN0cmluZ1tdOyB1bmlxdWU/OiBib29sZWFuIH1bXTtcbiAgICAgICAga2V5PzogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgICAgICAgb3B0aW9ucz86IGFueTtcbiAgICAgIH07XG4gICAgICBpZiAob3B0aW9ucy5sb2dnaW5nKSB0aGlzLmxvZ2dlcihgRXhlY3V0aW5nIE1vbmdvREI6ICR7c3RtdH1gKTtcblxuICAgICAgY29uc3QgY29sbGVjdGlvbk5hbWUgPSBjbWQubmFtZSB8fCBjbWQuY29sbGVjdGlvbjtcbiAgICAgIGlmICghY29sbGVjdGlvbk5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb25nb0RCIGNvbW1hbmQgbWlzc2luZyBjb2xsZWN0aW9uIG5hbWU6ICR7c3RtdH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBkYi5jb2xsZWN0aW9uKGNvbGxlY3Rpb25OYW1lKTtcblxuICAgICAgaWYgKGNtZC5hY3Rpb24gPT09ICdjcmVhdGVDb2xsZWN0aW9uJykge1xuICAgICAgICBhd2FpdCBkYi5jcmVhdGVDb2xsZWN0aW9uKGNtZC5uYW1lKTtcbiAgICAgICAgaWYgKGNtZC5pbmRleGVzPy5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGlkeCBvZiBjbWQuaW5kZXhlcykge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gT2JqZWN0LmZyb21FbnRyaWVzKGlkeC5jb2x1bW5zLm1hcCgoYzogc3RyaW5nKSA9PiBbYywgMV0pKTtcbiAgICAgICAgICAgIGF3YWl0IGNvbGxlY3Rpb24uY3JlYXRlSW5kZXgoa2V5LCB7IHVuaXF1ZTogaWR4LnVuaXF1ZSwgbmFtZTogaWR4Lm5hbWUgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdkcm9wQ29sbGVjdGlvbicpIHtcbiAgICAgICAgYXdhaXQgY29sbGVjdGlvbi5kcm9wKCk7XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdjcmVhdGVJbmRleCcpIHtcbiAgICAgICAgYXdhaXQgY29sbGVjdGlvbi5jcmVhdGVJbmRleChjbWQua2V5LCBjbWQub3B0aW9ucyk7XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdkcm9wSW5kZXgnKSB7XG4gICAgICAgIGF3YWl0IGNvbGxlY3Rpb24uZHJvcEluZGV4KGNtZC5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVTcWxTeW5jU3RhdGVtZW50cyhcbiAgICBzdGF0ZW1lbnRzOiBzdHJpbmdbXSxcbiAgICBvcHRpb25zOiB7IGxvZ2dpbmc/OiBib29sZWFuIH0sXG4gICAgcXVlcmllcjogUXVlcmllcixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFpc1NxbFF1ZXJpZXIocXVlcmllcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllciBmb3IgdGhpcyBkaWFsZWN0Jyk7XG4gICAgfVxuICAgIGF3YWl0IHF1ZXJpZXIuYmVnaW5UcmFuc2FjdGlvbigpO1xuICAgIGZvciAoY29uc3Qgc3FsIG9mIHN0YXRlbWVudHMpIHtcbiAgICAgIGlmIChvcHRpb25zLmxvZ2dpbmcpIHRoaXMubG9nZ2VyKGBFeGVjdXRpbmc6ICR7c3FsfWApO1xuICAgICAgYXdhaXQgcXVlcmllci5ydW4oc3FsKTtcbiAgICB9XG4gICAgYXdhaXQgcXVlcmllci5jb21taXRUcmFuc2FjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBtaWdyYXRpb24gc3RhdHVzXG4gICAqL1xuICBhc3luYyBzdGF0dXMoKTogUHJvbWlzZTx7IHBlbmRpbmc6IHN0cmluZ1tdOyBleGVjdXRlZDogc3RyaW5nW10gfT4ge1xuICAgIGNvbnN0IFtwZW5kaW5nLCBleGVjdXRlZF0gPSBhd2FpdCBQcm9taXNlLmFsbChbdGhpcy5wZW5kaW5nKCkudGhlbigobSkgPT4gbS5tYXAoKHgpID0+IHgubmFtZSkpLCB0aGlzLmV4ZWN1dGVkKCldKTtcblxuICAgIHJldHVybiB7IHBlbmRpbmcsIGV4ZWN1dGVkIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1pZ3JhdGlvbiBmaWxlcyBmcm9tIHRoZSBtaWdyYXRpb25zIGRpcmVjdG9yeVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRNaWdyYXRpb25GaWxlcygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgcmVhZGRpcih0aGlzLm1pZ3JhdGlvbnNQYXRoKTtcbiAgICAgIHJldHVybiBmaWxlc1xuICAgICAgICAuZmlsdGVyKChmKSA9PiAvXFwuKHRzfGpzfG1qcykkLy50ZXN0KGYpKVxuICAgICAgICAuZmlsdGVyKChmKSA9PiAhZi5lbmRzV2l0aCgnLmQudHMnKSlcbiAgICAgICAgLnNvcnQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKChlcnJvciBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb24pLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgbWlncmF0aW9uIGZyb20gYSBmaWxlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWRNaWdyYXRpb24oZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8TWlncmF0aW9uIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHRoaXMubWlncmF0aW9uc1BhdGgsIGZpbGVOYW1lKTtcbiAgICBjb25zdCBmaWxlVXJsID0gcGF0aFRvRmlsZVVSTChmaWxlUGF0aCkuaHJlZjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBpbXBvcnQoZmlsZVVybCk7XG4gICAgICBjb25zdCBtaWdyYXRpb24gPSBtb2R1bGUuZGVmYXVsdCA/PyBtb2R1bGU7XG5cbiAgICAgIGlmICh0aGlzLmlzTWlncmF0aW9uKG1pZ3JhdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiB0aGlzLmdldE1pZ3JhdGlvbk5hbWUoZmlsZU5hbWUpLFxuICAgICAgICAgIHVwOiBtaWdyYXRpb24udXAuYmluZChtaWdyYXRpb24pLFxuICAgICAgICAgIGRvd246IG1pZ3JhdGlvbi5kb3duLmJpbmQobWlncmF0aW9uKSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2dnZXIoYFdhcm5pbmc6ICR7ZmlsZU5hbWV9IGlzIG5vdCBhIHZhbGlkIG1pZ3JhdGlvbmApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIoYEVycm9yIGxvYWRpbmcgbWlncmF0aW9uICR7ZmlsZU5hbWV9OiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFuIG9iamVjdCBpcyBhIHZhbGlkIG1pZ3JhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBpc01pZ3JhdGlvbihvYmo6IHVua25vd24pOiBvYmogaXMgTWlncmF0aW9uRGVmaW5pdGlvbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmXG4gICAgICBvYmogIT09IHVuZGVmaW5lZCAmJlxuICAgICAgb2JqICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgKG9iaiBhcyBNaWdyYXRpb25EZWZpbml0aW9uKS51cCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgdHlwZW9mIChvYmogYXMgTWlncmF0aW9uRGVmaW5pdGlvbikuZG93biA9PT0gJ2Z1bmN0aW9uJ1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBtaWdyYXRpb24gbmFtZSBmcm9tIGZpbGVuYW1lXG4gICAqL1xuICBwcml2YXRlIGdldE1pZ3JhdGlvbk5hbWUoZmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGJhc2VuYW1lKGZpbGVOYW1lLCBleHRuYW1lKGZpbGVOYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgdGltZXN0YW1wIHN0cmluZyBmb3IgbWlncmF0aW9uIG5hbWVzXG4gICAqL1xuICBwcml2YXRlIGdldFRpbWVzdGFtcCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5vdy5nZXRGdWxsWWVhcigpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKSxcbiAgICAgIFN0cmluZyhub3cuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRIb3VycygpKS5wYWRTdGFydCgyLCAnMCcpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRNaW51dGVzKCkpLnBhZFN0YXJ0KDIsICcwJyksXG4gICAgICBTdHJpbmcobm93LmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgJzAnKSxcbiAgICBdLmpvaW4oJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBzbHVnIGZvciBmaWxlbmFtZXNcbiAgICovXG4gIHByaXZhdGUgc2x1Z2lmeSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZXh0XG4gICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgLnJlcGxhY2UoL1teYS16MC05XSsvZywgJ18nKVxuICAgICAgLnJlcGxhY2UoL15fK3xfKyQvZywgJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIG1pZ3JhdGlvbiBmaWxlIGNvbnRlbnRcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVNaWdyYXRpb25Db250ZW50KG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIC8qdHMqLyBgaW1wb3J0IHR5cGUgeyBTcWxRdWVyaWVyIH0gZnJvbSAnQHVxbC9taWdyYXRlJztcblxuLyoqXG4gKiBNaWdyYXRpb246ICR7bmFtZX1cbiAqIENyZWF0ZWQ6ICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIGFzeW5jIHVwKHF1ZXJpZXI6IFNxbFF1ZXJpZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBBZGQgeW91ciBtaWdyYXRpb24gbG9naWMgaGVyZVxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gYXdhaXQgcXVlcmllci5ydW4oXFxgXG4gICAgLy8gICBDUkVBVEUgVEFCTEUgXCJ1c2Vyc1wiIChcbiAgICAvLyAgICAgXCJpZFwiIFNFUklBTCBQUklNQVJZIEtFWSxcbiAgICAvLyAgICAgXCJuYW1lXCIgVkFSQ0hBUigyNTUpIE5PVCBOVUxMLFxuICAgIC8vICAgICBcImVtYWlsXCIgVkFSQ0hBUigyNTUpIFVOSVFVRSBOT1QgTlVMTCxcbiAgICAvLyAgICAgXCJjcmVhdGVkQXRcIiBUSU1FU1RBTVAgREVGQVVMVCBDVVJSRU5UX1RJTUVTVEFNUFxuICAgIC8vICAgKVxuICAgIC8vIFxcYCk7XG4gIH0sXG5cbiAgYXN5bmMgZG93bihxdWVyaWVyOiBTcWxRdWVyaWVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQWRkIHlvdXIgcm9sbGJhY2sgbG9naWMgaGVyZVxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gYXdhaXQgcXVlcmllci5ydW4oXFxgRFJPUCBUQUJMRSBJRiBFWElTVFMgXCJ1c2Vyc1wiXFxgKTtcbiAgfSxcbn07XG5gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIG1pZ3JhdGlvbiBmaWxlIGNvbnRlbnQgd2l0aCBTUUwgc3RhdGVtZW50c1xuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZU1pZ3JhdGlvbkNvbnRlbnRXaXRoU3RhdGVtZW50cyhcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgdXBTdGF0ZW1lbnRzOiBzdHJpbmdbXSxcbiAgICBkb3duU3RhdGVtZW50czogc3RyaW5nW10sXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgdXBTcWwgPSB1cFN0YXRlbWVudHMubWFwKChzKSA9PiAvKnRzKi8gYCAgICBhd2FpdCBxdWVyaWVyLnJ1bihcXGAke3N9XFxgKTtgKS5qb2luKCdcXG4nKTtcbiAgICBjb25zdCBkb3duU3FsID0gZG93blN0YXRlbWVudHMubWFwKChzKSA9PiAvKnRzKi8gYCAgICBhd2FpdCBxdWVyaWVyLnJ1bihcXGAke3N9XFxgKTtgKS5qb2luKCdcXG4nKTtcblxuICAgIHJldHVybiAvKnRzKi8gYGltcG9ydCB0eXBlIHsgU3FsUXVlcmllciB9IGZyb20gJ0B1cWwvbWlncmF0ZSc7XG5cbi8qKlxuICogTWlncmF0aW9uOiAke25hbWV9XG4gKiBDcmVhdGVkOiAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1cbiAqIEdlbmVyYXRlZCBmcm9tIGVudGl0eSBkZWZpbml0aW9uc1xuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIGFzeW5jIHVwKHF1ZXJpZXI6IFNxbFF1ZXJpZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiR7dXBTcWx9XG4gIH0sXG5cbiAgYXN5bmMgZG93bihxdWVyaWVyOiBTcWxRdWVyaWVyKTogUHJvbWlzZTx2b2lkPiB7XG4ke2Rvd25TcWx9XG4gIH0sXG59O1xuYDtcbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBkZWZpbmUgYSBtaWdyYXRpb24gd2l0aCBwcm9wZXIgdHlwaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVNaWdyYXRpb24obWlncmF0aW9uOiBNaWdyYXRpb25EZWZpbml0aW9uKTogTWlncmF0aW9uRGVmaW5pdGlvbiB7XG4gIHJldHVybiBtaWdyYXRpb247XG59XG4iXX0=
|