diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81287d6..5b70219 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,8 +29,19 @@ jobs: changelog: https://github.com/${{github.repository}}/blob/main/CHANGELOG.md readme: https://github.com/${{github.repository}}/blob/main/README.md + # Use NPM to build the packs + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: '18.x' + cache: 'npm' + - name: Install Dependencies + run: npm ci + - name: Build Packs + run: npm run build + # Create a zip file with all files required by the module to add to the release - - run: zip -r ./module.zip module.json LICENSE css/ lang/ packs/ src/ templates/ + - run: zip -r ./module.zip module.json LICENSE css/ lang/ packs/ src/ templates/ --exclude "packs/_source/*" # Create a release for this specific version - name: Update Release with Files diff --git a/module.json b/module.json index 01a8a7d..8ce046a 100644 --- a/module.json +++ b/module.json @@ -5,7 +5,7 @@ "authors": [{ "name": "kaelad", "discord": "kaelad#1693" }], "version": "0.1", "compatibility": { - "minimum": "11", + "minimum": "11.315", "verified": "12" }, "relationships": { @@ -29,7 +29,7 @@ "name": "sample-items", "label": "AR Message Sample Items", "system": "dnd5e", - "path": "packs/sample-items.db", + "path": "packs/sample-items", "type": "Item" } ], diff --git a/package-lock.json b/package-lock.json index 2c55de9..b01ff0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,10 @@ "name": "adv-reminder", "version": "0.4.0", "devDependencies": { - "jest": "^27.4.7" + "@foundryvtt/foundryvtt-cli": "^1.0.3", + "fancy-log": "^2.0.0", + "jest": "^27.4.7", + "yargs": "^17.7.2" } }, "node_modules/@babel/code-frame": { @@ -571,6 +574,57 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@foundryvtt/foundryvtt-cli": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-1.0.3.tgz", + "integrity": "sha512-M8NrMXFYpOEsLAbgRWfuMvUa9F6HwrROLtqhhBljqfVS1lgm0RJJY/7MObuXsTJOC6+Uu+QOPZTlw4k+hguG7w==", + "dev": true, + "dependencies": { + "chalk": "^5.2.0", + "classic-level": "^1.2.0", + "esm": "^3.2.25", + "js-yaml": "^4.1.0", + "mkdirp": "^3.0.0", + "nedb-promises": "^6.2.1", + "yargs": "^17.7.1" + }, + "bin": { + "fvtt": "fvtt.mjs" + }, + "engines": { + "node": ">17.0.0" + } + }, + "node_modules/@foundryvtt/foundryvtt-cli/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@foundryvtt/foundryvtt-cli/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@foundryvtt/foundryvtt-cli/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -836,6 +890,23 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@seald-io/binary-search-tree": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz", + "integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==", + "dev": true + }, + "node_modules/@seald-io/nedb": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-4.0.4.tgz", + "integrity": "sha512-CUNcMio7QUHTA+sIJ/DC5JzVNNsHe743TPmC4H5Gij9zDLMbmrCT2li3eVB72/gF63BPS8pWEZrjlAMRKA8FDw==", + "dev": true, + "dependencies": { + "@seald-io/binary-search-tree": "^1.0.3", + "localforage": "^1.9.0", + "util": "^0.12.4" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -976,6 +1047,24 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "node_modules/abstract-level": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.4.tgz", + "integrity": "sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -1098,6 +1187,21 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-jest": { "version": "27.4.6", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", @@ -1196,6 +1300,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "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/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1256,12 +1380,55 @@ "node-int64": "^0.4.0" } }, + "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", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1290,6 +1457,15 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1327,15 +1503,35 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/classic-level": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.4.1.tgz", + "integrity": "sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/co": { @@ -1372,6 +1568,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1495,6 +1700,23 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1567,6 +1789,27 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1607,6 +1850,15 @@ "source-map": "~0.6.1" } }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -1685,6 +1937,18 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "dev": true, + "dependencies": { + "color-support": "^1.1.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1731,6 +1995,15 @@ "node": ">=8" } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -1766,10 +2039,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -1789,6 +2065,25 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -1839,6 +2134,18 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", @@ -1866,6 +2173,69 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -1932,6 +2302,32 @@ "node": ">=0.10.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/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -1976,6 +2372,57 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "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" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", @@ -2006,6 +2453,21 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2033,6 +2495,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2214,6 +2691,44 @@ } } }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-cli/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/jest-config": { "version": "27.4.7", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", @@ -2839,6 +3354,28 @@ "node": ">=6" } }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -2861,6 +3398,24 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dev": true, + "dependencies": { + "lie": "3.1.1" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2982,18 +3537,68 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/nedb-promises": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.2.3.tgz", + "integrity": "sha512-enq0IjNyBz9Qy9W/QPCcLGh/QORGBjXbIeZeWvIjO3OMLyAvlKT3hiJubP2BKEiFniUlR3L01o18ktqgn5jxqA==", + "dev": true, + "dependencies": { + "@seald-io/nedb": "^4.0.2" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -3188,6 +3793,15 @@ "node": ">=8" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -3251,6 +3865,26 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -3361,6 +3995,23 @@ "semver": "bin/semver.js" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3680,6 +4331,19 @@ "node": ">= 4.0.0" } }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -3786,6 +4450,25 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -3879,30 +4562,30 @@ "dev": true }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "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==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } } }, @@ -4331,6 +5014,44 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@foundryvtt/foundryvtt-cli": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-1.0.3.tgz", + "integrity": "sha512-M8NrMXFYpOEsLAbgRWfuMvUa9F6HwrROLtqhhBljqfVS1lgm0RJJY/7MObuXsTJOC6+Uu+QOPZTlw4k+hguG7w==", + "dev": true, + "requires": { + "chalk": "^5.2.0", + "classic-level": "^1.2.0", + "esm": "^3.2.25", + "js-yaml": "^4.1.0", + "mkdirp": "^3.0.0", + "nedb-promises": "^6.2.1", + "yargs": "^17.7.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4541,6 +5262,23 @@ "chalk": "^4.0.0" } }, + "@seald-io/binary-search-tree": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz", + "integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==", + "dev": true + }, + "@seald-io/nedb": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-4.0.4.tgz", + "integrity": "sha512-CUNcMio7QUHTA+sIJ/DC5JzVNNsHe743TPmC4H5Gij9zDLMbmrCT2li3eVB72/gF63BPS8pWEZrjlAMRKA8FDw==", + "dev": true, + "requires": { + "@seald-io/binary-search-tree": "^1.0.3", + "localforage": "^1.9.0", + "util": "^0.12.4" + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -4678,6 +5416,21 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "abstract-level": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.4.tgz", + "integrity": "sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + } + }, "acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -4766,6 +5519,15 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, "babel-jest": { "version": "27.4.6", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", @@ -4843,6 +5605,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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 + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4890,12 +5658,35 @@ "node-int64": "^0.4.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4914,6 +5705,12 @@ "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==", "dev": true }, + "catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4942,14 +5739,27 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "classic-level": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.4.1.tgz", + "integrity": "sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + } + }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -4980,6 +5790,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5082,6 +5898,17 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5135,6 +5962,21 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5160,6 +6002,12 @@ "source-map": "~0.6.1" } }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -5213,6 +6061,15 @@ "jest-message-util": "^27.4.6" } }, + "fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "dev": true, + "requires": { + "color-support": "^1.1.3" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5253,6 +6110,15 @@ "path-exists": "^4.0.0" } }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -5278,9 +6144,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "gensync": { @@ -5295,6 +6161,19 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -5327,6 +6206,15 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", @@ -5348,6 +6236,45 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -5399,6 +6326,18 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -5431,6 +6370,28 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, "is-core-module": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", @@ -5452,6 +6413,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5470,6 +6440,15 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.14" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -5600,6 +6579,40 @@ "jest-validate": "^27.4.6", "prompts": "^2.0.1", "yargs": "^16.2.0" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "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 + } } }, "jest-config": { @@ -6094,6 +7107,22 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "dev": true + }, + "level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -6110,6 +7139,24 @@ "type-check": "~0.3.2" } }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dev": true, + "requires": { + "lie": "3.1.1" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -6204,18 +7251,51 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true + }, + "module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "nedb-promises": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.2.3.tgz", + "integrity": "sha512-enq0IjNyBz9Qy9W/QPCcLGh/QORGBjXbIeZeWvIjO3OMLyAvlKT3hiJubP2BKEiFniUlR3L01o18ktqgn5jxqA==", + "dev": true, + "requires": { + "@seald-io/nedb": "^4.0.2" + } + }, + "node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "dev": true + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6362,6 +7442,12 @@ "find-up": "^4.0.0" } }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -6409,6 +7495,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -6489,6 +7581,20 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6730,6 +7836,19 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -6817,6 +7936,19 @@ "isexe": "^2.0.0" } }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -6884,24 +8016,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" } }, "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==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } diff --git a/package.json b/package.json index 14e170d..77f4943 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,14 @@ "private": true, "type": "module", "scripts": { + "build": "node ./utils/packs.mjs package pack", + "unpack": "node ./utils/packs.mjs package unpack", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" }, "devDependencies": { - "jest": "^27.4.7" + "@foundryvtt/foundryvtt-cli": "^1.0.3", + "fancy-log": "^2.0.0", + "jest": "^27.4.7", + "yargs": "^17.7.2" } } diff --git a/packs/_source/sample-items/dwarven-resilience.json b/packs/_source/sample-items/dwarven-resilience.json new file mode 100644 index 0000000..cf9a146 --- /dev/null +++ b/packs/_source/sample-items/dwarven-resilience.json @@ -0,0 +1,123 @@ +{ + "name": "Dwarven Resilience", + "ownership": { + "default": 0 + }, + "type": "feat", + "system": { + "description": { + "value": "

You have advantage on saving throws against poison, and you have resistance against poison damage.

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 20" + }, + "activation": { + "type": "", + "cost": null, + "condition": "" + }, + "duration": { + "value": null, + "units": "" + }, + "target": { + "value": null, + "width": null, + "units": "", + "type": "" + }, + "range": { + "value": null, + "long": null, + "units": "" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "" + }, + "consume": { + "type": "", + "target": null, + "amount": null + }, + "ability": "", + "actionType": "", + "attackBonus": 0, + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [], + "versatile": "" + }, + "formula": "", + "save": { + "ability": "", + "dc": null, + "scaling": "spell" + }, + "requirements": "Dwarf", + "recharge": { + "value": null, + "charged": false + } + }, + "flags": {}, + "img": "icons/creatures/abilities/stinger-poison-green.webp", + "effects": [ + { + "_id": "hIaIpLxcMZSY3qXi", + "changes": [ + { + "key": "system.traits.dr.value", + "value": "poison", + "mode": 2, + "priority": null + }, + { + "key": "flags.adv-reminder.message.ability.save.con", + "mode": 0, + "value": "Advantage against poison", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "seconds": null, + "combat": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "icon": "icons/creatures/abilities/stinger-poison-green.webp", + "origin": "Item.ufysTkqet2Ctmtyi", + "transfer": true, + "flags": {}, + "tint": null, + "name": "Dwarven Resilience", + "description": "", + "statuses": [], + "_key": "!items.effects!hBhQ4hKPvKhIFNED.hIaIpLxcMZSY3qXi" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234474, + "modifiedTime": 1726183385573, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "hBhQ4hKPvKhIFNED", + "_key": "!items!hBhQ4hKPvKhIFNED" +} diff --git a/packs/_source/sample-items/enhance-ability.json b/packs/_source/sample-items/enhance-ability.json new file mode 100644 index 0000000..ab66325 --- /dev/null +++ b/packs/_source/sample-items/enhance-ability.json @@ -0,0 +1,154 @@ +{ + "name": "Enhance Ability", + "ownership": { + "default": 0 + }, + "type": "spell", + "system": { + "description": { + "value": "

You touch a creature and bestow upon it a magical enhancement. Choose one of the following effects; the target gains that effect until the spell ends.

\n\n

At Higher Levels. When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd.

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 237" + }, + "activation": { + "type": "action", + "cost": 1, + "condition": "" + }, + "duration": { + "value": "1", + "units": "hour" + }, + "target": { + "value": 1, + "width": null, + "units": "", + "type": "creature", + "prompt": true + }, + "range": { + "value": null, + "long": null, + "units": "touch" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "", + "prompt": true + }, + "consume": { + "type": "", + "target": null, + "amount": null, + "scale": false + }, + "ability": "", + "actionType": "heal", + "attackBonus": "", + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [ + [ + "2d6", + "temphp" + ] + ], + "versatile": "", + "value": "" + }, + "formula": "", + "save": { + "ability": "", + "dc": null, + "scaling": "spell", + "value": "" + }, + "level": 2, + "school": "trs", + "components": { + "value": "", + "vocal": true, + "somatic": true, + "material": true, + "ritual": false, + "concentration": true + }, + "materials": { + "value": "Fur or a feather from a beast", + "consumed": false, + "cost": 0, + "supply": 0 + }, + "preparation": { + "mode": "prepared", + "prepared": false + }, + "scaling": { + "mode": "level", + "formula": "" + }, + "cover": null, + "crewed": false, + "properties": [ + "vocal", + "somatic", + "material", + "concentration" + ] + }, + "flags": {}, + "img": "icons/magic/control/buff-flight-wings-runes-purple.webp", + "effects": [ + { + "disabled": true, + "duration": { + "startTime": null, + "seconds": 3600, + "rounds": 600, + "turns": null, + "startRound": null, + "startTurn": null, + "combat": null + }, + "icon": "icons/magic/control/buff-flight-wings-runes-purple.webp", + "origin": "Compendium.adv-reminder.sample-items.R42RilUrQV3hqp6p", + "tint": null, + "transfer": true, + "changes": [ + { + "key": "flags.adv-reminder.message.ability.check.all", + "mode": 0, + "value": "Advantage on the enhanced ability", + "priority": null + } + ], + "_id": "bXlqfa8MPBVZZapf", + "flags": {}, + "name": "Enhance Ability", + "description": "", + "statuses": [], + "_key": "!items.effects!R42RilUrQV3hqp6p.bXlqfa8MPBVZZapf" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234084, + "modifiedTime": 1726183385639, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "R42RilUrQV3hqp6p", + "_key": "!items!R42RilUrQV3hqp6p" +} diff --git a/packs/_source/sample-items/enlarge-reduce.json b/packs/_source/sample-items/enlarge-reduce.json new file mode 100644 index 0000000..d449d7a --- /dev/null +++ b/packs/_source/sample-items/enlarge-reduce.json @@ -0,0 +1,166 @@ +{ + "name": "Enlarge/Reduce", + "ownership": { + "default": 0 + }, + "type": "spell", + "system": { + "description": { + "value": "

You cause a creature or an object you can see within range to grow larger or smaller for the Duration. Choose either a creature or an object that is neither worn nor carried. If the target is unwilling, it can make a Constitution saving throw. On a success, the spell has no effect.

If the target is a creature, everything it is wearing and carrying changes size with it. Any item dropped by an affected creature returns to normal size at once.

Enlarge. The target's size doubles in all dimensions, and its weight is multiplied by eight. This growth increases its size by one category—from Medium to Large, for example. If there isn't enough room for the target to double its size, the creature or object attains the maximum possible size in the space available. Until the spell ends, the target also has advantage on Strength Checks and Strength Saving Throws. The target's Weapons also grow to match its new size. While these Weapons are enlarged, the target's attacks with them deal 1d4 extra damage.

Reduce. The target's size is halved in all dimensions, and its weight is reduced to one-eighth of normal. This reduction decreases its size by one category—from Medium to Small, for example. Until the spell ends, the target also has disadvantage on Strength Checks and Strength Saving Throws. The target's Weapons also shrink to match its new size. While these Weapons are reduced, the target's attacks with them deal 1d4 less damage (this can't reduce the damage below 1).

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 237" + }, + "activation": { + "type": "action", + "cost": 1, + "condition": "" + }, + "duration": { + "value": "1", + "units": "minute" + }, + "target": { + "value": 1, + "width": null, + "units": "", + "type": "creature", + "prompt": true + }, + "range": { + "value": 30, + "long": null, + "units": "ft" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "", + "prompt": true + }, + "consume": { + "type": "", + "target": null, + "amount": null, + "scale": false + }, + "ability": "", + "actionType": "save", + "attackBonus": "", + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [], + "versatile": "", + "value": "" + }, + "formula": "", + "save": { + "ability": "con", + "dc": null, + "scaling": "spell" + }, + "level": 2, + "school": "trs", + "components": { + "value": "", + "vocal": true, + "somatic": true, + "material": true, + "ritual": false, + "concentration": true + }, + "materials": { + "value": "A pinch of powdered iron", + "consumed": false, + "cost": 0, + "supply": 0 + }, + "preparation": { + "mode": "prepared", + "prepared": false + }, + "scaling": { + "mode": "none", + "formula": "" + }, + "cover": null, + "crewed": false, + "properties": [ + "vocal", + "somatic", + "material", + "concentration" + ] + }, + "flags": {}, + "img": "icons/magic/control/energy-stream-link-large-blue.webp", + "effects": [ + { + "disabled": true, + "duration": { + "startTime": null, + "seconds": 60, + "rounds": 10, + "turns": null, + "startRound": null, + "startTurn": null, + "combat": null + }, + "icon": "icons/magic/control/energy-stream-link-large-blue.webp", + "origin": "Compendium.adv-reminder.sample-items.UmWhRvI4lb3MmUld", + "tint": null, + "transfer": true, + "changes": [ + { + "key": "flags.adv-reminder.message.ability.check.str", + "mode": 0, + "value": "Advantage if enlarged, Disadvantage if reduced", + "priority": null + }, + { + "key": "flags.adv-reminder.message.ability.save.str", + "mode": 0, + "value": "Advantage if enlarged, Disadvantage if reduced", + "priority": null + }, + { + "key": "flags.adv-reminder.message.damage.mwak", + "mode": 0, + "value": "[[/r +1d4]]{Enlarged} or [[/r -1d4]]{Reduced}", + "priority": null + }, + { + "key": "flags.adv-reminder.message.damage.rwak", + "mode": 0, + "value": "[[/r +1d4]]{Enlarged} or [[/r -1d4]]{Reduced}", + "priority": null + } + ], + "_id": "i6PJKNSmx5O0nJ7U", + "flags": {}, + "name": "Enlarge/Reduce", + "description": "", + "statuses": [], + "_key": "!items.effects!UmWhRvI4lb3MmUld.i6PJKNSmx5O0nJ7U" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234153, + "modifiedTime": 1726183385646, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "UmWhRvI4lb3MmUld", + "_key": "!items!UmWhRvI4lb3MmUld" +} diff --git a/packs/_source/sample-items/fey-ancestry.json b/packs/_source/sample-items/fey-ancestry.json new file mode 100644 index 0000000..223c590 --- /dev/null +++ b/packs/_source/sample-items/fey-ancestry.json @@ -0,0 +1,117 @@ +{ + "name": "Fey Ancestry", + "ownership": { + "default": 0 + }, + "type": "feat", + "system": { + "description": { + "value": "

You have advantage on saving throws against being charmed, and magic can't put you to sleep.

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 23, 39" + }, + "activation": { + "type": "", + "cost": null, + "condition": "" + }, + "duration": { + "value": null, + "units": "" + }, + "target": { + "value": null, + "width": null, + "units": "", + "type": "" + }, + "range": { + "value": null, + "long": null, + "units": "" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "" + }, + "consume": { + "type": "", + "target": null, + "amount": null + }, + "ability": "", + "actionType": "", + "attackBonus": 0, + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [], + "versatile": "" + }, + "formula": "", + "save": { + "ability": "", + "dc": null, + "scaling": "spell" + }, + "requirements": "Elf, Half-Elf", + "recharge": { + "value": null, + "charged": false + } + }, + "flags": {}, + "img": "icons/creatures/mammals/elk-moose-marked-green.webp", + "effects": [ + { + "disabled": false, + "duration": { + "startTime": 0, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": 1, + "startTurn": 0, + "combat": null + }, + "icon": "icons/creatures/mammals/elk-moose-marked-green.webp", + "origin": "Compendium.adv-reminder.sample-items.qdXssoktmNpdirM2", + "tint": null, + "transfer": true, + "changes": [ + { + "key": "flags.adv-reminder.message.ability.save.wis", + "mode": 0, + "value": "You have advantage when saving against being charmed.", + "priority": null + } + ], + "_id": "sza7fSreKpLWrFB4", + "flags": {}, + "name": "Fey Ancestry", + "description": "", + "statuses": [], + "_key": "!items.effects!qdXssoktmNpdirM2.sza7fSreKpLWrFB4" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234471, + "modifiedTime": 1726183385574, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "qdXssoktmNpdirM2", + "_key": "!items!qdXssoktmNpdirM2" +} diff --git a/packs/_source/sample-items/guidance.json b/packs/_source/sample-items/guidance.json new file mode 100644 index 0000000..fcc1952 --- /dev/null +++ b/packs/_source/sample-items/guidance.json @@ -0,0 +1,148 @@ +{ + "name": "Guidance", + "ownership": { + "default": 0 + }, + "type": "spell", + "system": { + "description": { + "value": "

You touch one willing creature. Once before the spell ends, the target can roll a d4 and add the number rolled to one ability check of its choice. It can roll the die before or after making the ability check. The spell then ends.

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 248" + }, + "activation": { + "type": "action", + "cost": 1, + "condition": "" + }, + "duration": { + "value": "1", + "units": "minute" + }, + "target": { + "value": 1, + "width": null, + "units": "", + "type": "creature", + "prompt": true + }, + "range": { + "value": null, + "long": null, + "units": "touch" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "", + "prompt": true + }, + "consume": { + "type": "", + "target": null, + "amount": null, + "scale": false + }, + "ability": "", + "actionType": "util", + "attackBonus": "", + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [], + "versatile": "", + "value": "" + }, + "formula": "1d4", + "save": { + "ability": "", + "dc": null, + "scaling": "spell", + "value": "" + }, + "level": 0, + "school": "div", + "components": { + "value": "", + "vocal": true, + "somatic": true, + "material": false, + "ritual": false, + "concentration": true + }, + "materials": { + "value": "", + "consumed": false, + "cost": 0, + "supply": 0 + }, + "preparation": { + "mode": "prepared", + "prepared": false + }, + "scaling": { + "mode": "none", + "formula": "" + }, + "cover": null, + "crewed": false, + "properties": [ + "vocal", + "somatic", + "concentration" + ] + }, + "flags": {}, + "img": "icons/magic/control/buff-flight-wings-blue.webp", + "effects": [ + { + "disabled": true, + "duration": { + "startTime": null, + "seconds": 60, + "rounds": 10, + "turns": null, + "startRound": null, + "startTurn": null, + "combat": null + }, + "icon": "icons/magic/control/buff-flight-wings-blue.webp", + "origin": "Compendium.adv-reminder.sample-items.5UAa8jcIguGkF1qJ", + "tint": null, + "transfer": true, + "changes": [ + { + "key": "flags.adv-reminder.message.ability.check.all", + "mode": 0, + "value": "[[/r 1d4]]{Guidance} on one ability check, can roll before or after", + "priority": null + } + ], + "_id": "SkoYMd0RXtSiQZD2", + "flags": {}, + "name": "Guidance", + "description": "", + "statuses": [], + "_key": "!items.effects!5UAa8jcIguGkF1qJ.SkoYMd0RXtSiQZD2" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234132, + "modifiedTime": 1726183385625, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "5UAa8jcIguGkF1qJ", + "_key": "!items!5UAa8jcIguGkF1qJ" +} diff --git a/packs/_source/sample-items/sneak-attack.json b/packs/_source/sample-items/sneak-attack.json new file mode 100644 index 0000000..43f8cb7 --- /dev/null +++ b/packs/_source/sample-items/sneak-attack.json @@ -0,0 +1,128 @@ +{ + "name": "Sneak Attack", + "ownership": { + "default": 0 + }, + "type": "feat", + "system": { + "description": { + "value": "

Beginning at 1st level, you know how to strike subtly and exploit a foe's distraction. Once per turn, you can deal an extra 1d6 damage to one creature you hit with an attack if you have advantage on the attack roll. The attack must use a finesse or a ranged weapon.

You don't need advantage on the attack roll if another enemy of the target is within 5 feet of it, that enemy isn't incapacitated, and you don't have disadvantage on the attack roll.

", + "chat": "", + "unidentified": "" + }, + "source": { + "custom": "PHB pg. 96" + }, + "activation": { + "type": "", + "cost": null, + "condition": "" + }, + "duration": { + "value": "", + "units": "" + }, + "target": { + "value": "", + "width": null, + "units": "", + "type": "" + }, + "range": { + "value": "", + "long": null, + "units": "" + }, + "uses": { + "value": null, + "max": "", + "per": null, + "recovery": "" + }, + "consume": { + "type": "", + "target": "", + "amount": null + }, + "ability": "", + "actionType": "other", + "attackBonus": 0, + "chatFlavor": "", + "critical": { + "threshold": null, + "damage": "" + }, + "damage": { + "parts": [ + [ + "@scale.rogue.sneak-attack", + "" + ] + ], + "versatile": "" + }, + "formula": "", + "save": { + "ability": "", + "dc": null, + "scaling": "spell" + }, + "requirements": "Rogue 1", + "recharge": { + "value": null, + "charged": false + } + }, + "flags": {}, + "img": "icons/skills/melee/strike-dagger-arcane-pink.webp", + "effects": [ + { + "disabled": false, + "duration": { + "startTime": 0, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": 1, + "startTurn": 0, + "combat": null + }, + "icon": "icons/skills/melee/strike-dagger-arcane-pink.webp", + "origin": "Compendium.adv-reminder.sample-items.3hOXS0gA0zia6vgU", + "tint": null, + "transfer": true, + "changes": [ + { + "key": "flags.adv-reminder.message.damage.mwak", + "mode": 0, + "value": "[[/r @scale.rogue.sneak-attack]]{Sneak Attack} once per turn", + "priority": null + }, + { + "key": "flags.adv-reminder.message.damage.rwak", + "mode": 0, + "value": "[[/r @scale.rogue.sneak-attack]]{Sneak Attack} once per turn", + "priority": null + } + ], + "_id": "7jUy2bl0IGt1f7dt", + "flags": {}, + "name": "Sneak Attack", + "description": "", + "statuses": [], + "_key": "!items.effects!3hOXS0gA0zia6vgU.7jUy2bl0IGt1f7dt" + } + ], + "_stats": { + "systemId": "dnd5e", + "systemVersion": "3.0.0", + "coreVersion": "11.315", + "createdTime": 1661787234348, + "modifiedTime": 1726183385571, + "lastModifiedBy": "dnd5ebuilder0000" + }, + "folder": null, + "sort": 0, + "_id": "3hOXS0gA0zia6vgU", + "_key": "!items!3hOXS0gA0zia6vgU" +} diff --git a/packs/sample-items.db b/packs/sample-items.db deleted file mode 100644 index 020d88e..0000000 --- a/packs/sample-items.db +++ /dev/null @@ -1,6 +0,0 @@ -{"name":"Sneak Attack","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"feat","system":{"description":{"value":"

Beginning at 1st level, you know how to strike subtly and exploit a foe's distraction. Once per turn, you can deal an extra 1d6 damage to one creature you hit with an attack if you have advantage on the attack roll. The attack must use a finesse or a ranged weapon.

You don't need advantage on the attack roll if another enemy of the target is within 5 feet of it, that enemy isn't incapacitated, and you don't have disadvantage on the attack roll.

","chat":"","unidentified":""},"source":"PHB pg. 96","activation":{"type":"","cost":0,"condition":""},"duration":{"value":"","units":""},"target":{"value":"","width":null,"units":"","type":""},"range":{"value":"","long":null,"units":""},"uses":{"value":null,"max":"","per":null,"recovery":""},"consume":{"type":"","target":"","amount":null},"ability":"","actionType":"other","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[["@scale.rogue.sneak-attack",""]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"spell"},"requirements":"Rogue 1","recharge":{"value":null,"charged":false}},"flags":{"core":{"sourceId":"Compendium.dnd5e.classfeatures.DPN2Gfk8yi1Z5wp7"}},"img":"icons/skills/melee/strike-dagger-arcane-pink.webp","effects":[{"disabled":false,"duration":{"startTime":0,"seconds":null,"rounds":null,"turns":null,"startRound":1,"startTurn":0,"combat":null},"icon":"icons/skills/melee/strike-dagger-arcane-pink.webp","label":"Sneak Attack","origin":"Compendium.adv-reminder.sample-items.3hOXS0gA0zia6vgU","tint":null,"transfer":true,"changes":[{"key":"flags.adv-reminder.message.damage.mwak","mode":0,"value":"[[/r @scale.rogue.sneak-attack]]{Sneak Attack} once per turn","priority":null},{"key":"flags.adv-reminder.message.damage.rwak","mode":0,"value":"[[/r @scale.rogue.sneak-attack]]{Sneak Attack} once per turn","priority":null}],"_id":"7jUy2bl0IGt1f7dt","flags":{}}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234348,"modifiedTime":1664175030439,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"3hOXS0gA0zia6vgU"} -{"name":"Guidance","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"spell","system":{"description":{"value":"

You touch one willing creature. Once before the spell ends, the target can roll a d4 and add the number rolled to one ability check of its choice. It can roll the die before or after making the ability check. The spell then ends.

","chat":"","unidentified":""},"source":"PHB pg. 248","activation":{"type":"action","cost":1,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":1,"width":null,"units":"","type":"creature"},"range":{"value":null,"long":null,"units":"touch"},"uses":{"value":0,"max":0,"per":"","recovery":""},"consume":{"type":"","target":null,"amount":null},"ability":"","actionType":"util","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[],"versatile":"","value":""},"formula":"1d4","save":{"ability":"","dc":null,"scaling":"spell","value":""},"level":0,"school":"div","components":{"value":"","vocal":true,"somatic":true,"material":false,"ritual":false,"concentration":true},"materials":{"value":"","consumed":false,"cost":0,"supply":0},"preparation":{"mode":"prepared","prepared":false},"scaling":{"mode":"none","formula":""}},"flags":{"core":{"sourceId":"Compendium.dnd5e.spells.P7mF2MxSuVJwHRRY"}},"img":"icons/magic/control/buff-flight-wings-blue.webp","effects":[{"disabled":true,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null,"combat":null},"icon":"icons/magic/control/buff-flight-wings-blue.webp","label":"Guidance","origin":"Compendium.adv-reminder.sample-items.5UAa8jcIguGkF1qJ","tint":null,"transfer":true,"changes":[{"key":"flags.adv-reminder.message.ability.check.all","mode":0,"value":"[[/r 1d4]]{Guidance} on one ability check, can roll before or after","priority":null}],"_id":"SkoYMd0RXtSiQZD2","flags":{}}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234132,"modifiedTime":1664175030541,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"5UAa8jcIguGkF1qJ"} -{"name":"Enhance Ability","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"spell","system":{"description":{"value":"

You touch a creature and bestow upon it a magical enhancement. Choose one of the following effects; the target gains that effect until the spell ends.

\n\n

At Higher Levels. When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd.

","chat":"","unidentified":""},"source":"PHB pg. 237","activation":{"type":"action","cost":1,"condition":""},"duration":{"value":1,"units":"hour"},"target":{"value":1,"width":null,"units":"","type":"creature"},"range":{"value":null,"long":null,"units":"touch"},"uses":{"value":0,"max":0,"per":"","recovery":""},"consume":{"type":"","target":null,"amount":null},"ability":"","actionType":"heal","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[["2d6","temphp"]],"versatile":"","value":""},"formula":"","save":{"ability":"","dc":null,"scaling":"spell","value":""},"level":2,"school":"trs","components":{"value":"","vocal":true,"somatic":true,"material":true,"ritual":false,"concentration":true},"materials":{"value":"Fur or a feather from a beast","consumed":false,"cost":0,"supply":0},"preparation":{"mode":"prepared","prepared":false},"scaling":{"mode":"level","formula":""}},"flags":{"core":{"sourceId":"Compendium.dnd5e.spells.9eOZDBImVKxbeOyZ"}},"img":"icons/magic/control/buff-flight-wings-runes-purple.webp","effects":[{"disabled":true,"duration":{"startTime":null,"seconds":3600,"rounds":600,"turns":null,"startRound":null,"startTurn":null,"combat":null},"icon":"icons/magic/control/buff-flight-wings-runes-purple.webp","label":"Enhance Ability","origin":"Compendium.adv-reminder.sample-items.R42RilUrQV3hqp6p","tint":null,"transfer":true,"changes":[{"key":"flags.adv-reminder.message.ability.check.all","mode":0,"value":"Advantage on the enhanced ability","priority":null}],"_id":"bXlqfa8MPBVZZapf","flags":{}}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234084,"modifiedTime":1664175030502,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"R42RilUrQV3hqp6p"} -{"name":"Enlarge/Reduce","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"spell","system":{"description":{"value":"

You cause a creature or an object you can see within range to grow larger or smaller for the Duration. Choose either a creature or an object that is neither worn nor carried. If the target is unwilling, it can make a Constitution saving throw. On a success, the spell has no effect.

If the target is a creature, everything it is wearing and carrying changes size with it. Any item dropped by an affected creature returns to normal size at once.

Enlarge. The target's size doubles in all dimensions, and its weight is multiplied by eight. This growth increases its size by one category—from Medium to Large, for example. If there isn't enough room for the target to double its size, the creature or object attains the maximum possible size in the space available. Until the spell ends, the target also has advantage on Strength Checks and Strength Saving Throws. The target's Weapons also grow to match its new size. While these Weapons are enlarged, the target's attacks with them deal 1d4 extra damage.

Reduce. The target's size is halved in all dimensions, and its weight is reduced to one-eighth of normal. This reduction decreases its size by one category—from Medium to Small, for example. Until the spell ends, the target also has disadvantage on Strength Checks and Strength Saving Throws. The target's Weapons also shrink to match its new size. While these Weapons are reduced, the target's attacks with them deal 1d4 less damage (this can't reduce the damage below 1).

","chat":"","unidentified":""},"source":"PHB pg. 237","activation":{"type":"action","cost":1,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":1,"width":null,"units":"","type":"creature"},"range":{"value":30,"long":0,"units":"ft"},"uses":{"value":0,"max":0,"per":"","recovery":""},"consume":{"type":"","target":null,"amount":null},"ability":"","actionType":"save","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[],"versatile":"","value":""},"formula":"","save":{"ability":"con","dc":null,"scaling":"spell"},"level":2,"school":"trs","components":{"value":"","vocal":true,"somatic":true,"material":true,"ritual":false,"concentration":true},"materials":{"value":"A pinch of powdered iron","consumed":false,"cost":0,"supply":0},"preparation":{"mode":"prepared","prepared":false},"scaling":{"mode":"none","formula":""}},"flags":{"core":{"sourceId":"Compendium.dnd5e.spells.WahI41a3goVUg0x1"}},"img":"icons/magic/control/energy-stream-link-large-blue.webp","effects":[{"disabled":true,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null,"combat":null},"icon":"icons/magic/control/energy-stream-link-large-blue.webp","label":"Enlarge/Reduce","origin":"Compendium.adv-reminder.sample-items.UmWhRvI4lb3MmUld","tint":null,"transfer":true,"changes":[{"key":"flags.adv-reminder.message.ability.check.str","mode":0,"value":"Advantage if enlarged, Disadvantage if reduced","priority":null},{"key":"flags.adv-reminder.message.ability.save.str","mode":0,"value":"Advantage if enlarged, Disadvantage if reduced","priority":null},{"key":"flags.adv-reminder.message.damage.mwak","mode":0,"value":"[[/r +1d4]]{Enlarged} or [[/r -1d4]]{Reduced}","priority":null},{"key":"flags.adv-reminder.message.damage.rwak","mode":0,"value":"[[/r +1d4]]{Enlarged} or [[/r -1d4]]{Reduced}","priority":null}],"_id":"i6PJKNSmx5O0nJ7U","flags":{}}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234153,"modifiedTime":1664175030523,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"UmWhRvI4lb3MmUld"} -{"name":"Dwarven Resilience","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"feat","system":{"description":{"value":"

You have advantage on saving throws against poison, and you have resistance against poison damage.

","chat":"","unidentified":""},"source":"PHB pg. 20","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":null,"recovery":""},"consume":{"type":"","target":null,"amount":null},"ability":"","actionType":"","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"spell"},"requirements":"Dwarf","recharge":{"value":null,"charged":false}},"flags":{"core":{"sourceId":"Compendium.dnd5e.races.ufysTkqet2Ctmtyi"}},"img":"icons/creatures/abilities/stinger-poison-green.webp","effects":[{"_id":"hIaIpLxcMZSY3qXi","changes":[{"key":"system.traits.dr.value","value":"poison","mode":2,"priority":null},{"key":"flags.adv-reminder.message.ability.save.con","mode":0,"value":"Advantage against poison"}],"disabled":false,"duration":{"startTime":null,"seconds":null,"combat":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"icons/creatures/abilities/stinger-poison-green.webp","label":"Dwarven Resilience","origin":"Item.ufysTkqet2Ctmtyi","transfer":true,"flags":{},"tint":null}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234474,"modifiedTime":1664175030462,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"hBhQ4hKPvKhIFNED"} -{"name":"Fey Ancestry","ownership":{"default":0,"GrX6tFOozYFBnDHq":3},"type":"feat","system":{"description":{"value":"

You have advantage on saving throws against being charmed, and magic can't put you to sleep.

","chat":"","unidentified":""},"source":"PHB pg. 23, 39","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":null,"recovery":""},"consume":{"type":"","target":null,"amount":null},"ability":"","actionType":"","attackBonus":0,"chatFlavor":"","critical":{"threshold":null,"damage":""},"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"spell"},"requirements":"Elf, Half-Elf","recharge":{"value":null,"charged":false}},"flags":{"core":{"sourceId":"Compendium.dnd5e.races.cnTbpPPeGW7vGjOV"}},"img":"icons/creatures/mammals/elk-moose-marked-green.webp","effects":[{"disabled":false,"duration":{"startTime":0,"seconds":null,"rounds":null,"turns":null,"startRound":1,"startTurn":0,"combat":null},"icon":"icons/creatures/mammals/elk-moose-marked-green.webp","label":"Fey Ancestry","origin":"Compendium.adv-reminder.sample-items.qdXssoktmNpdirM2","tint":null,"transfer":true,"changes":[{"key":"flags.adv-reminder.message.ability.save.wis","mode":0,"value":"You have advantage when saving against being charmed.","priority":null}],"_id":"sza7fSreKpLWrFB4","flags":{}}],"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.286","createdTime":1661787234471,"modifiedTime":1664175030479,"lastModifiedBy":"GrX6tFOozYFBnDHq"},"folder":null,"sort":0,"_id":"qdXssoktmNpdirM2"} diff --git a/utils/packs.mjs b/utils/packs.mjs new file mode 100644 index 0000000..088ca25 --- /dev/null +++ b/utils/packs.mjs @@ -0,0 +1,277 @@ +import fs from "fs"; +import { readdir, readFile, writeFile } from "node:fs/promises"; +import logger from "fancy-log"; +import path from "path"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { compilePack, extractPack } from "@foundryvtt/foundryvtt-cli"; + + +/** + * Folder where the compiled compendium packs should be located relative to the + * base 5e system folder. + * @type {string} + */ +const PACK_DEST = "packs"; + +/** + * Folder where source JSON files should be located relative to the 5e system folder. + * @type {string} + */ +const PACK_SRC = "packs/_source"; + + +// eslint-disable-next-line +const argv = yargs(hideBin(process.argv)) + .command(packageCommand()) + .help().alias("help", "h") + .argv; + + +// eslint-disable-next-line +function packageCommand() { + return { + command: "package [action] [pack] [entry]", + describe: "Manage packages", + builder: yargs => { + yargs.positional("action", { + describe: "The action to perform.", + type: "string", + choices: ["unpack", "pack", "clean"] + }); + yargs.positional("pack", { + describe: "Name of the pack upon which to work.", + type: "string" + }); + yargs.positional("entry", { + describe: "Name of any entry within a pack upon which to work. Only applicable to extract & clean commands.", + type: "string" + }); + }, + handler: async argv => { + const { action, pack, entry } = argv; + switch ( action ) { + case "clean": + return await cleanPacks(pack, entry); + case "pack": + return await compilePacks(pack); + case "unpack": + return await extractPacks(pack, entry); + } + } + }; +} + + +/* ----------------------------------------- */ +/* Clean Packs */ +/* ----------------------------------------- */ + +/** + * Removes unwanted flags, permissions, and other data from entries before extracting or compiling. + * @param {object} data Data for a single entry to clean. + * @param {object} [options={}] + * @param {boolean} [options.clearSourceId=true] Should the core sourceId flag be deleted. + * @param {number} [options.ownership=0] Value to reset default ownership to. + */ +function cleanPackEntry(data, { clearSourceId=true, ownership=0 }={}) { + if ( data.ownership ) data.ownership = { default: ownership }; + if ( clearSourceId ) { + delete data._stats?.compendiumSource; + delete data.flags?.core?.sourceId; + } + delete data.flags?.importSource; + delete data.flags?.exportSource; + if ( data._stats?.lastModifiedBy ) data._stats.lastModifiedBy = "dnd5ebuilder0000"; + + // Remove empty entries in flags + if ( !data.flags ) data.flags = {}; + Object.entries(data.flags).forEach(([key, contents]) => { + if ( Object.keys(contents).length === 0 ) delete data.flags[key]; + }); + + if ( data.system?.activation?.cost === 0 ) data.system.activation.cost = null; + if ( data.system?.duration?.value === "0" ) data.system.duration.value = ""; + if ( data.system?.target?.value === 0 ) data.system.target.value = null; + if ( data.system?.target?.width === 0 ) data.system.target.width = null; + if ( data.system?.range?.value === 0 ) data.system.range.value = null; + if ( data.system?.range?.long === 0 ) data.system.range.long = null; + if ( data.system?.uses?.value === 0 ) data.system.uses.value = null; + if ( data.system?.uses?.max === "0" ) data.system.duration.value = ""; + if ( data.system?.save?.dc === 0 ) data.system.save.dc = null; + if ( data.system?.capacity?.value === 0 ) data.system.capacity.value = null; + if ( data.system?.strength === 0 ) data.system.strength = null; + + // Remove mystery-man.svg from Actors + if ( ["character", "npc"].includes(data.type) && data.img === "icons/svg/mystery-man.svg" ) { + data.img = ""; + data.prototypeToken.texture.src = ""; + } + + if ( data.effects ) data.effects.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.items ) data.items.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.pages ) data.pages.forEach(i => cleanPackEntry(i, { ownership: -1 })); + if ( data.system?.description?.value ) data.system.description.value = cleanString(data.system.description.value); + if ( data.label ) data.label = cleanString(data.label); + if ( data.name ) data.name = cleanString(data.name); +} + + +/** + * Removes invisible whitespace characters and normalizes single- and double-quotes. + * @param {string} str The string to be cleaned. + * @returns {string} The cleaned string. + */ +function cleanString(str) { + return str.replace(/\u2060/gu, "").replace(/[‘’]/gu, "'").replace(/[“”]/gu, '"'); +} + + +/** + * Cleans and formats source JSON files, removing unnecessary permissions and flags and adding the proper spacing. + * @param {string} [packName] Name of pack to clean. If none provided, all packs will be cleaned. + * @param {string} [entryName] Name of a specific entry to clean. + * + * - `npm run build:clean` - Clean all source JSON files. + * - `npm run build:clean -- classes` - Only clean the source files for the specified compendium. + * - `npm run build:clean -- classes Barbarian` - Only clean a single item from the specified compendium. + */ +async function cleanPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + /** + * Walk through directories to find JSON files. + * @param {string} directoryPath + * @yields {string} + */ + async function* _walkDir(directoryPath) { + const directory = await readdir(directoryPath, { withFileTypes: true }); + for ( const entry of directory ) { + const entryPath = path.join(directoryPath, entry.name); + if ( entry.isDirectory() ) yield* _walkDir(entryPath); + else if ( path.extname(entry.name) === ".json" ) yield entryPath; + } + } + + for ( const folder of folders ) { + logger.info(`Cleaning pack ${folder.name}`); + for await ( const src of _walkDir(path.join(PACK_SRC, folder.name)) ) { + const json = JSON.parse(await readFile(src, { encoding: "utf8" })); + if ( entryName && (entryName !== json.name.toLowerCase()) ) continue; + if ( !json._id || !json._key ) { + console.log(`Failed to clean \x1b[31m${src}\x1b[0m, must have _id and _key.`); + continue; + } + cleanPackEntry(json); + fs.rmSync(src, { force: true }); + writeFile(src, `${JSON.stringify(json, null, 2)}\n`, { mode: 0o664 }); + } + } +} + + +/* ----------------------------------------- */ +/* Compile Packs */ +/* ----------------------------------------- */ + +/** + * Compile the source JSON files into compendium packs. + * @param {string} [packName] Name of pack to compile. If none provided, all packs will be packed. + * + * - `npm run build:db` - Compile all JSON files into their LevelDB files. + * - `npm run build:db -- classes` - Only compile the specified pack. + */ +async function compilePacks(packName) { + // Determine which source folders to process + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + for ( const folder of folders ) { + const src = path.join(PACK_SRC, folder.name); + const dest = path.join(PACK_DEST, folder.name); + logger.info(`Compiling pack ${folder.name}`); + await compilePack(src, dest, { recursive: true, log: true, transformEntry: cleanPackEntry }); + } +} + + +/* ----------------------------------------- */ +/* Extract Packs */ +/* ----------------------------------------- */ + +/** + * Extract the contents of compendium packs to JSON files. + * @param {string} [packName] Name of pack to extract. If none provided, all packs will be unpacked. + * @param {string} [entryName] Name of a specific entry to extract. + * + * - `npm build:json - Extract all compendium LevelDB files into JSON files. + * - `npm build:json -- classes` - Only extract the contents of the specified compendium. + * - `npm build:json -- classes Barbarian` - Only extract a single item from the specified compendium. + */ +async function extractPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + + // Load module.json. + const system = JSON.parse(fs.readFileSync("./module.json", { encoding: "utf8" })); + + // Determine which source packs to process. + const packs = system.packs.filter(p => !packName || p.name === packName); + + for ( const packInfo of packs ) { + const dest = path.join(PACK_SRC, packInfo.name); + logger.info(`Extracting pack ${packInfo.name}`); + + const folders = {}; + const containers = {}; + await extractPack(packInfo.path, dest, { + log: false, transformEntry: e => { + if ( e._key.startsWith("!folders") ) folders[e._id] = { name: slugify(e.name), folder: e.folder }; + else if ( e.type === "container" ) containers[e._id] = { + name: slugify(e.name), container: e.system?.container, folder: e.folder + }; + return false; + } + }); + const buildPath = (collection, entry, parentKey) => { + let parent = collection[entry[parentKey]]; + entry.path = entry.name; + while ( parent ) { + entry.path = path.join(parent.name, entry.path); + parent = collection[parent[parentKey]]; + } + }; + Object.values(folders).forEach(f => buildPath(folders, f, "folder")); + Object.values(containers).forEach(c => { + buildPath(containers, c, "container"); + const folder = folders[c.folder]; + if ( folder ) c.path = path.join(folder.path, c.path); + }); + + await extractPack(packInfo.path, dest, { + log: true, transformEntry: entry => { + if ( entryName && (entryName !== entry.name.toLowerCase()) ) return false; + cleanPackEntry(entry); + }, transformName: entry => { + if ( entry._id in folders ) return path.join(folders[entry._id].path, "_folder.json"); + if ( entry._id in containers ) return path.join(containers[entry._id].path, "_container.json"); + const outputName = slugify(entry.name); + const parent = containers[entry.system?.container] ?? folders[entry.folder]; + return path.join(parent?.path ?? "", `${outputName}.json`); + } + }); + } +} + + +/** + * Standardize name format. + * @param {string} name + * @returns {string} + */ +function slugify(name) { + return name.toLowerCase().replace("'", "").replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+|-{2,}/g, "-"); +}