From ef2d7cf9bbadc125bed837cbaf9e649818221c2f Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 22 Dec 2024 00:37:06 +0100 Subject: [PATCH 01/18] chore: drop swc --- package-lock.json | 1467 ++------------------------------------------- package.json | 1 - 2 files changed, 49 insertions(+), 1419 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5156d9b..7c21034 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,6 @@ "eslint": "^9.17.0", "globals": "^15.14.0", "jest": "^29.7.0", - "swc": "^1.0.11", "ts-jest": "^29.2.4", "ts-node": "^10.9.2", "tsx": "^3.8.0", @@ -1798,26 +1797,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mole-inc/bin-wrapper": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz", - "integrity": "sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bin-check": "^4.1.0", - "bin-version-check": "^5.0.0", - "content-disposition": "^0.5.4", - "ext-name": "^5.0.0", - "file-type": "^17.1.6", - "filenamify": "^5.0.2", - "got": "^11.8.5", - "os-filter-obj": "^2.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1869,19 +1848,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@sindresorhus/merge-streams": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", @@ -1914,331 +1880,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@swc/cli": { - "version": "0.1.65", - "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.1.65.tgz", - "integrity": "sha512-4NcgsvJVHhA7trDnMmkGLLvWMHu2kSy+qHx6QwRhhJhdiYdNUrhdp+ERxen73sYtaeEOYeLJcWrQ60nzKi6rpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@mole-inc/bin-wrapper": "^8.0.1", - "commander": "^7.1.0", - "fast-glob": "^3.2.5", - "minimatch": "^9.0.3", - "semver": "^7.3.8", - "slash": "3.0.0", - "source-map": "^0.7.3" - }, - "bin": { - "spack": "bin/spack.js", - "swc": "bin/swc.js", - "swcx": "bin/swcx.js" - }, - "engines": { - "node": ">= 12.13" - }, - "peerDependencies": { - "@swc/core": "^1.2.66", - "chokidar": "^3.5.1" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@swc/cli/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@swc/cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@swc/cli/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@swc/cli/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@swc/core": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz", - "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.17" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.10.1", - "@swc/core-darwin-x64": "1.10.1", - "@swc/core-linux-arm-gnueabihf": "1.10.1", - "@swc/core-linux-arm64-gnu": "1.10.1", - "@swc/core-linux-arm64-musl": "1.10.1", - "@swc/core-linux-x64-gnu": "1.10.1", - "@swc/core-linux-x64-musl": "1.10.1", - "@swc/core-win32-arm64-msvc": "1.10.1", - "@swc/core-win32-ia32-msvc": "1.10.1", - "@swc/core-win32-x64-msvc": "1.10.1" - }, - "peerDependencies": { - "@swc/helpers": "*" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz", - "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz", - "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz", - "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz", - "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz", - "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz", - "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz", - "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz", - "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz", - "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz", - "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@swc/types": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", - "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true, - "license": "MIT" - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -2312,19 +1953,6 @@ "@babel/types": "^7.20.7" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -2342,13 +1970,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/inquirer": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz", @@ -2405,16 +2026,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -2425,16 +2036,6 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2801,27 +2402,6 @@ "node": ">= 8" } }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "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" - } - ], - "license": "MIT" - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -2942,346 +2522,72 @@ "semver": "bin/semver.js" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/bin-check": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", - "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^0.7.0", - "executable": "^4.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/bin-check/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-check/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/bin-check/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-check/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-check/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/bin-check/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/bin-check/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true, - "license": "ISC" - }, - "node_modules/bin-version": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz", - "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "find-versions": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bin-version-check": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz", - "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bin-version": "^6.0.0", - "semver": "^7.5.3", - "semver-truncate": "^3.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bin-version/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/bin-version/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bin-version/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, "engines": { - "node": ">=10.17.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/bin-version/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/bin-version/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.0.0" + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/bin-version/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/bin-version/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -3370,51 +2676,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3516,19 +2777,6 @@ "node": ">=12" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -3583,19 +2831,6 @@ "dev": true, "license": "MIT" }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3697,35 +2932,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -3758,16 +2964,6 @@ "node": ">=0.10.0" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3841,16 +3037,6 @@ "dev": true, "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -4200,19 +3386,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -4239,33 +3412,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "^1.28.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4365,24 +3511,6 @@ "node": ">=16.0.0" } }, - "node_modules/file-type": { - "version": "17.1.6", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.6.tgz", - "integrity": "sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-web-to-node-stream": "^3.0.2", - "strtok3": "^7.0.0-alpha.9", - "token-types": "^5.0.0-alpha.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -4416,37 +3544,6 @@ "node": ">=10" } }, - "node_modules/filename-reserved-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", - "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/filenamify": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-5.1.1.tgz", - "integrity": "sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^3.0.0", - "strip-outer": "^2.0.0", - "trim-repeated": "^2.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4477,22 +3574,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-versions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver-regex": "^4.0.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -4653,32 +3734,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4723,27 +3778,6 @@ "dev": true, "license": "MIT" }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/human-signals": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", @@ -4753,27 +3787,6 @@ "node": ">=18.18.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" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -6397,16 +5410,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -6481,16 +5484,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6501,16 +5494,6 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6562,19 +5545,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm-run-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", @@ -6647,39 +5617,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-filter-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", - "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arch": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6802,20 +5739,6 @@ "dev": true, "license": "MIT" }, - "node_modules/peek-readable": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz", - "integrity": "sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6836,16 +5759,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -6979,24 +5892,6 @@ "node": ">= 6" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7045,19 +5940,6 @@ ], "license": "MIT" }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -7065,38 +5947,6 @@ "dev": true, "license": "MIT" }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7128,13 +5978,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true, - "license": "MIT" - }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -7188,19 +6031,6 @@ "node": ">=10" } }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7246,27 +6076,6 @@ "tslib": "^2.1.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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" - } - ], - "license": "MIT" - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -7280,35 +6089,6 @@ "node": ">=10" } }, - "node_modules/semver-regex": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", - "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver-truncate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz", - "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7359,42 +6139,6 @@ "node": ">=8" } }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7446,16 +6190,6 @@ "node": ">=8" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -7507,16 +6241,6 @@ "node": ">=8" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", @@ -7542,37 +6266,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-outer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-2.0.0.tgz", - "integrity": "sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strtok3": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.1.1.tgz", - "integrity": "sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.1.3" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7599,17 +6292,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/swc": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/swc/-/swc-1.0.11.tgz", - "integrity": "sha512-YbG4eija7g/ajQ0lu4P2WPgKt5zCm743VgKn+buBrXXo1IETftO2r/8VdBPhv8wpTyg3CO+VU1z2wHuL4iohmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@swc/cli": "^0.1.26", - "@swc/core": "^1.2.12" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -7645,50 +6327,6 @@ "node": ">=8.0" } }, - "node_modules/token-types": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/trim-repeated": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-2.0.0.tgz", - "integrity": "sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -7964,13 +6602,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", diff --git a/package.json b/package.json index a3c0364..c22f146 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "eslint": "^9.17.0", "globals": "^15.14.0", "jest": "^29.7.0", - "swc": "^1.0.11", "ts-jest": "^29.2.4", "ts-node": "^10.9.2", "typescript": "^5.5.3", From ea63e9f5169ca614ef40521595ab0a9aad5c770c Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 22 Dec 2024 00:37:53 +0100 Subject: [PATCH 02/18] chore: improve logger xn display --- src/utils/logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/logger.ts b/src/utils/logger.ts index fcd272a..6daa572 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -17,10 +17,11 @@ const logNR = ( ) => { if (logCounts[message]) { logCounts[message]++; + const count = chalk.bold.yellow(`(x${logCounts[message]})`); process.stdout.write( ansiEscapes.cursorUp(1) + ansiEscapes.eraseLine + - type(`${message} x${logCounts[message]}`) + + type(`${message} ${count}`) + "\n", ); } else { From 1912706699fe39f26dc96a9f7239d7a1bb3d1af9 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 22 Dec 2024 00:47:26 +0100 Subject: [PATCH 03/18] feat: change logger util API --- src/commands/dispatch-dump.ts | 4 ++-- src/utils/logger.ts | 27 ++++++--------------------- src/utils/utils.ts | 5 ++++- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 7572114..008f9a5 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -46,8 +46,8 @@ const dispatch = async ({ if (lights.find(light => matchSetFile(light, flat))) { return flat; } else { - logger.infoNR( - `Skippingg ${flat.setName} seq ${flat.sequenceId} from the ASIAIR, No light matching.`, + logger.info( + `skipping ${flat.setName} (seq ${flat.sequenceId}). No light matching.`, ); } }); diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 6daa572..dac699f 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -33,37 +33,22 @@ const logNR = ( export const logger = { debug: (message: string, ...optionalParams: unknown[]) => { - console.log(debug(message), ...optionalParams); + logNR(debug, message, ...optionalParams); }, info: (message: string, ...optionalParams: unknown[]) => { - console.log(info(message), ...optionalParams); + logNR(info, message, ...optionalParams); }, success: (message: string, ...optionalParams: unknown[]) => { - console.log(success(message), ...optionalParams); + logNR(success, message, ...optionalParams); }, warning: (message: string, ...optionalParams: unknown[]) => { - console.log(warning(message), ...optionalParams); + logNR(warning, message, ...optionalParams); }, error: (message: string, ...optionalParams: unknown[]) => { - console.log(error(message), ...optionalParams); + logNR(error, message, ...optionalParams); }, errorThrow: (message: string, ...optionalParams: unknown[]) => { - console.log(error(message), ...optionalParams); - throw new Error(message); - }, - debugNR: (message: string, ...optionalParams: unknown[]) => { - logNR(debug, message, ...optionalParams); - }, - infoNR: (message: string, ...optionalParams: unknown[]) => { - logNR(info, message, ...optionalParams); - }, - successNR: (message: string, ...optionalParams: unknown[]) => { - logNR(success, message, ...optionalParams); - }, - warningNR: (message: string, ...optionalParams: unknown[]) => { - logNR(warning, message, ...optionalParams); - }, - errorNR: (message: string, ...optionalParams: unknown[]) => { logNR(error, message, ...optionalParams); + throw new Error(message); }, }; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 0359d4f..767d3d4 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -28,11 +28,14 @@ export const getFitsFromDirectory = ({ if (file.isDirectory()) { return; } + if (file.name.endsWith("_thn.jpg")) { + logger.info(`Skipping thumbnail file (xxx_thn.jpg)`); + } if ( !(file.isFile() || file.isSymbolicLink()) || !file.name.endsWith(".fit") ) { - logger.debugNR("Skipping ", file.name); + logger.info(`Skipping ${file.name}`); return; } From f8cbb8fbf223a1dbec57372fe1bca1e994a1b818 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 22 Dec 2024 16:22:00 +0100 Subject: [PATCH 04/18] feat: some good steps in the re-writing --- .swcrc | 27 ---- src/commands/dispatch-dump.ts | 262 +++++++++++++++++++++++++++++----- src/utils/types.ts | 36 ++++- src/utils/utils.ts | 2 +- tsconfig.json | 13 -- 5 files changed, 262 insertions(+), 78 deletions(-) delete mode 100644 .swcrc diff --git a/.swcrc b/.swcrc deleted file mode 100644 index a26032a..0000000 --- a/.swcrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - "exclude": "node_modules/", - "jsc": { - "parser": { - "syntax": "typescript", - "topLevelAwait": true - }, - "target": "esnext", - "baseUrl": ".", - "experimental": { - "plugins": [ - [ - "@swc/plugin-transform-imports", - { - "^(.*?)(\\.ts)$": { - "skipDefaultConversion": true, - "transform": "{{matches.[1]}}.js" - } - } - ] - ] - } - }, - "module": { - "type": "nodenext" - } -} diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 008f9a5..100106f 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -14,7 +14,12 @@ import { matchSetFile, getImageSpecFromSetName, } from "../utils/utils"; -import { FileImageSpec, LayerSet, PotoProject } from "../utils/types"; +import { + FileImageSpec, + LayerSet, + LightsFlatsMatch, + PotoProject, +} from "../utils/types"; import { POTO_JSON } from "../utils/const"; export type DispatchOptions = { @@ -38,48 +43,118 @@ const dispatch = async ({ projectDirectory, ); - const lights = inputFiles.filter(file => file.type === "Light"); + const allLights = inputFiles.filter(file => file.type === "Light"); - const matchingFlats = inputFiles - .filter(x => x.type === "Flat") - .filter(flat => { - if (lights.find(light => matchSetFile(light, flat))) { - return flat; - } else { - logger.info( - `skipping ${flat.setName} (seq ${flat.sequenceId}). No light matching.`, - ); - } - }); + const allFlatsMatchingLights = getFlatsMatchingLightsNaive( + inputFiles, + allLights, + ); - logger.info( - `Found ${matchingFlats.length} matching flats.`, - matchingFlats.map(x => x.fileName), + const lightsFlatsMatches = await matchLightsToFlats( + allFlatsMatchingLights, + allLights, ); + const layerSets: LayerSet[] = []; + + for (const lightsFlatsMatch of lightsFlatsMatches) { + const lights = allLights.filter( + light => + light.sequenceId === lightsFlatsMatch.lightSequenceId && + light.setName === lightsFlatsMatch.lightSetName, + ); + if (!lights) { + throw new Error( + `❓❓❓❗️ Light ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.lightSequenceId} not found.`, + ); + } + + const flats = allFlatsMatchingLights.filter( + flat => + flat.sequenceId === lightsFlatsMatch.flatSequenceId && + flat.setName === lightsFlatsMatch.lightSetName, + ); + if (!flats) { + throw new Error( + `❓❓❓❗️ Flat ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.flatSequenceId} not found.`, + ); + } + + const layerSetId = lightsFlatsMatch.isAdvancedMatching + ? `${lights[0].setName}__sequence-${lights[0].sequenceId}` + : lights[0].setName; + + const lightSequenceIds = new Set( + [...lights].map(light => light.sequenceId), + ); + const lightSequences: LayerSet["lightSequences"] = []; + for (const lightSequenceId of lightSequenceIds) { + const lightsOfSequence = lights.filter( + light => light.sequenceId === lightSequenceId, + ); + + const count = lightsOfSequence.length; + const integrationMs = lightsOfSequence.reduce( + (total, light) => total + light.bulbMs, + 0, + ); + lightSequences.push({ + sequenceId: lightSequenceId, + count, + integrationMinutes: integrationMs / 1000 / 60, + }); + } + + const lightTotalIntegrationMs = lights.reduce( + (total, light) => total + light.bulbMs, + 0, + ); + + const layerSet = { + layerSetId, + filter: lights[0].filter, + + lights, + lightSequences, + lightTotalCount: lights.length, + lightTotalIntegrationMinutes: lightTotalIntegrationMs / 1000 / 60, + + flats, + flatSet: flats[0].setName, + flatSequenceId: flats[0].sequenceId, + flatsCount: flats.length, + } as LayerSet; + + layerSets.push(layerSet); + } + + // TODO. Add biases and darks to the layerSets. + + return; + const importedLightsFlatsFiles: FileImageSpec[] = []; const importedDarksBiasesFiles: FileImageSpec[] = []; // Dispatch the ASIAIR Lights files to the project directory. - const lightFiles = inputFiles.filter(file => file.type === "Light"); - lightFiles.forEach(file => { - copyFileToProject(file); - importedLightsFlatsFiles.push(file); - }); + // const lightFiles = inputFiles.filter(file => file.type === "Light"); + // lightFiles.forEach(file => { + // copyFileToProject(file); + // importedLightsFlatsFiles.push(file); + // }); // Dispatch associated flats. - inputFiles - .filter(x => x.type === "Flat") - .forEach(file => { - if (lightFiles.find(f => matchSetFile(f, file))) { - copyFileToProject(file); - importedLightsFlatsFiles.push(file); - } else { - logger.info( - `Skipping ${file.fileName} from the ASIAIR, No light matching.`, - ); - } - }); + // inputFiles + // .filter(x => x.type === "Flat") + // .forEach(file => { + // if (lightFiles.find(f => matchSetFile(f, file))) { + // copyFileToProject(file); + // importedLightsFlatsFiles.push(file); + // } else { + // logger.info( + // `Skipping ${file.fileName} from the ASIAIR, No light matching.`, + // ); + // } + // }); // Search for the darks and biases we need to copy. const bankFiles = getFitsFromDirectory({ @@ -105,7 +180,7 @@ const dispatch = async ({ const darkFiles = files.filter(file => file.type === "Dark"); const biasFiles = files.filter(file => file.type === "Bias"); - const layerSets = [ + const layerSetsOld = [ ...new Set( files.filter(file => file.type === "Light").map(file => file.setName), ), @@ -235,3 +310,122 @@ const getAllFitsInInputDirectories = ( logger.info(`Found ${files.length} files to dispatch.`); return files; }; + +/** + * Naive matching of flats with lights. + * Sufficient enough to skip the flats that do not have a matching light at all. + */ +const getFlatsMatchingLightsNaive = ( + inputFiles: FileImageSpec[], + lights: FileImageSpec[], +): FileImageSpec[] => { + const matchingFlats = inputFiles + .filter(x => x.type === "Flat") + .filter(flat => { + if (lights.find(light => matchSetFile(light, flat))) { + return flat; + } else { + logger.warning( + `Found ${flat.setName} (seq ${flat.sequenceId}) but light matching. Skipping 🤔.`, + ); + } + }); + + const sequences = [...new Set(matchingFlats.map(file => file.sequenceId))]; + logger.info( + `Found ${matchingFlats.length} (${sequences.length} sequences) matching flats.`, + ); + + return matchingFlats; +}; + +/** + * Process the light and flat matching. + * If multiple sequences are found for a flat, ask the user to select the flat sequence to use for each light sequence. + */ +const matchLightsToFlats = async ( + matchingFlats: FileImageSpec[], + lights: FileImageSpec[], +): Promise => { + const flatSets = [...new Set(matchingFlats.map(file => file.setName))]; + + const LightFlatMatches: LightsFlatsMatch[] = []; + + for (const flatSet of flatSets) { + const flatSequenceIds = [ + ...new Set( + matchingFlats + .filter(flat => flat.setName === flatSet) + .map(flat => flat.sequenceId), + ), + ]; + if (flatSequenceIds.length === 0) { + throw new Error(`❓❓❓❗️ No sequences found for flat ${flatSet}.`); + } + + if (flatSequenceIds.length === 1) { + LightFlatMatches.push({ + lightSequenceId: lights[0].sequenceId, + lightSetName: lights[0].setName, + flatSequenceId: flatSequenceIds[0], + isAdvancedMatching: false, + }); + continue; + } + + logger.info( + `Multiple sequences found for flat set ${flatSet}: ${flatSequenceIds.join( + ", ", + )}`, + ); + logger.info( + "👉 We need to accurately link each light sequence to their respective flat sequence.", + ); + + const lightsConcerned = [ + ...new Set( + lights + .filter(light => + matchSetFile(light, getImageSpecFromSetName(flatSet)), + ) + .map(light => ({ + setName: light.setName, + sequenceId: light.sequenceId, + })), + ), + ].sort((a, b) => { + // Sort by setName first. + if (a.setName !== b.setName) { + return a.setName.localeCompare(b.setName); + } + // Then by sequenceId. + return a.sequenceId.localeCompare(b.sequenceId); + }); + + for (const lightConcerned of lightsConcerned) { + // Ask the user to select the flat sequence to use. + const enquirer = new Enquirer(); + const response = (await enquirer.prompt({ + type: "select", + name: "selectedFlatSequence", + message: `Select the flat sequence to use for the lights sequence ${lightConcerned.setName} ${lightConcerned.sequenceId}.`, + choices: flatSequenceIds, + })) as { selectedFlatSequence: string }; + LightFlatMatches.push({ + lightSetName: lightConcerned.setName, + lightSequenceId: lightConcerned.sequenceId, + flatSequenceId: response.selectedFlatSequence, + isAdvancedMatching: true, + }); + } + } + + logger.info("👉 Light -> Flat matching summary:"); + for (const pair of LightFlatMatches) { + logger.info( + ` Light set ${pair.lightSetName}, sequence ${pair.lightSequenceId} will use flat sequence ${pair.flatSequenceId}.`, + ); + } + + return LightFlatMatches; +}; diff --git a/src/utils/types.ts b/src/utils/types.ts index c9fdd9a..89e426c 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -14,6 +14,7 @@ export type ImageSpec = { * Bulb duration: 60.0s, 810.0ms, etc... */ bulb: string; + bulbMs: number; // TODO. Compute this. /** * Binning: Bin1, Bin2, Bin 3 & Bin 4. */ @@ -82,12 +83,31 @@ export type FileImageSpec = ImageSpec & { * Each set has unique filter + exposure + gain + bin combination. */ export type LayerSet = { - filter: string; + /** + * `Flat_520.0ms_Bin1_O_gain0` format. + * `Flat_520.0ms_Bin1_O_gain0__sequence-01` format for advanced light-flats matching. + */ + layerSetId: string; + + /** + * Filter: L, R, G, B, H... As Specified in the ASIAIR zwo wheel. + * Optional. + */ + filter: string | null; - lightSet: string; - lightsCount: number; + /** + * Sequences of lights used. + */ + lightSequences: { + sequenceId: string; + count: number; + integrationMinutes: number; + }[]; + lightTotalCount: number; + lightTotalIntegrationMinutes: number; flatSet: string; + flatSequenceId: string; flatsCount: number; darkSet: string; @@ -107,3 +127,13 @@ export type PotoProject = { potoVersion: string; layerSets: LayerSet[]; }; + +export type LightsFlatsMatch = { + lightSetName: string; + lightSequenceId: string; + flatSequenceId: string; + /** + * True if the light was manually matched because several flats sequences were available. + */ + isAdvancedMatching: boolean; +}; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 767d3d4..f563b52 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -188,7 +188,7 @@ export const copyFileToProject = (file: FileImageSpec) => { * - Light with Flat (allowing for different gain). * - Flat with Bias. */ -export const matchSetFile = (A: FileImageSpec, B: FileImageSpec): boolean => { +export const matchSetFile = (A: ImageSpec, B: ImageSpec): boolean => { if (A.type === "Light" && B.type === "Dark") { return ( // TODO. Filter based on the temperature. diff --git a/tsconfig.json b/tsconfig.json index 244a211..285a49f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,16 +16,3 @@ "exclude": ["node_modules"], "include": ["src/**/*.ts", "bin/*.ts"] } - -// { -// "compilerOptions": { -// "target": "ES2023", -// "module": "ESNext", -// "esModuleInterop": true, -// "moduleResolution": "node", -// "outDir": "./dist", -// "strict": true, -// "types": ["node", "jest"] -// }, -// "include": ["src/**/*"] -// } From d6b4a05ba5aad48170019dbabb47061b5d211adf Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sat, 28 Dec 2024 21:55:48 +0100 Subject: [PATCH 05/18] feat: some progress to the refacto but bugged so far --- src/commands/dispatch-dump.ts | 87 ++++++++++++++++++++++++----------- src/tests/fixtures.ts | 4 +- src/utils/logger.ts | 31 ++++++++++--- src/utils/types.ts | 3 ++ 4 files changed, 89 insertions(+), 36 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 100106f..2101ec8 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -7,7 +7,7 @@ import fs from "fs"; import Enquirer from "enquirer"; -import { logger } from "../utils/logger"; +import { formatMessage, logger } from "../utils/logger"; import { copyFileToProject, getFitsFromDirectory, @@ -70,9 +70,7 @@ const dispatch = async ({ } const flats = allFlatsMatchingLights.filter( - flat => - flat.sequenceId === lightsFlatsMatch.flatSequenceId && - flat.setName === lightsFlatsMatch.lightSetName, + flat => flat.sequenceId === lightsFlatsMatch.flatSequenceId, ); if (!flats) { throw new Error( @@ -80,6 +78,15 @@ const dispatch = async ({ ); } + logger.error( + "lights", + lights.map(x => x.fileName), + ); + logger.error( + "flats", + flats.map(x => x.fileName), + ); + const layerSetId = lightsFlatsMatch.isAdvancedMatching ? `${lights[0].setName}__sequence-${lights[0].sequenceId}` : lights[0].setName; @@ -128,6 +135,18 @@ const dispatch = async ({ layerSets.push(layerSet); } + const debug = layerSets.map(x => { + return { + layerSetId: x.layerSetId, + lightTotalCount: x.lightTotalCount, + lightsStr: x.lights.map(x => x.fileName).join(", "), + flatsCount: x.flatsCount, + flatsStr: x.flats.map(x => x.fileName).join(", "), + }; + }); + + logger.success("debug", debug); + // TODO. Add biases and darks to the layerSets. return; @@ -326,7 +345,7 @@ const getFlatsMatchingLightsNaive = ( return flat; } else { logger.warning( - `Found ${flat.setName} (seq ${flat.sequenceId}) but light matching. Skipping 🤔.`, + `${flat.setName} (seq ${flat.sequenceId}) has no light matching 🤔. Skipping.`, ); } }); @@ -352,31 +371,34 @@ const matchLightsToFlats = async ( const LightFlatMatches: LightsFlatsMatch[] = []; for (const flatSet of flatSets) { - const flatSequenceIds = [ + const flatSetNameSequenceIds = [ ...new Set( matchingFlats .filter(flat => flat.setName === flatSet) - .map(flat => flat.sequenceId), + .map(flat => `${flat.setName}__${flat.sequenceId}`), ), ]; - if (flatSequenceIds.length === 0) { + if (flatSetNameSequenceIds.length === 0) { throw new Error(`❓❓❓❗️ No sequences found for flat ${flatSet}.`); } - if (flatSequenceIds.length === 1) { + if (flatSetNameSequenceIds.length === 1) { LightFlatMatches.push({ lightSequenceId: lights[0].sequenceId, lightSetName: lights[0].setName, - flatSequenceId: flatSequenceIds[0], + + flatSetName: flatSetNameSequenceIds[0].split("__")[0], + flatSequenceId: flatSetNameSequenceIds[0].split("__")[1], + isAdvancedMatching: false, }); continue; } logger.info( - `Multiple sequences found for flat set ${flatSet}: ${flatSequenceIds.join( - ", ", - )}`, + `Multiple sequences found for flat set ${flatSet}:\n${flatSetNameSequenceIds + .map(seq => `- ${seq}`) + .join("\n")}`, ); logger.info( "👉 We need to accurately link each light sequence to their respective flat sequence.", @@ -391,30 +413,39 @@ const matchLightsToFlats = async ( .map(light => ({ setName: light.setName, sequenceId: light.sequenceId, - })), + })) + .sort((a, b) => { + return a.sequenceId.localeCompare(b.sequenceId); + }) + .map(light => `${light.setName}__${light.sequenceId}`), ), - ].sort((a, b) => { - // Sort by setName first. - if (a.setName !== b.setName) { - return a.setName.localeCompare(b.setName); - } - // Then by sequenceId. - return a.sequenceId.localeCompare(b.sequenceId); - }); + ]; for (const lightConcerned of lightsConcerned) { + const lightConcernedSetName = lightConcerned.split("__")[0]; + const lightConcernedSequenceId = lightConcerned.split("__")[1]; + // Ask the user to select the flat sequence to use. const enquirer = new Enquirer(); const response = (await enquirer.prompt({ type: "select", name: "selectedFlatSequence", - message: `Select the flat sequence to use for the lights sequence ${lightConcerned.setName} ${lightConcerned.sequenceId}.`, - choices: flatSequenceIds, + message: formatMessage( + `Select 👇 the flat sequence to use for ${lightConcernedSetName} ${lightConcernedSequenceId}:)`, + ), + choices: flatSetNameSequenceIds.map(x => ({ + name: x, + message: formatMessage(x), + })), })) as { selectedFlatSequence: string }; + LightFlatMatches.push({ - lightSetName: lightConcerned.setName, - lightSequenceId: lightConcerned.sequenceId, - flatSequenceId: response.selectedFlatSequence, + lightSetName: lightConcernedSetName, + lightSequenceId: lightConcernedSequenceId, + + flatSetName: response.selectedFlatSequence.split("__")[0], + flatSequenceId: response.selectedFlatSequence.split("__")[1], + isAdvancedMatching: true, }); } @@ -423,7 +454,7 @@ const matchLightsToFlats = async ( logger.info("👉 Light -> Flat matching summary:"); for (const pair of LightFlatMatches) { logger.info( - ` Light set ${pair.lightSetName}, sequence ${pair.lightSequenceId} will use flat sequence ${pair.flatSequenceId}.`, + ` Light set ${pair.lightSetName} (seq ${pair.lightSequenceId}) will use \n flat set ${pair.flatSetName} (seq ${pair.flatSequenceId}).`, ); } diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts index bb57f98..fb041ef 100644 --- a/src/tests/fixtures.ts +++ b/src/tests/fixtures.ts @@ -78,7 +78,7 @@ const dataset_1 = [ // Flats not matching any sets. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin2_S_gain100_20240511-094304_-10.5C_0001.fit", // Another bin. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_O_gain100_20240511-094305_-10.0C_0002.fit", // Another Filter. - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094304_-10.5C_0001.fot", // Not a fit. + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094304_-10.5C_0001.fot", // Not a fit file based on extension. // Darks matching set A. "bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", @@ -106,7 +106,7 @@ const dataset_1 = [ "bank/Bias/Bias_1.0ms_Bin1_gain0_20230910-101133_-9.8C_0001.fit", // Won't match set B, because flat gain is 100. "bank/Bias/Bias_1.0ms_Bin2_gain100_20230910-101133_-9.8C_0002.fit", // Another bin. - // thumbnails. + // Thumbnails from ASIAIR. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001_thn.jpg", "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002_thn.jpg", "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003_thn.jpg", diff --git a/src/utils/logger.ts b/src/utils/logger.ts index dac699f..3b0ff51 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -31,24 +31,43 @@ const logNR = ( } }; +export const formatMessage = (message: string) => { + return message + .replace(/(Light|Flat|Dark|Bias)_/g, chalk.hex("#001f3f")("$1_")) // Color image type. + .replace(/(\d+\.\d(ms|s))/g, chalk.hex("#003f5c")("$1")) // Color bulb. + .replace(/(Bin\d)/g, chalk.hex("#2f4b7c")("$1")) // Color binning. + .replace(/(_[A-Za-z]_)/g, chalk.hex("#665191")("$1")) // Color filter. + .replace(/(gain\d+)/g, chalk.hex("#a05195")("$1")) // Color gain. + .replace( + /(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})/g, + (_, y, m, d, h, min, s) => + `${chalk.hex("#d45087")(y)}${chalk.hex("#f95d6a")(m)}${chalk.hex( + "#ff7c43", + )(d)}-${chalk.hex("#ffa600")(h)}${chalk.hex("#ffb000")(min)}${chalk.hex( + "#ffc000", + )(s)}`, + ) // Adjusted colors for date and time. + .replace(/_thn.jpg/g, chalk.bgHex("#ff0000")("_thn.jpg")); // Color thumbnail. +}; + export const logger = { debug: (message: string, ...optionalParams: unknown[]) => { - logNR(debug, message, ...optionalParams); + logNR(debug, formatMessage(message), ...optionalParams); }, info: (message: string, ...optionalParams: unknown[]) => { - logNR(info, message, ...optionalParams); + logNR(info, formatMessage(message), ...optionalParams); }, success: (message: string, ...optionalParams: unknown[]) => { - logNR(success, message, ...optionalParams); + logNR(success, formatMessage(message), ...optionalParams); }, warning: (message: string, ...optionalParams: unknown[]) => { - logNR(warning, message, ...optionalParams); + logNR(warning, formatMessage(message), ...optionalParams); }, error: (message: string, ...optionalParams: unknown[]) => { - logNR(error, message, ...optionalParams); + logNR(error, formatMessage(message), ...optionalParams); }, errorThrow: (message: string, ...optionalParams: unknown[]) => { - logNR(error, message, ...optionalParams); + logNR(error, formatMessage(message), ...optionalParams); throw new Error(message); }, }; diff --git a/src/utils/types.ts b/src/utils/types.ts index 89e426c..6bafb1b 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -131,7 +131,10 @@ export type PotoProject = { export type LightsFlatsMatch = { lightSetName: string; lightSequenceId: string; + + flatSetName: string; flatSequenceId: string; + /** * True if the light was manually matched because several flats sequences were available. */ From 68f7ab06fcc8fa61ca4e1caf9f9ac46fa28a7dab Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sat, 28 Dec 2024 23:57:23 +0100 Subject: [PATCH 06/18] feat: closing light-flat matching, huge UX improvements --- README.md | 5 +- eslint.config.mjs | 1 + src/commands/dispatch-dump.ts | 263 +++++++++++++++++++++------------- src/tests/fixtures.ts | 38 ++--- src/utils/logger.ts | 51 +++++-- src/utils/types.ts | 2 +- src/utils/utils.ts | 14 +- 7 files changed, 235 insertions(+), 139 deletions(-) diff --git a/README.md b/README.md index 0e35d92..3e57795 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Automatization around Siril () and ASIAIR for deep sky astro **Poto-Siril is a CLI tool to automate the pre-processing of astrophotography images on top of Siril.** -Poto-Siril's primary goal is to **overcome the repetitive** work when pre-processing multiple layers before compositing a (L)RGB image (e.g. narrowband filters with monochrome camera or color camera with dual-band filters). It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follows the same [naming convention and directory structure](#poto-siril-project-architecture). +Poto-Siril's primary goal is to **overcome the repetitive and tedious** work when pre-processing multiple layers before compositing a (L)RGB image (e.g. narrowband filters with monochrome camera or color camera with dual-band filters). It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follows the same [naming convention and directory structure](#poto-siril-project-architecture). ### Workflow 🚀 @@ -18,6 +18,9 @@ Poto-Siril's primary goal is to **overcome the repetitive** work when pre-proces Import one or several night sessions (lights and flats from `autorun` or `plan` mode with ASIAIR) and automatically pick the darks and bias from the bank folder (matching bulb, gain, binning, ...). A summary resumes the light sequence(s) and the calibration files associated. ![dispatch](./img/poto-siril_dispatch.png) +- **Complex Light - Flat matching** + The project consists of multiple night sessions where the flats changed over the time? e.g., a significant date gap between shooting sessions and the lights aren't coming with the same collimation and/or dust in the optical train. + Poto-Siril will auto-detect that and help you to associate the right flats to the right lights. - **Multi-layers project structure** The imported files ☝️ are organized by filters and light sets (bulb, gain & binning, if there's multiple combinations). Each light set will map to a light sequence in Siril that you preprocess separately. 👉 You can easily work on a LRGB or LRGBHaOIIISII project. diff --git a/eslint.config.mjs b/eslint.config.mjs index 97313ef..6a1ec22 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -21,6 +21,7 @@ export default [ ...compat.extends( "eslint:recommended", "plugin:@typescript-eslint/recommended", + "prettier", ), { plugins: { diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 2101ec8..92f5aba 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -37,6 +37,8 @@ const dispatch = async ({ }: DispatchOptions) => { await ensureProjectDirectoryExists(projectDirectory); + logger.step("Reading input directories"); + const inputFiles = getAllFitsInInputDirectories( asiAirDirectory, shootingMode, @@ -45,95 +47,27 @@ const dispatch = async ({ const allLights = inputFiles.filter(file => file.type === "Light"); + logger.step("Matching lights and flats (early stage)"); + const allFlatsMatchingLights = getFlatsMatchingLightsNaive( inputFiles, allLights, ); + logger.step("Matching lights and flats (final stage)"); + const lightsFlatsMatches = await matchLightsToFlats( allFlatsMatchingLights, allLights, ); - const layerSets: LayerSet[] = []; - - for (const lightsFlatsMatch of lightsFlatsMatches) { - const lights = allLights.filter( - light => - light.sequenceId === lightsFlatsMatch.lightSequenceId && - light.setName === lightsFlatsMatch.lightSetName, - ); - if (!lights) { - throw new Error( - `❓❓❓❗️ Light ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.lightSequenceId} not found.`, - ); - } - - const flats = allFlatsMatchingLights.filter( - flat => flat.sequenceId === lightsFlatsMatch.flatSequenceId, - ); - if (!flats) { - throw new Error( - `❓❓❓❗️ Flat ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.flatSequenceId} not found.`, - ); - } - - logger.error( - "lights", - lights.map(x => x.fileName), - ); - logger.error( - "flats", - flats.map(x => x.fileName), - ); - - const layerSetId = lightsFlatsMatch.isAdvancedMatching - ? `${lights[0].setName}__sequence-${lights[0].sequenceId}` - : lights[0].setName; - - const lightSequenceIds = new Set( - [...lights].map(light => light.sequenceId), - ); - const lightSequences: LayerSet["lightSequences"] = []; - for (const lightSequenceId of lightSequenceIds) { - const lightsOfSequence = lights.filter( - light => light.sequenceId === lightSequenceId, - ); - - const count = lightsOfSequence.length; - const integrationMs = lightsOfSequence.reduce( - (total, light) => total + light.bulbMs, - 0, - ); - lightSequences.push({ - sequenceId: lightSequenceId, - count, - integrationMinutes: integrationMs / 1000 / 60, - }); - } - - const lightTotalIntegrationMs = lights.reduce( - (total, light) => total + light.bulbMs, - 0, - ); - - const layerSet = { - layerSetId, - filter: lights[0].filter, - - lights, - lightSequences, - lightTotalCount: lights.length, - lightTotalIntegrationMinutes: lightTotalIntegrationMs / 1000 / 60, - - flats, - flatSet: flats[0].setName, - flatSequenceId: flats[0].sequenceId, - flatsCount: flats.length, - } as LayerSet; + const layerSets: LayerSet[] = initLayerSetsWithLightsnFlats( + lightsFlatsMatches, + allLights, + allFlatsMatchingLights, + ); - layerSets.push(layerSet); - } + logger.step("Debug"); const debug = layerSets.map(x => { return { @@ -147,6 +81,7 @@ const dispatch = async ({ logger.success("debug", debug); + // TODO. custom sort if LRGBSHO filter names to ease reading. // TODO. Add biases and darks to the layerSets. return; @@ -297,6 +232,8 @@ export default dispatch; /** * Ensure that the project directory exists. * If it does not exist, ask the user if they want to create it. + * + * @param projectDirectory - The directory of the current project. */ const ensureProjectDirectoryExists = async (projectDirectory: string) => { if (!fs.existsSync(projectDirectory)) { @@ -315,6 +252,15 @@ const ensureProjectDirectoryExists = async (projectDirectory: string) => { // TODO. Decouple from ASIAIR. Just warn if files both found in Autorun and Plan, and ask the user to probably review the input files first. // TODO. Allow multiple directories in input. + +/** + * Retrieve all FITS files from the input directories. + * + * @param asiAirDirectory - The directory where ASIAIR files are stored. + * @param shootingMode - The shooting mode, either "autorun" or "plan". + * @param projectDirectory - The directory of the current project. + * @returns An array of FileImageSpec objects representing the FITS files. + */ const getAllFitsInInputDirectories = ( asiAirDirectory: string, shootingMode: string, @@ -333,26 +279,33 @@ const getAllFitsInInputDirectories = ( /** * Naive matching of flats with lights. * Sufficient enough to skip the flats that do not have a matching light at all. + * + * @param inputFiles - The input files to process. Searching for the flats in this list. + * @param lights - The lights to match with the flats. */ const getFlatsMatchingLightsNaive = ( inputFiles: FileImageSpec[], lights: FileImageSpec[], ): FileImageSpec[] => { + const notMatchedFlats: string[] = []; const matchingFlats = inputFiles .filter(x => x.type === "Flat") .filter(flat => { if (lights.find(light => matchSetFile(light, flat))) { return flat; } else { - logger.warning( - `${flat.setName} (seq ${flat.sequenceId}) has no light matching 🤔. Skipping.`, + notMatchedFlats.push( + `No matching light for ${flat.setName} (seq ${flat.sequenceId}). Skipping.`, ); } }); const sequences = [...new Set(matchingFlats.map(file => file.sequenceId))]; + for (const skip of [...new Set(notMatchedFlats)]) { + logger.warning(skip); + } logger.info( - `Found ${matchingFlats.length} (${sequences.length} sequences) matching flats.`, + `Found ${matchingFlats.length} matching flats (${sequences.length} sequences).`, ); return matchingFlats; @@ -361,6 +314,10 @@ const getFlatsMatchingLightsNaive = ( /** * Process the light and flat matching. * If multiple sequences are found for a flat, ask the user to select the flat sequence to use for each light sequence. + * NOTE. We expect that all flats have a matching light at this point, thanks to the `getFlatsMatchingLightsNaive` function. + * + * @param matchingFlats - The flats that have a matching light. + * @param lights - The lights to match with the flats. */ const matchLightsToFlats = async ( matchingFlats: FileImageSpec[], @@ -383,27 +340,49 @@ const matchLightsToFlats = async ( } if (flatSetNameSequenceIds.length === 1) { - LightFlatMatches.push({ - lightSequenceId: lights[0].sequenceId, - lightSetName: lights[0].setName, + // Auto match the flat to the light. Nothing to ask from the user. + const flatSetNameSequenceId = flatSetNameSequenceIds[0]; + const matchingLights = lights.filter(light => + matchSetFile(light, getImageSpecFromSetName(flatSet)), + ); + const matchingLightSetNameSequenceIds = [ + ...new Set( + matchingLights.map(light => `${light.setName}__${light.sequenceId}`), + ), + ]; - flatSetName: flatSetNameSequenceIds[0].split("__")[0], - flatSequenceId: flatSetNameSequenceIds[0].split("__")[1], + for (const lightSetSequence of matchingLightSetNameSequenceIds) { + LightFlatMatches.push({ + lightSetName: lightSetSequence.split("__")[0], + lightSequenceId: lightSetSequence.split("__")[1], - isAdvancedMatching: false, - }); + flatSetName: flatSetNameSequenceId.split("__")[0], + flatSequenceId: flatSetNameSequenceId.split("__")[1], + + isManualMatch: false, + }); + } continue; } + logger.info(`🤚 Several sequences found for flat set ${flatSet}:`); logger.info( - `Multiple sequences found for flat set ${flatSet}:\n${flatSetNameSequenceIds - .map(seq => `- ${seq}`) + `${flatSetNameSequenceIds + .map(x => ` - ${x.split("__")[1]}`) .join("\n")}`, ); + logger.debug( + "We assume that multiple sequences of the same flat set indicate multiple night sessions where the flats had to be re-shot in between (e.g., a significant date gap between shooting sessions and the lights were not collected with the same collimation and/or same dust in the optical train).", + ); logger.info( - "👉 We need to accurately link each light sequence to their respective flat sequence.", + "We will ask you to tag each concerned light sequence to the right flat sequence.", ); + // TODO. Provide a smart way to match the sequences. + // E.G Flats always before / after lights. + // Propose the choice manual / auto (light before flats) / auto (flats before lights). + // show the summary for auto, and ask if needs to be reviewed in manual mode. + const lightsConcerned = [ ...new Set( lights @@ -431,11 +410,11 @@ const matchLightsToFlats = async ( type: "select", name: "selectedFlatSequence", message: formatMessage( - `Select 👇 the flat sequence to use for ${lightConcernedSetName} ${lightConcernedSequenceId}:)`, + `${lightConcernedSetName} ${lightConcernedSequenceId} will use`, ), choices: flatSetNameSequenceIds.map(x => ({ name: x, - message: formatMessage(x), + message: formatMessage(x.replace("__", " ")), })), })) as { selectedFlatSequence: string }; @@ -446,17 +425,107 @@ const matchLightsToFlats = async ( flatSetName: response.selectedFlatSequence.split("__")[0], flatSequenceId: response.selectedFlatSequence.split("__")[1], - isAdvancedMatching: true, + isManualMatch: true, }); } } - logger.info("👉 Light -> Flat matching summary:"); + logger.space(); + logger.info("👉 Light - Flat matching summary:"); for (const pair of LightFlatMatches) { - logger.info( - ` Light set ${pair.lightSetName} (seq ${pair.lightSequenceId}) will use \n flat set ${pair.flatSetName} (seq ${pair.flatSequenceId}).`, + logger.debug( + ` - ${pair.lightSetName} ${pair.lightSequenceId} 🏹 ${pair.flatSetName} ${pair.flatSequenceId}`, ); } return LightFlatMatches; }; + +/** + * Initialize the layer sets with lights and flats matches. + * + * @param lightsFlatsMatches - The lights and flats matches. + * @param allLights - All the lights. + * @param allFlatsMatchingLights - All the flats matching lights. + */ +const initLayerSetsWithLightsnFlats = ( + lightsFlatsMatches: LightsFlatsMatch[], + allLights: FileImageSpec[], + allFlatsMatchingLights: FileImageSpec[], +) => { + const layerSets: LayerSet[] = []; + + for (const lightsFlatsMatch of lightsFlatsMatches) { + const lights = lightsFlatsMatch.isManualMatch + ? allLights.filter( + light => + light.sequenceId === lightsFlatsMatch.lightSequenceId && + light.setName === lightsFlatsMatch.lightSetName, + ) + : allLights.filter( + light => light.setName === lightsFlatsMatch.lightSetName, + ); + if (!lights) { + throw new Error( + `❓❓❓❗️ Light ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.lightSequenceId} not found.`, + ); + } + + const flats = allFlatsMatchingLights.filter( + flat => flat.sequenceId === lightsFlatsMatch.flatSequenceId, + ); + if (!flats) { + throw new Error( + `❓❓❓❗️ Flat ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.flatSequenceId} not found.`, + ); + } + + const layerSetId = lightsFlatsMatch.isManualMatch + ? `${lights[0].setName}__sequence-${lights[0].sequenceId}` + : lights[0].setName; + + const lightSequenceIds = new Set( + [...lights].map(light => light.sequenceId), + ); + const lightSequences: LayerSet["lightSequences"] = []; + for (const lightSequenceId of lightSequenceIds) { + const lightsOfSequence = lights.filter( + light => light.sequenceId === lightSequenceId, + ); + + const count = lightsOfSequence.length; + const integrationMs = lightsOfSequence.reduce( + (total, light) => total + light.bulbMs, + 0, + ); + lightSequences.push({ + sequenceId: lightSequenceId, + count, + integrationMinutes: integrationMs / 1000 / 60, + }); + } + + const lightTotalIntegrationMs = lights.reduce( + (total, light) => total + light.bulbMs, + 0, + ); + + const layerSet = { + layerSetId, + filter: lights[0].filter, + + lights, + lightSequences, + lightTotalCount: lights.length, + lightTotalIntegrationMinutes: lightTotalIntegrationMs / 1000 / 60, + + flats, + flatSet: flats[0].setName, + flatSequenceId: flats[0].sequenceId, + flatsCount: flats.length, + } as LayerSet; + + layerSets.push(layerSet); + } + return layerSets; +}; diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts index fb041ef..0935d38 100644 --- a/src/tests/fixtures.ts +++ b/src/tests/fixtures.ts @@ -1,9 +1,11 @@ import path from "path"; import fs from "fs"; +import { logger } from "src/utils/logger"; const tmpDir = "tmp"; export const spawnMockedDatasetToFs_dataset_1 = () => { + logger.dev("Creating ./tmp directory with dataset_1."); return spawnMockedDatasetToFs(dataset_1); }; @@ -32,8 +34,6 @@ const spawnMockedDatasetToFs = ( const bankDirectory = path.join(tmpDir, "bank"); const projectDirectory = path.join(tmpDir, "project"); - console.log("Creating ./tmp directory"); - return { directory: tmpDir, asiAirDirectory, @@ -50,9 +50,9 @@ const spawnMockedDatasetToFs = ( */ const dataset_1 = [ // Lights set A (60.0s_Bin1_S_gain100). - "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit", - "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit", - "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit", + "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit", + "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit", + "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit", // Lights set B (60.0s_Bin1_H_gain0). "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_H_gain0_20240625-010850_-10.1C_0001.fit", @@ -60,7 +60,7 @@ const dataset_1 = [ "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_H_gain0_20240625-010852_-10.1C_0003.fit", // Lights set C (120.0s_Bin1_S_gain0). - "asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit", + "asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit", // Flats matching set A. Flats matching set C. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", // Sequence that aims to match the lights set A (collimation of that day). @@ -72,13 +72,13 @@ const dataset_1 = [ // Flats matching set B. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001.fit", // Gain 100, but can still matching with lights gain 0! - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit", - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit", + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit", + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit", // Flats not matching any sets. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin2_S_gain100_20240511-094304_-10.5C_0001.fit", // Another bin. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_O_gain100_20240511-094305_-10.0C_0002.fit", // Another Filter. - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094304_-10.5C_0001.fot", // Not a fit file based on extension. + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094306_-10.5C_0001.fot", // Not a fit file based on extension. // Darks matching set A. "bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", @@ -89,25 +89,25 @@ const dataset_1 = [ "bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", // Darks matching set C. - "bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit", + "bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit", // Darks not matching any sets. - "bank/Darks/Dark_300.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", // Another bulb. - "bank/Darks/Dark_60.0s_Bin2_L_gain100_20240308-155722_-10.0C_0001.fit", // Another bin. - "bank/Darks/Dark_60.0s_Bin1_L_gain50_20240308-155722_-10.0C_0001.fit", // Another gain. + "bank/Darks/Dark_300.0s_Bin1_L_gain100_20240308-155724_-10.0C_0001.fit", // Another bulb. + "bank/Darks/Dark_60.0s_Bin2_L_gain100_20240308-155725_-10.0C_0001.fit", // Another bin. + "bank/Darks/Dark_60.0s_Bin1_L_gain50_20240308-155726_-10.0C_0001.fit", // Another gain. // Biases matching set A. Biases matching set C. // Biases matching set B. Matching with Flat of gain 100, despite lights being gain 0. - "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", - "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", + "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", // Biases not matching any sets. - "bank/Bias/Bias_1.0ms_Bin1_gain0_20230910-101133_-9.8C_0001.fit", // Won't match set B, because flat gain is 100. - "bank/Bias/Bias_1.0ms_Bin2_gain100_20230910-101133_-9.8C_0002.fit", // Another bin. + "bank/Bias/Bias_1.0ms_Bin1_gain0_20230910-101141_-9.8C_0001.fit", // Won't match set B, because flat gain is 100. + "bank/Bias/Bias_1.0ms_Bin2_gain100_20230910-101142_-9.8C_0002.fit", // Another bin. // Thumbnails from ASIAIR. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001_thn.jpg", - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002_thn.jpg", - "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003_thn.jpg", + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002_thn.jpg", + "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003_thn.jpg", ]; diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 3b0ff51..7de3efb 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -1,7 +1,7 @@ import chalk from "chalk"; import ansiEscapes from "ansi-escapes"; -const debug = chalk.gray; +const debug = chalk.gray.italic; const info = chalk.blue; const success = chalk.bold.green; const warning = chalk.bold.yellow; @@ -10,25 +10,33 @@ const error = chalk.bold.red; const logCounts: { [key: string]: number } = {}; const lastMessages: { [key: string]: string } = {}; +const log = ( + type: (message: string) => string, + message: string, + ...optionalParams: unknown[] +) => { + console.log(type(message), ...optionalParams); +}; + const logNR = ( type: (message: string) => string, message: string, ...optionalParams: unknown[] ) => { - if (logCounts[message]) { - logCounts[message]++; - const count = chalk.bold.yellow(`(x${logCounts[message]})`); - process.stdout.write( - ansiEscapes.cursorUp(1) + - ansiEscapes.eraseLine + - type(`${message} ${count}`) + - "\n", - ); - } else { - logCounts[message] = 1; - lastMessages[message] = type(message); - console.log(type(message), ...optionalParams); - } + // if (logCounts[message]) { + // logCounts[message]++; + // const count = chalk.bold.yellow(`(x${logCounts[message]})`); + // process.stdout.write( + // ansiEscapes.cursorUp(1) + + // ansiEscapes.eraseLine + + // type(`${message} ${count}`) + + // "\n", + // ); + // } else { + logCounts[message] = 1; + lastMessages[message] = type(message); + console.log(type(message), ...optionalParams); + // } }; export const formatMessage = (message: string) => { @@ -70,4 +78,17 @@ export const logger = { logNR(error, formatMessage(message), ...optionalParams); throw new Error(message); }, + dev: (message: string, ...optionalParams: unknown[]) => { + log(debug, `DEV: ${message}`, ...optionalParams); + }, + step: (message: string, ...optionalParams: unknown[]) => { + log( + info, + `\n${"=".repeat(80)}\n📌 ${message}\n${"=".repeat(80)}\n`, + ...optionalParams, + ); + }, + space: () => { + console.log(); + }, }; diff --git a/src/utils/types.ts b/src/utils/types.ts index 6bafb1b..5221652 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -138,5 +138,5 @@ export type LightsFlatsMatch = { /** * True if the light was manually matched because several flats sequences were available. */ - isAdvancedMatching: boolean; + isManualMatch: boolean; }; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index f563b52..6cf6176 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -29,13 +29,15 @@ export const getFitsFromDirectory = ({ return; } if (file.name.endsWith("_thn.jpg")) { - logger.info(`Skipping thumbnail file (xxx_thn.jpg)`); + logger.debug(`Skipping thumbnail file (${file.name})`); + return; + } + if (!(file.isFile() || file.isSymbolicLink())) { + logger.debug(`Skipping not-file or symlink (${file.name})`); + return; } - if ( - !(file.isFile() || file.isSymbolicLink()) || - !file.name.endsWith(".fit") - ) { - logger.info(`Skipping ${file.name}`); + if (!file.name.endsWith(".fit")) { + logger.debug(`Skipping unknown file (${file.name})`); return; } From 7a70c643540218e091bb2ffeb9e7bc86b2bf4b94 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 00:14:31 +0100 Subject: [PATCH 07/18] feat: bullet proof the filter parsing --- .../tests/__snapshots__/utils.spec.ts.snap | 41 +++++++++++++++++++ src/utils/tests/utils.spec.ts | 38 +++++++++++++++++ src/utils/utils.ts | 4 +- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 src/utils/tests/__snapshots__/utils.spec.ts.snap create mode 100644 src/utils/tests/utils.spec.ts diff --git a/src/utils/tests/__snapshots__/utils.spec.ts.snap b/src/utils/tests/__snapshots__/utils.spec.ts.snap new file mode 100644 index 0000000..f45476b --- /dev/null +++ b/src/utils/tests/__snapshots__/utils.spec.ts.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR filter named with spaces) 1`] = ` +{ + "bin": "Bin1", + "bulb": "120.0s", + "datetime": 2024-07-07T00:23:48.000Z, + "extension": "fit", + "fileName": "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit", + "filter": "filterh", + "gain": 100, + "projectDirectory": "project/bar/filterh/Light_120.0s_Bin1_filterh_gain100", + "sequenceId": "20240707-002348", + "sequencePosition": 1, + "setName": "Light_120.0s_Bin1_filterh_gain100", + "sourceDirectory": "input/bar", + "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit", + "temperature": "-10.0C", + "type": "Light", +} +`; + +exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR plan target format) 1`] = ` +{ + "bin": "Bin1", + "bulb": "120.0s", + "datetime": 2024-07-07T00:23:48.000Z, + "extension": "fit", + "fileName": "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + "filter": "H", + "gain": 100, + "projectDirectory": "project/bar/H/Light_120.0s_Bin1_H_gain100", + "sequenceId": "20240707-002348", + "sequencePosition": 1, + "setName": "Light_120.0s_Bin1_H_gain100", + "sourceDirectory": "input/bar", + "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + "temperature": "-10.0C", + "type": "Light", +} +`; diff --git a/src/utils/tests/utils.spec.ts b/src/utils/tests/utils.spec.ts new file mode 100644 index 0000000..e22987e --- /dev/null +++ b/src/utils/tests/utils.spec.ts @@ -0,0 +1,38 @@ +import { jest } from "@jest/globals"; // Import Jest globals + +import fs from "fs"; +import { getFileImageSpecFromFilename } from "../utils"; + +describe("utils", () => { + describe("getFileImageSpecFromFilename", () => { + it("should match snapshot (ASIAIR plan target format)", () => { + const file = new fs.Dirent(); + file.name = + "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit"; + file.path = "input/bar"; + const projectDirectory = "project/bar"; + const previousFile = null; + + expect( + getFileImageSpecFromFilename(file, projectDirectory, previousFile), + ).toMatchSnapshot(); + }); + + it("should match snapshot (ASIAIR filter named with spaces)", () => { + const file = new fs.Dirent(); + file.name = + "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit"; + file.path = "input/bar"; + const projectDirectory = "project/bar"; + const previousFile = null; + + const specs = getFileImageSpecFromFilename( + file, + projectDirectory, + previousFile, + ); + expect(specs).toMatchSnapshot(); + expect(specs.filter).toBe("filterh"); + }); + }); +}); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 6cf6176..08a90f6 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -72,7 +72,7 @@ export const getFileImageSpecFromFilename = ( // Note: Filter is not always specified in the filename. const regex = - /^(?[A-Za-z]+)(?:_[^_]+)?_(?[^_]+)_(?Bin\d)_((?[A-Za-z0-9])_)?gain(?\d+)_(?\d{8}-\d{6})_(?-?\d+\.\d+C)_(?\d{4})\.(?fit)$/; + /^(?[A-Za-z]+)(?:_[^_]+)?_(?[^_]+)_(?Bin\d)_((?[A-Za-z0-9 ]+)_)?gain(?\d+)_(?\d{8}-\d{6})_(?-?\d+\.\d+C)_(?\d{4})\.(?fit)$/; const match = fileFS.name.match(regex); // TODO. Check if well sorted! @@ -97,7 +97,7 @@ export const getFileImageSpecFromFilename = ( type: match.groups.type, bulb: match.groups.bulb, bin: match.groups.bin, - filter: match.groups.filter ?? null, + filter: match.groups.filter.replaceAll(" ", "").trim() ?? null, gain: parseInt(match.groups.gain, 10), sequenceId, From b94c9decbf729888193fa422a751349ac9c01c97 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 00:22:23 +0100 Subject: [PATCH 08/18] feat: cleanup too ambitious logger code, add test coverage --- src/utils/logger.ts | 36 ++-------- src/utils/tests/logger.spec.ts | 117 +++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 30 deletions(-) create mode 100644 src/utils/tests/logger.spec.ts diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 7de3efb..9c62ae5 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -7,9 +7,6 @@ const success = chalk.bold.green; const warning = chalk.bold.yellow; const error = chalk.bold.red; -const logCounts: { [key: string]: number } = {}; -const lastMessages: { [key: string]: string } = {}; - const log = ( type: (message: string) => string, message: string, @@ -18,27 +15,6 @@ const log = ( console.log(type(message), ...optionalParams); }; -const logNR = ( - type: (message: string) => string, - message: string, - ...optionalParams: unknown[] -) => { - // if (logCounts[message]) { - // logCounts[message]++; - // const count = chalk.bold.yellow(`(x${logCounts[message]})`); - // process.stdout.write( - // ansiEscapes.cursorUp(1) + - // ansiEscapes.eraseLine + - // type(`${message} ${count}`) + - // "\n", - // ); - // } else { - logCounts[message] = 1; - lastMessages[message] = type(message); - console.log(type(message), ...optionalParams); - // } -}; - export const formatMessage = (message: string) => { return message .replace(/(Light|Flat|Dark|Bias)_/g, chalk.hex("#001f3f")("$1_")) // Color image type. @@ -60,22 +36,22 @@ export const formatMessage = (message: string) => { export const logger = { debug: (message: string, ...optionalParams: unknown[]) => { - logNR(debug, formatMessage(message), ...optionalParams); + log(debug, formatMessage(message), ...optionalParams); }, info: (message: string, ...optionalParams: unknown[]) => { - logNR(info, formatMessage(message), ...optionalParams); + log(info, formatMessage(message), ...optionalParams); }, success: (message: string, ...optionalParams: unknown[]) => { - logNR(success, formatMessage(message), ...optionalParams); + log(success, formatMessage(message), ...optionalParams); }, warning: (message: string, ...optionalParams: unknown[]) => { - logNR(warning, formatMessage(message), ...optionalParams); + log(warning, formatMessage(message), ...optionalParams); }, error: (message: string, ...optionalParams: unknown[]) => { - logNR(error, formatMessage(message), ...optionalParams); + log(error, formatMessage(message), ...optionalParams); }, errorThrow: (message: string, ...optionalParams: unknown[]) => { - logNR(error, formatMessage(message), ...optionalParams); + log(error, formatMessage(message), ...optionalParams); throw new Error(message); }, dev: (message: string, ...optionalParams: unknown[]) => { diff --git a/src/utils/tests/logger.spec.ts b/src/utils/tests/logger.spec.ts new file mode 100644 index 0000000..81871da --- /dev/null +++ b/src/utils/tests/logger.spec.ts @@ -0,0 +1,117 @@ +import { logger, formatMessage } from "../logger"; +import chalk from "chalk"; + +describe("logger", () => { + const consoleLogSpy = jest.spyOn(console, "log").mockImplementation(); + + afterEach(() => { + consoleLogSpy.mockClear(); + }); + + afterAll(() => { + consoleLogSpy.mockRestore(); + }); + + it("should log debug messages", () => { + logger.debug("Debug message"); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.gray.italic("Debug message"), + ); + }); + + it("should log info messages", () => { + logger.info("Info message"); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue("Info message")); + }); + + it("should log success messages", () => { + logger.success("Success message"); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.bold.green("Success message"), + ); + }); + + it("should log warning messages", () => { + logger.warning("Warning message"); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.bold.yellow("Warning message"), + ); + }); + + it("should log error messages", () => { + logger.error("Error message"); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.bold.red("Error message")); + }); + + it("should throw an error with errorThrow", () => { + expect(() => logger.errorThrow("Error message")).toThrow("Error message"); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.bold.red("Error message")); + }); + + it("should log dev messages", () => { + logger.dev("Dev message"); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.gray.italic("DEV: Dev message"), + ); + }); + + it("should log step messages", () => { + logger.step("Step message"); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.blue(`\n${"=".repeat(80)}\n📌 Step message\n${"=".repeat(80)}\n`), + ); + }); + + it("should log a space", () => { + logger.space(); + expect(consoleLogSpy).toHaveBeenCalledWith(); + }); + + it("should format and log messages with optional parameters", () => { + logger.info("Info message with params", { param1: "value1" }); + expect(consoleLogSpy).toHaveBeenCalledWith( + chalk.blue("Info message with params"), + { param1: "value1" }, + ); + }); + + it("should handle empty messages", () => { + logger.info(""); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue("")); + }); + + it("should handle undefined messages", () => { + logger.info(undefined); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue("undefined")); + }); +}); + +describe("formatMessage", () => { + it("should format messages correctly", () => { + const message = "Light_1234 gain10 Bin2 20220101-120000_thn.jpg"; + const formattedMessage = formatMessage(message); + expect(formattedMessage).toContain(chalk.hex("#001f3f")("Light_")); + expect(formattedMessage).toContain(chalk.hex("#a05195")("gain10")); + expect(formattedMessage).toContain(chalk.hex("#2f4b7c")("Bin2")); + expect(formattedMessage).toContain( + `${chalk.hex("#d45087")("2022")}${chalk.hex("#f95d6a")("01")}${chalk.hex( + "#ff7c43", + )("01")}-${chalk.hex("#ffa600")("12")}${chalk.hex("#ffb000")( + "00", + )}${chalk.hex("#ffc000")("00")}`, + ); + expect(formattedMessage).toContain(chalk.bgHex("#ff0000")("_thn.jpg")); + }); + + it("should handle empty messages", () => { + const message = ""; + const formattedMessage = formatMessage(message); + expect(formattedMessage).toBe(""); + }); + + it("should handle undefined messages", () => { + const message = undefined; + const formattedMessage = formatMessage(message); + expect(formattedMessage).toBe("undefined"); + }); +}); From b732d583a994186f30ca9dfb88f98a666e40a407 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 00:41:05 +0100 Subject: [PATCH 09/18] feat: more tests coverage, and fix bound bugs --- src/utils/logger.ts | 4 + .../tests/__snapshots__/utils.spec.ts.snap | 34 +++- src/utils/tests/logger.spec.ts | 8 +- src/utils/tests/utils.spec.ts | 157 +++++++++++++++++- src/utils/utils.ts | 4 +- 5 files changed, 193 insertions(+), 14 deletions(-) diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 9c62ae5..123dd48 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -16,6 +16,10 @@ const log = ( }; export const formatMessage = (message: string) => { + if (!message) { + return message; + } + return message .replace(/(Light|Flat|Dark|Bias)_/g, chalk.hex("#001f3f")("$1_")) // Color image type. .replace(/(\d+\.\d(ms|s))/g, chalk.hex("#003f5c")("$1")) // Color bulb. diff --git a/src/utils/tests/__snapshots__/utils.spec.ts.snap b/src/utils/tests/__snapshots__/utils.spec.ts.snap index f45476b..7959036 100644 --- a/src/utils/tests/__snapshots__/utils.spec.ts.snap +++ b/src/utils/tests/__snapshots__/utils.spec.ts.snap @@ -1,6 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR filter named with spaces) 1`] = ` +exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR plan target format) 1`] = ` +{ + "bin": "Bin1", + "bulb": "120.0s", + "datetime": 2024-07-07T00:23:48.000Z, + "extension": "fit", + "fileName": "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + "filter": "H", + "gain": 100, + "projectDirectory": "project/bar/H/Light_120.0s_Bin1_H_gain100", + "sequenceId": "20240707-002348", + "sequencePosition": 1, + "setName": "Light_120.0s_Bin1_H_gain100", + "sourceDirectory": "input/bar", + "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + "temperature": "-10.0C", + "type": "Light", +} +`; + +exports[`utils getFileImageSpecFromFilename should match snapshot (filter named with spaces) 1`] = ` { "bin": "Bin1", "bulb": "120.0s", @@ -20,21 +40,21 @@ exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR filter } `; -exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR plan target format) 1`] = ` +exports[`utils getFileImageSpecFromFilename should match snapshot (no filter) 1`] = ` { "bin": "Bin1", "bulb": "120.0s", "datetime": 2024-07-07T00:23:48.000Z, "extension": "fit", - "fileName": "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", - "filter": "H", + "fileName": "Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit", + "filter": null, "gain": 100, - "projectDirectory": "project/bar/H/Light_120.0s_Bin1_H_gain100", + "projectDirectory": "project/bar/Light_120.0s_Bin1_gain100", "sequenceId": "20240707-002348", "sequencePosition": 1, - "setName": "Light_120.0s_Bin1_H_gain100", + "setName": "Light_120.0s_Bin1_gain100", "sourceDirectory": "input/bar", - "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit", "temperature": "-10.0C", "type": "Light", } diff --git a/src/utils/tests/logger.spec.ts b/src/utils/tests/logger.spec.ts index 81871da..2dd9425 100644 --- a/src/utils/tests/logger.spec.ts +++ b/src/utils/tests/logger.spec.ts @@ -1,8 +1,10 @@ +import { jest } from "@jest/globals"; // Import Jest globals + import { logger, formatMessage } from "../logger"; import chalk from "chalk"; describe("logger", () => { - const consoleLogSpy = jest.spyOn(console, "log").mockImplementation(); + const consoleLogSpy = jest.spyOn(console, "log"); afterEach(() => { consoleLogSpy.mockClear(); @@ -82,7 +84,7 @@ describe("logger", () => { it("should handle undefined messages", () => { logger.info(undefined); - expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue("undefined")); + expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue(undefined)); }); }); @@ -112,6 +114,6 @@ describe("formatMessage", () => { it("should handle undefined messages", () => { const message = undefined; const formattedMessage = formatMessage(message); - expect(formattedMessage).toBe("undefined"); + expect(formattedMessage).toBe(undefined); }); }); diff --git a/src/utils/tests/utils.spec.ts b/src/utils/tests/utils.spec.ts index e22987e..dbeab98 100644 --- a/src/utils/tests/utils.spec.ts +++ b/src/utils/tests/utils.spec.ts @@ -1,7 +1,15 @@ import { jest } from "@jest/globals"; // Import Jest globals import fs from "fs"; -import { getFileImageSpecFromFilename } from "../utils"; +import path from "path"; +import { + getFileImageSpecFromFilename, + getFitsFromDirectory, + copyFileToProject, + matchSetFile, + getImageSpecFromSetName, +} from "../utils"; +import { FileImageSpec, ImageSpec } from "../types"; describe("utils", () => { describe("getFileImageSpecFromFilename", () => { @@ -18,7 +26,7 @@ describe("utils", () => { ).toMatchSnapshot(); }); - it("should match snapshot (ASIAIR filter named with spaces)", () => { + it("should match snapshot (filter named with spaces)", () => { const file = new fs.Dirent(); file.name = "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit"; @@ -34,5 +42,150 @@ describe("utils", () => { expect(specs).toMatchSnapshot(); expect(specs.filter).toBe("filterh"); }); + + it("should match snapshot (no filter)", () => { + const file = new fs.Dirent(); + file.name = + "Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit"; + file.path = "input/bar"; + const projectDirectory = "project/bar"; + const previousFile = null; + + const specs = getFileImageSpecFromFilename( + file, + projectDirectory, + previousFile, + ); + expect(specs).toMatchSnapshot(); + expect(specs.filter).toBeNull(); + }); + }); + + describe("getFitsFromDirectory", () => { + it("should retrieve FITS files from a directory", () => { + jest.spyOn(fs, "readdirSync").mockReturnValue([ + Object.assign(new fs.Dirent(), { + name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + isFile: () => true, + path: "input/dir", + }), + Object.assign(new fs.Dirent(), { + name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002349_-10.0C_0002.fit", + isFile: () => true, + path: "input/dir", + }), + Object.assign(new fs.Dirent(), { + name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001_thn.jpg", + isFile: () => true, + path: "input/dir", + }), + ]); + + const result = getFitsFromDirectory({ + directory: "input/dir", + projectDirectory: "project/dir", + }); + + expect(result).toHaveLength(2); + expect(result[0].fileName).toBe( + "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", + ); + expect(result[1].fileName).toBe( + "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002349_-10.0C_0002.fit", + ); + }); + }); + + describe("copyFileToProject", () => { + it("should copy a file to the project directory", () => { + const file = { + projectDirectory: "project/dir", + fileName: "file1.fit", + sourceFilePath: "input/dir/file1.fit", + } as FileImageSpec; + + jest.spyOn(fs, "existsSync").mockReturnValue(false); + jest.spyOn(fs, "mkdirSync").mockImplementation(_ => ""); + jest.spyOn(fs, "copyFileSync").mockImplementation(() => {}); + + copyFileToProject(file); + + expect(fs.existsSync).toHaveBeenCalledWith("project/dir"); + expect(fs.mkdirSync).toHaveBeenCalledWith("project/dir", { + recursive: true, + }); + expect(fs.copyFileSync).toHaveBeenCalledWith( + "input/dir/file1.fit", + "project/dir/file1.fit", + ); + }); + }); + + describe("matchSetFile", () => { + it("should match Light with Dark", () => { + const A = { + type: "Light", + bulb: "120.0s", + bin: "Bin1", + gain: 100, + } as ImageSpec; + const B = { + type: "Dark", + bulb: "120.0s", + bin: "Bin1", + gain: 100, + } as ImageSpec; + expect(matchSetFile(A, B)).toBe(true); + }); + + it("should match Light with Flat", () => { + const A = { type: "Light", bin: "Bin1", filter: "H" } as ImageSpec; + const B = { type: "Flat", bin: "Bin1", filter: "H" } as ImageSpec; + expect(matchSetFile(A, B)).toBe(true); + }); + + it("should match Flat with Bias", () => { + const A = { type: "Flat", bin: "Bin1", gain: 100 } as ImageSpec; + const B = { + type: "Bias", + bin: "Bin1", + gain: 100, + } as ImageSpec; + expect(matchSetFile(A, B)).toBe(true); + }); + + it("should not match Light with Bias", () => { + const A = { type: "Light" } as ImageSpec; + const B = { type: "Bias" } as ImageSpec; + expect(matchSetFile(A, B)).toBe(false); + }); + }); + + describe("getImageSpecFromSetName", () => { + it("should return the correct ImageSpec with filter", () => { + const setName = "Flat_520.0ms_Bin1_H_gain0"; + const result = getImageSpecFromSetName(setName); + expect(result).toEqual({ + setName, + type: "Flat", + bulb: "520.0ms", + bin: "Bin1", + filter: "H", + gain: 0, + }); + }); + + it("should return the correct ImageSpec without filter", () => { + const setName = "Flat_520.0ms_Bin1_gain0"; + const result = getImageSpecFromSetName(setName); + expect(result).toEqual({ + setName, + type: "Flat", + bulb: "520.0ms", + bin: "Bin1", + filter: null, + gain: 0, + }); + }); }); }); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 08a90f6..1145cff 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -97,7 +97,7 @@ export const getFileImageSpecFromFilename = ( type: match.groups.type, bulb: match.groups.bulb, bin: match.groups.bin, - filter: match.groups.filter.replaceAll(" ", "").trim() ?? null, + filter: match.groups.filter?.replaceAll(" ", "").trim() ?? null, gain: parseInt(match.groups.gain, 10), sequenceId, @@ -146,7 +146,7 @@ const parseDate = (datetimeString: string): Date => { const [_, year, month, day, hour, minute, second] = matchResult; const parsedDate = new Date( parseInt(year, 10), - parseInt(month, 10) - 1, // Month is zero-based in JavaScript Date + parseInt(month, 10) - 1, // Month is zero-based in JavaScript Date. parseInt(day, 10), parseInt(hour, 10), parseInt(minute, 10), From 0f880123590a338d1915908eff9d47b7c5e1ec2e Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:21:05 +0100 Subject: [PATCH 10/18] feat: assign darks and biases --- src/commands/dispatch-dump.ts | 359 +++++++++++++++++++--------------- 1 file changed, 203 insertions(+), 156 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 92f5aba..1ff8c1f 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -20,7 +20,7 @@ import { LightsFlatsMatch, PotoProject, } from "../utils/types"; -import { POTO_JSON } from "../utils/const"; +import { POTO_JSON, POTO_VERSION } from "../utils/const"; export type DispatchOptions = { projectDirectory: string; @@ -61,170 +61,60 @@ const dispatch = async ({ allLights, ); - const layerSets: LayerSet[] = initLayerSetsWithLightsnFlats( + let layerSets: LayerSet[] = initLayerSetsWithLightsnFlats( lightsFlatsMatches, allLights, allFlatsMatchingLights, ); - logger.step("Debug"); + logger.step("Tagging darks and biases"); - const debug = layerSets.map(x => { - return { - layerSetId: x.layerSetId, - lightTotalCount: x.lightTotalCount, - lightsStr: x.lights.map(x => x.fileName).join(", "), - flatsCount: x.flatsCount, - flatsStr: x.flats.map(x => x.fileName).join(", "), - }; - }); - - logger.success("debug", debug); - - // TODO. custom sort if LRGBSHO filter names to ease reading. - // TODO. Add biases and darks to the layerSets. - - return; - - const importedLightsFlatsFiles: FileImageSpec[] = []; - const importedDarksBiasesFiles: FileImageSpec[] = []; - - // Dispatch the ASIAIR Lights files to the project directory. - // const lightFiles = inputFiles.filter(file => file.type === "Light"); - // lightFiles.forEach(file => { - // copyFileToProject(file); - // importedLightsFlatsFiles.push(file); - // }); - - // Dispatch associated flats. - // inputFiles - // .filter(x => x.type === "Flat") - // .forEach(file => { - // if (lightFiles.find(f => matchSetFile(f, file))) { - // copyFileToProject(file); - // importedLightsFlatsFiles.push(file); - // } else { - // logger.info( - // `Skipping ${file.fileName} from the ASIAIR, No light matching.`, - // ); - // } - // }); - - // Search for the darks and biases we need to copy. - const bankFiles = getFitsFromDirectory({ - directory: bankDirectory, + const bankFiles = getAllFitsInBankDirectories( + bankDirectory, projectDirectory, - }); - logger.info(`Found ${bankFiles.length} files in the bank.`); - bankFiles.forEach(file => { - // Check if the file is needed from the bank. - if (importedLightsFlatsFiles.find(f => matchSetFile(f, file))) { - copyFileToProject(file); - importedDarksBiasesFiles.push(file); - } else { - logger.debug(`Skipping ${file.fileName} from the bank, not needed.`); - } - }); - - // TODO. Extract below to a new isolated stats function. - - // Check that there's flat, darks and biases for each sets. - const files = [...importedLightsFlatsFiles, ...importedDarksBiasesFiles]; - const flatFiles = files.filter(file => file.type === "Flat"); - const darkFiles = files.filter(file => file.type === "Dark"); - const biasFiles = files.filter(file => file.type === "Bias"); - - const layerSetsOld = [ - ...new Set( - files.filter(file => file.type === "Light").map(file => file.setName), - ), - ].map(layerSetName => { - const setSpecs = getImageSpecFromSetName(layerSetName); - - const layerSet = { - filter: setSpecs.filter, - lightSet: layerSetName, - // TODO. Refactor to use the filter function here too. Or store the decision previously made (during the bank selection) to reuse it here. - // The core issue is that we kinda recompute the same thing twice when importing files + when generating the poto project file. - lights: lightFiles.filter(file => file.setName === layerSetName), - darks: darkFiles.filter( - file => - file.bin === setSpecs.bin && - file.gain === setSpecs.gain && - file.bulb === setSpecs.bulb, - ), - flats: flatFiles.filter( - file => file.bin === setSpecs.bin && file.filter === setSpecs.filter, - ), - } as LayerSet; + ); - const biases = biasFiles.filter( - file => - file.bin === (layerSet.flats[0]?.bin ?? undefined) && - file.gain === (layerSet.flats[0]?.gain ?? undefined), - ); + layerSets = AssignDarksBiasesToLayerSets(layerSets, bankFiles); - return { - filter: layerSet.filter, - - lightSet: layerSet.lightSet, - flatSet: layerSet.flats[0]?.setName ?? undefined, - darkSet: layerSet.darks[0]?.setName ?? undefined, - biasSet: biases[0]?.setName ?? undefined, - - lightsCount: layerSet.lights.length, - flatsCount: layerSet.flats.length, - darksCount: layerSet.darks.length, - biasesCount: biases.length, - - lights: layerSet.lights, - darks: layerSet.darks, - flats: layerSet.flats, - biases, - } as LayerSet; - }); + logger.step("Preview before dispatching"); - logger.info( - `🔭 Project size: ${layerSets.reduce( - (total, layerSet) => total + layerSet.flatsCount, - 0, - )} lights, ${layerSets.reduce( - (total, layerSet) => total + layerSet.darksCount, - 0, - )} darks, ${layerSets.reduce( - (total, layerSet) => total + layerSet.flatsCount, - 0, - )} flats, ${layerSets.reduce( - (total, layerSet) => total + layerSet.biasesCount, - 0, - )} biases.`, - ); + const go = await previewBeforeDispatching(layerSets); - for (const layerSet of layerSets) { - const log = ` 🌌 Set ${layerSet.lightSet} has ${layerSet.lights.length} lights, ${layerSet.darks.length} darks, ${layerSet.flats.length} flats, ${layerSet.biases.length} biases.`; - if ( - layerSet.lights.length > 0 && - layerSet.flats.length > 0 && - layerSet.darks.length > 0 && - layerSet.biases.length > 0 - ) { - logger.info(log); - } else { - logger.warning(log); - } + if (!go) { + logger.warning("Aborted."); + return; } + logger.step("Dispatching"); const potoProject: PotoProject = { generatedAt: new Date(), - potoVersion: "0.1.0", + potoVersion: POTO_VERSION, layerSets, }; - const potoJsonPath = `${projectDirectory}/${POTO_JSON}`; + await dispatchProject(potoProject, projectDirectory); - fs.writeFileSync(potoJsonPath, JSON.stringify(potoProject, null, 2)); + logger.success("Dispatch done ✅. POTO project generated 💃."); - logger.success(`Dispatch done ✅. ${POTO_JSON} generated 💃.`); + logger.step("Debug."); + + const debug = layerSets.map(x => { + return { + layerSetId: x.layerSetId, + lightTotalCount: x.lightTotalCount, + lightsStr: x.lights.map(x => x.fileName).join(", "), + flatsCount: x.flatsCount, + flatsStr: x.flats.map(x => x.fileName).join(", "), + darksCount: x.darksCount, + darksStr: x.darks.map(x => x.fileName).join(", "), + biasesCount: x.biasesCount, + biasesStr: x.biases.map(x => x.fileName).join(", "), + }; + }); + + logger.success("debug", debug); + + // TODO. custom sort if LRGBSHO filter names to ease reading. }; export default dispatch; @@ -250,9 +140,6 @@ const ensureProjectDirectoryExists = async (projectDirectory: string) => { } }; -// TODO. Decouple from ASIAIR. Just warn if files both found in Autorun and Plan, and ask the user to probably review the input files first. -// TODO. Allow multiple directories in input. - /** * Retrieve all FITS files from the input directories. * @@ -265,14 +152,17 @@ const getAllFitsInInputDirectories = ( asiAirDirectory: string, shootingMode: string, projectDirectory: string, -) => { +): FileImageSpec[] => { + // TODO. Allow multiple directories in input. + // TODO. Decouple from ASIAIR. Just warn if files both found in Autorun and Plan, and ask the user to probably review the input files first. const files = getFitsFromDirectory({ directory: `${asiAirDirectory}/${ shootingMode === "autorun" ? "Autorun" : "Plan" }`, projectDirectory, }); - logger.info(`Found ${files.length} files to dispatch.`); + logger.info(`Found ${files.length} files in input dir(s) to dispatch.`); + return files; }; @@ -367,9 +257,7 @@ const matchLightsToFlats = async ( logger.info(`🤚 Several sequences found for flat set ${flatSet}:`); logger.info( - `${flatSetNameSequenceIds - .map(x => ` - ${x.split("__")[1]}`) - .join("\n")}`, + `${flatSetNameSequenceIds.map(x => `- ${x.split("__")[1]}`).join("\n")}`, ); logger.debug( "We assume that multiple sequences of the same flat set indicate multiple night sessions where the flats had to be re-shot in between (e.g., a significant date gap between shooting sessions and the lights were not collected with the same collimation and/or same dust in the optical train).", @@ -434,7 +322,7 @@ const matchLightsToFlats = async ( logger.info("👉 Light - Flat matching summary:"); for (const pair of LightFlatMatches) { logger.debug( - ` - ${pair.lightSetName} ${pair.lightSequenceId} 🏹 ${pair.flatSetName} ${pair.flatSequenceId}`, + `- ${pair.lightSetName} ${pair.lightSequenceId} 🏹 ${pair.flatSetName} ${pair.flatSequenceId}`, ); } @@ -452,7 +340,7 @@ const initLayerSetsWithLightsnFlats = ( lightsFlatsMatches: LightsFlatsMatch[], allLights: FileImageSpec[], allFlatsMatchingLights: FileImageSpec[], -) => { +): LayerSet[] => { const layerSets: LayerSet[] = []; for (const lightsFlatsMatch of lightsFlatsMatches) { @@ -481,7 +369,7 @@ const initLayerSetsWithLightsnFlats = ( } const layerSetId = lightsFlatsMatch.isManualMatch - ? `${lights[0].setName}__sequence-${lights[0].sequenceId}` + ? `${lights[0].setName}__${lights[0].sequenceId}` : lights[0].setName; const lightSequenceIds = new Set( @@ -529,3 +417,162 @@ const initLayerSetsWithLightsnFlats = ( } return layerSets; }; + +/** + * Retrieve all FITS files from the input directories. + * + * @param bankDirectory - The directory where ASIAIR files are stored. + * @param projectDirectory - The directory of the current project. + * @returns An array of FileImageSpec objects representing the FITS files. + */ +const getAllFitsInBankDirectories = ( + bankDirectory: string, + projectDirectory: string, +): FileImageSpec[] => { + // TODO. Allow multiple directories in input. + const files = getFitsFromDirectory({ + directory: bankDirectory, + projectDirectory, + }); + logger.info(`Found ${files.length} files in the bank.`); + return files; +}; + +/** + * Assign darks and biases to the layer sets. + * We darks are assigned to lights, and biases are assigned to flats. + * + * @param layerSets - The layer sets with lights and flats filled in. + * @param bankFiles - The bank files available. + */ +const AssignDarksBiasesToLayerSets = ( + layerSets: LayerSet[], + bankFiles: FileImageSpec[], +): LayerSet[] => { + for (const layerSet of layerSets) { + const darks = bankFiles.filter( + dark => dark.type === "Dark" && matchSetFile(layerSet.lights[0], dark), + ); + + if (darks.length === 0) { + logger.error(`No darks found for ${layerSet.lights[0].setName}.`); + } else { + layerSet.darkSet = darks[0].setName; + layerSet.darks = darks; + layerSet.darksCount = darks.length; + } + + const biases = bankFiles.filter( + bias => bias.type === "Bias" && matchSetFile(layerSet.flats[0], bias), + ); + + if (biases.length === 0) { + logger.error(`No biases found for ${layerSet.flats[0].setName}.`); + } else { + layerSet.biasSet = biases[0].setName; + layerSet.biases = biases; + layerSet.biasesCount = biases.length; + } + + // Warn if there are multiple sequences for the same layer set + const darkSequences = new Set(darks.map(dark => dark.sequenceId)); + if (darkSequences.size > 1) { + logger.warning( + `Multiple dark sequences found for ${layerSet.lights[0].setName}: ${[ + ...darkSequences, + ].join(", ")}`, + ); + logger.warning( + "Gathering them all for the master dark. Make sure that's what you want.", + ); + } + + const biasSequences = new Set(biases.map(bias => bias.sequenceId)); + if (biasSequences.size > 1) { + logger.warning( + `Multiple bias sequences found for ${layerSet.flats[0].setName}: ${[ + ...biasSequences, + ].join(", ")}`, + ); + logger.warning( + "Gathering them all for the master flat. Make sure that's what you want.", + ); + } + } + + return layerSets; +}; + +/** + * Preview the project composition before dispatching. + * + * @param layerSets - The layer sets to preview. + */ +const previewBeforeDispatching = async (layerSets: LayerSet[]) => { + logger.info( + `🔭 Cumulated integration: ${layerSets.reduce( + (total, layerSet) => total + layerSet.lightTotalIntegrationMinutes, + 0, + )} minutes.`, + ); + logger.info( + `📦 Project size: ${layerSets.reduce( + (total, layerSet) => total + layerSet.lightTotalCount, + 0, + )} lights, ${layerSets.reduce( + (total, layerSet) => total + layerSet.darksCount, + 0, + )} darks, ${layerSets.reduce( + (total, layerSet) => total + layerSet.flatsCount, + 0, + )} flats, ${layerSets.reduce( + (total, layerSet) => total + layerSet.biasesCount, + 0, + )} biases.`, + ); + + logger.space(); + + logger.info("🌌 Layer sets:"); + for (const layerSet of layerSets) { + const log = `- ${layerSet.layerSetId} has ${layerSet.lights.length} lights, ${layerSet.darks.length} darks, ${layerSet.flats.length} flats, ${layerSet.biases.length} biases.`; + if ( + layerSet.lights.length > 0 && + layerSet.flats.length > 0 && + layerSet.darks.length > 0 && + layerSet.biases.length > 0 + ) { + logger.debug(log); + } else { + logger.warning(log); + } + } + + logger.space(); + + const enquirer = new Enquirer(); + const response = (await enquirer.prompt({ + type: "confirm", + name: "go", + message: "Do you want to proceed with the dispatch?", + })) as { go: boolean }; + + return response.go; +}; + +/** + * Dispatch the project json and the files to the poto project directory. + * + * @param potoProject - The POTO project to dispatch. + * @param projectDirectory - The project directory. + */ +const dispatchProject = ( + potoProject: PotoProject, + projectDirectory: string, +): void => { + const potoJsonPath = `${projectDirectory}/${POTO_JSON}`; + + fs.writeFileSync(potoJsonPath, JSON.stringify(potoProject, null, 2)); + + // TODO. Copy the files to the project directory. +}; From d53e568f88e0ac4efbb0bf85434f19e069a50b6c Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:29:58 +0100 Subject: [PATCH 11/18] feat: implement bulbMS --- src/commands/dispatch-dump.ts | 2 +- .../tests/__snapshots__/utils.spec.ts.snap | 3 +++ src/utils/tests/utils.spec.ts | 19 ++++++++++++++++++- src/utils/utils.ts | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 1ff8c1f..5273ba8 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -510,7 +510,7 @@ const AssignDarksBiasesToLayerSets = ( */ const previewBeforeDispatching = async (layerSets: LayerSet[]) => { logger.info( - `🔭 Cumulated integration: ${layerSets.reduce( + `🔭 Cumulated light integration: ${layerSets.reduce( (total, layerSet) => total + layerSet.lightTotalIntegrationMinutes, 0, )} minutes.`, diff --git a/src/utils/tests/__snapshots__/utils.spec.ts.snap b/src/utils/tests/__snapshots__/utils.spec.ts.snap index 7959036..cef66ae 100644 --- a/src/utils/tests/__snapshots__/utils.spec.ts.snap +++ b/src/utils/tests/__snapshots__/utils.spec.ts.snap @@ -4,6 +4,7 @@ exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR plan t { "bin": "Bin1", "bulb": "120.0s", + "bulbMs": 120000, "datetime": 2024-07-07T00:23:48.000Z, "extension": "fit", "fileName": "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit", @@ -24,6 +25,7 @@ exports[`utils getFileImageSpecFromFilename should match snapshot (filter named { "bin": "Bin1", "bulb": "120.0s", + "bulbMs": 120000, "datetime": 2024-07-07T00:23:48.000Z, "extension": "fit", "fileName": "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit", @@ -44,6 +46,7 @@ exports[`utils getFileImageSpecFromFilename should match snapshot (no filter) 1` { "bin": "Bin1", "bulb": "120.0s", + "bulbMs": 120000, "datetime": 2024-07-07T00:23:48.000Z, "extension": "fit", "fileName": "Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit", diff --git a/src/utils/tests/utils.spec.ts b/src/utils/tests/utils.spec.ts index dbeab98..b32751e 100644 --- a/src/utils/tests/utils.spec.ts +++ b/src/utils/tests/utils.spec.ts @@ -1,7 +1,6 @@ import { jest } from "@jest/globals"; // Import Jest globals import fs from "fs"; -import path from "path"; import { getFileImageSpecFromFilename, getFitsFromDirectory, @@ -61,6 +60,24 @@ describe("utils", () => { }); }); + it.each([ + { bulb: "120.0s", expected: 120000 }, + { bulb: "810.0ms", expected: 810 }, + ])("should parse bulb in ms (%s)", data => { + const file = new fs.Dirent(); + file.name = `Light_LDN 1093_${data.bulb}_Bin1_gain100_20240707-002348_-10.0C_0001.fit`; + file.path = "input/bar"; + const projectDirectory = "project/bar"; + const previousFile = null; + + const specs = getFileImageSpecFromFilename( + file, + projectDirectory, + previousFile, + ); + expect(specs.bulbMs).toBe(data.expected); + }); + describe("getFitsFromDirectory", () => { it("should retrieve FITS files from a directory", () => { jest.spyOn(fs, "readdirSync").mockReturnValue([ diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 1145cff..47a2345 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -96,6 +96,7 @@ export const getFileImageSpecFromFilename = ( type: match.groups.type, bulb: match.groups.bulb, + bulbMs: parseBulbString(match.groups.bulb), bin: match.groups.bin, filter: match.groups.filter?.replaceAll(" ", "").trim() ?? null, gain: parseInt(match.groups.gain, 10), @@ -171,6 +172,23 @@ const unParseDate = (datetime: Date): string => { )}`; }; +/** + * + * @param bulbString `120.0s` or `810.0ms`. + * @returns 120000 or 810 (in ms). + */ +const parseBulbString = (bulbString: string): number => { + const bulbRegex = /(\d+\.\d+)(ms|s)/; + const matchResult = bulbString.match(bulbRegex); + + if (matchResult) { + const [_, bulb, unit] = matchResult; + return unit === "s" ? parseFloat(bulb) * 1000 : parseFloat(bulb); + } else { + throw new Error(`Invalid bulb string: ${bulbString}`); + } +}; + export const copyFileToProject = (file: FileImageSpec) => { if (!fs.existsSync(file.projectDirectory)) { fs.mkdirSync(file.projectDirectory, { recursive: true }); From 2ec3bfd9c2247fd15e4b8ce26421c03e189a4a61 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:36:22 +0100 Subject: [PATCH 12/18] chore: bump version --- package.json | 2 +- src/poto-siril.ts | 3 ++- src/utils/const.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c22f146..08420a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "poto-siril", - "version": "0.1.0", + "version": "0.2.0", "description": "Automatization around Siril () and ASIAIR for deep sky astrophotography.", "main": "poto.sh", "type": "module", diff --git a/src/poto-siril.ts b/src/poto-siril.ts index 8a24239..4ed6077 100644 --- a/src/poto-siril.ts +++ b/src/poto-siril.ts @@ -6,13 +6,14 @@ import { } from "./commands/asiair-dump-cleaning"; import { generateScripts } from "./commands/generate-scripts"; import { runScripts } from "./commands/run-scripts"; +import { POTO_VERSION } from "./utils/const"; const program = new Command(); program .name("poto-siril") .description("CLI to some ASIAIR import and SIRIL processing") - .version("0.1.0"); + .version(POTO_VERSION); // const parseMode = (value: string, previous: string) => { // if (value != "autorun" && value != "plan") { diff --git a/src/utils/const.ts b/src/utils/const.ts index 5b804a1..f25a19e 100644 --- a/src/utils/const.ts +++ b/src/utils/const.ts @@ -1,4 +1,4 @@ -export const POTO_VERSION = "0.1.0"; +export const POTO_VERSION = "0.2.0"; export const POTO_JSON = "poto.json"; From 119097e530336f01e69318f18ed4eccea1e9abca Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:36:45 +0100 Subject: [PATCH 13/18] chore: review fields order to print a better poto json --- src/commands/dispatch-dump.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index 5273ba8..b25e639 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -402,15 +402,15 @@ const initLayerSetsWithLightsnFlats = ( layerSetId, filter: lights[0].filter, - lights, lightSequences, lightTotalCount: lights.length, lightTotalIntegrationMinutes: lightTotalIntegrationMs / 1000 / 60, + lights, - flats, flatSet: flats[0].setName, flatSequenceId: flats[0].sequenceId, flatsCount: flats.length, + flats, } as LayerSet; layerSets.push(layerSet); @@ -458,8 +458,8 @@ const AssignDarksBiasesToLayerSets = ( logger.error(`No darks found for ${layerSet.lights[0].setName}.`); } else { layerSet.darkSet = darks[0].setName; - layerSet.darks = darks; layerSet.darksCount = darks.length; + layerSet.darks = darks; } const biases = bankFiles.filter( @@ -470,8 +470,8 @@ const AssignDarksBiasesToLayerSets = ( logger.error(`No biases found for ${layerSet.flats[0].setName}.`); } else { layerSet.biasSet = biases[0].setName; - layerSet.biases = biases; layerSet.biasesCount = biases.length; + layerSet.biases = biases; } // Warn if there are multiple sequences for the same layer set @@ -576,3 +576,8 @@ const dispatchProject = ( // TODO. Copy the files to the project directory. }; + +// TODO. Enrich dataset 1 for a layerset with a missing dark. +// TODO. Enrich dataset 1 for a layerset with a missing flat. +// TODO. Enrich dataset 1 for a layerset with multiple dark sequences +// or in separated dataset TBD. From 0aa05e7f9f222aebe35ef7f8f2dfa626e4a6799b Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:42:22 +0100 Subject: [PATCH 14/18] chore: comment in dataset 1 --- src/tests/fixtures.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts index 0935d38..a3b09d2 100644 --- a/src/tests/fixtures.ts +++ b/src/tests/fixtures.ts @@ -80,7 +80,7 @@ const dataset_1 = [ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_O_gain100_20240511-094305_-10.0C_0002.fit", // Another Filter. "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094306_-10.5C_0001.fot", // Not a fit file based on extension. - // Darks matching set A. + // Darks matching set A. Not same filter as lights set A, but filter is irrelevant for darks. "bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", "bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155723_-10.0C_0002.fit", "bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155724_-10.0C_0003.fit", From 4450f9cd1de4b7e1b524b1f1df19f41a65f3e579 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 01:48:36 +0100 Subject: [PATCH 15/18] feat: dispatch files, cleanup --- src/commands/dispatch-dump.ts | 31 +++++++++++-------------------- src/utils/types.ts | 1 + src/utils/utils.ts | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index b25e639..b1b5c6a 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -94,25 +94,7 @@ const dispatch = async ({ await dispatchProject(potoProject, projectDirectory); - logger.success("Dispatch done ✅. POTO project generated 💃."); - - logger.step("Debug."); - - const debug = layerSets.map(x => { - return { - layerSetId: x.layerSetId, - lightTotalCount: x.lightTotalCount, - lightsStr: x.lights.map(x => x.fileName).join(", "), - flatsCount: x.flatsCount, - flatsStr: x.flats.map(x => x.fileName).join(", "), - darksCount: x.darksCount, - darksStr: x.darks.map(x => x.fileName).join(", "), - biasesCount: x.biasesCount, - biasesStr: x.biases.map(x => x.fileName).join(", "), - }; - }); - - logger.success("debug", debug); + logger.success("Dispatch complete."); // TODO. custom sort if LRGBSHO filter names to ease reading. }; @@ -574,7 +556,16 @@ const dispatchProject = ( fs.writeFileSync(potoJsonPath, JSON.stringify(potoProject, null, 2)); - // TODO. Copy the files to the project directory. + for (const layerSet of potoProject.layerSets) { + for (const file of [ + ...layerSet.lights, + ...layerSet.darks, + ...layerSet.flats, + ...layerSet.biases, + ]) { + copyFileToProject(file); + } + } }; // TODO. Enrich dataset 1 for a layerset with a missing dark. diff --git a/src/utils/types.ts b/src/utils/types.ts index 5221652..a697a53 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -126,6 +126,7 @@ export type PotoProject = { generatedAt: Date; potoVersion: string; layerSets: LayerSet[]; + // TODO. Move total light integrations & various stats here. }; export type LightsFlatsMatch = { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 47a2345..5ac8f37 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -197,7 +197,7 @@ export const copyFileToProject = (file: FileImageSpec) => { const targetFile = path.join(file.projectDirectory, file.fileName); fs.copyFileSync(file.sourceFilePath, targetFile); - logger.debug(`Copied ${file.fileName} to ${targetFile}`); + logger.debug(`- ${file.fileName} dispatched.`); }; /** From 99209596a2378eb2120e20044f19cbccfcb53675 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 02:04:33 +0100 Subject: [PATCH 16/18] chore: lint --- eslint.config.mjs | 3 +-- src/utils/logger.ts | 1 - src/utils/tests/utils.spec.ts | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 6a1ec22..a369e28 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -21,7 +21,6 @@ export default [ ...compat.extends( "eslint:recommended", "plugin:@typescript-eslint/recommended", - "prettier", ), { plugins: { @@ -42,7 +41,7 @@ export default [ rules: { indent: [ - "error", + "warn", 2, { offsetTernaryExpressions: true, diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 123dd48..637bbbc 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -1,5 +1,4 @@ import chalk from "chalk"; -import ansiEscapes from "ansi-escapes"; const debug = chalk.gray.italic; const info = chalk.blue; diff --git a/src/utils/tests/utils.spec.ts b/src/utils/tests/utils.spec.ts index b32751e..05f9a27 100644 --- a/src/utils/tests/utils.spec.ts +++ b/src/utils/tests/utils.spec.ts @@ -122,7 +122,7 @@ describe("utils", () => { } as FileImageSpec; jest.spyOn(fs, "existsSync").mockReturnValue(false); - jest.spyOn(fs, "mkdirSync").mockImplementation(_ => ""); + jest.spyOn(fs, "mkdirSync"); jest.spyOn(fs, "copyFileSync").mockImplementation(() => {}); copyFileToProject(file); From 4e9062d8fda70b238eb4206b1e2cd1867f257924 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 02:11:39 +0100 Subject: [PATCH 17/18] feat: fix generate script --- src/commands/generate-scripts.ts | 18 +++++++++--------- src/tests/fixtures.ts | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/commands/generate-scripts.ts b/src/commands/generate-scripts.ts index 32b65d4..8849d6c 100644 --- a/src/commands/generate-scripts.ts +++ b/src/commands/generate-scripts.ts @@ -50,14 +50,14 @@ const generateScriptForLightSet = ( const anyDirectory = path.join(projectDirectory, "any"); const processDirectory = path.join( filterDirectory, - `${set.lightSet}_process`, + `${set.layerSetId}_process`, ); if (!fs.existsSync(processDirectory)) { fs.mkdirSync(processDirectory, { recursive: false }); } const mastersDirectory = path.join( filterDirectory, - `${set.lightSet}_masters`, + `${set.layerSetId}_masters`, ); if (!fs.existsSync(mastersDirectory)) { fs.mkdirSync(mastersDirectory, { recursive: false }); @@ -73,7 +73,7 @@ const generateScriptForLightSet = ( // TODO. Move checkers to dispatch-dump. const lightsdirs = [...new Set(set.lights.map(x => x.projectDirectory))]; if (lightsdirs.length === 0) { - throw new Error("No lights found for filter " + set.lightSet); + throw new Error("No lights found for filter " + set.layerSetId); } if (lightsdirs.length > 1) { logger.errorThrow("Multiple sets of light for ", lightsdirs); @@ -82,28 +82,28 @@ const generateScriptForLightSet = ( const flatsDirs = [...new Set(set.flats.map(x => x.projectDirectory))]; if (flatsDirs.length === 0) { - throw new Error("No flats found for filter " + set.lightSet); + throw new Error("No flats found for filter " + set.layerSetId); } if (flatsDirs.length > 1) { - throw new Error("Multiple sets of flat for " + set.lightSet); + throw new Error("Multiple sets of flat for " + set.layerSetId); } const flatsDir = flatsDirs[0]; const darksDirs = [...new Set(set.darks.map(x => x.projectDirectory))]; if (darksDirs.length === 0) { - throw new Error("No darks found for filter " + set.lightSet); + throw new Error("No darks found for filter " + set.layerSetId); } if (darksDirs.length > 1) { - throw new Error("Multiple sets of darks for " + set.lightSet); + throw new Error("Multiple sets of darks for " + set.layerSetId); } const darksDir = darksDirs[0]; const biasesDirs = [...new Set(set.biases.map(x => x.projectDirectory))]; if (biasesDirs.length === 0) { - throw new Error("No biases found for filter " + set.lightSet); + throw new Error("No biases found for filter " + set.layerSetId); } if (biasesDirs.length > 1) { - throw new Error("Multiple sets of biases for " + set.lightSet); + throw new Error("Multiple sets of biases for " + set.layerSetId); } const biasesDir = biasesDirs[0]; diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts index a3b09d2..e73b582 100644 --- a/src/tests/fixtures.ts +++ b/src/tests/fixtures.ts @@ -1,6 +1,6 @@ import path from "path"; import fs from "fs"; -import { logger } from "src/utils/logger"; +import { logger } from "../utils/logger"; const tmpDir = "tmp"; From 18f2818738ba585313d74a5da76fa2336b1aaf05 Mon Sep 17 00:00:00 2001 From: Joris La Cancellera Date: Sun, 29 Dec 2024 02:53:24 +0100 Subject: [PATCH 18/18] feat: resolve e2e tests, update snapshot --- src/commands/dispatch-dump.ts | 7 +- .../__snapshots__/e2e-testing.spec.ts.snap | 631 ++++++++---------- src/tests/e2e/e2e-testing.spec.ts | 172 +++-- src/utils/types.ts | 4 +- 4 files changed, 396 insertions(+), 418 deletions(-) diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts index b1b5c6a..32e545c 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/dispatch-dump.ts @@ -29,6 +29,8 @@ export type DispatchOptions = { bankDirectory: string; }; +const enquirer = new Enquirer(); + const dispatch = async ({ projectDirectory, asiAirDirectory, @@ -109,7 +111,6 @@ export default dispatch; */ const ensureProjectDirectoryExists = async (projectDirectory: string) => { if (!fs.existsSync(projectDirectory)) { - const enquirer = new Enquirer(); const response = (await enquirer.prompt({ type: "confirm", name: "createProjectDirectory", @@ -274,8 +275,6 @@ const matchLightsToFlats = async ( const lightConcernedSetName = lightConcerned.split("__")[0]; const lightConcernedSequenceId = lightConcerned.split("__")[1]; - // Ask the user to select the flat sequence to use. - const enquirer = new Enquirer(); const response = (await enquirer.prompt({ type: "select", name: "selectedFlatSequence", @@ -532,7 +531,6 @@ const previewBeforeDispatching = async (layerSets: LayerSet[]) => { logger.space(); - const enquirer = new Enquirer(); const response = (await enquirer.prompt({ type: "confirm", name: "go", @@ -569,6 +567,7 @@ const dispatchProject = ( }; // TODO. Enrich dataset 1 for a layerset with a missing dark. +// TODO. Create a dataset 1 Light D (exact same as Light A, but another sequence, to be matched with another flat sequence). // TODO. Enrich dataset 1 for a layerset with a missing flat. // TODO. Enrich dataset 1 for a layerset with multiple dark sequences // or in separated dataset TBD. diff --git a/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap b/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap index e95a243..93e6a24 100644 --- a/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap +++ b/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap @@ -3,229 +3,26 @@ exports[`E2E should be neat 2`] = ` "{ "generatedAt": "2024-10-15T00:00:00.000Z", - "potoVersion": "0.1.0", + "potoVersion": "0.2.0", "layerSets": [ { - "filter": "S", - "lightSet": "Light_120.0s_Bin1_S_gain0", - "flatSet": "Flat_1.0ms_Bin1_S_gain100", - "darkSet": "Dark_120.0s_Bin1_L_gain0", - "biasSet": "Bias_1.0ms_Bin1_gain100", - "lightsCount": 1, - "flatsCount": 6, - "darksCount": 1, - "biasesCount": 3, - "lights": [ - { - "setName": "Light_120.0s_Bin1_S_gain0", - "type": "Light", - "bulb": "120.0s", - "bin": "Bin1", - "filter": "S", - "gain": 0, - "sequenceId": "20240626-010850", - "sequencePosition": 1, - "datetime": "2024-06-26T01:08:50.000Z", - "temperature": "-10.1C", - "fileName": "Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV", - "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit", - "projectDirectory": "tmp/project/S/Light_120.0s_Bin1_S_gain0" - } - ], - "darks": [ - { - "setName": "Dark_120.0s_Bin1_L_gain0", - "type": "Dark", - "bulb": "120.0s", - "bin": "Bin1", - "filter": "L", - "gain": 0, - "sequenceId": "20240308-155722", - "sequencePosition": 1, - "datetime": "2024-03-08T15:57:22.000Z", - "temperature": "-10.0C", - "fileName": "Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/bank/Darks", - "sourceFilePath": "tmp/bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit", - "projectDirectory": "tmp/project/any/Dark_120.0s_Bin1_gain0" - } - ], - "flats": [ - { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240624-094304", - "sequencePosition": 1, - "datetime": "2024-06-24T09:43:04.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, - { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240624-094304", - "sequencePosition": 2, - "datetime": "2024-06-24T09:43:05.000Z", - "temperature": "-10.0C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, - { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240624-094304", - "sequencePosition": 3, - "datetime": "2024-06-24T09:43:06.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, - { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240626-094304", - "sequencePosition": 1, - "datetime": "2024-06-26T09:43:04.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, - { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240626-094304", - "sequencePosition": 2, - "datetime": "2024-06-26T09:43:05.000Z", - "temperature": "-10.0C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, + "layerSetId": "Light_60.0s_Bin1_H_gain0", + "filter": "H", + "lightSequences": [ { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": "S", - "gain": 100, - "sequenceId": "20240626-094304", - "sequencePosition": 3, - "datetime": "2024-06-26T09:43:06.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit", - "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + "sequenceId": "20240625-010850", + "count": 3, + "integrationMinutes": 3 } ], - "biases": [ - { - "setName": "Bias_1.0ms_Bin1_gain100", - "type": "Bias", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": null, - "gain": 100, - "sequenceId": "20230910-101133", - "sequencePosition": 1, - "datetime": "2023-09-10T10:11:33.000Z", - "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", - "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" - }, - { - "setName": "Bias_1.0ms_Bin1_gain100", - "type": "Bias", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": null, - "gain": 100, - "sequenceId": "20230910-101133", - "sequencePosition": 2, - "datetime": "2023-09-10T10:11:33.000Z", - "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", - "extension": "fit", - "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", - "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" - }, - { - "setName": "Bias_1.0ms_Bin1_gain100", - "type": "Bias", - "bulb": "1.0ms", - "bin": "Bin1", - "filter": null, - "gain": 100, - "sequenceId": "20230910-101133", - "sequencePosition": 3, - "datetime": "2023-09-10T10:11:33.000Z", - "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", - "extension": "fit", - "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", - "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" - } - ] - }, - { - "filter": "H", - "lightSet": "Light_60.0s_Bin1_H_gain0", - "flatSet": "Flat_1.0ms_Bin1_H_gain100", - "darkSet": "Dark_60.0s_Bin1_gain0", - "biasSet": "Bias_1.0ms_Bin1_gain100", - "lightsCount": 3, - "flatsCount": 3, - "darksCount": 1, - "biasesCount": 3, + "lightTotalCount": 3, + "lightTotalIntegrationMinutes": 3, "lights": [ { "setName": "Light_60.0s_Bin1_H_gain0", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "H", "gain": 0, @@ -243,6 +40,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Light_60.0s_Bin1_H_gain0", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "H", "gain": 0, @@ -260,6 +58,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Light_60.0s_Bin1_H_gain0", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "H", "gain": 0, @@ -274,30 +73,15 @@ exports[`E2E should be neat 2`] = ` "projectDirectory": "tmp/project/H/Light_60.0s_Bin1_H_gain0" } ], - "darks": [ - { - "setName": "Dark_60.0s_Bin1_gain0", - "type": "Dark", - "bulb": "60.0s", - "bin": "Bin1", - "filter": null, - "gain": 0, - "sequenceId": "20240308-155722", - "sequencePosition": 1, - "datetime": "2024-03-08T15:57:22.000Z", - "temperature": "-10.0C", - "fileName": "Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", - "extension": "fit", - "sourceDirectory": "tmp/bank/Darks", - "sourceFilePath": "tmp/bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", - "projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain0" - } - ], + "flatSet": "Flat_1.0ms_Bin1_H_gain100", + "flatSequenceId": "20240511-094306", + "flatsCount": 3, "flats": [ { "setName": "Flat_1.0ms_Bin1_H_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "H", "gain": 100, @@ -315,80 +99,109 @@ exports[`E2E should be neat 2`] = ` "setName": "Flat_1.0ms_Bin1_H_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "H", "gain": 100, "sequenceId": "20240511-094306", "sequencePosition": 2, - "datetime": "2024-05-11T09:43:06.000Z", + "datetime": "2024-05-11T09:43:07.000Z", "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit", + "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit", "extension": "fit", "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit", + "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit", "projectDirectory": "tmp/project/H/Flat_1.0ms_Bin1_H_gain100" }, { "setName": "Flat_1.0ms_Bin1_H_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "H", "gain": 100, "sequenceId": "20240511-094306", "sequencePosition": 3, - "datetime": "2024-05-11T09:43:06.000Z", + "datetime": "2024-05-11T09:43:08.000Z", "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit", + "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit", "extension": "fit", "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit", + "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit", "projectDirectory": "tmp/project/H/Flat_1.0ms_Bin1_H_gain100" } ], + "darkSet": "Dark_60.0s_Bin1_gain0", + "darksCount": 1, + "darks": [ + { + "setName": "Dark_60.0s_Bin1_gain0", + "type": "Dark", + "bulb": "60.0s", + "bulbMs": 60000, + "bin": "Bin1", + "filter": null, + "gain": 0, + "sequenceId": "20240308-155722", + "sequencePosition": 1, + "datetime": "2024-03-08T15:57:22.000Z", + "temperature": "-10.0C", + "fileName": "Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", + "extension": "fit", + "sourceDirectory": "tmp/bank/Darks", + "sourceFilePath": "tmp/bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", + "projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain0" + } + ], + "biasSet": "Bias_1.0ms_Bin1_gain100", + "biasesCount": 3, "biases": [ { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 1, - "datetime": "2023-09-10T10:11:33.000Z", + "datetime": "2023-09-10T10:11:31.000Z", "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", "extension": "fit", "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 2, - "datetime": "2023-09-10T10:11:33.000Z", + "datetime": "2023-09-10T10:11:32.000Z", "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "extension": "fit", "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 3, "datetime": "2023-09-10T10:11:33.000Z", "temperature": "-9.8C", @@ -401,73 +214,140 @@ exports[`E2E should be neat 2`] = ` ] }, { + "layerSetId": "Light_60.0s_Bin1_S_gain100__20240624-010840", "filter": "S", - "lightSet": "Light_60.0s_Bin1_S_gain100", - "flatSet": "Flat_1.0ms_Bin1_S_gain100", - "darkSet": "Dark_60.0s_Bin1_L_gain100", - "biasSet": "Bias_1.0ms_Bin1_gain100", - "lightsCount": 3, - "flatsCount": 6, - "darksCount": 3, - "biasesCount": 3, + "lightSequences": [ + { + "sequenceId": "20240624-010840", + "count": 3, + "integrationMinutes": 3 + } + ], + "lightTotalCount": 3, + "lightTotalIntegrationMinutes": 3, "lights": [ { "setName": "Light_60.0s_Bin1_S_gain100", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "S", "gain": 100, - "sequenceId": "20240624-010850", + "sequenceId": "20240624-010840", "sequencePosition": 1, - "datetime": "2024-06-24T01:08:50.000Z", + "datetime": "2024-06-24T01:08:40.000Z", "temperature": "-10.1C", - "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit", + "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit", "extension": "fit", "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV", - "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit", + "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit", "projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100" }, { "setName": "Light_60.0s_Bin1_S_gain100", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "S", "gain": 100, - "sequenceId": "20240624-010850", + "sequenceId": "20240624-010840", "sequencePosition": 2, - "datetime": "2024-06-24T01:08:51.000Z", + "datetime": "2024-06-24T01:08:41.000Z", "temperature": "-10.1C", - "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit", + "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit", "extension": "fit", "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV", - "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit", + "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit", "projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100" }, { "setName": "Light_60.0s_Bin1_S_gain100", "type": "Light", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "S", "gain": 100, - "sequenceId": "20240624-010850", + "sequenceId": "20240624-010840", "sequencePosition": 3, - "datetime": "2024-06-24T01:08:52.000Z", + "datetime": "2024-06-24T01:08:42.000Z", "temperature": "-10.1C", - "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit", + "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit", "extension": "fit", "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV", - "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit", + "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit", "projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100" } ], + "flatSet": "Flat_1.0ms_Bin1_S_gain100", + "flatSequenceId": "20240624-094304", + "flatsCount": 3, + "flats": [ + { + "setName": "Flat_1.0ms_Bin1_S_gain100", + "type": "Flat", + "bulb": "1.0ms", + "bulbMs": 1, + "bin": "Bin1", + "filter": "S", + "gain": 100, + "sequenceId": "20240624-094304", + "sequencePosition": 1, + "datetime": "2024-06-24T09:43:04.000Z", + "temperature": "-10.5C", + "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", + "extension": "fit", + "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", + "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", + "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + }, + { + "setName": "Flat_1.0ms_Bin1_S_gain100", + "type": "Flat", + "bulb": "1.0ms", + "bulbMs": 1, + "bin": "Bin1", + "filter": "S", + "gain": 100, + "sequenceId": "20240624-094304", + "sequencePosition": 2, + "datetime": "2024-06-24T09:43:05.000Z", + "temperature": "-10.0C", + "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", + "extension": "fit", + "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", + "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", + "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + }, + { + "setName": "Flat_1.0ms_Bin1_S_gain100", + "type": "Flat", + "bulb": "1.0ms", + "bulbMs": 1, + "bin": "Bin1", + "filter": "S", + "gain": 100, + "sequenceId": "20240624-094304", + "sequencePosition": 3, + "datetime": "2024-06-24T09:43:06.000Z", + "temperature": "-10.5C", + "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", + "extension": "fit", + "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", + "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", + "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + } + ], + "darkSet": "Dark_60.0s_Bin1_L_gain100", + "darksCount": 3, "darks": [ { "setName": "Dark_60.0s_Bin1_L_gain100", "type": "Dark", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "L", "gain": 100, @@ -485,6 +365,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Dark_60.0s_Bin1_L_gain100", "type": "Dark", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "L", "gain": 100, @@ -502,6 +383,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Dark_60.0s_Bin1_L_gain100", "type": "Dark", "bulb": "60.0s", + "bulbMs": 60000, "bin": "Bin1", "filter": "L", "gain": 100, @@ -516,62 +398,106 @@ exports[`E2E should be neat 2`] = ` "projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain100" } ], - "flats": [ + "biasSet": "Bias_1.0ms_Bin1_gain100", + "biasesCount": 3, + "biases": [ { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", + "setName": "Bias_1.0ms_Bin1_gain100", + "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", - "filter": "S", + "filter": null, "gain": 100, - "sequenceId": "20240624-094304", + "sequenceId": "20230910-101131", "sequencePosition": 1, - "datetime": "2024-06-24T09:43:04.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", + "datetime": "2023-09-10T10:11:31.000Z", + "temperature": "-9.8C", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + "sourceDirectory": "tmp/bank/Bias", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", + "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", + "setName": "Bias_1.0ms_Bin1_gain100", + "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", - "filter": "S", + "filter": null, "gain": 100, - "sequenceId": "20240624-094304", + "sequenceId": "20230910-101131", "sequencePosition": 2, - "datetime": "2024-06-24T09:43:05.000Z", - "temperature": "-10.0C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", + "datetime": "2023-09-10T10:11:32.000Z", + "temperature": "-9.8C", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" + "sourceDirectory": "tmp/bank/Bias", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", + "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { - "setName": "Flat_1.0ms_Bin1_S_gain100", - "type": "Flat", + "setName": "Bias_1.0ms_Bin1_gain100", + "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", - "filter": "S", + "filter": null, "gain": 100, - "sequenceId": "20240624-094304", + "sequenceId": "20230910-101131", "sequencePosition": 3, - "datetime": "2024-06-24T09:43:06.000Z", - "temperature": "-10.5C", - "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", + "datetime": "2023-09-10T10:11:33.000Z", + "temperature": "-9.8C", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", "extension": "fit", - "sourceDirectory": "tmp/asiair-dump/Autorun/Flat", - "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit", - "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" - }, + "sourceDirectory": "tmp/bank/Bias", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", + "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" + } + ] + }, + { + "layerSetId": "Light_120.0s_Bin1_S_gain0__20240626-010853", + "filter": "S", + "lightSequences": [ + { + "sequenceId": "20240626-010853", + "count": 1, + "integrationMinutes": 2 + } + ], + "lightTotalCount": 1, + "lightTotalIntegrationMinutes": 2, + "lights": [ + { + "setName": "Light_120.0s_Bin1_S_gain0", + "type": "Light", + "bulb": "120.0s", + "bulbMs": 120000, + "bin": "Bin1", + "filter": "S", + "gain": 0, + "sequenceId": "20240626-010853", + "sequencePosition": 1, + "datetime": "2024-06-26T01:08:53.000Z", + "temperature": "-10.1C", + "fileName": "Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit", + "extension": "fit", + "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV", + "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit", + "projectDirectory": "tmp/project/S/Light_120.0s_Bin1_S_gain0" + } + ], + "flatSet": "Flat_1.0ms_Bin1_S_gain100", + "flatSequenceId": "20240626-094304", + "flatsCount": 3, + "flats": [ { "setName": "Flat_1.0ms_Bin1_S_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "S", "gain": 100, @@ -589,6 +515,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Flat_1.0ms_Bin1_S_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "S", "gain": 100, @@ -606,6 +533,7 @@ exports[`E2E should be neat 2`] = ` "setName": "Flat_1.0ms_Bin1_S_gain100", "type": "Flat", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": "S", "gain": 100, @@ -620,49 +548,76 @@ exports[`E2E should be neat 2`] = ` "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100" } ], + "darkSet": "Dark_120.0s_Bin1_L_gain0", + "darksCount": 1, + "darks": [ + { + "setName": "Dark_120.0s_Bin1_L_gain0", + "type": "Dark", + "bulb": "120.0s", + "bulbMs": 120000, + "bin": "Bin1", + "filter": "L", + "gain": 0, + "sequenceId": "20240308-155723", + "sequencePosition": 1, + "datetime": "2024-03-08T15:57:23.000Z", + "temperature": "-10.0C", + "fileName": "Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit", + "extension": "fit", + "sourceDirectory": "tmp/bank/Darks", + "sourceFilePath": "tmp/bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit", + "projectDirectory": "tmp/project/any/Dark_120.0s_Bin1_gain0" + } + ], + "biasSet": "Bias_1.0ms_Bin1_gain100", + "biasesCount": 3, "biases": [ { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 1, - "datetime": "2023-09-10T10:11:33.000Z", + "datetime": "2023-09-10T10:11:31.000Z", "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", "extension": "fit", "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 2, - "datetime": "2023-09-10T10:11:33.000Z", + "datetime": "2023-09-10T10:11:32.000Z", "temperature": "-9.8C", - "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "extension": "fit", "sourceDirectory": "tmp/bank/Bias", - "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100" }, { "setName": "Bias_1.0ms_Bin1_gain100", "type": "Bias", "bulb": "1.0ms", + "bulbMs": 1, "bin": "Bin1", "filter": null, "gain": 100, - "sequenceId": "20230910-101133", + "sequenceId": "20230910-101131", "sequencePosition": 3, "datetime": "2023-09-10T10:11:33.000Z", "temperature": "-9.8C", @@ -763,8 +718,8 @@ exports[`E2E should be neat 5`] = ` # flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ # darks: tmp/project/any/Dark_120.0s_Bin1_gain0/ # lights: tmp/project/S/Light_120.0s_Bin1_S_gain0/ -# process: tmp/project/S/Light_120.0s_Bin1_S_gain0_process/ -# masters: tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/ +# process: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/ +# masters: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/ # ############################################ @@ -772,38 +727,38 @@ requires 1.2.0 # Convert Bias Frames to .fit files cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process +convert bias -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked # Convert Flat Frames to .fit files cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100 -convert flat -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process +convert flat -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/bias_stacked +calibrate flat -bias=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked # Convert Dark Frames to .fit files cd tmp/project/any/Dark_120.0s_Bin1_gain0 -convert dark -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process +convert dark -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked # Convert Light Frames to .fit files cd tmp/project/S/Light_120.0s_Bin1_S_gain0 -convert light -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process +convert light -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Calibrate Light Frames -calibrate light -dark=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/dark_stacked -flat=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/pp_flat_stacked -cc=dark +calibrate light -dark=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked -flat=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light @@ -830,8 +785,8 @@ exports[`E2E should be neat 6`] = ` # flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ # darks: tmp/project/any/Dark_60.0s_Bin1_gain100/ # lights: tmp/project/S/Light_60.0s_Bin1_S_gain100/ -# process: tmp/project/S/Light_60.0s_Bin1_S_gain100_process/ -# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/ +# process: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/ +# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/ # ############################################ @@ -839,38 +794,38 @@ requires 1.2.0 # Convert Bias Frames to .fit files cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process +convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked # Convert Flat Frames to .fit files cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100 -convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process +convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/bias_stacked +calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked # Convert Dark Frames to .fit files cd tmp/project/any/Dark_60.0s_Bin1_gain100 -convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process +convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked # Convert Light Frames to .fit files cd tmp/project/S/Light_60.0s_Bin1_S_gain100 -convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process +convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Calibrate Light Frames -calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/pp_flat_stacked -cc=dark +calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light diff --git a/src/tests/e2e/e2e-testing.spec.ts b/src/tests/e2e/e2e-testing.spec.ts index 9d0afc2..2f2996f 100644 --- a/src/tests/e2e/e2e-testing.spec.ts +++ b/src/tests/e2e/e2e-testing.spec.ts @@ -1,12 +1,16 @@ import { jest } from "@jest/globals"; // Import Jest globals import path from "path"; import fs from "fs"; +import Enquirer from "enquirer"; + import dispatch from "../../commands/dispatch-dump"; import { POTO_JSON } from "../../utils/const"; import { cleanThumbnails } from "../../commands/asiair-dump-cleaning"; import { generateScripts } from "../../commands/generate-scripts"; import { spawnMockedDatasetToFs_dataset_1 } from "../fixtures"; +jest.mock("enquirer"); + describe("E2E", () => { let asiAirDirectory: string = ""; let bankDirectory: string = ""; @@ -19,38 +23,56 @@ describe("E2E", () => { spawnMockedDatasetToFs_dataset_1()); }); - test("should be neat", async () => { - let files = fs.readdirSync(asiAirDirectory, { - recursive: true, - withFileTypes: false, - encoding: "utf8", - }); - expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(3); - - cleanThumbnails(asiAirDirectory); - - files = fs.readdirSync(asiAirDirectory, { - recursive: true, - withFileTypes: false, - encoding: "utf8", - }); - expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(0); - - fs.mkdirSync(projectDirectory, { recursive: true }); - await dispatch({ - projectDirectory, - asiAirDirectory, - shootingMode: "autorun", - bankDirectory, - }); - - files = fs.readdirSync(projectDirectory, { - recursive: true, - withFileTypes: false, - encoding: "utf8", - }); - - expect(files).toMatchInlineSnapshot(` + test( + "should be neat", + async () => { + const promptMock = jest.fn(); + (Enquirer.prototype.prompt as jest.Mock) = promptMock; + + promptMock + .mockResolvedValueOnce({ + createProjectDirectory: true, + } as never) + .mockResolvedValueOnce({ + selectedFlatSequence: "Flat_1.0ms_Bin1_S_gain100__20240624-094304", + } as never) + .mockResolvedValueOnce({ + selectedFlatSequence: "Flat_1.0ms_Bin1_S_gain100__20240626-094304", + } as never) + .mockResolvedValueOnce({ + go: true, + } as never); + + let files = fs.readdirSync(asiAirDirectory, { + recursive: true, + withFileTypes: false, + encoding: "utf8", + }); + expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(3); + + cleanThumbnails(asiAirDirectory); + + files = fs.readdirSync(asiAirDirectory, { + recursive: true, + withFileTypes: false, + encoding: "utf8", + }); + expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(0); + + await dispatch({ + projectDirectory, + asiAirDirectory, + shootingMode: "autorun", + bankDirectory, + }); + + files = fs.readdirSync(projectDirectory, { + recursive: true, + withFileTypes: false, + encoding: "utf8", + }); + + expect(files).toMatchInlineSnapshot(` [ "H", "S", @@ -66,8 +88,8 @@ describe("E2E", () => { "any/Dark_60.0s_Bin1_gain0", "any/Dark_60.0s_Bin1_gain100", "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001.fit", - "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit", - "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit", + "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit", + "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit", "H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010850_-10.1C_0001.fit", "H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010851_-10.1C_0002.fit", "H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010852_-10.1C_0003.fit", @@ -77,14 +99,14 @@ describe("E2E", () => { "S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit", "S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit", "S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit", - "S/Light_120.0s_Bin1_S_gain0/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit", - "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit", - "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit", - "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit", - "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit", - "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit", + "S/Light_120.0s_Bin1_S_gain0/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit", + "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit", + "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit", + "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit", + "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit", + "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit", "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit", - "any/Dark_120.0s_Bin1_gain0/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit", + "any/Dark_120.0s_Bin1_gain0/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit", "any/Dark_60.0s_Bin1_gain0/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit", "any/Dark_60.0s_Bin1_gain100/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", "any/Dark_60.0s_Bin1_gain100/Dark_60.0s_Bin1_L_gain100_20240308-155723_-10.0C_0002.fit", @@ -92,46 +114,48 @@ describe("E2E", () => { ] `); - const potoJson = fs.readFileSync(path.join(projectDirectory, POTO_JSON), { - encoding: "utf8", - }); + const potoJson = fs.readFileSync(path.join(projectDirectory, POTO_JSON), { + encoding: "utf8", + }); - expect(potoJson).toMatchSnapshot(); + expect(potoJson).toMatchSnapshot(); - await generateScripts( - projectDirectory, - "src/process/mono_processing_process/1_preprocessing.ssf", - ); + await generateScripts( + projectDirectory, + "src/process/mono_processing_process/1_preprocessing.ssf", + ); - files = fs.readdirSync(projectDirectory, { - recursive: true, - withFileTypes: false, - encoding: "utf8", - }); + files = fs.readdirSync(projectDirectory, { + recursive: true, + withFileTypes: false, + encoding: "utf8", + }); - const scripts = files.filter(f => f.endsWith(".ssf")); - expect(scripts).toHaveLength(3); - expect(scripts).toMatchInlineSnapshot(` + const scripts = files.filter(f => f.endsWith(".ssf")); + expect(scripts).toHaveLength(3); + expect(scripts).toMatchInlineSnapshot(` [ "H/Light_60.0s_Bin1_H_gain0_process/poto_1_preprocessing.ssf", - "S/Light_120.0s_Bin1_S_gain0_process/poto_1_preprocessing.ssf", - "S/Light_60.0s_Bin1_S_gain100_process/poto_1_preprocessing.ssf", + "S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/poto_1_preprocessing.ssf", + "S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/poto_1_preprocessing.ssf", ] `); - const script1 = fs.readFileSync(path.join(projectDirectory, scripts[0]), { - encoding: "utf8", - }); - expect(script1).toMatchSnapshot(); - - const script2 = fs.readFileSync(path.join(projectDirectory, scripts[1]), { - encoding: "utf8", - }); - expect(script2).toMatchSnapshot(); - - const script3 = fs.readFileSync(path.join(projectDirectory, scripts[2]), { - encoding: "utf8", - }); - expect(script3).toMatchSnapshot(); - }); + const script1 = fs.readFileSync(path.join(projectDirectory, scripts[0]), { + encoding: "utf8", + }); + expect(script1).toMatchSnapshot(); + + const script2 = fs.readFileSync(path.join(projectDirectory, scripts[1]), { + encoding: "utf8", + }); + expect(script2).toMatchSnapshot(); + + const script3 = fs.readFileSync(path.join(projectDirectory, scripts[2]), { + encoding: "utf8", + }); + expect(script3).toMatchSnapshot(); + }, + 30 * 1000, + ); }); diff --git a/src/utils/types.ts b/src/utils/types.ts index a697a53..2197b33 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -103,8 +103,8 @@ export type LayerSet = { count: number; integrationMinutes: number; }[]; - lightTotalCount: number; - lightTotalIntegrationMinutes: number; + lightTotalCount: number; // TODO. fix duplicate of sum of lightSequences.count + lightTotalIntegrationMinutes: number; // TODO. fix duplicate of sum of lightSequences.integrationMinutes flatSet: string; flatSequenceId: string;