Replace mock-fs to memfs

This commit is contained in:
okou 2024-10-08 19:11:03 +09:00
parent 995edadc13
commit 37bd795e4b
32 changed files with 341 additions and 285 deletions

View file

@ -14,4 +14,7 @@ module.exports = {
"^@/(.*)$": "<rootDir>/src/$1", "^@/(.*)$": "<rootDir>/src/$1",
}, },
transformIgnorePatterns: [], transformIgnorePatterns: [],
setupFilesAfterEnv: [
"./tests/setup-memfs.ts",
],
}; };

316
package-lock.json generated
View file

@ -18,22 +18,21 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-env": "^7.23.8", "@babel/preset-env": "^7.23.8",
"@types/adm-zip": "^0.5.5",
"@types/jest": "^29.5.11", "@types/jest": "^29.5.11",
"@types/mock-fs": "^4.13.4",
"@types/node": "^16.18.31", "@types/node": "^16.18.31",
"@types/node-fetch": "^2.6.10", "@types/node-fetch": "^2.6.10",
"@types/semver": "^7.5.6", "@types/semver": "^7.5.6",
"@types/yazl": "^2.4.5",
"@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1", "@typescript-eslint/parser": "^6.18.1",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.1",
"adm-zip": "^0.5.16",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"mock-fs": "^5.2.0", "memfs": "^4.13.0",
"ts-jest": "^29.1.1", "ts-jest": "^29.1.1",
"typescript": "^5.3.3", "typescript": "^5.3.3"
"yazl": "^2.5.1"
} }
}, },
"node_modules/@aashutoshrathi/word-wrap": { "node_modules/@aashutoshrathi/word-wrap": {
@ -2656,6 +2655,63 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@jsonjoy.com/base64": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz",
"integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"peerDependencies": {
"tslib": "2"
}
},
"node_modules/@jsonjoy.com/json-pack": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz",
"integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jsonjoy.com/base64": "^1.1.1",
"@jsonjoy.com/util": "^1.1.2",
"hyperdyperid": "^1.2.0",
"thingies": "^1.20.0"
},
"engines": {
"node": ">=10.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"peerDependencies": {
"tslib": "2"
}
},
"node_modules/@jsonjoy.com/util": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz",
"integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"peerDependencies": {
"tslib": "2"
}
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -2712,6 +2768,16 @@
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
} }
}, },
"node_modules/@types/adm-zip": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.5.tgz",
"integrity": "sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/babel__core": { "node_modules/@types/babel__core": {
"version": "7.20.5", "version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@ -2802,15 +2868,6 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true "dev": true
}, },
"node_modules/@types/mock-fs": {
"version": "4.13.4",
"resolved": "https://registry.npmjs.org/@types/mock-fs/-/mock-fs-4.13.4.tgz",
"integrity": "sha512-mXmM0o6lULPI8z3XNnQCpL0BGxPwx1Ul1wXYEPBGl4efShyxW2Rln0JOPEWGyZaYZMM6OVXM/15zUuFMY52ljg==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.18.70", "version": "16.18.70",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz",
@ -2854,15 +2911,6 @@
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"dev": true "dev": true
}, },
"node_modules/@types/yazl": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@types/yazl/-/yazl-2.4.5.tgz",
"integrity": "sha512-qpmPfx32HS7vlGJf7EsoM9qJnLZhXJBf1KH0hzfdc+D794rljQWh4H0I/UrZy+6Nhqn0l2jdBZXBGZtR1vnHqw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.18.1", "version": "6.18.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz",
@ -3113,6 +3161,16 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/adm-zip": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -3491,15 +3549,6 @@
"node-int64": "^0.4.0" "node-int64": "^0.4.0"
} }
}, },
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/buffer-from": { "node_modules/buffer-from": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@ -4666,6 +4715,16 @@
"node": ">=10.17.0" "node": ">=10.17.0"
} }
}, },
"node_modules/hyperdyperid": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz",
"integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.18"
}
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
@ -6656,6 +6715,26 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"node_modules/memfs": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.13.0.tgz",
"integrity": "sha512-dIs5KGy24fbdDhIAg0RxXpFqQp3RwL6wgSMRF9OSuphL/Uc9a4u2/SDJKPLj/zUgtOGKuHrRMrj563+IErj4Cg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jsonjoy.com/json-pack": "^1.0.3",
"@jsonjoy.com/util": "^1.3.0",
"tree-dump": "^1.0.1",
"tslib": "^2.0.0"
},
"engines": {
"node": ">= 4.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
}
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -6724,15 +6803,6 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/mock-fs": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.2.0.tgz",
"integrity": "sha512-2dF2R6YMSZbpip1V1WHKGLNjr/k48uQClqMVb5H3MOvwc9qhYis3/IWbj02qIg/Y8MDXKFF4c5v0rxx2o6xTZw==",
"dev": true,
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -7529,6 +7599,19 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true "dev": true
}, },
"node_modules/thingies": {
"version": "1.21.0",
"resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz",
"integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==",
"dev": true,
"license": "Unlicense",
"engines": {
"node": ">=10.18"
},
"peerDependencies": {
"tslib": "^2"
}
},
"node_modules/tmpl": { "node_modules/tmpl": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@ -7560,6 +7643,23 @@
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
}, },
"node_modules/tree-dump": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz",
"integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"peerDependencies": {
"tslib": "2"
}
},
"node_modules/ts-api-utils": { "node_modules/ts-api-utils": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
@ -7615,6 +7715,13 @@
} }
} }
}, },
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -7905,15 +8012,6 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/yazl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
"dev": true,
"dependencies": {
"buffer-crc32": "~0.2.3"
}
},
"node_modules/yocto-queue": { "node_modules/yocto-queue": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@ -9794,6 +9892,32 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"@jsonjoy.com/base64": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz",
"integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==",
"dev": true,
"requires": {}
},
"@jsonjoy.com/json-pack": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz",
"integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==",
"dev": true,
"requires": {
"@jsonjoy.com/base64": "^1.1.1",
"@jsonjoy.com/util": "^1.1.2",
"hyperdyperid": "^1.2.0",
"thingies": "^1.20.0"
}
},
"@jsonjoy.com/util": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz",
"integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==",
"dev": true,
"requires": {}
},
"@nodelib/fs.scandir": { "@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -9841,6 +9965,15 @@
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
} }
}, },
"@types/adm-zip": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.5.tgz",
"integrity": "sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/babel__core": { "@types/babel__core": {
"version": "7.20.5", "version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@ -9931,15 +10064,6 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true "dev": true
}, },
"@types/mock-fs": {
"version": "4.13.4",
"resolved": "https://registry.npmjs.org/@types/mock-fs/-/mock-fs-4.13.4.tgz",
"integrity": "sha512-mXmM0o6lULPI8z3XNnQCpL0BGxPwx1Ul1wXYEPBGl4efShyxW2Rln0JOPEWGyZaYZMM6OVXM/15zUuFMY52ljg==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": { "@types/node": {
"version": "16.18.70", "version": "16.18.70",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz",
@ -9983,15 +10107,6 @@
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"dev": true "dev": true
}, },
"@types/yazl": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@types/yazl/-/yazl-2.4.5.tgz",
"integrity": "sha512-qpmPfx32HS7vlGJf7EsoM9qJnLZhXJBf1KH0hzfdc+D794rljQWh4H0I/UrZy+6Nhqn0l2jdBZXBGZtR1vnHqw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "6.18.1", "version": "6.18.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz",
@ -10138,6 +10253,12 @@
"dev": true, "dev": true,
"requires": {} "requires": {}
}, },
"adm-zip": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
"dev": true
},
"ajv": { "ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -10418,12 +10539,6 @@
"node-int64": "^0.4.0" "node-int64": "^0.4.0"
} }
}, },
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true
},
"buffer-from": { "buffer-from": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@ -11260,6 +11375,12 @@
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true "dev": true
}, },
"hyperdyperid": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz",
"integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==",
"dev": true
},
"ignore": { "ignore": {
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
@ -12748,6 +12869,18 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"memfs": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.13.0.tgz",
"integrity": "sha512-dIs5KGy24fbdDhIAg0RxXpFqQp3RwL6wgSMRF9OSuphL/Uc9a4u2/SDJKPLj/zUgtOGKuHrRMrj563+IErj4Cg==",
"dev": true,
"requires": {
"@jsonjoy.com/json-pack": "^1.0.3",
"@jsonjoy.com/util": "^1.3.0",
"tree-dump": "^1.0.1",
"tslib": "^2.0.0"
}
},
"merge-stream": { "merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -12798,12 +12931,6 @@
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
}, },
"mock-fs": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.2.0.tgz",
"integrity": "sha512-2dF2R6YMSZbpip1V1WHKGLNjr/k48uQClqMVb5H3MOvwc9qhYis3/IWbj02qIg/Y8MDXKFF4c5v0rxx2o6xTZw==",
"dev": true
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -13361,6 +13488,13 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true "dev": true
}, },
"thingies": {
"version": "1.21.0",
"resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz",
"integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==",
"dev": true,
"requires": {}
},
"tmpl": { "tmpl": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@ -13386,6 +13520,13 @@
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
}, },
"tree-dump": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz",
"integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==",
"dev": true,
"requires": {}
},
"ts-api-utils": { "ts-api-utils": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
@ -13409,6 +13550,12 @@
"yargs-parser": "^21.0.1" "yargs-parser": "^21.0.1"
} }
}, },
"tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true
},
"type-check": { "type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -13608,15 +13755,6 @@
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true "dev": true
}, },
"yazl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3"
}
},
"yocto-queue": { "yocto-queue": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View file

@ -35,22 +35,21 @@
"homepage": "https://github.com/Kir-Antipov/mc-publish#readme", "homepage": "https://github.com/Kir-Antipov/mc-publish#readme",
"devDependencies": { "devDependencies": {
"@babel/preset-env": "^7.23.8", "@babel/preset-env": "^7.23.8",
"@types/adm-zip": "^0.5.5",
"@types/jest": "^29.5.11", "@types/jest": "^29.5.11",
"@types/mock-fs": "^4.13.4",
"@types/node": "^16.18.31", "@types/node": "^16.18.31",
"@types/node-fetch": "^2.6.10", "@types/node-fetch": "^2.6.10",
"@types/semver": "^7.5.6", "@types/semver": "^7.5.6",
"@types/yazl": "^2.4.5",
"@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1", "@typescript-eslint/parser": "^6.18.1",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.1",
"adm-zip": "^0.5.16",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"mock-fs": "^5.2.0", "memfs": "^4.13.0",
"ts-jest": "^29.1.1", "ts-jest": "^29.1.1",
"typescript": "^5.3.3", "typescript": "^5.3.3"
"yazl": "^2.5.1"
}, },
"dependencies": { "dependencies": {
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",

6
tests/setup-memfs.ts Normal file
View file

@ -0,0 +1,6 @@
import { fs } from "memfs";
jest.mock("node:fs", () => fs);
jest.mock("node:fs/promises", () => fs.promises);
jest.mock("fs", () => fs);
jest.mock("fs/promises", () => fs.promises);

View file

@ -1,4 +1,4 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import { parseVersion } from "@/utils/versioning/version"; import { parseVersion } from "@/utils/versioning/version";
import { VersionType } from "@/utils/versioning/version-type"; import { VersionType } from "@/utils/versioning/version-type";
@ -87,7 +87,7 @@ describe("MinecraftVersion", () => {
describe("getMinecraftVersionManifestEntries", () => { describe("getMinecraftVersionManifestEntries", () => {
const manifest : MinecraftVersionManifest = JSON.parse( const manifest : MinecraftVersionManifest = JSON.parse(
readFileSync(resolve(__dirname, "../../../content/mojang/version_manifest_v2.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/mojang/version_manifest_v2.json"), "utf8")
); );
test("returns correct number of entries", () => { test("returns correct number of entries", () => {

View file

@ -1,19 +1,15 @@
import { zipFile } from "@/../tests/utils/zip-utils"; import { zipFile } from "@/../tests/utils/zip-utils";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { FabricMetadata } from "@/loaders/fabric/fabric-metadata"; import { FabricMetadata } from "@/loaders/fabric/fabric-metadata";
import { FabricMetadataReader } from "@/loaders/fabric/fabric-metadata-reader"; import { FabricMetadataReader } from "@/loaders/fabric/fabric-metadata-reader";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromJSON({
"fabric.mod.jar": await zipFile([__dirname, "../../../content/fabric/fabric.mod.json"]), "fabric.mod.jar": zipFile([__dirname, "../../../content/fabric/fabric.mod.json"]),
"text.txt": "", "text.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("FabricMetadataReader", () => { describe("FabricMetadataReader", () => {
test("successfully reads fabric.mod.json", async () => { test("successfully reads fabric.mod.json", async () => {
const reader = new FabricMetadataReader(); const reader = new FabricMetadataReader();

View file

@ -1,4 +1,4 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve as resolvePath } from "node:path"; import { resolve as resolvePath } from "node:path";
import { DependencyType } from "@/dependencies/dependency-type"; import { DependencyType } from "@/dependencies/dependency-type";
import { PlatformType } from "@/platforms/platform-type"; import { PlatformType } from "@/platforms/platform-type";
@ -6,7 +6,7 @@ import { RawFabricMetadata } from "@/loaders/fabric/raw-fabric-metadata";
import { FabricMetadata } from "@/loaders/fabric/fabric-metadata"; import { FabricMetadata } from "@/loaders/fabric/fabric-metadata";
const RAW_METADATA: RawFabricMetadata = Object.freeze(JSON.parse( const RAW_METADATA: RawFabricMetadata = Object.freeze(JSON.parse(
readFileSync(resolvePath(__dirname, "../../../content/fabric/fabric.mod.json"), "utf8") actualFs.readFileSync(resolvePath(__dirname, "../../../content/fabric/fabric.mod.json"), "utf8")
)); ));
describe("FabricMetadata", () => { describe("FabricMetadata", () => {

View file

@ -1,19 +1,15 @@
import { zipFile } from "@/../tests/utils/zip-utils"; import { zipFile } from "@/../tests/utils/zip-utils";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { ForgeMetadata } from "@/loaders/forge/forge-metadata"; import { ForgeMetadata } from "@/loaders/forge/forge-metadata";
import { ForgeMetadataReader } from "@/loaders/forge/forge-metadata-reader"; import { ForgeMetadataReader } from "@/loaders/forge/forge-metadata-reader";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromJSON({
"forge.mod.jar": await zipFile([__dirname, "../../../content/forge/mods.toml"], "META-INF/mods.toml"), "forge.mod.jar": zipFile([__dirname, "../../../content/forge/mods.toml"], "META-INF/mods.toml"),
"text.txt": "", "text.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("ForgeMetadataReader", () => { describe("ForgeMetadataReader", () => {
test("successfully reads mods.toml", async () => { test("successfully reads mods.toml", async () => {
const reader = new ForgeMetadataReader(); const reader = new ForgeMetadataReader();

View file

@ -1,4 +1,4 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve as resolvePath } from "node:path"; import { resolve as resolvePath } from "node:path";
import { parse as parseToml } from "toml"; import { parse as parseToml } from "toml";
import { DependencyType } from "@/dependencies/dependency-type"; import { DependencyType } from "@/dependencies/dependency-type";
@ -7,7 +7,7 @@ import { RawForgeMetadata } from "@/loaders/forge/raw-forge-metadata";
import { ForgeMetadata } from "@/loaders/forge/forge-metadata"; import { ForgeMetadata } from "@/loaders/forge/forge-metadata";
const RAW_METADATA: RawForgeMetadata = Object.freeze(parseToml( const RAW_METADATA: RawForgeMetadata = Object.freeze(parseToml(
readFileSync(resolvePath(__dirname, "../../../content/forge/mods.toml"), "utf8") actualFs.readFileSync(resolvePath(__dirname, "../../../content/forge/mods.toml"), "utf8")
)); ));
describe("ForgeMetadata", () => { describe("ForgeMetadata", () => {

View file

@ -1,6 +1,6 @@
import { zipFile } from "@/../tests/utils/zip-utils"; import { zipFile } from "@/../tests/utils/zip-utils";
import { LoaderType } from "@/loaders/loader-type"; import { LoaderType } from "@/loaders/loader-type";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { import {
LoaderMetadataReader, LoaderMetadataReader,
combineLoaderMetadataReaders, combineLoaderMetadataReaders,
@ -8,21 +8,17 @@ import {
createDefaultLoaderMetadataReader, createDefaultLoaderMetadataReader,
} from "@/loaders/loader-metadata-reader"; } from "@/loaders/loader-metadata-reader";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromJSON({
"fabric.jar": await zipFile([__dirname, "../../content/fabric/fabric.mod.json"]), "fabric.jar": zipFile([__dirname, "../../content/fabric/fabric.mod.json"]),
"quilt.jar": await zipFile([__dirname, "../../content/quilt/quilt.mod.json"]), "quilt.jar": zipFile([__dirname, "../../content/quilt/quilt.mod.json"]),
"forge.jar": await zipFile([__dirname, "../../content/forge/mods.toml"], "META-INF/mods.toml"), "forge.jar": zipFile([__dirname, "../../content/forge/mods.toml"], "META-INF/mods.toml"),
"neoforge.jar": await zipFile([__dirname, "../../content/neoforge/neoforge.mods.toml"], "META-INF/neoforge.mods.toml"), "neoforge.jar": zipFile([__dirname, "../../content/neoforge/neoforge.mods.toml"], "META-INF/neoforge.mods.toml"),
"neoforge.legacy.jar": await zipFile([__dirname, "../../content/neoforge/neoforge.mods.toml"], "META-INF/mods.toml"), "neoforge.legacy.jar": zipFile([__dirname, "../../content/neoforge/neoforge.mods.toml"], "META-INF/mods.toml"),
"text.txt": "", "text.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("combineLoaderMetadataReaders", () => { describe("combineLoaderMetadataReaders", () => {
test("combined reader returns metadata from the first underlying reader that successfully reads the metadata", async () => { test("combined reader returns metadata from the first underlying reader that successfully reads the metadata", async () => {
const reader1 = { readMetadataFile: jest.fn().mockImplementation(x => x === "1" ? Promise.resolve({ id: "1" }) : Promise.reject(new Error("Unknown id"))) } as LoaderMetadataReader; const reader1 = { readMetadataFile: jest.fn().mockImplementation(x => x === "1" ? Promise.resolve({ id: "1" }) : Promise.reject(new Error("Unknown id"))) } as LoaderMetadataReader;

View file

@ -1,19 +1,15 @@
import { zipFile } from "@/../tests/utils/zip-utils"; import { zipFile } from "@/../tests/utils/zip-utils";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { NeoForgeMetadata } from "@/loaders/neoforge/neoforge-metadata"; import { NeoForgeMetadata } from "@/loaders/neoforge/neoforge-metadata";
import { NeoForgeMetadataReader } from "@/loaders/neoforge/neoforge-metadata-reader"; import { NeoForgeMetadataReader } from "@/loaders/neoforge/neoforge-metadata-reader";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromJSON({
"neoforge.mod.jar": await zipFile([__dirname, "../../../content/neoforge/neoforge.mods.toml"], "META-INF/neoforge.mods.toml"), "neoforge.mod.jar": zipFile([__dirname, "../../../content/neoforge/neoforge.mods.toml"], "META-INF/neoforge.mods.toml"),
"text.txt": "", "text.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("NeoForgeMetadataReader", () => { describe("NeoForgeMetadataReader", () => {
test("successfully reads neoforge.mods.toml", async () => { test("successfully reads neoforge.mods.toml", async () => {
const reader = new NeoForgeMetadataReader(); const reader = new NeoForgeMetadataReader();

View file

@ -1,4 +1,4 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve as resolvePath } from "node:path"; import { resolve as resolvePath } from "node:path";
import { parse as parseToml } from "toml"; import { parse as parseToml } from "toml";
import { DependencyType } from "@/dependencies/dependency-type"; import { DependencyType } from "@/dependencies/dependency-type";
@ -7,7 +7,7 @@ import { RawNeoForgeMetadata } from "@/loaders/neoforge/raw-neoforge-metadata";
import { NeoForgeMetadata } from "@/loaders/neoforge/neoforge-metadata"; import { NeoForgeMetadata } from "@/loaders/neoforge/neoforge-metadata";
const RAW_METADATA: RawNeoForgeMetadata = Object.freeze(parseToml( const RAW_METADATA: RawNeoForgeMetadata = Object.freeze(parseToml(
readFileSync(resolvePath(__dirname, "../../../content/neoforge/neoforge.mods.toml"), "utf8") actualFs.readFileSync(resolvePath(__dirname, "../../../content/neoforge/neoforge.mods.toml"), "utf8")
)); ));
describe("NeoForgeMetadata", () => { describe("NeoForgeMetadata", () => {

View file

@ -1,19 +1,15 @@
import { zipFile } from "@/../tests/utils/zip-utils"; import { zipFile } from "@/../tests/utils/zip-utils";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { QuiltMetadata } from "@/loaders/quilt/quilt-metadata"; import { QuiltMetadata } from "@/loaders/quilt/quilt-metadata";
import { QuiltMetadataReader } from "@/loaders/quilt/quilt-metadata-reader"; import { QuiltMetadataReader } from "@/loaders/quilt/quilt-metadata-reader";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromJSON({
"quilt.mod.jar": await zipFile([__dirname, "../../../content/quilt/quilt.mod.json"]), "quilt.mod.jar": zipFile([__dirname, "../../../content/quilt/quilt.mod.json"]),
"text.txt": "", "text.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("QuiltMetadataReader", () => { describe("QuiltMetadataReader", () => {
test("successfully reads quilt.mod.json", async () => { test("successfully reads quilt.mod.json", async () => {
const reader = new QuiltMetadataReader(); const reader = new QuiltMetadataReader();

View file

@ -1,4 +1,4 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve as resolvePath } from "node:path"; import { resolve as resolvePath } from "node:path";
import { DependencyType } from "@/dependencies/dependency-type"; import { DependencyType } from "@/dependencies/dependency-type";
import { PlatformType } from "@/platforms/platform-type"; import { PlatformType } from "@/platforms/platform-type";
@ -6,7 +6,7 @@ import { RawQuiltMetadata } from "@/loaders/quilt/raw-quilt-metadata";
import { QuiltMetadata } from "@/loaders/quilt/quilt-metadata"; import { QuiltMetadata } from "@/loaders/quilt/quilt-metadata";
const RAW_METADATA: RawQuiltMetadata = Object.freeze(JSON.parse( const RAW_METADATA: RawQuiltMetadata = Object.freeze(JSON.parse(
readFileSync(resolvePath(__dirname, "../../../content/quilt/quilt.mod.json"), "utf8") actualFs.readFileSync(resolvePath(__dirname, "../../../content/quilt/quilt.mod.json"), "utf8")
)); ));
describe("QuiltMetadata", () => { describe("QuiltMetadata", () => {

View file

@ -1,13 +1,13 @@
import { resolve } from "node:path"; import { resolve } from "node:path";
import { readFile } from "node:fs/promises"; import { actualFsPromises } from "@/../tests/utils/actual-fs";
import { BUKKIT_GAME_VERSION_TYPE } from "@/platforms/curseforge/curseforge-game-version-type"; import { BUKKIT_GAME_VERSION_TYPE } from "@/platforms/curseforge/curseforge-game-version-type";
import { createCurseForgeGameVersionMap } from "@/platforms/curseforge/curseforge-game-version-map"; import { createCurseForgeGameVersionMap } from "@/platforms/curseforge/curseforge-game-version-map";
describe("createCurseForgeGameVersionMap", () => { describe("createCurseForgeGameVersionMap", () => {
test("organizes the provided versions into their respective buckets", async () => { test("organizes the provided versions into their respective buckets", async () => {
const [versionsSource, versionTypesSource] = await Promise.all([ const [versionsSource, versionTypesSource] = await Promise.all([
readFile(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8"), actualFsPromises.readFile(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8"),
readFile(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8"), actualFsPromises.readFile(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8"),
]); ]);
const versions = JSON.parse(versionsSource); const versions = JSON.parse(versionsSource);
const versionTypes = [...JSON.parse(versionTypesSource), BUKKIT_GAME_VERSION_TYPE]; const versionTypes = [...JSON.parse(versionTypesSource), BUKKIT_GAME_VERSION_TYPE];

View file

@ -1,6 +1,6 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { createFakeFetch } from "../../../utils/fetch-utils"; import { createFakeFetch } from "../../../utils/fetch-utils";
import { FormData } from "@/utils/net/form-data"; import { FormData } from "@/utils/net/form-data";
import { HttpResponse } from "@/utils/net/http-response"; import { HttpResponse } from "@/utils/net/http-response";
@ -16,11 +16,11 @@ const FILES = Object.freeze([
const DB = Object.freeze({ const DB = Object.freeze({
versionTypes: Object.freeze(JSON.parse( versionTypes: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8")
)), )),
versions: Object.freeze(JSON.parse( versions: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8")
)), )),
projects: Object.freeze([ projects: Object.freeze([
@ -157,11 +157,7 @@ const CURSEFORGE_FETCH = createFakeFetch({
beforeEach(() => { beforeEach(() => {
const fakeFiles = FILES.reduce((a, b) => ({ ...a, [b]: "" }), {}); const fakeFiles = FILES.reduce((a, b) => ({ ...a, [b]: "" }), {});
mockFs(fakeFiles); vol.fromJSON(fakeFiles);
});
afterEach(() => {
mockFs.restore();
}); });
describe("CurseForgeUploadApiClient", () => { describe("CurseForgeUploadApiClient", () => {

View file

@ -1,6 +1,6 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { createCombinedFetch, createFakeFetch } from "../../../utils/fetch-utils"; import { createCombinedFetch, createFakeFetch } from "../../../utils/fetch-utils";
import { PlatformType } from "@/platforms/platform-type"; import { PlatformType } from "@/platforms/platform-type";
import { SecureString } from "@/utils/security/secure-string"; import { SecureString } from "@/utils/security/secure-string";
@ -17,11 +17,11 @@ import { CurseForgeUploader } from "@/platforms/curseforge/curseforge-uploader";
const DB = Object.freeze({ const DB = Object.freeze({
versionTypes: Object.freeze(JSON.parse( versionTypes: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/curseforge/version-types.json"), "utf8")
)), )),
versions: Object.freeze(JSON.parse( versions: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/curseforge/versions.json"), "utf8")
)), )),
}); });
@ -96,15 +96,11 @@ const CURSEFORGE_FETCH = createCombinedFetch(
); );
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"file.txt": "", "file.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("CurseForgeUploader", () => { describe("CurseForgeUploader", () => {
describe("platform", () => { describe("platform", () => {
test("returns `PlatformType.CURSEFORGE`", () => { test("returns `PlatformType.CURSEFORGE`", () => {

View file

@ -1,6 +1,6 @@
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { createFakeFetch } from "../../../utils/fetch-utils"; import { createFakeFetch } from "../../../utils/fetch-utils";
import { HttpResponse } from "@/utils/net/http-response"; import { HttpResponse } from "@/utils/net/http-response";
import { GitHubRelease, GitHubReleaseInit, GitHubReleasePatch } from "@/platforms/github/github-release"; import { GitHubRelease, GitHubReleaseInit, GitHubReleasePatch } from "@/platforms/github/github-release";
@ -8,7 +8,7 @@ import { GITHUB_API_URL, GitHubApiClient } from "@/platforms/github/github-api-c
const DB = Object.freeze({ const DB = Object.freeze({
releases: Object.freeze(JSON.parse( releases: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/github/releases.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/github/releases.json"), "utf8")
)) as GitHubRelease[], )) as GitHubRelease[],
}); });
@ -120,11 +120,7 @@ beforeEach(() => {
const fileNames = DB.releases.flatMap(x => x.assets).map(x => x.name); const fileNames = DB.releases.flatMap(x => x.assets).map(x => x.name);
const fakeFiles = fileNames.reduce((a, b) => ({ ...a, [b]: "" }), {}); const fakeFiles = fileNames.reduce((a, b) => ({ ...a, [b]: "" }), {});
mockFs(fakeFiles); vol.fromJSON(fakeFiles);
});
afterEach(() => {
mockFs.restore();
}); });
describe("GitHubApiClient", () => { describe("GitHubApiClient", () => {

View file

@ -1,4 +1,4 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { GitHubContext } from "@/platforms/github/github-context"; import { GitHubContext } from "@/platforms/github/github-context";
describe("GitHubContext", () => { describe("GitHubContext", () => {
@ -74,15 +74,11 @@ describe("GitHubContext", () => {
describe("payload", () => { describe("payload", () => {
beforeAll(() => { beforeAll(() => {
mockFs({ vol.fromJSON({
"payload.json": JSON.stringify({ release: { id: 42 } }), "payload.json": JSON.stringify({ release: { id: 42 } }),
}); });
}); });
afterAll(() => {
mockFs.restore();
});
test("returns payload when GITHUB_EVENT_PATH is set and file exists", () => { test("returns payload when GITHUB_EVENT_PATH is set and file exists", () => {
const context = new GitHubContext({ GITHUB_EVENT_PATH: "payload.json" }); const context = new GitHubContext({ GITHUB_EVENT_PATH: "payload.json" });

View file

@ -1,4 +1,4 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { createFakeFetch } from "../../../utils/fetch-utils"; import { createFakeFetch } from "../../../utils/fetch-utils";
import { PlatformType } from "@/platforms/platform-type"; import { PlatformType } from "@/platforms/platform-type";
import { SecureString } from "@/utils/security/secure-string"; import { SecureString } from "@/utils/security/secure-string";
@ -63,15 +63,11 @@ const CONTEXT = new GitHubContext({
}); });
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"file.txt": "", "file.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("GitHubUploader", () => { describe("GitHubUploader", () => {
describe("platform", () => { describe("platform", () => {
test("returns `PlatformType.GITHUB`", () => { test("returns `PlatformType.GITHUB`", () => {

View file

@ -1,5 +1,5 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import { createFakeFetch } from "../../../utils/fetch-utils"; import { createFakeFetch } from "../../../utils/fetch-utils";
import { FormData } from "@/utils/net/form-data"; import { FormData } from "@/utils/net/form-data";
@ -13,19 +13,19 @@ import { MODRINTH_API_URL, ModrinthApiClient } from "@/platforms/modrinth/modrin
const DB = Object.freeze({ const DB = Object.freeze({
loaders: Object.freeze(JSON.parse( loaders: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/loader.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/loader.json"), "utf8")
)) as ModrinthLoader[], )) as ModrinthLoader[],
gameVersions: Object.freeze(JSON.parse( gameVersions: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/game_version.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/game_version.json"), "utf8")
)) as ModrinthGameVersion[], )) as ModrinthGameVersion[],
projects: Object.freeze(JSON.parse( projects: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/projects.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/projects.json"), "utf8")
)) as ModrinthProject[], )) as ModrinthProject[],
versions: Object.freeze(JSON.parse( versions: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/versions.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/versions.json"), "utf8")
)) as ModrinthVersion[], )) as ModrinthVersion[],
}); });
@ -196,11 +196,7 @@ beforeEach(() => {
const fileNames = DB.versions.flatMap(x => x.files).map(x => x.filename); const fileNames = DB.versions.flatMap(x => x.files).map(x => x.filename);
const fakeFiles = fileNames.reduce((a, b) => ({ ...a, [b]: "" }), {}); const fakeFiles = fileNames.reduce((a, b) => ({ ...a, [b]: "" }), {});
mockFs(fakeFiles); vol.fromJSON(fakeFiles);
});
afterEach(() => {
mockFs.restore();
}); });
describe("ModrinthApiClient", () => { describe("ModrinthApiClient", () => {

View file

@ -1,6 +1,6 @@
import { resolve } from "node:path"; import { resolve } from "node:path";
import { readFileSync } from "node:fs"; import { actualFs } from "@/../tests/utils/actual-fs";
import mockFs from "mock-fs"; import { vol } from "memfs";
import { createFakeFetch } from "../../../utils/fetch-utils"; import { createFakeFetch } from "../../../utils/fetch-utils";
import { SecureString } from "@/utils/security/secure-string"; import { SecureString } from "@/utils/security/secure-string";
import { PlatformType } from "@/platforms/platform-type"; import { PlatformType } from "@/platforms/platform-type";
@ -17,11 +17,11 @@ import { ModrinthUploader } from "@/platforms/modrinth/modrinth-uploader";
const DB = Object.freeze({ const DB = Object.freeze({
loaders: Object.freeze(JSON.parse( loaders: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/loader.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/loader.json"), "utf8")
)), )),
gameVersions: Object.freeze(JSON.parse( gameVersions: Object.freeze(JSON.parse(
readFileSync(resolve(__dirname, "../../../content/modrinth/game_version.json"), "utf8") actualFs.readFileSync(resolve(__dirname, "../../../content/modrinth/game_version.json"), "utf8")
)), )),
}); });
@ -80,15 +80,11 @@ const MODRINTH_FETCH = createFakeFetch({
}); });
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"file.txt": "", "file.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("ModrinthUploader", () => { describe("ModrinthUploader", () => {
describe("platform", () => { describe("platform", () => {
test("returns `PlatformType.MODRINTH`", () => { test("returns `PlatformType.MODRINTH`", () => {

View file

@ -1,8 +1,8 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { parseActionMetadataFromFile, parseActionMetadataFromString } from "@/utils/actions/action-metadata"; import { parseActionMetadataFromFile, parseActionMetadataFromString } from "@/utils/actions/action-metadata";
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"action.yml": ` "action.yml": `
name: Test Action name: Test Action
description: This is a test action description: This is a test action
@ -17,10 +17,6 @@ beforeEach(() => {
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("parseActionMetadataFromString", () => { describe("parseActionMetadataFromString", () => {
test("returns the parsed ActionMetadata object for valid YAML text", () => { test("returns the parsed ActionMetadata object for valid YAML text", () => {
const actionYamlText = ` const actionYamlText = `

View file

@ -1,4 +1,4 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { readFile } from "node:fs/promises"; import { readFile } from "node:fs/promises";
import { ActionMetadata } from "@/utils/actions/action-metadata"; import { ActionMetadata } from "@/utils/actions/action-metadata";
import { ActionParameterPathParser } from "@/utils/actions/action-parameter-path-parser"; import { ActionParameterPathParser } from "@/utils/actions/action-parameter-path-parser";
@ -9,15 +9,11 @@ const ENV = Object.freeze({
}); });
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"output.txt": "", "output.txt": "",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("setActionOutput", () => { describe("setActionOutput", () => {
test("writes the value of an output to a file", async () => { test("writes the value of an output to a file", async () => {
setActionOutput("output1", "value1", ENV); setActionOutput("output1", "value1", ENV);

View file

@ -1,5 +1,5 @@
import { FileNotFoundError } from "@/utils/errors/file-not-found-error"; import { FileNotFoundError } from "@/utils/errors/file-not-found-error";
import mockFs from "mock-fs"; import { vol } from "memfs";
describe("FileNotFoundError", () => { describe("FileNotFoundError", () => {
describe("constructor", () => { describe("constructor", () => {
@ -24,11 +24,7 @@ describe("FileNotFoundError", () => {
describe("throwIfNotFound", () => { describe("throwIfNotFound", () => {
beforeEach(() => { beforeEach(() => {
mockFs({ test: "test" }); vol.fromJSON({ test: "test" });
});
afterEach(() => {
mockFs.restore();
}); });
test("throws error if file does not exist", () => { test("throws error if file does not exist", () => {

View file

@ -1,5 +1,4 @@
import { statSync } from "node:fs"; import { fs as memfs, vol } from "memfs";
import mockFs from "mock-fs";
import { zipContent } from "../../../utils/zip-utils"; import { zipContent } from "../../../utils/zip-utils";
import { import {
FileInfo, FileInfo,
@ -14,20 +13,16 @@ import {
readZippedFile, readZippedFile,
} from "@/utils/io/file-info"; } from "@/utils/io/file-info";
beforeEach(async () => { beforeEach(() => {
mockFs({ vol.fromNestedJSON({
"path/to": { "path/to": {
"test.txt": "test", "test.txt": "test",
"test.json": JSON.stringify({ foo: 42 }), "test.json": JSON.stringify({ foo: 42 }),
"test.zip": await zipContent("test", "test.txt"), "test.zip": zipContent("test", "test.txt"),
}, },
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("FileInfo", () => { describe("FileInfo", () => {
describe("constructor", () => { describe("constructor", () => {
test("constructs a new instance with the given path", () => { test("constructs a new instance with the given path", () => {
@ -95,7 +90,7 @@ describe("FileInfo", () => {
test("returns the file size", () => { test("returns the file size", () => {
const info = new FileInfo("path/to/test.txt"); const info = new FileInfo("path/to/test.txt");
expect(info.size).toBe(statSync("path/to/test.txt").size); expect(info.size).toBe(memfs.statSync("path/to/test.txt").size);
}); });
test("throws if the file does not exist", () => { test("throws if the file does not exist", () => {

View file

@ -1,16 +1,12 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { Blob, isBlob, readBlob, readBlobSync } from "@/utils/net/blob"; import { Blob, isBlob, readBlob, readBlobSync } from "@/utils/net/blob";
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"test.txt": "test", "test.txt": "test",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("isBlob", () => { describe("isBlob", () => {
test("returns true for Blob instances", () => { test("returns true for Blob instances", () => {
expect(isBlob(new Blob([]))).toBe(true); expect(isBlob(new Blob([]))).toBe(true);

View file

@ -1,18 +1,14 @@
import mockFs from "mock-fs"; import { vol } from "memfs";
import { FileInfo } from "@/utils/io/file-info"; import { FileInfo } from "@/utils/io/file-info";
import { FILE_PATH, FormData, isFormData, toFormData } from "@/utils/net/form-data"; import { FILE_PATH, FormData, isFormData, toFormData } from "@/utils/net/form-data";
import { isBlob } from "@/utils/net/blob"; import { isBlob } from "@/utils/net/blob";
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"file.json": "{}", "file.json": "{}",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("FormData", () => { describe("FormData", () => {
describe("constructor", () => { describe("constructor", () => {
test("creates a new FormData instance", () => { test("creates a new FormData instance", () => {

View file

@ -1,19 +1,14 @@
import { createReadStream, statSync } from "node:fs"; import { fs as memfs, vol } from "memfs";
import mockFs from "mock-fs";
import { ArrayMap, MultiMap } from "@/utils/collections/map"; import { ArrayMap, MultiMap } from "@/utils/collections/map";
import { Blob } from "@/utils/net/blob"; import { Blob } from "@/utils/net/blob";
import { appendHeader, appendHeaders, cloneHeaders, deleteHeader, deleteHeaders, getHeader, hasHeader, inferHttpRequestBodyHeaders, setDefaultHeader, setDefaultHeaders, setHeader, setHeaders } from "@/utils/net"; import { appendHeader, appendHeaders, cloneHeaders, deleteHeader, deleteHeaders, getHeader, hasHeader, inferHttpRequestBodyHeaders, setDefaultHeader, setDefaultHeaders, setHeader, setHeaders } from "@/utils/net";
beforeEach(() => { beforeEach(() => {
mockFs({ vol.fromJSON({
"file.json": "{}", "file.json": "{}",
}); });
}); });
afterEach(() => {
mockFs.restore();
});
describe("hasHeader", () => { describe("hasHeader", () => {
test("returns true when header exists in a Record", () => { test("returns true when header exists in a Record", () => {
const headers = { "Content-Type": "application/json" }; const headers = { "Content-Type": "application/json" };
@ -575,11 +570,11 @@ describe("inferHttpRequestBodyHeaders", () => {
}); });
test("returns correct headers when body is a ReadableStream created from a file path", () => { test("returns correct headers when body is a ReadableStream created from a file path", () => {
const body = createReadStream("file.json"); const body = memfs.createReadStream("file.json");
const headers = inferHttpRequestBodyHeaders(body); const headers = inferHttpRequestBodyHeaders(body);
expect(headers["Content-Type"]).toBe("application/octet-stream"); expect(headers["Content-Type"]).toBe("application/octet-stream");
expect(headers["Content-Length"]).toBe(String(statSync("file.json").size)); expect(headers["Content-Length"]).toBe(String(memfs.statSync("file.json").size));
}); });
}); });

2
tests/utils/actual-fs.ts Normal file
View file

@ -0,0 +1,2 @@
export const actualFs = jest.requireActual<typeof import("node:fs")>("node:fs");
export const actualFsPromises = jest.requireActual<typeof import("node:fs/promises")>("node:fs/promises");

View file

@ -1,5 +1,4 @@
import { readFile } from "node:fs/promises"; import { actualFs, actualFsPromises } from "./actual-fs";
import { existsSync } from "node:fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import { Fetch, HttpMethod, HttpRequest, HttpResponse, createFetch } from "@/utils/net"; import { Fetch, HttpMethod, HttpRequest, HttpResponse, createFetch } from "@/utils/net";
@ -32,8 +31,8 @@ async function normalizeResponse(response: FetchInterceptorResponse): Promise<Ht
if (Array.isArray(response) && response.length && response.every(x => typeof x === "string")) { if (Array.isArray(response) && response.length && response.every(x => typeof x === "string")) {
const path = resolve(...response); const path = resolve(...response);
if (existsSync(path)) { if (actualFs.existsSync(path)) {
const content = await readFile(path, "utf8"); const content = await actualFsPromises.readFile(path, "utf8");
return HttpResponse.text(content); return HttpResponse.text(content);
} }
} }

View file

@ -1,31 +1,18 @@
import { basename, resolve as resolvePath } from "node:path"; import { basename, resolve as resolvePath } from "node:path";
import { ZipFile } from "yazl"; import Zip from "adm-zip";
export async function zipFile(path: string | string[], zipPath?: string): Promise<Buffer> { export function zipFile(path: string | string[], zipPath?: string): Buffer {
const fs = jest.requireActual<typeof import("node:fs")>("node:fs");
const realPath = typeof path === "string" ? path : resolvePath(...path); const realPath = typeof path === "string" ? path : resolvePath(...path);
zipPath ||= basename(realPath); zipPath ||= basename(realPath);
const zip = new ZipFile(); const zip = new Zip();
zip.addFile(realPath, zipPath); zip.addFile(zipPath, fs.readFileSync(realPath));
zip.end(); return zip.toBuffer();
const chunks = [] as Buffer[];
for await (const chunk of zip.outputStream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks);
} }
export async function zipContent(content: string | Buffer, zipPath: string): Promise<Buffer> { export function zipContent(content: string | Buffer, zipPath: string): Buffer {
const zip = new ZipFile(); const zip = new Zip();
zip.addBuffer(Buffer.from(content), zipPath); zip.addFile(zipPath, typeof content === "string" ? Buffer.from(content) : content);
zip.end(); return zip.toBuffer();
const chunks = [] as Buffer[];
for await (const chunk of zip.outputStream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks);
} }