diff --git a/.swcrc b/.swcrc index 7a9a30c09..2a607fd8f 100644 --- a/.swcrc +++ b/.swcrc @@ -16,7 +16,7 @@ }, "exclude": [ ".*\\.d\\.ts$", - "/lib/" + // "/lib/" // TODO: Why was this line here? ], "module": { "type": "commonjs", diff --git a/build.gradle b/build.gradle index cee655141..3ecd9ff6d 100644 --- a/build.gradle +++ b/build.gradle @@ -38,10 +38,13 @@ dependencies { include "com.enonic.xp:lib-node:${xpVersion}" include "com.enonic.xp:lib-auth:${xpVersion}" include "com.enonic.xp:lib-i18n:${xpVersion}" + include "com.enonic.xp:lib-io:${xpVersion}" include "com.enonic.lib:lib-admin-ui:${libAdminUiVersion}" devResources "com.enonic.lib:lib-admin-ui:${libAdminUiVersion}" include "com.enonic.lib:lib-graphql:2.0.1" include "com.enonic.lib:lib-mustache:2.1.0" + include 'com.enonic.lib:lib-router:3.1.0' + include 'com.enonic.lib:lib-static:1.0.3' testImplementation "com.enonic.xp:testing:${xpVersion}" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' diff --git a/package-lock.json b/package-lock.json index 83e0ad7b9..d9ce3faba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,20 @@ "@enonic/lib-admin-ui": "file:./.xp/dev/lib-admin-ui", "hasher": "^1.2.0", "jquery": "^3.7.1", + "jquery-ui": "^1.13.2", "nanoid": "^4.0.2", "owasp-password-strength-test": "^1.3.0", "q": "^1.5.1" }, "devDependencies": { + "@enonic-types/global": "^7.13.2", + "@enonic-types/lib-admin": "^7.13.2", + "@enonic-types/lib-i18n": "^7.13.2", + "@enonic-types/lib-io": "^7.13.2", + "@enonic-types/lib-portal": "^7.13.2", + "@enonic/esbuild-plugin-copy-with-hash": "^0.0.1", "@enonic/eslint-config": "^1.2.0", + "@enonic/tsup-plugin-manifest": "^0.0.1", "@fal-works/esbuild-plugin-global-externals": "^2.1.2", "@swc/core": "^1.3.83", "@types/hasher": "^0.0.32", @@ -32,10 +40,12 @@ "concurrently": "^8.2.1", "css-loader": "^6.8.1", "cssnano": "^6.0.1", + "del-cli": "^5.1.0", "enonic-admin-artifacts": "^1.8.3", "esbuild-plugin-external-global": "^1.0.1", "esbuild-plugin-globals": "^0.2.0", "eslint": "^8.49.0", + "glob": "^10.3.4", "less": "^4.2.0", "less-loader": "^11.1.3", "mini-css-extract-plugin": "^2.7.6", @@ -114,6 +124,46 @@ "node": ">=6.9.0" } }, + "node_modules/@cjs-exporter/globby": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@cjs-exporter/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-rxSVbUhNmIYTZKzrtb6cJIUfFk0PDxzeR4+dzi8edKYmmbqRBO/k7N+tW///QmtY6OznemXiLMSZ20E6DHegxQ==", + "dev": true, + "dependencies": { + "globby": "13.1.3" + } + }, + "node_modules/@cjs-exporter/globby/node_modules/globby": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@cjs-exporter/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -129,6 +179,62 @@ "node": ">=10.0.0" } }, + "node_modules/@enonic-types/core": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/core/-/core-7.13.2.tgz", + "integrity": "sha512-rX7oxB5MO3iQfPpoqfQSghCIKskI7Yukcz5z1zzQXKg+nnpVWpWt2F6WRWbYlR8fKJstxZAC6MDAjBDOJSl8KA==", + "dev": true + }, + "node_modules/@enonic-types/global": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/global/-/global-7.13.2.tgz", + "integrity": "sha512-0Jir7BSz4acKAb5xjT3Tb1F+JJ/9senGTvQVrixxp9DqKl63cr4OdenS7VfgW2JQisKkkfI8ONBuA4z+JEGQXQ==", + "dev": true + }, + "node_modules/@enonic-types/lib-admin": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/lib-admin/-/lib-admin-7.13.2.tgz", + "integrity": "sha512-goEkaHW6L4WI3++Ev5moDZ4P267rM74wsQ8t+3K/+tjHLGNtJJMeydHHOU0QqwCDi6CZ4GtKPA+0i84TNbrmUQ==", + "dev": true + }, + "node_modules/@enonic-types/lib-i18n": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/lib-i18n/-/lib-i18n-7.13.2.tgz", + "integrity": "sha512-9smc4S1IloN4rLaU44sk0lMiMRykD0UxiymUsXdzsjHWIoyqYdl5UIY1V9rZFjENqWty/Bg50ayQ5hcwyh3S4g==", + "dev": true + }, + "node_modules/@enonic-types/lib-io": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/lib-io/-/lib-io-7.13.2.tgz", + "integrity": "sha512-xQqQzVuU5ZURIR5HGiUm8ETiWv12Ab29PvMK+bn7TGxqPujKiiZJ4MXAxyyxWB4yxaxb40SKbTX0yOFMyQuR3Q==", + "dev": true, + "dependencies": { + "@enonic-types/core": "7.13.2" + } + }, + "node_modules/@enonic-types/lib-portal": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@enonic-types/lib-portal/-/lib-portal-7.13.2.tgz", + "integrity": "sha512-ociPRl4TSyr33ChLM7FYs80IGYHUp8huwdHpu+T7HZLWf9y1hdfUc6WMPGjElN4TllliHxwaIe9esR7kxhYBQw==", + "dev": true, + "dependencies": { + "@enonic-types/core": "7.13.2" + } + }, + "node_modules/@enonic/esbuild-plugin-copy-with-hash": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@enonic/esbuild-plugin-copy-with-hash/-/esbuild-plugin-copy-with-hash-0.0.1.tgz", + "integrity": "sha512-HUEF1znqgEJyjd9TUsIZeIo9VL59xgaIpwoHeICAtWLmcUIQ2OBjPw8udBepM/mrI2jf0tVDT47IB+85bqjVvw==", + "dev": true, + "dependencies": { + "@cjs-exporter/globby": "^13.1.3", + "colorette": "^2.0.20", + "xxh3-ts": "^1.0.6" + }, + "peerDependencies": { + "esbuild": "~0" + } + }, "node_modules/@enonic/eslint-config": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@enonic/eslint-config/-/eslint-config-1.2.0.tgz", @@ -167,6 +273,18 @@ "postcss": "^8.2.2" } }, + "node_modules/@enonic/tsup-plugin-manifest": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@enonic/tsup-plugin-manifest/-/tsup-plugin-manifest-0.0.1.tgz", + "integrity": "sha512-AL3X7xm6S8iE6bDbFP4Fnb9pOUembe/YpiAVw5/Dfj494ckiT42eeRb3HEFEFyiWrRjqP5weGb18t+sqL+GZfw==", + "dev": true, + "dependencies": { + "colorette": "^2.0.20" + }, + "peerDependencies": { + "esbuild": "~0" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -660,6 +778,102 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -753,6 +967,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@swc/core": { "version": "1.3.84", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.84.tgz", @@ -878,6 +1102,12 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, "node_modules/@types/mousetrap": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.11.tgz", @@ -898,6 +1128,12 @@ "integrity": "sha512-NXKvBVUzIbs6ylBwmOwHFkZS2EXCcjnqr8ZCRNaXBkHAf+3mn/rPcJxwrzuc6movh8fxQAsUUfYklJ/EG+hZqQ==", "dev": true }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, "node_modules/@types/owasp-password-strength-test": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@types/owasp-password-strength-test/-/owasp-password-strength-test-1.3.0.tgz", @@ -1459,6 +1695,22 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1575,6 +1827,15 @@ "node": ">=8" } }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.15", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", @@ -1630,6 +1891,26 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1709,6 +1990,30 @@ "npm": ">= 6.14.8" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1752,6 +2057,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -1867,6 +2214,33 @@ "node": ">=6.0.0" } }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1917,9 +2291,9 @@ "dev": true }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, "node_modules/commander": { @@ -2321,6 +2695,52 @@ "ms": "^2.1.1" } }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2343,6 +2763,79 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/del": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-7.1.0.tgz", + "integrity": "sha512-v2KyNk7efxhlyHpjEvfyxaAihKKK0nWCuf6ZtqZcFFpQRG0bJ12Qsr0RpvsICMjAAZ8DOVCxrlqpxISlMHC4Kg==", + "dev": true, + "dependencies": { + "globby": "^13.1.2", + "graceful-fs": "^4.2.10", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^5.5.0", + "rimraf": "^3.0.2", + "slash": "^4.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del-cli": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-5.1.0.tgz", + "integrity": "sha512-xwMeh2acluWeccsfzE7VLsG3yTr7nWikbfw+xhMnpRrF15pGSkw+3/vJZWlGoE4I86UiLRNHicmKt4tkIX9Jtg==", + "dev": true, + "dependencies": { + "del": "^7.1.0", + "meow": "^10.1.3" + }, + "bin": { + "del": "cli.js", + "del-cli": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", @@ -2436,6 +2929,12 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.4.482", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.482.tgz", @@ -3154,6 +3653,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fraction.js": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", @@ -3298,20 +3825,22 @@ } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3335,6 +3864,30 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "13.21.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", @@ -3409,6 +3962,15 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3537,6 +4099,26 @@ "postcss": "^8.1.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -3597,6 +4179,18 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3792,6 +4386,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -3926,6 +4553,24 @@ "node": ">=0.10.0" } }, + "node_modules/jackspeak": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz", + "integrity": "sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest-worker": { "version": "27.4.5", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", @@ -4267,6 +4912,18 @@ "semver": "bin/semver" } }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -4282,6 +4939,80 @@ "node": ">= 0.10.0" } }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4353,6 +5084,15 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/mini-css-extract-plugin": { "version": "2.7.6", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", @@ -4431,10 +5171,33 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" }, "engines": { - "node": "*" + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/mousetrap": { @@ -4804,6 +5567,21 @@ "node": ">=6" } }, + "node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -4894,6 +5672,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5807,6 +6610,18 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5848,6 +6663,126 @@ "node": ">=4" } }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/read-pkg/node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -5881,6 +6816,22 @@ "node": ">=8.10.0" } }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", @@ -5994,6 +6945,26 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "3.29.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.1.tgz", @@ -6321,6 +7292,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.padend": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", @@ -6378,6 +7364,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -6396,6 +7395,21 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -6675,6 +7689,18 @@ "tree-kill": "cli.js" } }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-api-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", @@ -7174,6 +8200,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7213,6 +8290,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "node_modules/xxh3-ts": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/xxh3-ts/-/xxh3-ts-1.0.6.tgz", + "integrity": "sha512-mFdXT/i6svQNNmwICmszSfKgnYBGBIaCKzPxYHfpM6e1hxYX2gfGPrI9mKRzSnFpi6ieBIK88TGlaudcPYZW5g==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3" + } + }, "node_modules/xxhashjs": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", diff --git a/package.json b/package.json index c4f0bd6f5..9e7e1028a 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "scripts": { "build": "concurrently -c auto -g --timings npm:build:*", "build:css": "postcss -o build/resources/main/assets/styles/main.css build/less/main.css", - "build:js": "tsup", + "build:server": "tsup -d build/resources/main", + "build:static": "tsup -d build/resources/main/static", "check:types": "tsc --pretty --skipLibCheck --noEmit", + "clean": "del build", "fix": "eslint --fix src/**/*.ts --cache", "less": "lessc --source-map src/main/resources/assets/styles/main.less build/less/main.css", "lint": "eslint src/**/*.ts --quiet --cache", @@ -21,12 +23,20 @@ "@enonic/lib-admin-ui": "file:./.xp/dev/lib-admin-ui", "hasher": "^1.2.0", "jquery": "^3.7.1", + "jquery-ui": "^1.13.2", "nanoid": "^4.0.2", "owasp-password-strength-test": "^1.3.0", "q": "^1.5.1" }, "devDependencies": { + "@enonic-types/global": "^7.13.2", + "@enonic-types/lib-admin": "^7.13.2", + "@enonic-types/lib-i18n": "^7.13.2", + "@enonic-types/lib-io": "^7.13.2", + "@enonic-types/lib-portal": "^7.13.2", + "@enonic/esbuild-plugin-copy-with-hash": "^0.0.1", "@enonic/eslint-config": "^1.2.0", + "@enonic/tsup-plugin-manifest": "^0.0.1", "@fal-works/esbuild-plugin-global-externals": "^2.1.2", "@swc/core": "^1.3.83", "@types/hasher": "^0.0.32", @@ -41,10 +51,12 @@ "concurrently": "^8.2.1", "css-loader": "^6.8.1", "cssnano": "^6.0.1", + "del-cli": "^5.1.0", "enonic-admin-artifacts": "^1.8.3", "esbuild-plugin-external-global": "^1.0.1", "esbuild-plugin-globals": "^0.2.0", "eslint": "^8.49.0", + "glob": "^10.3.4", "less": "^4.2.0", "less-loader": "^11.1.3", "mini-css-extract-plugin": "^2.7.6", diff --git a/src/main/resources/admin/tools/main/main.html b/src/main/resources/admin/tools/main/main.html index 8d071bae2..9d11894bd 100644 --- a/src/main/resources/admin/tools/main/main.html +++ b/src/main/resources/admin/tools/main/main.html @@ -1,6 +1,8 @@ + + @@ -42,7 +44,7 @@ - + diff --git a/src/main/resources/admin/tools/main/main.js b/src/main/resources/admin/tools/main/main.js deleted file mode 100644 index 3a5d2efa5..000000000 --- a/src/main/resources/admin/tools/main/main.js +++ /dev/null @@ -1,29 +0,0 @@ -const admin = require('/lib/xp/admin'); -const mustache = require('/lib/mustache'); -const portal = require('/lib/xp/portal'); -const i18n = require('/lib/xp/i18n'); - -function handleGet() { - const view = resolve('./main.html'); - - const params = { - assetsUri: portal.assetUrl({path: ''}), - appName: i18n.localize({ - key: 'admin.tool.displayName', - bundles: ['i18n/phrases'], - locale: admin.getLocales() - }), - launcherPath: admin.getLauncherPath(), - configServiceUrl: portal.serviceUrl({service: 'config'}) - }; - - return { - contentType: 'text/html', - body: mustache.render(view, params), - headers: { - 'Content-Security-Policy': 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; object-src \'none\'; img-src \'self\' data:' - } - }; -} - -exports.get = handleGet; diff --git a/src/main/resources/admin/tools/main/main.ts b/src/main/resources/admin/tools/main/main.ts new file mode 100644 index 000000000..60370361a --- /dev/null +++ b/src/main/resources/admin/tools/main/main.ts @@ -0,0 +1,71 @@ +import type { + Request, + Response, +} from '/types'; + + +import { + getLauncherPath, + getLocales +} from '/lib/xp/admin'; +// @ts-expect-error Cannot find module '/lib/mustache' or its corresponding type declarations.ts(2307) +import mustache from '/lib/mustache'; +// @ts-expect-error Cannot find module '/lib/router' or its corresponding type declarations.ts(2307) +import Router from '/lib/router'; +import { + assetUrl, + serviceUrl +} from '/lib/xp/portal'; +import { localize } from '/lib/xp/i18n'; +import { immutableGetter, getAdminUrl } from '/lib/urlHelper'; +import { + FILEPATH_MANIFEST_CJS, + FILEPATH_MANIFEST_NODE_MODULES, + GETTER_ROOT, +} from '/constants'; + +const TOOL_NAME = 'main'; +const VIEW = resolve('./main.html'); + +const router = Router(); + +router.all(`/${GETTER_ROOT}/{path:.+}`, (r: Request) => { + return immutableGetter(r); +}); + +function get(_request: Request): Response { + const params = { + appUsersBundleUrl: getAdminUrl({ + path: 'main.js' + }, TOOL_NAME), + assetsUri: assetUrl({path: ''}), + appName: localize({ + key: 'admin.tool.displayName', + bundles: ['i18n/phrases'], + locale: getLocales() + }), + configServiceUrl: serviceUrl({service: 'config'}), + jqueryUrl: getAdminUrl({ + manifestPath: FILEPATH_MANIFEST_NODE_MODULES, + path: 'jquery/dist/jquery.min.js', + }, TOOL_NAME), + jqueryUiUrl: getAdminUrl({ + manifestPath: FILEPATH_MANIFEST_NODE_MODULES, + path: 'jquery-ui/dist/jquery-ui.min.js', + }, TOOL_NAME), + launcherPath: getLauncherPath(), + }; + + return { + contentType: 'text/html', + body: mustache.render(VIEW, params), + headers: { + 'content-security-policy': 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; object-src \'none\'; img-src \'self\' data:' + } + }; +} + +router.get('', (r: Request) => get(r)); // Default admin tool path +router.get('/', (r: Request) => get(r)); // Just in case someone adds a slash on the end + +export const all = (r: Request) => router.dispatch(r); diff --git a/src/main/resources/constants.ts b/src/main/resources/constants.ts new file mode 100644 index 000000000..245a4afc9 --- /dev/null +++ b/src/main/resources/constants.ts @@ -0,0 +1,4 @@ +export const GETTER_ROOT = 'static'; +export const FILEPATH_MANIFEST_CJS = `/${GETTER_ROOT}/manifest.cjs.json`; +// export const FILEPATH_MANIFEST_ESM = `/${GETTER_ROOT}/manifest.esm.json`; +export const FILEPATH_MANIFEST_NODE_MODULES = `/${GETTER_ROOT}/node_modules-manifest.json`; diff --git a/src/main/resources/lib/ioResource.ts b/src/main/resources/lib/ioResource.ts new file mode 100644 index 000000000..7c378d59d --- /dev/null +++ b/src/main/resources/lib/ioResource.ts @@ -0,0 +1,38 @@ +import { + getResource, + readText +} from '/lib/xp/io'; + + +export function readResource(filename: string) { + const resource = getResource(filename); + if (!resource || !resource.exists()) { + throw new Error(`Empty or not found: ${filename}`); + } + let content: string; + try { + content = readText(resource.getStream()); + // log.debug('readResource: filename:%s content:%s', filename, content); + } catch (e) { + log.error(e.message); + throw new Error(`Couldn't read resource: ${filename}`); + } + return content; +} + +function jsonParseResource(filename: string) { + const content = readResource(filename); + let obj: object; + try { + obj = JSON.parse(content); + log.debug('jsonParseResource obj:%s', JSON.stringify(obj, null, 4)); + } catch (e) { + log.error(e.message); + log.info("Content dump from '" + filename + "':\n" + content); + throw new Error(`couldn't parse as JSON content of resource: ${filename}`); + } + return obj; +} + + +export default jsonParseResource; diff --git a/src/main/resources/lib/runMode.ts b/src/main/resources/lib/runMode.ts new file mode 100644 index 000000000..3c692207a --- /dev/null +++ b/src/main/resources/lib/runMode.ts @@ -0,0 +1,9 @@ +declare const Java: { + type: (_classPath: string) => { + get: () => string + } +}; + +export const XP_RUN_MODE = `${Java.type('com.enonic.xp.server.RunMode').get()}`; // PROD || DEV +export const IS_DEV_MODE = XP_RUN_MODE === 'DEV'; +export const IS_PROD_MODE = XP_RUN_MODE === 'PROD'; diff --git a/src/main/resources/lib/urlHelper.ts b/src/main/resources/lib/urlHelper.ts new file mode 100644 index 000000000..ae43411d8 --- /dev/null +++ b/src/main/resources/lib/urlHelper.ts @@ -0,0 +1,70 @@ +import type {Request, Response} from '/types'; + +// @ts-expect-error TS2307: Cannot find module '/lib/enonic/static' or its corresponding type declarations. +import { buildGetter } from '/lib/enonic/static'; +import { getToolUrl } from '/lib/xp/admin'; +import { + FILEPATH_MANIFEST_CJS, + FILEPATH_MANIFEST_NODE_MODULES, + GETTER_ROOT +} from '../constants'; +import ioResource from './ioResource'; +import { IS_DEV_MODE } from './runMode'; + + +interface UrlPostfixParams { + manifestPath?: string + path: string, +}; + +type UrlParams = UrlPostfixParams & {urlPrefix: string}; + + +const manifests = { + [FILEPATH_MANIFEST_CJS]: ioResource(FILEPATH_MANIFEST_CJS), + // [FILEPATH_MANIFEST_ESM]: ioResource(FILEPATH_MANIFEST_ESM), + [FILEPATH_MANIFEST_NODE_MODULES]: ioResource(FILEPATH_MANIFEST_NODE_MODULES), +} + +const getImmutableUrl = ({ + manifestPath = FILEPATH_MANIFEST_CJS, + path, + urlPrefix +}: UrlParams) => { + if (IS_DEV_MODE) { + manifests[manifestPath] = ioResource(manifestPath); + } + + return `${urlPrefix}/${GETTER_ROOT}/${manifests[manifestPath][path]}`; +} + +export const getAdminUrl = ({ + manifestPath = FILEPATH_MANIFEST_CJS, + path, +}: UrlPostfixParams, tool: string) => { + const urlPrefix = getToolUrl(app.name, tool); + + return getImmutableUrl({ + manifestPath, + path, + urlPrefix + }); +} + +export const immutableGetter = buildGetter({ + etag: false, // default is true in production and false in development + getCleanPath: (request: Request) => { + log.debug('request:%s', JSON.stringify(request, null, 4)); + log.debug('contextPath:%s', request.contextPath); + log.debug('rawPath:%s', request.rawPath); + + const prefix = request.contextPath; + let cleanPath = prefix ? request.rawPath.substring(prefix.length) : request.rawPath; + cleanPath = cleanPath.replace(`${GETTER_ROOT}/`, ''); + + log.debug('cleanPath:%s', cleanPath); + + return cleanPath; + }, + root: GETTER_ROOT +}) as (_request: Request) => Response; diff --git a/src/main/resources/assets/js/app/Router.ts b/src/main/resources/static/app/Router.ts similarity index 100% rename from src/main/resources/assets/js/app/Router.ts rename to src/main/resources/static/app/Router.ts diff --git a/src/main/resources/assets/js/app/UserAppPanel.ts b/src/main/resources/static/app/UserAppPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/UserAppPanel.ts rename to src/main/resources/static/app/UserAppPanel.ts diff --git a/src/main/resources/assets/js/app/access/IdProviderAccess.ts b/src/main/resources/static/app/access/IdProviderAccess.ts similarity index 100% rename from src/main/resources/assets/js/app/access/IdProviderAccess.ts rename to src/main/resources/static/app/access/IdProviderAccess.ts diff --git a/src/main/resources/assets/js/app/access/IdProviderAccessControlEntry.ts b/src/main/resources/static/app/access/IdProviderAccessControlEntry.ts similarity index 100% rename from src/main/resources/assets/js/app/access/IdProviderAccessControlEntry.ts rename to src/main/resources/static/app/access/IdProviderAccessControlEntry.ts diff --git a/src/main/resources/assets/js/app/access/IdProviderAccessControlEntryJson.ts b/src/main/resources/static/app/access/IdProviderAccessControlEntryJson.ts similarity index 100% rename from src/main/resources/assets/js/app/access/IdProviderAccessControlEntryJson.ts rename to src/main/resources/static/app/access/IdProviderAccessControlEntryJson.ts diff --git a/src/main/resources/assets/js/app/access/IdProviderAccessControlList.ts b/src/main/resources/static/app/access/IdProviderAccessControlList.ts similarity index 100% rename from src/main/resources/assets/js/app/access/IdProviderAccessControlList.ts rename to src/main/resources/static/app/access/IdProviderAccessControlList.ts diff --git a/src/main/resources/assets/js/app/browse/BaseUserEvent.ts b/src/main/resources/static/app/browse/BaseUserEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/BaseUserEvent.ts rename to src/main/resources/static/app/browse/BaseUserEvent.ts diff --git a/src/main/resources/assets/js/app/browse/EditPrincipalEvent.ts b/src/main/resources/static/app/browse/EditPrincipalEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/EditPrincipalEvent.ts rename to src/main/resources/static/app/browse/EditPrincipalEvent.ts diff --git a/src/main/resources/assets/js/app/browse/NewPrincipalEvent.ts b/src/main/resources/static/app/browse/NewPrincipalEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/NewPrincipalEvent.ts rename to src/main/resources/static/app/browse/NewPrincipalEvent.ts diff --git a/src/main/resources/assets/js/app/browse/PrincipalDuplicatedEvent.ts b/src/main/resources/static/app/browse/PrincipalDuplicatedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/PrincipalDuplicatedEvent.ts rename to src/main/resources/static/app/browse/PrincipalDuplicatedEvent.ts diff --git a/src/main/resources/assets/js/app/browse/PrincipalSynchronizedEvent.ts b/src/main/resources/static/app/browse/PrincipalSynchronizedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/PrincipalSynchronizedEvent.ts rename to src/main/resources/static/app/browse/PrincipalSynchronizedEvent.ts diff --git a/src/main/resources/assets/js/app/browse/ShowNewPrincipalDialogEvent.ts b/src/main/resources/static/app/browse/ShowNewPrincipalDialogEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/ShowNewPrincipalDialogEvent.ts rename to src/main/resources/static/app/browse/ShowNewPrincipalDialogEvent.ts diff --git a/src/main/resources/assets/js/app/browse/UpdatePrincipalEvent.ts b/src/main/resources/static/app/browse/UpdatePrincipalEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UpdatePrincipalEvent.ts rename to src/main/resources/static/app/browse/UpdatePrincipalEvent.ts diff --git a/src/main/resources/assets/js/app/browse/UserBrowseItemPanel.ts b/src/main/resources/static/app/browse/UserBrowseItemPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserBrowseItemPanel.ts rename to src/main/resources/static/app/browse/UserBrowseItemPanel.ts diff --git a/src/main/resources/assets/js/app/browse/UserBrowsePanel.ts b/src/main/resources/static/app/browse/UserBrowsePanel.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserBrowsePanel.ts rename to src/main/resources/static/app/browse/UserBrowsePanel.ts diff --git a/src/main/resources/assets/js/app/browse/UserBrowseToolbar.ts b/src/main/resources/static/app/browse/UserBrowseToolbar.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserBrowseToolbar.ts rename to src/main/resources/static/app/browse/UserBrowseToolbar.ts diff --git a/src/main/resources/assets/js/app/browse/UserItemDeletePromptEvent.ts b/src/main/resources/static/app/browse/UserItemDeletePromptEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserItemDeletePromptEvent.ts rename to src/main/resources/static/app/browse/UserItemDeletePromptEvent.ts diff --git a/src/main/resources/assets/js/app/browse/UserItemType.ts b/src/main/resources/static/app/browse/UserItemType.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserItemType.ts rename to src/main/resources/static/app/browse/UserItemType.ts diff --git a/src/main/resources/assets/js/app/browse/UserItemsRowFormatter.ts b/src/main/resources/static/app/browse/UserItemsRowFormatter.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserItemsRowFormatter.ts rename to src/main/resources/static/app/browse/UserItemsRowFormatter.ts diff --git a/src/main/resources/assets/js/app/browse/UserItemsTreeGrid.ts b/src/main/resources/static/app/browse/UserItemsTreeGrid.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserItemsTreeGrid.ts rename to src/main/resources/static/app/browse/UserItemsTreeGrid.ts diff --git a/src/main/resources/assets/js/app/browse/UserTreeGridActions.ts b/src/main/resources/static/app/browse/UserTreeGridActions.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserTreeGridActions.ts rename to src/main/resources/static/app/browse/UserTreeGridActions.ts diff --git a/src/main/resources/assets/js/app/browse/UserTreeGridItem.ts b/src/main/resources/static/app/browse/UserTreeGridItem.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserTreeGridItem.ts rename to src/main/resources/static/app/browse/UserTreeGridItem.ts diff --git a/src/main/resources/assets/js/app/browse/UserTreeGridItemViewer.ts b/src/main/resources/static/app/browse/UserTreeGridItemViewer.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/UserTreeGridItemViewer.ts rename to src/main/resources/static/app/browse/UserTreeGridItemViewer.ts diff --git a/src/main/resources/assets/js/app/browse/action/DeletePrincipalAction.ts b/src/main/resources/static/app/browse/action/DeletePrincipalAction.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/action/DeletePrincipalAction.ts rename to src/main/resources/static/app/browse/action/DeletePrincipalAction.ts diff --git a/src/main/resources/assets/js/app/browse/action/EditPrincipalAction.ts b/src/main/resources/static/app/browse/action/EditPrincipalAction.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/action/EditPrincipalAction.ts rename to src/main/resources/static/app/browse/action/EditPrincipalAction.ts diff --git a/src/main/resources/assets/js/app/browse/action/NewPrincipalAction.ts b/src/main/resources/static/app/browse/action/NewPrincipalAction.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/action/NewPrincipalAction.ts rename to src/main/resources/static/app/browse/action/NewPrincipalAction.ts diff --git a/src/main/resources/assets/js/app/browse/action/SyncPrincipalAction.ts b/src/main/resources/static/app/browse/action/SyncPrincipalAction.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/action/SyncPrincipalAction.ts rename to src/main/resources/static/app/browse/action/SyncPrincipalAction.ts diff --git a/src/main/resources/assets/js/app/browse/filter/PrincipalBrowseFilterPanel.ts b/src/main/resources/static/app/browse/filter/PrincipalBrowseFilterPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/filter/PrincipalBrowseFilterPanel.ts rename to src/main/resources/static/app/browse/filter/PrincipalBrowseFilterPanel.ts diff --git a/src/main/resources/assets/js/app/browse/filter/PrincipalBrowseSearchData.ts b/src/main/resources/static/app/browse/filter/PrincipalBrowseSearchData.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/filter/PrincipalBrowseSearchData.ts rename to src/main/resources/static/app/browse/filter/PrincipalBrowseSearchData.ts diff --git a/src/main/resources/assets/js/app/browse/serviceaccount/PublicKey.ts b/src/main/resources/static/app/browse/serviceaccount/PublicKey.ts similarity index 100% rename from src/main/resources/assets/js/app/browse/serviceaccount/PublicKey.ts rename to src/main/resources/static/app/browse/serviceaccount/PublicKey.ts diff --git a/src/main/resources/assets/js/app/create/NewPrincipalDialog.ts b/src/main/resources/static/app/create/NewPrincipalDialog.ts similarity index 100% rename from src/main/resources/assets/js/app/create/NewPrincipalDialog.ts rename to src/main/resources/static/app/create/NewPrincipalDialog.ts diff --git a/src/main/resources/assets/js/app/create/UserItemTypesRowFormatter.ts b/src/main/resources/static/app/create/UserItemTypesRowFormatter.ts similarity index 100% rename from src/main/resources/assets/js/app/create/UserItemTypesRowFormatter.ts rename to src/main/resources/static/app/create/UserItemTypesRowFormatter.ts diff --git a/src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts b/src/main/resources/static/app/create/UserItemTypesTreeGrid.ts similarity index 100% rename from src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts rename to src/main/resources/static/app/create/UserItemTypesTreeGrid.ts diff --git a/src/main/resources/assets/js/app/create/UserTypeTreeGridItem.ts b/src/main/resources/static/app/create/UserTypeTreeGridItem.ts similarity index 100% rename from src/main/resources/assets/js/app/create/UserTypeTreeGridItem.ts rename to src/main/resources/static/app/create/UserTypeTreeGridItem.ts diff --git a/src/main/resources/assets/js/app/create/UserTypesTreeGridItemViewer.ts b/src/main/resources/static/app/create/UserTypesTreeGridItemViewer.ts similarity index 100% rename from src/main/resources/assets/js/app/create/UserTypesTreeGridItemViewer.ts rename to src/main/resources/static/app/create/UserTypesTreeGridItemViewer.ts diff --git a/src/main/resources/assets/js/app/event/PrincipalServerChange.ts b/src/main/resources/static/app/event/PrincipalServerChange.ts similarity index 100% rename from src/main/resources/assets/js/app/event/PrincipalServerChange.ts rename to src/main/resources/static/app/event/PrincipalServerChange.ts diff --git a/src/main/resources/assets/js/app/event/PrincipalServerChangeItem.ts b/src/main/resources/static/app/event/PrincipalServerChangeItem.ts similarity index 100% rename from src/main/resources/assets/js/app/event/PrincipalServerChangeItem.ts rename to src/main/resources/static/app/event/PrincipalServerChangeItem.ts diff --git a/src/main/resources/assets/js/app/event/PrincipalServerEvent.ts b/src/main/resources/static/app/event/PrincipalServerEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/PrincipalServerEvent.ts rename to src/main/resources/static/app/event/PrincipalServerEvent.ts diff --git a/src/main/resources/assets/js/app/event/PrincipalServerEventsHandler.ts b/src/main/resources/static/app/event/PrincipalServerEventsHandler.ts similarity index 100% rename from src/main/resources/assets/js/app/event/PrincipalServerEventsHandler.ts rename to src/main/resources/static/app/event/PrincipalServerEventsHandler.ts diff --git a/src/main/resources/assets/js/app/event/ReportServerChange.ts b/src/main/resources/static/app/event/ReportServerChange.ts similarity index 100% rename from src/main/resources/assets/js/app/event/ReportServerChange.ts rename to src/main/resources/static/app/event/ReportServerChange.ts diff --git a/src/main/resources/assets/js/app/event/ReportServerChangeItem.ts b/src/main/resources/static/app/event/ReportServerChangeItem.ts similarity index 100% rename from src/main/resources/assets/js/app/event/ReportServerChangeItem.ts rename to src/main/resources/static/app/event/ReportServerChangeItem.ts diff --git a/src/main/resources/assets/js/app/event/ReportServerEvent.ts b/src/main/resources/static/app/event/ReportServerEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/ReportServerEvent.ts rename to src/main/resources/static/app/event/ReportServerEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserFilteredDataScrollEvent.ts b/src/main/resources/static/app/event/UserFilteredDataScrollEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserFilteredDataScrollEvent.ts rename to src/main/resources/static/app/event/UserFilteredDataScrollEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserItemCreatedEvent.ts b/src/main/resources/static/app/event/UserItemCreatedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserItemCreatedEvent.ts rename to src/main/resources/static/app/event/UserItemCreatedEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserItemDeletedEvent.ts b/src/main/resources/static/app/event/UserItemDeletedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserItemDeletedEvent.ts rename to src/main/resources/static/app/event/UserItemDeletedEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserItemNamedEvent.ts b/src/main/resources/static/app/event/UserItemNamedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserItemNamedEvent.ts rename to src/main/resources/static/app/event/UserItemNamedEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserItemUpdatedEvent.ts b/src/main/resources/static/app/event/UserItemUpdatedEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserItemUpdatedEvent.ts rename to src/main/resources/static/app/event/UserItemUpdatedEvent.ts diff --git a/src/main/resources/assets/js/app/event/UserItemsStopScrollEvent.ts b/src/main/resources/static/app/event/UserItemsStopScrollEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UserItemsStopScrollEvent.ts rename to src/main/resources/static/app/event/UserItemsStopScrollEvent.ts diff --git a/src/main/resources/assets/js/app/event/UsersServerEventsListener.ts b/src/main/resources/static/app/event/UsersServerEventsListener.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UsersServerEventsListener.ts rename to src/main/resources/static/app/event/UsersServerEventsListener.ts diff --git a/src/main/resources/assets/js/app/event/UsersServerEventsTranslator.ts b/src/main/resources/static/app/event/UsersServerEventsTranslator.ts similarity index 100% rename from src/main/resources/assets/js/app/event/UsersServerEventsTranslator.ts rename to src/main/resources/static/app/event/UsersServerEventsTranslator.ts diff --git a/src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationComboBox.ts b/src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationComboBox.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationComboBox.ts rename to src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationComboBox.ts diff --git a/src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationLoader.ts b/src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationLoader.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationLoader.ts rename to src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationLoader.ts diff --git a/src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionView.ts b/src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionView.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionView.ts rename to src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionView.ts diff --git a/src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionsView.ts b/src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionsView.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionsView.ts rename to src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelectedOptionsView.ts diff --git a/src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelector.ts b/src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelector.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/authapplicationselector/AuthApplicationSelector.ts rename to src/main/resources/static/app/inputtype/authapplicationselector/AuthApplicationSelector.ts diff --git a/src/main/resources/assets/js/app/inputtype/selector/PrincipalSelector.ts b/src/main/resources/static/app/inputtype/selector/PrincipalSelector.ts similarity index 100% rename from src/main/resources/assets/js/app/inputtype/selector/PrincipalSelector.ts rename to src/main/resources/static/app/inputtype/selector/PrincipalSelector.ts diff --git a/src/main/resources/assets/js/app/principal/FindPrincipalsRequest.ts b/src/main/resources/static/app/principal/FindPrincipalsRequest.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/FindPrincipalsRequest.ts rename to src/main/resources/static/app/principal/FindPrincipalsRequest.ts diff --git a/src/main/resources/assets/js/app/principal/GetPrincipalsByKeysRequest.ts b/src/main/resources/static/app/principal/GetPrincipalsByKeysRequest.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/GetPrincipalsByKeysRequest.ts rename to src/main/resources/static/app/principal/GetPrincipalsByKeysRequest.ts diff --git a/src/main/resources/assets/js/app/principal/Group.ts b/src/main/resources/static/app/principal/Group.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/Group.ts rename to src/main/resources/static/app/principal/Group.ts diff --git a/src/main/resources/assets/js/app/principal/GroupJson.ts b/src/main/resources/static/app/principal/GroupJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/GroupJson.ts rename to src/main/resources/static/app/principal/GroupJson.ts diff --git a/src/main/resources/assets/js/app/principal/IdProvider.ts b/src/main/resources/static/app/principal/IdProvider.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/IdProvider.ts rename to src/main/resources/static/app/principal/IdProvider.ts diff --git a/src/main/resources/assets/js/app/principal/IdProviderJson.ts b/src/main/resources/static/app/principal/IdProviderJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/IdProviderJson.ts rename to src/main/resources/static/app/principal/IdProviderJson.ts diff --git a/src/main/resources/assets/js/app/principal/Members.ts b/src/main/resources/static/app/principal/Members.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/Members.ts rename to src/main/resources/static/app/principal/Members.ts diff --git a/src/main/resources/assets/js/app/principal/MembersJson.ts b/src/main/resources/static/app/principal/MembersJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/MembersJson.ts rename to src/main/resources/static/app/principal/MembersJson.ts diff --git a/src/main/resources/assets/js/app/principal/PrincipalLoader.ts b/src/main/resources/static/app/principal/PrincipalLoader.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/PrincipalLoader.ts rename to src/main/resources/static/app/principal/PrincipalLoader.ts diff --git a/src/main/resources/assets/js/app/principal/PublicKeyJson.ts b/src/main/resources/static/app/principal/PublicKeyJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/PublicKeyJson.ts rename to src/main/resources/static/app/principal/PublicKeyJson.ts diff --git a/src/main/resources/assets/js/app/principal/Role.ts b/src/main/resources/static/app/principal/Role.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/Role.ts rename to src/main/resources/static/app/principal/Role.ts diff --git a/src/main/resources/assets/js/app/principal/RoleJson.ts b/src/main/resources/static/app/principal/RoleJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/RoleJson.ts rename to src/main/resources/static/app/principal/RoleJson.ts diff --git a/src/main/resources/assets/js/app/principal/User.ts b/src/main/resources/static/app/principal/User.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/User.ts rename to src/main/resources/static/app/principal/User.ts diff --git a/src/main/resources/assets/js/app/principal/UserJson.ts b/src/main/resources/static/app/principal/UserJson.ts similarity index 100% rename from src/main/resources/assets/js/app/principal/UserJson.ts rename to src/main/resources/static/app/principal/UserJson.ts diff --git a/src/main/resources/assets/js/app/report/Report.ts b/src/main/resources/static/app/report/Report.ts similarity index 100% rename from src/main/resources/assets/js/app/report/Report.ts rename to src/main/resources/static/app/report/Report.ts diff --git a/src/main/resources/assets/js/app/report/Repository.ts b/src/main/resources/static/app/report/Repository.ts similarity index 100% rename from src/main/resources/assets/js/app/report/Repository.ts rename to src/main/resources/static/app/report/Repository.ts diff --git a/src/main/resources/assets/js/app/report/RepositoryComboBox.ts b/src/main/resources/static/app/report/RepositoryComboBox.ts similarity index 100% rename from src/main/resources/assets/js/app/report/RepositoryComboBox.ts rename to src/main/resources/static/app/report/RepositoryComboBox.ts diff --git a/src/main/resources/assets/js/app/report/RepositoryLoader.ts b/src/main/resources/static/app/report/RepositoryLoader.ts similarity index 100% rename from src/main/resources/assets/js/app/report/RepositoryLoader.ts rename to src/main/resources/static/app/report/RepositoryLoader.ts diff --git a/src/main/resources/assets/js/app/report/RepositoryViewer.ts b/src/main/resources/static/app/report/RepositoryViewer.ts similarity index 100% rename from src/main/resources/assets/js/app/report/RepositoryViewer.ts rename to src/main/resources/static/app/report/RepositoryViewer.ts diff --git a/src/main/resources/assets/js/app/resource/ListIdProviderApplicationsRequest.ts b/src/main/resources/static/app/resource/ListIdProviderApplicationsRequest.ts similarity index 100% rename from src/main/resources/assets/js/app/resource/ListIdProviderApplicationsRequest.ts rename to src/main/resources/static/app/resource/ListIdProviderApplicationsRequest.ts diff --git a/src/main/resources/assets/js/app/view/MembersListing.ts b/src/main/resources/static/app/view/MembersListing.ts similarity index 100% rename from src/main/resources/assets/js/app/view/MembersListing.ts rename to src/main/resources/static/app/view/MembersListing.ts diff --git a/src/main/resources/assets/js/app/view/PublicKeysGrid.ts b/src/main/resources/static/app/view/PublicKeysGrid.ts similarity index 100% rename from src/main/resources/assets/js/app/view/PublicKeysGrid.ts rename to src/main/resources/static/app/view/PublicKeysGrid.ts diff --git a/src/main/resources/assets/js/app/view/UserItemStatisticsHeader.ts b/src/main/resources/static/app/view/UserItemStatisticsHeader.ts similarity index 100% rename from src/main/resources/assets/js/app/view/UserItemStatisticsHeader.ts rename to src/main/resources/static/app/view/UserItemStatisticsHeader.ts diff --git a/src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts b/src/main/resources/static/app/view/UserItemStatisticsPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts rename to src/main/resources/static/app/view/UserItemStatisticsPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/ChangeUserPasswordDialog.ts b/src/main/resources/static/app/wizard/ChangeUserPasswordDialog.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/ChangeUserPasswordDialog.ts rename to src/main/resources/static/app/wizard/ChangeUserPasswordDialog.ts diff --git a/src/main/resources/assets/js/app/wizard/GroupWizardPanel.ts b/src/main/resources/static/app/wizard/GroupWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/GroupWizardPanel.ts rename to src/main/resources/static/app/wizard/GroupWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderAccessControlComboBox.ts b/src/main/resources/static/app/wizard/IdProviderAccessControlComboBox.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderAccessControlComboBox.ts rename to src/main/resources/static/app/wizard/IdProviderAccessControlComboBox.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderAccessControlEntryView.ts b/src/main/resources/static/app/wizard/IdProviderAccessControlEntryView.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderAccessControlEntryView.ts rename to src/main/resources/static/app/wizard/IdProviderAccessControlEntryView.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderAccessSelector.ts b/src/main/resources/static/app/wizard/IdProviderAccessSelector.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderAccessSelector.ts rename to src/main/resources/static/app/wizard/IdProviderAccessSelector.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderWizardActions.ts b/src/main/resources/static/app/wizard/IdProviderWizardActions.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderWizardActions.ts rename to src/main/resources/static/app/wizard/IdProviderWizardActions.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderWizardDataLoader.ts b/src/main/resources/static/app/wizard/IdProviderWizardDataLoader.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderWizardDataLoader.ts rename to src/main/resources/static/app/wizard/IdProviderWizardDataLoader.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderWizardPanel.ts b/src/main/resources/static/app/wizard/IdProviderWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderWizardPanel.ts rename to src/main/resources/static/app/wizard/IdProviderWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderWizardPanelParams.ts b/src/main/resources/static/app/wizard/IdProviderWizardPanelParams.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderWizardPanelParams.ts rename to src/main/resources/static/app/wizard/IdProviderWizardPanelParams.ts diff --git a/src/main/resources/assets/js/app/wizard/IdProviderWizardStepForm.ts b/src/main/resources/static/app/wizard/IdProviderWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/IdProviderWizardStepForm.ts rename to src/main/resources/static/app/wizard/IdProviderWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/MembersWizardPanel.ts b/src/main/resources/static/app/wizard/MembersWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/MembersWizardPanel.ts rename to src/main/resources/static/app/wizard/MembersWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/MembersWizardStepForm.ts b/src/main/resources/static/app/wizard/MembersWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/MembersWizardStepForm.ts rename to src/main/resources/static/app/wizard/MembersWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/NewPublicKeyDialog.ts b/src/main/resources/static/app/wizard/NewPublicKeyDialog.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/NewPublicKeyDialog.ts rename to src/main/resources/static/app/wizard/NewPublicKeyDialog.ts diff --git a/src/main/resources/assets/js/app/wizard/OpenChangePasswordDialogEvent.ts b/src/main/resources/static/app/wizard/OpenChangePasswordDialogEvent.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/OpenChangePasswordDialogEvent.ts rename to src/main/resources/static/app/wizard/OpenChangePasswordDialogEvent.ts diff --git a/src/main/resources/assets/js/app/wizard/PasswordGenerator.ts b/src/main/resources/static/app/wizard/PasswordGenerator.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PasswordGenerator.ts rename to src/main/resources/static/app/wizard/PasswordGenerator.ts diff --git a/src/main/resources/assets/js/app/wizard/PasswordStrengthBlock.ts b/src/main/resources/static/app/wizard/PasswordStrengthBlock.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PasswordStrengthBlock.ts rename to src/main/resources/static/app/wizard/PasswordStrengthBlock.ts diff --git a/src/main/resources/assets/js/app/wizard/PrincipalDescriptionWizardStepForm.ts b/src/main/resources/static/app/wizard/PrincipalDescriptionWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PrincipalDescriptionWizardStepForm.ts rename to src/main/resources/static/app/wizard/PrincipalDescriptionWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/PrincipalWizardDataLoader.ts b/src/main/resources/static/app/wizard/PrincipalWizardDataLoader.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PrincipalWizardDataLoader.ts rename to src/main/resources/static/app/wizard/PrincipalWizardDataLoader.ts diff --git a/src/main/resources/assets/js/app/wizard/PrincipalWizardPanel.ts b/src/main/resources/static/app/wizard/PrincipalWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PrincipalWizardPanel.ts rename to src/main/resources/static/app/wizard/PrincipalWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/PrincipalWizardPanelParams.ts b/src/main/resources/static/app/wizard/PrincipalWizardPanelParams.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PrincipalWizardPanelParams.ts rename to src/main/resources/static/app/wizard/PrincipalWizardPanelParams.ts diff --git a/src/main/resources/assets/js/app/wizard/PublicKeyDetailsDialog.ts b/src/main/resources/static/app/wizard/PublicKeyDetailsDialog.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/PublicKeyDetailsDialog.ts rename to src/main/resources/static/app/wizard/PublicKeyDetailsDialog.ts diff --git a/src/main/resources/assets/js/app/wizard/RoleWizardPanel.ts b/src/main/resources/static/app/wizard/RoleWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/RoleWizardPanel.ts rename to src/main/resources/static/app/wizard/RoleWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/RolesWizardStepForm.ts b/src/main/resources/static/app/wizard/RolesWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/RolesWizardStepForm.ts rename to src/main/resources/static/app/wizard/RolesWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/SecurityWizardStepForm.ts b/src/main/resources/static/app/wizard/SecurityWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/SecurityWizardStepForm.ts rename to src/main/resources/static/app/wizard/SecurityWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/SetUserPasswordRequest.ts b/src/main/resources/static/app/wizard/SetUserPasswordRequest.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/SetUserPasswordRequest.ts rename to src/main/resources/static/app/wizard/SetUserPasswordRequest.ts diff --git a/src/main/resources/assets/js/app/wizard/UserEmailWizardStepForm.ts b/src/main/resources/static/app/wizard/UserEmailWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserEmailWizardStepForm.ts rename to src/main/resources/static/app/wizard/UserEmailWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/UserItemWizardPanel.ts b/src/main/resources/static/app/wizard/UserItemWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserItemWizardPanel.ts rename to src/main/resources/static/app/wizard/UserItemWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/UserItemWizardPanelParams.ts b/src/main/resources/static/app/wizard/UserItemWizardPanelParams.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserItemWizardPanelParams.ts rename to src/main/resources/static/app/wizard/UserItemWizardPanelParams.ts diff --git a/src/main/resources/assets/js/app/wizard/UserItemWizardStepForm.ts b/src/main/resources/static/app/wizard/UserItemWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserItemWizardStepForm.ts rename to src/main/resources/static/app/wizard/UserItemWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/UserKeyDetailsDialog.ts b/src/main/resources/static/app/wizard/UserKeyDetailsDialog.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserKeyDetailsDialog.ts rename to src/main/resources/static/app/wizard/UserKeyDetailsDialog.ts diff --git a/src/main/resources/assets/js/app/wizard/UserMembershipsWizardStepForm.ts b/src/main/resources/static/app/wizard/UserMembershipsWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserMembershipsWizardStepForm.ts rename to src/main/resources/static/app/wizard/UserMembershipsWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/UserPasswordWizardStepForm.ts b/src/main/resources/static/app/wizard/UserPasswordWizardStepForm.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserPasswordWizardStepForm.ts rename to src/main/resources/static/app/wizard/UserPasswordWizardStepForm.ts diff --git a/src/main/resources/assets/js/app/wizard/UserWizardPanel.ts b/src/main/resources/static/app/wizard/UserWizardPanel.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/UserWizardPanel.ts rename to src/main/resources/static/app/wizard/UserWizardPanel.ts diff --git a/src/main/resources/assets/js/app/wizard/action/DeleteUserItemAction.ts b/src/main/resources/static/app/wizard/action/DeleteUserItemAction.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/action/DeleteUserItemAction.ts rename to src/main/resources/static/app/wizard/action/DeleteUserItemAction.ts diff --git a/src/main/resources/assets/js/app/wizard/action/UserItemWizardActions.ts b/src/main/resources/static/app/wizard/action/UserItemWizardActions.ts similarity index 100% rename from src/main/resources/assets/js/app/wizard/action/UserItemWizardActions.ts rename to src/main/resources/static/app/wizard/action/UserItemWizardActions.ts diff --git a/src/main/resources/assets/js/graphql/GraphQlRequest.ts b/src/main/resources/static/graphql/GraphQlRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/GraphQlRequest.ts rename to src/main/resources/static/graphql/GraphQlRequest.ts diff --git a/src/main/resources/assets/js/graphql/ListGraphQlRequest.ts b/src/main/resources/static/graphql/ListGraphQlRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/ListGraphQlRequest.ts rename to src/main/resources/static/graphql/ListGraphQlRequest.ts diff --git a/src/main/resources/assets/js/graphql/aggregation/UserItemAggregationHelper.ts b/src/main/resources/static/graphql/aggregation/UserItemAggregationHelper.ts similarity index 100% rename from src/main/resources/assets/js/graphql/aggregation/UserItemAggregationHelper.ts rename to src/main/resources/static/graphql/aggregation/UserItemAggregationHelper.ts diff --git a/src/main/resources/assets/js/graphql/aggregation/UserItemBucketAggregationJson.ts b/src/main/resources/static/graphql/aggregation/UserItemBucketAggregationJson.ts similarity index 100% rename from src/main/resources/assets/js/graphql/aggregation/UserItemBucketAggregationJson.ts rename to src/main/resources/static/graphql/aggregation/UserItemBucketAggregationJson.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/CreateIdProviderRequest.ts b/src/main/resources/static/graphql/idprovider/CreateIdProviderRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/CreateIdProviderRequest.ts rename to src/main/resources/static/graphql/idprovider/CreateIdProviderRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/DeleteIdProviderRequest.ts b/src/main/resources/static/graphql/idprovider/DeleteIdProviderRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/DeleteIdProviderRequest.ts rename to src/main/resources/static/graphql/idprovider/DeleteIdProviderRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/GetDefaultIdProviderRequest.ts b/src/main/resources/static/graphql/idprovider/GetDefaultIdProviderRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/GetDefaultIdProviderRequest.ts rename to src/main/resources/static/graphql/idprovider/GetDefaultIdProviderRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/GetIdProviderByKeyRequest.ts b/src/main/resources/static/graphql/idprovider/GetIdProviderByKeyRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/GetIdProviderByKeyRequest.ts rename to src/main/resources/static/graphql/idprovider/GetIdProviderByKeyRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/IdProviderListResult.ts b/src/main/resources/static/graphql/idprovider/IdProviderListResult.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/IdProviderListResult.ts rename to src/main/resources/static/graphql/idprovider/IdProviderListResult.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/ListIdProvidersRequest.ts b/src/main/resources/static/graphql/idprovider/ListIdProvidersRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/ListIdProvidersRequest.ts rename to src/main/resources/static/graphql/idprovider/ListIdProvidersRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/SaveIdProviderRequest.ts b/src/main/resources/static/graphql/idprovider/SaveIdProviderRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/SaveIdProviderRequest.ts rename to src/main/resources/static/graphql/idprovider/SaveIdProviderRequest.ts diff --git a/src/main/resources/assets/js/graphql/idprovider/UpdateIdProviderRequest.ts b/src/main/resources/static/graphql/idprovider/UpdateIdProviderRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/idprovider/UpdateIdProviderRequest.ts rename to src/main/resources/static/graphql/idprovider/UpdateIdProviderRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/DeletePrincipalRequest.ts b/src/main/resources/static/graphql/principal/DeletePrincipalRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/DeletePrincipalRequest.ts rename to src/main/resources/static/graphql/principal/DeletePrincipalRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/GetPrincipalByKeyRequest.ts b/src/main/resources/static/graphql/principal/GetPrincipalByKeyRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/GetPrincipalByKeyRequest.ts rename to src/main/resources/static/graphql/principal/GetPrincipalByKeyRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/GetPrincipalsByKeysRequest.ts b/src/main/resources/static/graphql/principal/GetPrincipalsByKeysRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/GetPrincipalsByKeysRequest.ts rename to src/main/resources/static/graphql/principal/GetPrincipalsByKeysRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/GetPrincipalsExistenceRequest.ts b/src/main/resources/static/graphql/principal/GetPrincipalsExistenceRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/GetPrincipalsExistenceRequest.ts rename to src/main/resources/static/graphql/principal/GetPrincipalsExistenceRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/ListItemsRequest.ts b/src/main/resources/static/graphql/principal/ListItemsRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/ListItemsRequest.ts rename to src/main/resources/static/graphql/principal/ListItemsRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/ListPrincipalsNamesRequest.ts b/src/main/resources/static/graphql/principal/ListPrincipalsNamesRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/ListPrincipalsNamesRequest.ts rename to src/main/resources/static/graphql/principal/ListPrincipalsNamesRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/ListPrincipalsRequest.ts b/src/main/resources/static/graphql/principal/ListPrincipalsRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/ListPrincipalsRequest.ts rename to src/main/resources/static/graphql/principal/ListPrincipalsRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/ListTypesRequest.ts b/src/main/resources/static/graphql/principal/ListTypesRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/ListTypesRequest.ts rename to src/main/resources/static/graphql/principal/ListTypesRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/ListUserItemsRequest.ts b/src/main/resources/static/graphql/principal/ListUserItemsRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/ListUserItemsRequest.ts rename to src/main/resources/static/graphql/principal/ListUserItemsRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/group/CreateGroupRequest.ts b/src/main/resources/static/graphql/principal/group/CreateGroupRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/group/CreateGroupRequest.ts rename to src/main/resources/static/graphql/principal/group/CreateGroupRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/group/UpdateGroupRequest.ts b/src/main/resources/static/graphql/principal/group/UpdateGroupRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/group/UpdateGroupRequest.ts rename to src/main/resources/static/graphql/principal/group/UpdateGroupRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/role/CreateRoleRequest.ts b/src/main/resources/static/graphql/principal/role/CreateRoleRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/role/CreateRoleRequest.ts rename to src/main/resources/static/graphql/principal/role/CreateRoleRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/role/UpdateRoleRequest.ts b/src/main/resources/static/graphql/principal/role/UpdateRoleRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/role/UpdateRoleRequest.ts rename to src/main/resources/static/graphql/principal/role/UpdateRoleRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/user/AddPublicKeyRequest.ts b/src/main/resources/static/graphql/principal/user/AddPublicKeyRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/user/AddPublicKeyRequest.ts rename to src/main/resources/static/graphql/principal/user/AddPublicKeyRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/user/CreateUserRequest.ts b/src/main/resources/static/graphql/principal/user/CreateUserRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/user/CreateUserRequest.ts rename to src/main/resources/static/graphql/principal/user/CreateUserRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/user/DeletePublicKeyRequest.ts b/src/main/resources/static/graphql/principal/user/DeletePublicKeyRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/user/DeletePublicKeyRequest.ts rename to src/main/resources/static/graphql/principal/user/DeletePublicKeyRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/user/UpdatePasswordRequest.ts b/src/main/resources/static/graphql/principal/user/UpdatePasswordRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/user/UpdatePasswordRequest.ts rename to src/main/resources/static/graphql/principal/user/UpdatePasswordRequest.ts diff --git a/src/main/resources/assets/js/graphql/principal/user/UpdateUserRequest.ts b/src/main/resources/static/graphql/principal/user/UpdateUserRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/principal/user/UpdateUserRequest.ts rename to src/main/resources/static/graphql/principal/user/UpdateUserRequest.ts diff --git a/src/main/resources/assets/js/graphql/repository/ListRepositoriesRequest.ts b/src/main/resources/static/graphql/repository/ListRepositoriesRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/repository/ListRepositoriesRequest.ts rename to src/main/resources/static/graphql/repository/ListRepositoriesRequest.ts diff --git a/src/main/resources/assets/js/graphql/useritem/DeleteUserItemJson.ts b/src/main/resources/static/graphql/useritem/DeleteUserItemJson.ts similarity index 100% rename from src/main/resources/assets/js/graphql/useritem/DeleteUserItemJson.ts rename to src/main/resources/static/graphql/useritem/DeleteUserItemJson.ts diff --git a/src/main/resources/assets/js/graphql/useritem/DeleteUserItemRequest.ts b/src/main/resources/static/graphql/useritem/DeleteUserItemRequest.ts similarity index 100% rename from src/main/resources/assets/js/graphql/useritem/DeleteUserItemRequest.ts rename to src/main/resources/static/graphql/useritem/DeleteUserItemRequest.ts diff --git a/src/main/resources/assets/js/graphql/useritem/DeleteUserItemResult.ts b/src/main/resources/static/graphql/useritem/DeleteUserItemResult.ts similarity index 100% rename from src/main/resources/assets/js/graphql/useritem/DeleteUserItemResult.ts rename to src/main/resources/static/graphql/useritem/DeleteUserItemResult.ts diff --git a/src/main/resources/assets/js/main.ts b/src/main/resources/static/main.ts similarity index 100% rename from src/main/resources/assets/js/main.ts rename to src/main/resources/static/main.ts diff --git a/src/main/resources/static/tsconfig.json b/src/main/resources/static/tsconfig.json new file mode 100644 index 000000000..e495448da --- /dev/null +++ b/src/main/resources/static/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "esModuleInterop": true, // Needed for the 'q' npm module + "module": "commonjs", + "lib": [ + "DOM", + "ES2020", + "ES2015.Promise" + ], + "moduleResolution": "node", + "paths": {}, + "rootDir": ".", + "skipLibCheck": true, + "target": "es5", // Modern browsers + "types": [ + "hasher", + "q", + "nanoid", + "owasp-password-strength-test" + ], + }, + "include": [ + "./**/*.ts" + ], +} diff --git a/src/main/resources/assets/js/util/CryptoWorker.ts b/src/main/resources/static/util/CryptoWorker.ts similarity index 100% rename from src/main/resources/assets/js/util/CryptoWorker.ts rename to src/main/resources/static/util/CryptoWorker.ts diff --git a/src/main/resources/assets/js/util/UrlHelper.ts b/src/main/resources/static/util/UrlHelper.ts similarity index 100% rename from src/main/resources/assets/js/util/UrlHelper.ts rename to src/main/resources/static/util/UrlHelper.ts diff --git a/src/main/resources/assets/js/worker/RSAKeysWorker.ts b/src/main/resources/static/worker/RSAKeysWorker.ts similarity index 100% rename from src/main/resources/assets/js/worker/RSAKeysWorker.ts rename to src/main/resources/static/worker/RSAKeysWorker.ts diff --git a/src/main/resources/tsconfig.json b/src/main/resources/tsconfig.json new file mode 100644 index 000000000..6649c2015 --- /dev/null +++ b/src/main/resources/tsconfig.json @@ -0,0 +1,31 @@ +{ + // This file is used by your code editor and the build system, + // for TypeScript files except for those under ./assets/. + // https://www.typescriptlang.org/tsconfig + "compilerOptions": { + "baseUrl": ".", + "lib": [ + "ES5" + ], + "paths": { + "/lib/xp/*": ["../../../node_modules/@enonic-types/lib-*"], + "/*": ["./*"] + }, + "rootDir": ".", + "skipLibCheck": true, + // "typeRoots": [ + // "node_modules/@types", + // "node_modules/@enonic-types" + // ], + "types": [ + "@enonic-types/global" + // "global" // When typeRoots is set the prefix @enonic-types/ must be removed. + ] + }, + "exclude": [ + "./assets/**/*", + ], + "include": [ + "./**/*.ts" + ] +} diff --git a/src/main/resources/types/PageContributions.d.ts b/src/main/resources/types/PageContributions.d.ts new file mode 100644 index 000000000..7bb74133b --- /dev/null +++ b/src/main/resources/types/PageContributions.d.ts @@ -0,0 +1,6 @@ +export interface PageContributions { + headBegin?: string[] + headEnd?: string[] + bodyBegin?: string[] + bodyEnd?: string[] +} diff --git a/src/main/resources/types/Request.d.ts b/src/main/resources/types/Request.d.ts new file mode 100644 index 000000000..1d7fe1446 --- /dev/null +++ b/src/main/resources/types/Request.d.ts @@ -0,0 +1,41 @@ +export type StringObject = Record; + +export interface DefaultHeaders extends Headers { + accept?: string + 'accept-charset'?: string + 'accept-encoding'?: string + authorization?: string + cookies?: string + 'if-none-match'?: string + language?: string + 'user-agent'?: string +} + +export type Method = 'GET'|'POST'|'HEAD'|'PUT'|'DELETE'|'PATCH' + +export type Mode = 'edit'|'inline'|'live'|'preview' + +export type Request< + Body = string, + Cookies extends StringObject = StringObject, + Headers extends StringObject = DefaultHeaders, + Params extends StringObject = StringObject, + PathParams extends StringObject = StringObject +> = { + body?: Body + branch?: string + contextPath?: string + cookies?: Cookies + headers?: Headers + host?: string + method?: Method + mode?: Mode + params?: Params + path?: string + pathParams?: PathParams + port?: string|number + rawPath?: string + remoteAddress?: string + scheme?: string + url?: string +} // Request diff --git a/src/main/resources/types/Response.d.ts b/src/main/resources/types/Response.d.ts new file mode 100644 index 000000000..b3ce4dc60 --- /dev/null +++ b/src/main/resources/types/Response.d.ts @@ -0,0 +1,33 @@ +import type {PageContributions} from './PageContributions'; + +// https://developer.enonic.com/docs/xp/stable/framework/http#http-response +export interface ComplexCookie { + value: string // Value (required) The value to store in the cookie. This example will create a cookie looking like this complex: value. + path?: string // The paths on the site where this cookie should be available from (and all containing paths). Defaults to empty + domain?: string // Add additional sites that should be able to read the cookie. Defaults to empty (Only the server that creates the cookie can read it.) + comment?: string // A comment describing the cookie. Default to `null. Deprecated and will be removed in future versions of XP. + maxAge?: number // Number of seconds before the browser is allowed to delete the cookie. Defaults to -1 (The cookie will live until the browser is shut down.) + secure?: boolean // Control if the cookie should only be accepted to be created and read over https and similar secure protocols. Defaults to false + httpOnly?: boolean // Control if the cookie is available for scripts or not. If true, only the serverside code can read the cookie. Defaults to false (Also client-side scripts can read the cookie.) + sameSite?: string // XP 7.3.0 SameSite flag for the cookie. Can be lax, strict, none or for "not set". Default is "not set", meaning "browser’s default". +} + +export interface Response< + Body = string, + Headers extends Record = { + 'content-type'?: string + 'cache-control'?: string + 'content-security-policy'?: string + etag?: string|number + } +> { + applyFilters?: boolean + body?: Body + contentType?: string + cookies?: Record + headers?: Headers + pageContributions?: PageContributions + postProcess?: boolean + redirect?: string + status?: number +} diff --git a/src/main/resources/types/index.d.ts b/src/main/resources/types/index.d.ts new file mode 100644 index 000000000..0b0901a9a --- /dev/null +++ b/src/main/resources/types/index.d.ts @@ -0,0 +1,2 @@ +export type { Request } from './Request.d'; +export type { Response } from './Response.d'; diff --git a/tsconfig.json b/tsconfig.json index 82d2985be..1b9aac367 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,16 +16,13 @@ "dom" ] }, - "files": [ - "./src/main/resources/assets/js/main.ts" - ], "exclude": [ "build/**/*", "out/**/*", - "node_modules/*" + "node_modules/*", + "src/main/resources/**/*" ], "include": [ - "src/**/*", "../lib-admin-ui/src/main/resources/assets/admin/common/js/_**/*.ts", ".xp/dev/lib-admin-ui/**/*.ts" ] diff --git a/tsup.config.ts b/tsup.config.ts index d0b511a4f..c5c2b92ef 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -1,58 +1,18 @@ -import { globalExternals } from "@fal-works/esbuild-plugin-global-externals"; -// import GlobalsPlugin from "esbuild-plugin-globals"; +import type { Options } from './tsup'; + import { defineConfig } from 'tsup'; -// import externalGlobalPlugin from 'esbuild-plugin-external-global'; +import { DIR_DST } from './tsup/constants'; + -export default defineConfig(() => { - return { - bundle: true, - dts: false, // d.ts files are use useless at runtime - entry: { - 'js/app-users-bundle': 'src/main/resources/assets/js/main.ts', - 'js/crypto-worker': 'src/main/resources/assets/js/worker/RSAKeysWorker.ts', - }, - // esbuildOptions(options, context) { - // options.external = [ - // 'jquery' - // ] - // }, - esbuildPlugins: [ - // GlobalsPlugin({ - // // 'jquery': 'jQuery', - // 'jquery': '$' - // }), - globalExternals({ - 'jquery': '$' - // 'jquery': 'jQuery' - }) - // externalGlobalPlugin({ - // // 'react': 'window.React', - // // 'react-dom': 'window.ReactDOM', - // 'jQuery': '$' // It seems jquery is available as $ in the global scope - // }) - ], - // external: [ - // // This will leave require('jquery') as is in the bundle - // // causes: Uncaught ReferenceError: require is not defined - // 'jquery' - // ], - format: [ - 'cjs' - ], - minify: process.env.NODE_ENV !== 'development', - noExternal: [ // Same as dependencies in package.json - /@enonic\/lib-admin-ui/, - 'hasher', - 'jquery', // This will bundle jQuery into the bundle - 'nanoid', - 'owasp-password-strength-test', - 'q' - ], - outDir: 'build/resources/main/assets', - platform: 'browser', - silent: ['QUIET', 'WARN'].includes(process.env.LOG_LEVEL_FROM_GRADLE||''), - // splitting: false, - sourcemap: process.env.NODE_ENV === 'development', - tsconfig: 'src/main/resources/assets/tsconfig.json', - }; +export default defineConfig((options: Options) => { + if (options.d === DIR_DST) { + return import('./tsup/server').then(m => m.default()); + } + if (options.d === 'build/resources/main/assets') { + return import('./tsup/assets').then(m => m.default()); + } + if (options.d === 'build/resources/main/static') { + return import('./tsup/static').then(m => m.default()); + } + throw new Error(`Unconfigured directory:${options.d}!`) }); diff --git a/tsup/assets.ts b/tsup/assets.ts new file mode 100644 index 000000000..2875d915a --- /dev/null +++ b/tsup/assets.ts @@ -0,0 +1,67 @@ +import type { Options } from '.'; + +// import { globalExternals } from "@fal-works/esbuild-plugin-global-externals"; +// import GlobalsPlugin from "esbuild-plugin-globals"; +import { defineConfig } from 'tsup'; +// const { externalGlobalPlugin } = require("esbuild-plugin-external-global"); +import esbuildPluginExternalGlobal from 'esbuild-plugin-external-global'; +import { DIR_DST } from './constants'; + + +export default function buildAssetConfig(): Options { + return { + bundle: true, + dts: false, // d.ts files are use useless at runtime + entry: { + 'js/app-users-bundle': 'src/main/resources/assets/js/main.ts', + 'js/crypto-worker': 'src/main/resources/assets/js/worker/RSAKeysWorker.ts', + }, + esbuildOptions(options, context) { + options.banner = { + js: `const jQuery = $;` // jQuery UI Tabbable requires this + }; + // options.external = [ + // 'jquery' + // ] + }, + esbuildPlugins: [ + // GlobalsPlugin({ + // // 'jquery': 'jQuery', + // 'jquery': '$' + // }), + // globalExternals({ + // 'jquery': 'window.$' + // // 'jquery': 'jQuery' + // }) + esbuildPluginExternalGlobal.externalGlobalPlugin({ + // 'react': 'window.React', + // 'react-dom': 'window.ReactDOM', + // 'jQuery': 'window.$' // It seems jquery is available as $ in the global scope + 'jquery': 'window.$' + }) + ], + // external: [ + // // This will leave require('jquery') as is in the bundle + // // causes: Uncaught ReferenceError: require is not defined + // 'jquery' + // ], + format: [ + 'cjs' + ], + minify: process.env.NODE_ENV !== 'development', + noExternal: [ // Same as dependencies in package.json + /@enonic\/lib-admin-ui/, + 'hasher', + 'jquery', // This will bundle jQuery into the bundle + 'nanoid', + 'owasp-password-strength-test', + 'q' + ], + outDir: 'build/resources/main/assets', + platform: 'browser', + silent: ['QUIET', 'WARN'].includes(process.env.LOG_LEVEL_FROM_GRADLE||''), + // splitting: false, + sourcemap: process.env.NODE_ENV === 'development', + tsconfig: 'src/main/resources/assets/tsconfig.json', + }; +} diff --git a/tsup/constants.ts b/tsup/constants.ts new file mode 100644 index 000000000..ab995304f --- /dev/null +++ b/tsup/constants.ts @@ -0,0 +1,5 @@ +export const DIR_DST = 'build/resources/main'; + +export const DIR_SRC = 'src/main/resources'; +export const DIR_SRC_ASSETS = `${DIR_SRC}/assets`; +export const DIR_SRC_STATIC = `${DIR_SRC}/static`; diff --git a/tsup/index.d.ts b/tsup/index.d.ts new file mode 100644 index 000000000..78bc72401 --- /dev/null +++ b/tsup/index.d.ts @@ -0,0 +1,5 @@ +import type { Options as TsupOptions } from 'tsup'; + +export interface Options extends TsupOptions { + d?: string +} diff --git a/tsup/server.ts b/tsup/server.ts new file mode 100644 index 000000000..21e5cc7b7 --- /dev/null +++ b/tsup/server.ts @@ -0,0 +1,161 @@ +import type { Options } from '.'; + + +import { globSync } from 'glob'; +// import { polyfillNode } from 'esbuild-plugin-polyfill-node'; +// import { print } from 'q-i'; +import { + DIR_SRC, + DIR_SRC_ASSETS, + DIR_SRC_STATIC +} from './constants'; + + +export default function buildServerConfig(): Options { + const GLOB_EXTENSIONS_SERVER = '{ts,js}'; + const FILES_SERVER = globSync( + `${DIR_SRC}/**/*.${GLOB_EXTENSIONS_SERVER}`, + { + absolute: false, + ignore: globSync(`${DIR_SRC_ASSETS}/**/*.${GLOB_EXTENSIONS_SERVER}`).concat( + globSync(`${DIR_SRC_STATIC}/**/*.${GLOB_EXTENSIONS_SERVER}`) + ) + } + ); + // print(FILES_SERVER, { maxItems: Infinity }); + + return { + bundle: true, // Needed to bundle @enonic/js-utils + dts: false, // d.ts files are use useless at runtime + entry: FILES_SERVER, + // env: { + // BROWSER_SYNC_PORT: '3000', + // }, + esbuildOptions(options, context) { + // options.alias = { + // 'alias': './src/main/resources/lib/filename.js' + // }; + + // Some node modules might need globalThis + // options.banner = { + // js: `const globalThis = (1, eval)('this');` // buffer polyfill needs this + // }; + + // If you have libs with chunks, use this to avoid collisions + options.chunkNames = '_chunks/[name]-[hash]'; + + options.mainFields = ['module', 'main']; + }, + esbuildPlugins: [ + // Some node modules might need parts of Node polyfilled: + // polyfillNode({ + // globals: { + // buffer: false, + // process: false + // }, + // polyfills: { + // _stream_duplex: false, + // _stream_passthrough: false, + // _stream_readable: false, + // _stream_transform: false, + // _stream_writable: false, + // assert: false, + // 'assert/strict': false, + // async_hooks: false, + // buffer: false, + // child_process: false, + // cluster: false, + // console: false, + // constants: false, + // crypto: false, + // dgram: false, + // diagnostics_channel: false, + // dns: false, + // domain: false, + // events: false, + // fs: false, + // 'fs/promises': false, + // http: false, + // http2: false, + // https: false, + // module: false, + // net: false, + // os: false, + // path: false, + // perf_hooks: false, + // process: false, //"empty", + // punycode: false, + // querystring: false, + // readline: false, + // repl: false, + // stream: false, + // string_decoder: false, + // sys: false, + // timers: false, + // 'timers/promises': false, + // tls: false, + // tty: false, + // url: false, + // util: false, // true, + // v8: false, + // vm: false, + // wasi: false, + // worker_threads: false, + // zlib: false, + // } + // }) // ReferenceError: "navigator" is not defined + ], + external: [ + '/lib/cache', + '/lib/enonic/static', + /^\/lib\/guillotine/, + '/lib/graphql', + '/lib/graphql-connection', + '/lib/http-client', + '/lib/license', + '/lib/mustache', + '/lib/router', + '/lib/util', + '/lib/vanilla', + '/lib/text-encoding', + '/lib/thymeleaf', + /^\/lib\/xp\//, + ], + format: 'cjs', + inject: [ + // Injects makes it possible to use some functionality in any file :) + // However it also makes every file larger, unless splitting: true + // If for some reason you cannot use code splitting, it is better + // to import a polyfill only in the entries that needs it. + // Code-js polyfills share code, so together they don't add the sum of all the polyfills. + // For example injecting both number/is-finite and is-integer only adds 60K, not 108K + + // Here are some things Nashorn doesn't support, comment them in to inject them: + // 'node_modules/core-js/stable/array/flat.js', // 69K (18K) minified + // 'node_modules/core-js/stable/array/includes.js', // 60K (15K) + // 'node_modules/core-js/stable/math/trunc.js', // 53K (14K) + // 'node_modules/core-js/stable/number/is-finite.js', // 54K (14K) + // 'node_modules/core-js/stable/number/is-integer.js', // 54K (14K) + // 'node_modules/core-js/stable/parse-float.js', // 59K (15K) + // 'node_modules/core-js/stable/reflect/index.js', // 88K (22K) + // 'node_modules/core-js/stable/string/pad-start.js', + + // TIP: I used this command to find sizes + // npm --silent run clean && npm --silent run build:server; ls -lh build/resources/main/empty.js; npm --silent run clean && npm --silent run build:server -- --minify; ls -lh build/resources/main/empty.js + ], + minify: false, // Minifying server files makes debugging harder + + // TIP: Command to check if there are any bad requires left behind + // grep -r 'require("' build/resources/main | grep -v 'require("/'|grep -v chunk + noExternal: [], + + platform: 'neutral', + silent: ['QUIET', 'WARN'].includes(process.env.LOG_LEVEL_FROM_GRADLE||''), + shims: false, // https://tsup.egoist.dev/#inject-cjs-and-esm-shims + splitting: true, + sourcemap: false, + target: 'es5', + tsconfig: 'src/main/resources/tsconfig.json', + }; +} + diff --git a/tsup/static.ts b/tsup/static.ts new file mode 100644 index 000000000..afa135227 --- /dev/null +++ b/tsup/static.ts @@ -0,0 +1,92 @@ +import type { Options } from '.'; + + +import CopyWithHashPlugin from '@enonic/esbuild-plugin-copy-with-hash'; +import TsupPluginManifest from '@enonic/tsup-plugin-manifest'; +// import { globSync } from 'glob'; +import { + DIR_DST, + DIR_SRC_STATIC +} from './constants'; + + +export default function buildStaticConfig(): Options { + const DIR_DST_STATIC = `${DIR_DST}/static`; + // const GLOB_EXTENSIONS_STATIC = '{tsx,ts,jsx,js}'; + // const FILES_STATIC = globSync(`${DIR_SRC_STATIC}/**/*.${GLOB_EXTENSIONS_STATIC}`); + + // const entry = {}; + // for (let i = 0; i < FILES_STATIC.length; i++) { + // const element = FILES_STATIC[i]; + // entry[element + // .replace(`${DIR_SRC_STATIC}/`, '') // Remove path + // .replace(/\.[^.]+$/, '') // Remove extension + // ] = element; + // } + return { + bundle: true, + dts: false, + // entry, + entry: { + 'app-users-bundle': 'src/main/resources/static/main.ts', + 'crypto-worker': 'src/main/resources/static/worker/RSAKeysWorker.ts', + }, + // esbuildOptions(options, context) { + // // options.banner = { + // // js: `const jQuery = window.$;` // jQuery UI Tabbable requires this + // // }; + // // options.external = [ + // // 'jquery' + // // ] + // }, + esbuildPlugins: [ + CopyWithHashPlugin({ + context: 'node_modules', + manifest: `node_modules-manifest.json`, + patterns: [ + 'jquery/dist/*.*', + 'jquery-ui/dist/*.*', + ] + }), + TsupPluginManifest({ + generate: (entries) => {// Executed once per format + const newEntries = {}; + Object.entries(entries).forEach(([k,v]) => { + console.log(k,v); + const ext = v.split('.').pop() as string; + const parts = k.replace(`${DIR_SRC_STATIC}/`, '').split('.'); + parts.pop(); + parts.push(ext); + newEntries[parts.join('.')] = v.replace(`${DIR_DST_STATIC}/`, ''); + }); + return newEntries; + } + }), + ], + format: [ + 'cjs' + ], + + minify: false, + // minify: process.env.NODE_ENV !== 'development', + + noExternal: [ // Same as dependencies in package.json + /@enonic\/lib-admin-ui.*/, + 'hasher', + // 'jquery', // This will bundle jQuery into the bundle + 'nanoid', + 'owasp-password-strength-test', + 'q' + ], + outDir: 'build/resources/main/static', + platform: 'browser', + silent: ['QUIET', 'WARN'].includes(process.env.LOG_LEVEL_FROM_GRADLE||''), + splitting: false, + + sourcemap: false, + // sourcemap: process.env.NODE_ENV === 'development', + // sourcemap: true, + + tsconfig: 'src/main/resources/static/tsconfig.json', + }; +}