Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85c8b8252f | ||
|
|
948fd1aec0 | ||
|
|
213a6fbf71 | ||
|
|
c089e392a9 | ||
|
|
387fa91a19 | ||
|
|
bde04d3ec6 | ||
|
|
ce7dceac93 | ||
|
|
18832c2f0d | ||
|
|
3fdcd6b1fa | ||
|
|
2b564ea543 | ||
|
|
6b62acfc40 | ||
|
|
62411c0bbf | ||
|
|
c10ebdc85f | ||
|
|
1b00b76bc1 | ||
|
|
8ffb34e4db | ||
|
|
81ce706243 |
31
HISTORY.md
31
HISTORY.md
@@ -1,5 +1,36 @@
|
||||
# Changelog
|
||||
|
||||
# [37.5.1](https://github.com/tj-actions/changed-files/compare/v37.5.0...v37.5.1) - (2023-07-28)
|
||||
|
||||
## <!-- 26 -->🔄 Update
|
||||
|
||||
- Update README.md ([ca51c3f](https://github.com/tj-actions/changed-files/commit/ca51c3f4304b9cd96adebaa47025a2014040eb61)) - (Tonye Jack)
|
||||
- Update README.md ([5716c62](https://github.com/tj-actions/changed-files/commit/5716c6246fcfd7031340a7be53243a6a6b689c3e)) - (Tonye Jack)
|
||||
- Update README.md ([f6edf88](https://github.com/tj-actions/changed-files/commit/f6edf885b4a59cd97f396367b3e6fe4f26454601)) - (Tonye Jack)
|
||||
- Update README.md ([331d2da](https://github.com/tj-actions/changed-files/commit/331d2daf96995ca6711e07b13681faa6a55bda62)) - (Tonye Jack)
|
||||
- Updated README.md ([#1412](https://github.com/tj-actions/changed-files/issues/1412))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([174b246](https://github.com/tj-actions/changed-files/commit/174b246d44adb53ce1a125fc589734fce01e47eb)) - (tj-actions[bot])
|
||||
- Update README.md ([0bf8395](https://github.com/tj-actions/changed-files/commit/0bf83955a913aa99abe90724dc460e86708af650)) - (Tonye Jack)
|
||||
- Update README.md ([69c6091](https://github.com/tj-actions/changed-files/commit/69c6091ee4f562b2c6509ded97c4e5330ac95b09)) - (Tonye Jack)
|
||||
- Update README.md ([ba9054e](https://github.com/tj-actions/changed-files/commit/ba9054e8d5ffe1537ded23c6a65348cb9b78e8c4)) - (Tonye Jack)
|
||||
- Update README.md ([7e9cc01](https://github.com/tj-actions/changed-files/commit/7e9cc01c5474ea22e06e55ea8a296c8653e64d0c)) - (Tonye Jack)
|
||||
|
||||
## <!-- 7 -->⚙️ Miscellaneous Tasks
|
||||
|
||||
- **deps:** Update dependency eslint to v8.46.0 ([#1417](https://github.com/tj-actions/changed-files/issues/1417)) ([a96679d](https://github.com/tj-actions/changed-files/commit/a96679dfee2a1e64b1db5a210c0ffaf1f2cb24ce)) - (renovate[bot])
|
||||
- **deps:** Lock file maintenance ([#1416](https://github.com/tj-actions/changed-files/issues/1416)) ([0c65957](https://github.com/tj-actions/changed-files/commit/0c659577d4b26faf3f99868ea9cabd2775f9b3cb)) - (renovate[bot])
|
||||
- **deps:** Update dependency jest to v29.6.2 ([#1415](https://github.com/tj-actions/changed-files/issues/1415)) ([ea41e77](https://github.com/tj-actions/changed-files/commit/ea41e772876ff19a8d86e3315c52ceff3dae1941)) - (renovate[bot])
|
||||
- **deps:** Update dependency @types/lodash to v4.14.196 ([#1413](https://github.com/tj-actions/changed-files/issues/1413)) ([4acaa72](https://github.com/tj-actions/changed-files/commit/4acaa728bbc362e0ced57dad81204885d253a0e6)) - (renovate[bot])
|
||||
- **deps:** Update dependency @types/node to v20.4.5 ([#1409](https://github.com/tj-actions/changed-files/issues/1409)) ([cf02ab9](https://github.com/tj-actions/changed-files/commit/cf02ab960fc3dee58fc4911fac2c6946f4f64552)) - (renovate[bot])
|
||||
- **deps:** Lock file maintenance ([#1408](https://github.com/tj-actions/changed-files/issues/1408)) ([b50d1ab](https://github.com/tj-actions/changed-files/commit/b50d1ab2d1388e35e9163a8eb2ae8b903e62ca8e)) - (renovate[bot])
|
||||
|
||||
## <!-- 9 -->⬆️ Upgrades
|
||||
|
||||
- Upgraded to v37.5.0 ([#1407](https://github.com/tj-actions/changed-files/issues/1407))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([0f52c86](https://github.com/tj-actions/changed-files/commit/0f52c861db7764988bb85cbb66a0b166787f586b)) - (tj-actions[bot])
|
||||
|
||||
# [37.5.0](https://github.com/tj-actions/changed-files/compare/v37.4.0...v37.5.0) - (2023-07-24)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
14
README.md
14
README.md
@@ -13,10 +13,6 @@
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
<div align="center">
|
||||
<img width="auto" alt="Screen Shot 2021-11-19 at 4 59 21 PM" src="https://user-images.githubusercontent.com/17484350/229027815-eee0bf22-f3e5-444d-9d90-6409c68a0dc9.png">
|
||||
</div>
|
||||
|
||||
## changed-files
|
||||
|
||||
Effortlessly track all changed files and directories relative to a target branch, preceding commit or the last remote commit returning **relative paths** from the project root using this GitHub action.
|
||||
@@ -66,7 +62,7 @@ Effortlessly track all changed files and directories relative to a target branch
|
||||
* Between the last remote branch commit and the current HEAD.
|
||||
* Restricts change detection to a subset of files and directories:
|
||||
* Provides boolean output indicating changes in specific files.
|
||||
* Uses [Glob pattern](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet) matching.
|
||||
* Uses [Glob pattern](https://codepen.io/mrmlnc/pen/OXQjMe) matching.
|
||||
* Supports Globstar.
|
||||
* Supports brace expansion.
|
||||
* Supports negation.
|
||||
@@ -80,8 +76,8 @@ And many more.
|
||||
|
||||
> **Warning**:
|
||||
>
|
||||
> * For `push` events: \*\*When configuring [`actions/checkout`](https://github.com/actions/checkout#usage), make sure to set [`fetch-depth`](https://github.com/actions/checkout#usage) to either `0` or `2`, depending on your use case.
|
||||
> * For mono repositories where pulling all the branch history might not be desired, you can still use the default [`fetch-depth`](https://github.com/actions/checkout#usage), which is set to `1` for `pull_request` events.
|
||||
> * For `push` events: When configuring [`actions/checkout`](https://github.com/actions/checkout#usage), make sure to set [`fetch-depth`](https://github.com/actions/checkout#usage) to either `0` or `2`, depending on your use case.
|
||||
> * For mono repositories where pulling all branch history might not be desired, you can still use the default [`fetch-depth`](https://github.com/actions/checkout#usage), which is set to `1` for `pull_request` events.
|
||||
> * Avoid using single or double quotes for multiline inputs, as the value is already a string separated by a newline character. See [Examples](#examples) for more information.
|
||||
> * If [`fetch-depth`](https://github.com/actions/checkout#usage) isn't set to `0`, ensure that `persist-credentials` is set to `true` when configuring [`actions/checkout`](https://github.com/actions/checkout#usage).
|
||||
> * For repositories that have PRs generated from forks, when configuring [`actions/checkout`](https://github.com/actions/checkout#usage), set the [`repository`](https://github.com/actions/checkout#usage) to `${{ github.event.pull_request.head.repo.full_name }}`. See [Example](https://github.com/tj-actions/changed-files/blob/main/.github/workflows/test.yml#L47-L51).
|
||||
@@ -300,6 +296,10 @@ Support this project with a :star:
|
||||
| U | Unmerged |
|
||||
| X | Unknown |
|
||||
|
||||
> **Warning**:
|
||||
>
|
||||
> * When using `files_yaml*` inputs ensure all outputs are prefixed by the key `test_{...}` e.g. `test_added_files`, `test_any_changed`
|
||||
|
||||
## Outputs
|
||||
|
||||
<!-- AUTO-DOC-OUTPUT:START - Do not remove or modify this section -->
|
||||
|
||||
149
dist/index.js
generated
vendored
149
dist/index.js
generated
vendored
@@ -153,16 +153,16 @@ exports.getAllDiffFiles = getAllDiffFiles;
|
||||
function* getChangeTypeFilesGenerator({ inputs, changedFiles, changeTypes }) {
|
||||
for (const changeType of changeTypes) {
|
||||
const files = changedFiles[changeType] || [];
|
||||
for (const file of files) {
|
||||
for (const filePath of files) {
|
||||
if (inputs.dirNames) {
|
||||
yield (0, utils_1.getDirnameMaxDepth)({
|
||||
pathStr: file,
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
});
|
||||
}
|
||||
else {
|
||||
yield file;
|
||||
yield filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,16 +184,16 @@ const getChangeTypeFiles = ({ inputs, changedFiles, changeTypes }) => __awaiter(
|
||||
});
|
||||
exports.getChangeTypeFiles = getChangeTypeFiles;
|
||||
function* getAllChangeTypeFilesGenerator({ inputs, changedFiles }) {
|
||||
for (const file of (0, flatten_1.default)(Object.values(changedFiles))) {
|
||||
for (const filePath of (0, flatten_1.default)(Object.values(changedFiles))) {
|
||||
if (inputs.dirNames) {
|
||||
yield (0, utils_1.getDirnameMaxDepth)({
|
||||
pathStr: file,
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
});
|
||||
}
|
||||
else {
|
||||
yield file;
|
||||
yield filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1642,7 +1642,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.hasLocalGitDirectory = exports.recoverDeletedFiles = exports.setOutput = exports.getRecoverFilePatterns = exports.getYamlFilePatterns = exports.getFilePatterns = exports.jsonOutput = exports.getDirnameMaxDepth = exports.canDiffCommits = exports.getPreviousGitTag = exports.verifyCommitSha = exports.getParentSha = exports.getRemoteBranchHeadSha = exports.isInsideWorkTree = exports.getHeadSha = exports.gitLog = exports.getFilteredChangedFiles = exports.getAllChangedFiles = exports.gitRenamedFiles = exports.gitSubmoduleDiffSHA = exports.getSubmodulePath = exports.gitFetchSubmodules = exports.gitFetch = exports.submoduleExists = exports.isRepoShallow = exports.updateGitGlobalConfig = exports.verifyMinimumGitVersion = void 0;
|
||||
exports.hasLocalGitDirectory = exports.recoverDeletedFiles = exports.setOutput = exports.getRecoverFilePatterns = exports.getYamlFilePatterns = exports.getFilePatterns = exports.jsonOutput = exports.getDirnameMaxDepth = exports.canDiffCommits = exports.getPreviousGitTag = exports.verifyCommitSha = exports.getParentSha = exports.getRemoteBranchHeadSha = exports.isInsideWorkTree = exports.getHeadSha = exports.gitLog = exports.getFilteredChangedFiles = exports.getAllChangedFiles = exports.gitRenamedFiles = exports.gitSubmoduleDiffSHA = exports.getSubmodulePath = exports.gitFetchSubmodules = exports.gitFetch = exports.submoduleExists = exports.isRepoShallow = exports.updateGitGlobalConfig = exports.verifyMinimumGitVersion = exports.getDirname = exports.normalizeSeparators = exports.isWindows = void 0;
|
||||
/*global AsyncIterableIterator*/
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
@@ -1654,16 +1654,19 @@ const path = __importStar(__nccwpck_require__(1017));
|
||||
const readline_1 = __nccwpck_require__(4521);
|
||||
const yaml_1 = __nccwpck_require__(4083);
|
||||
const changedFiles_1 = __nccwpck_require__(7358);
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const MINIMUM_GIT_VERSION = '2.18.0';
|
||||
const isWindows = () => {
|
||||
return process.platform === 'win32';
|
||||
};
|
||||
exports.isWindows = isWindows;
|
||||
/**
|
||||
* Normalize file path separators to '/' on Windows and Linux/macOS
|
||||
* @param p file path
|
||||
* Normalize file path separators to '/' on Linux/macOS and '\\' on Windows
|
||||
* @param p - file path
|
||||
* @returns file path with normalized separators
|
||||
*/
|
||||
const normalizeSeparators = (p) => {
|
||||
// Windows
|
||||
if (IS_WINDOWS) {
|
||||
if ((0, exports.isWindows)()) {
|
||||
// Convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// Remove redundant slashes
|
||||
@@ -1673,9 +1676,18 @@ const normalizeSeparators = (p) => {
|
||||
// Remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
};
|
||||
exports.normalizeSeparators = normalizeSeparators;
|
||||
/**
|
||||
* Normalize file path separators to '/' on all platforms
|
||||
* @param p - file path
|
||||
* @returns file path with normalized separators
|
||||
*/
|
||||
const normalizePath = (p) => {
|
||||
return p.replace(/\\/g, '/');
|
||||
};
|
||||
/**
|
||||
* Trims unnecessary trailing slash from file path
|
||||
* @param p file path
|
||||
* @param p - file path
|
||||
* @returns file path without unnecessary trailing slash
|
||||
*/
|
||||
const safeTrimTrailingSeparator = (p) => {
|
||||
@@ -1684,7 +1696,7 @@ const safeTrimTrailingSeparator = (p) => {
|
||||
return '';
|
||||
}
|
||||
// Normalize separators
|
||||
p = normalizeSeparators(p);
|
||||
p = (0, exports.normalizeSeparators)(p);
|
||||
// No trailing slash
|
||||
if (!p.endsWith(path.sep)) {
|
||||
return p;
|
||||
@@ -1694,31 +1706,51 @@ const safeTrimTrailingSeparator = (p) => {
|
||||
return p;
|
||||
}
|
||||
// On Windows, avoid trimming the drive root, e.g. C:\ or \\hello
|
||||
if (IS_WINDOWS && /^[A-Z]:\\$/i.test(p)) {
|
||||
if ((0, exports.isWindows)() && /^[A-Z]:\\$/i.test(p)) {
|
||||
return p;
|
||||
}
|
||||
// Trim trailing slash
|
||||
return p.substring(0, p.length - 1);
|
||||
};
|
||||
const dirname = (p) => {
|
||||
/**
|
||||
* Gets the dirname of a path, similar to the Node.js path.dirname() function except that this function
|
||||
* also works for Windows UNC root paths, e.g. \\hello\world
|
||||
* @param p - file path
|
||||
* @returns dirname of path
|
||||
*/
|
||||
const getDirname = (p) => {
|
||||
// Normalize slashes and trim unnecessary trailing slash
|
||||
p = safeTrimTrailingSeparator(p);
|
||||
// Windows UNC root, e.g. \\hello or \\hello\world
|
||||
if (IS_WINDOWS && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) {
|
||||
if ((0, exports.isWindows)() && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) {
|
||||
return p;
|
||||
}
|
||||
// Get dirname
|
||||
let result = path.dirname(p);
|
||||
// Trim trailing slash for Windows UNC root, e.g. \\hello\world\
|
||||
if (IS_WINDOWS && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) {
|
||||
if ((0, exports.isWindows)() && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) {
|
||||
result = safeTrimTrailingSeparator(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
exports.getDirname = getDirname;
|
||||
/**
|
||||
* Converts the version string to a number
|
||||
* @param version - version string
|
||||
* @returns version number
|
||||
*/
|
||||
const versionToNumber = (version) => {
|
||||
const [major, minor, patch] = version.split('.').map(Number);
|
||||
return major * 1000000 + minor * 1000 + patch;
|
||||
};
|
||||
/**
|
||||
* Verifies the minimum required git version
|
||||
* @returns minimum required git version
|
||||
* @throws Minimum git version requirement is not met
|
||||
* @throws Git is not installed
|
||||
* @throws Git is not found in PATH
|
||||
* @throws An unexpected error occurred
|
||||
*/
|
||||
const verifyMinimumGitVersion = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode, stdout, stderr } = yield exec.getExecOutput('git', ['--version'], { silent: !core.isDebug() });
|
||||
if (exitCode !== 0) {
|
||||
@@ -1730,6 +1762,11 @@ const verifyMinimumGitVersion = () => __awaiter(void 0, void 0, void 0, function
|
||||
}
|
||||
});
|
||||
exports.verifyMinimumGitVersion = verifyMinimumGitVersion;
|
||||
/**
|
||||
* Checks if a path exists
|
||||
* @param filePath - path to check
|
||||
* @returns path exists
|
||||
*/
|
||||
const exists = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
try {
|
||||
yield fs_1.promises.access(filePath);
|
||||
@@ -1739,6 +1776,11 @@ const exists = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Generates lines of a file as an async iterable iterator
|
||||
* @param filePath - path of file to read
|
||||
* @param excludedFiles - whether to exclude files
|
||||
*/
|
||||
function lineOfFileGenerator({ filePath, excludedFiles }) {
|
||||
return __asyncGenerator(this, arguments, function* lineOfFileGenerator_1() {
|
||||
var _a, e_1, _b, _c;
|
||||
@@ -1780,6 +1822,11 @@ function lineOfFileGenerator({ filePath, excludedFiles }) {
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets the file patterns from a source file
|
||||
* @param filePaths - paths of files to read
|
||||
* @param excludedFiles - whether to exclude the file patterns
|
||||
*/
|
||||
const getFilesFromSourceFile = ({ filePaths, excludedFiles = false }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
var _b, e_2, _c, _d;
|
||||
const lines = [];
|
||||
@@ -1802,6 +1849,12 @@ const getFilesFromSourceFile = ({ filePaths, excludedFiles = false }) => __await
|
||||
}
|
||||
return lines;
|
||||
});
|
||||
/**
|
||||
* Sets the global git configs
|
||||
* @param name - name of config
|
||||
* @param value - value of config
|
||||
* @throws Couldn't update git global config
|
||||
*/
|
||||
const updateGitGlobalConfig = ({ name, value }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode, stderr } = yield exec.getExecOutput('git', ['config', '--global', name, value], {
|
||||
ignoreReturnCode: true,
|
||||
@@ -1813,6 +1866,11 @@ const updateGitGlobalConfig = ({ name, value }) => __awaiter(void 0, void 0, voi
|
||||
}
|
||||
});
|
||||
exports.updateGitGlobalConfig = updateGitGlobalConfig;
|
||||
/**
|
||||
* Checks if a git repository is shallow
|
||||
* @param cwd - working directory
|
||||
* @returns repository is shallow
|
||||
*/
|
||||
const isRepoShallow = ({ cwd }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { stdout } = yield exec.getExecOutput('git', ['rev-parse', '--is-shallow-repository'], {
|
||||
cwd,
|
||||
@@ -1821,6 +1879,11 @@ const isRepoShallow = ({ cwd }) => __awaiter(void 0, void 0, void 0, function* (
|
||||
return stdout.trim() === 'true';
|
||||
});
|
||||
exports.isRepoShallow = isRepoShallow;
|
||||
/**
|
||||
* Checks if a submodule exists
|
||||
* @param cwd - working directory
|
||||
* @returns submodule exists
|
||||
*/
|
||||
const submoduleExists = ({ cwd }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { stdout, exitCode, stderr } = yield exec.getExecOutput('git', ['submodule', 'status'], {
|
||||
cwd,
|
||||
@@ -1834,6 +1897,11 @@ const submoduleExists = ({ cwd }) => __awaiter(void 0, void 0, void 0, function*
|
||||
return stdout.trim() !== '';
|
||||
});
|
||||
exports.submoduleExists = submoduleExists;
|
||||
/**
|
||||
* Fetches the git repository
|
||||
* @param args - arguments for fetch command
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
const gitFetch = ({ args, cwd }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode } = yield exec.getExecOutput('git', ['fetch', '-q', ...args], {
|
||||
cwd,
|
||||
@@ -1843,6 +1911,11 @@ const gitFetch = ({ args, cwd }) => __awaiter(void 0, void 0, void 0, function*
|
||||
return exitCode;
|
||||
});
|
||||
exports.gitFetch = gitFetch;
|
||||
/**
|
||||
* Fetches the git repository submodules
|
||||
* @param args - arguments for fetch command
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
const gitFetchSubmodules = ({ args, cwd }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode, stderr } = yield exec.getExecOutput('git', ['submodule', 'foreach', 'git', 'fetch', '-q', ...args], {
|
||||
cwd,
|
||||
@@ -1855,9 +1928,10 @@ const gitFetchSubmodules = ({ args, cwd }) => __awaiter(void 0, void 0, void 0,
|
||||
}
|
||||
});
|
||||
exports.gitFetchSubmodules = gitFetchSubmodules;
|
||||
const normalizePath = (p) => {
|
||||
return p.replace(/\\/g, '/');
|
||||
};
|
||||
/**
|
||||
* Retrieves all the submodule paths
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
const getSubmodulePath = ({ cwd }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode, stdout, stderr } = yield exec.getExecOutput('git', ['submodule', 'status'], {
|
||||
cwd,
|
||||
@@ -1874,9 +1948,17 @@ const getSubmodulePath = ({ cwd }) => __awaiter(void 0, void 0, void 0, function
|
||||
.map((line) => normalizePath(line.trim().split(' ')[1]));
|
||||
});
|
||||
exports.getSubmodulePath = getSubmodulePath;
|
||||
/**
|
||||
* Retrieves commit sha of a submodule from a parent commit
|
||||
* @param cwd - working directory
|
||||
* @param parentSha1 - parent commit sha
|
||||
* @param parentSha2 - parent commit sha
|
||||
* @param submodulePath - path of submodule
|
||||
* @param diff - diff type between parent commits (`..` or `...`)
|
||||
*/
|
||||
const gitSubmoduleDiffSHA = ({ cwd, parentSha1, parentSha2, submodulePath, diff }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
var _h, _j, _k, _l;
|
||||
const { stdout } = yield exec.getExecOutput('git', ['diff', parentSha1, parentSha2, '--', submodulePath], {
|
||||
const { stdout } = yield exec.getExecOutput('git', ['diff', `${parentSha1}${diff}${parentSha2}`, '--', submodulePath], {
|
||||
cwd,
|
||||
silent: !core.isDebug()
|
||||
});
|
||||
@@ -1930,6 +2012,16 @@ const gitRenamedFiles = ({ cwd, sha1, sha2, diff, oldNewSeparator, isSubmodule =
|
||||
});
|
||||
});
|
||||
exports.gitRenamedFiles = gitRenamedFiles;
|
||||
/**
|
||||
* Retrieves all the changed files between two commits
|
||||
* @param cwd - working directory
|
||||
* @param sha1 - commit sha
|
||||
* @param sha2 - commit sha
|
||||
* @param diff - diff type between parent commits (`..` or `...`)
|
||||
* @param isSubmodule - is the repo a submodule
|
||||
* @param parentDir - parent directory of the submodule
|
||||
* @param outputRenamedFilesAsDeletedAndAdded - output renamed files as deleted and added
|
||||
*/
|
||||
const getAllChangedFiles = ({ cwd, sha1, sha2, diff, isSubmodule = false, parentDir = '', outputRenamedFilesAsDeletedAndAdded = false }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { exitCode, stdout, stderr } = yield exec.getExecOutput('git', [
|
||||
'diff',
|
||||
@@ -1988,6 +2080,11 @@ const getAllChangedFiles = ({ cwd, sha1, sha2, diff, isSubmodule = false, parent
|
||||
return changedFiles;
|
||||
});
|
||||
exports.getAllChangedFiles = getAllChangedFiles;
|
||||
/**
|
||||
* Filters the changed files by the file patterns
|
||||
* @param allDiffFiles - all the changed files
|
||||
* @param filePatterns - file patterns to filter by
|
||||
*/
|
||||
const getFilteredChangedFiles = ({ allDiffFiles, filePatterns }) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const changedFiles = {
|
||||
[changedFiles_1.ChangeTypeEnum.Added]: [],
|
||||
@@ -2005,7 +2102,7 @@ const getFilteredChangedFiles = ({ allDiffFiles, filePatterns }) => __awaiter(vo
|
||||
if (hasFilePatterns) {
|
||||
changedFiles[changeType] = (0, micromatch_1.default)(files, filePatterns, {
|
||||
dot: true,
|
||||
windows: IS_WINDOWS,
|
||||
windows: (0, exports.isWindows)(),
|
||||
noext: true
|
||||
});
|
||||
}
|
||||
@@ -2113,8 +2210,8 @@ const canDiffCommits = ({ cwd, sha1, sha2, diff }) => __awaiter(void 0, void 0,
|
||||
return true;
|
||||
});
|
||||
exports.canDiffCommits = canDiffCommits;
|
||||
const getDirnameMaxDepth = ({ pathStr, dirNamesMaxDepth, excludeCurrentDir }) => {
|
||||
const pathArr = dirname(pathStr).split(path.sep);
|
||||
const getDirnameMaxDepth = ({ relativePath, dirNamesMaxDepth, excludeCurrentDir }) => {
|
||||
const pathArr = (0, exports.getDirname)(relativePath).split(path.sep);
|
||||
const maxDepth = Math.min(dirNamesMaxDepth || pathArr.length, pathArr.length);
|
||||
let output = pathArr[0];
|
||||
for (let i = 1; i < maxDepth; i++) {
|
||||
@@ -2173,7 +2270,7 @@ const getFilePatterns = ({ inputs, workingDirectory }) => __awaiter(void 0, void
|
||||
core.debug(`files ignore from source files patterns: ${filesIgnoreFromSourceFiles}`);
|
||||
filePatterns = filePatterns.concat('\n', filesIgnoreFromSourceFiles);
|
||||
}
|
||||
if (IS_WINDOWS) {
|
||||
if ((0, exports.isWindows)()) {
|
||||
filePatterns = filePatterns.replace(/\r\n/g, '\n');
|
||||
filePatterns = filePatterns.replace(/\r/g, '\n');
|
||||
}
|
||||
@@ -2358,7 +2455,7 @@ const recoverDeletedFiles = ({ inputs, workingDirectory, deletedFiles, recoverPa
|
||||
if (recoverPatterns.length > 0) {
|
||||
recoverableDeletedFiles = (0, micromatch_1.default)(deletedFiles, recoverPatterns, {
|
||||
dot: true,
|
||||
windows: IS_WINDOWS,
|
||||
windows: (0, exports.isWindows)(),
|
||||
noext: true
|
||||
});
|
||||
core.debug(`filtered recoverable deleted files: ${recoverableDeletedFiles}`);
|
||||
|
||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
425
src/__tests__/utils.test.ts
Normal file
425
src/__tests__/utils.test.ts
Normal file
@@ -0,0 +1,425 @@
|
||||
import {ChangeTypeEnum} from '../changedFiles'
|
||||
import {
|
||||
getDirname,
|
||||
getDirnameMaxDepth,
|
||||
getFilteredChangedFiles,
|
||||
normalizeSeparators
|
||||
} from '../utils'
|
||||
|
||||
const originalPlatform = process.platform
|
||||
|
||||
function mockedPlatform(platform: string): void {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: platform
|
||||
})
|
||||
}
|
||||
|
||||
describe('utils test', () => {
|
||||
afterEach(() => {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: originalPlatform
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDirnameMaxDepth_function', () => {
|
||||
// Tests that the function returns the correct dirname when the relative path has multiple directories
|
||||
it('test_multiple_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to/some/file',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path has only one directory
|
||||
it('test_single_directory', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path has no directories
|
||||
it('test_no_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'file.txt',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when dirNamesMaxDepth is set to a value less than the number of directories in the relative path
|
||||
it('test_dirnames_max_depth_less_than_num_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to/some/file',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path')
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty string when excludeCurrentDir is true and the output is '.'
|
||||
it('test_exclude_current_dir_is_true_and_output_is_dot', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: '.',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path is a Windows drive root and excludeCurrentDir is true
|
||||
it('test_windows_drive_root_and_exclude_current_dir_is_true', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'C:\\',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth handles a relative path with a trailing separator correctly
|
||||
it('test_trailing_separator', () => {
|
||||
const input = {
|
||||
relativePath: 'path/to/dir/',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = 'path/to'
|
||||
const actualOutput = getDirnameMaxDepth(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns an empty string when excludeCurrentDir is true and the output is '.'
|
||||
it('test_trailing_separator_exclude_current_dir', () => {
|
||||
const input = {
|
||||
relativePath: 'file',
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = ''
|
||||
const actualOutput = getDirnameMaxDepth(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct output for a Windows UNC root path
|
||||
it('test_windows_unc_root', () => {
|
||||
const input = {
|
||||
relativePath: '\\hello',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = ''
|
||||
expect(getDirnameMaxDepth(input)).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns an empty string when given a Windows UNC root and excludeCurrentDir is true
|
||||
it('test_windows_unc_root_exclude_current_dir', () => {
|
||||
const relativePath = '\\hello'
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct dirname with a relative path that contains both forward and backward slashes
|
||||
it('test_relative_path_with_slashes', () => {
|
||||
const relativePath = 'path/to\file'
|
||||
const expectedOutput = 'path'
|
||||
const actualOutput = getDirnameMaxDepth({relativePath})
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct dirname for a relative path that contains special characters
|
||||
it('test_special_characters', () => {
|
||||
const relativePath =
|
||||
'path/with/special/characters/!@#$%^&*()_+{}|:<>?[];,./'
|
||||
const expectedDirname = 'path/with/special/characters'
|
||||
const actualDirname = getDirnameMaxDepth({relativePath})
|
||||
expect(actualDirname).toEqual(expectedDirname)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDirname_function', () => {
|
||||
// Tests that the function returns the correct dirname for a valid path
|
||||
it('test valid path', () => {
|
||||
expect(getDirname('/path/to/file')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a valid Windows UNC root path
|
||||
it('test windows unc root path', () => {
|
||||
expect(getDirname('\\helloworld')).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a path with a trailing slash
|
||||
it('test path with trailing slash', () => {
|
||||
expect(getDirname('/path/to/file/')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a Windows UNC root path with a trailing slash
|
||||
it('test windows unc root path with trailing slash', () => {
|
||||
expect(getDirname('\\hello\\world\\')).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a path with multiple slashes
|
||||
it('test path with multiple slashes', () => {
|
||||
expect(getDirname('/path//to/file')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a Windows UNC root path with multiple slashes
|
||||
it('test windows unc root path with multiple slashes', () => {
|
||||
expect(getDirname('\\hello\\world')).toEqual('.')
|
||||
})
|
||||
})
|
||||
|
||||
describe('normalizeSeparators_function', () => {
|
||||
// Tests that forward slashes are normalized on Linux
|
||||
it('test forward slashes linux', () => {
|
||||
const input = 'path/to/file'
|
||||
const expectedOutput = 'path/to/file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that backslashes are normalized on Windows
|
||||
it('test backslashes windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'path\\to\\file'
|
||||
const expectedOutput = 'path\\to\\file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that mixed slashes are normalized on Windows
|
||||
it('test mixed slashes windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'path\\to/file'
|
||||
const expectedOutput = 'path\\to\\file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that an empty string returns an empty string
|
||||
it('test empty string', () => {
|
||||
const input = ''
|
||||
const expectedOutput = ''
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that multiple consecutive slashes are removed
|
||||
it('test multiple consecutive slashes', () => {
|
||||
const input = 'path//to//file'
|
||||
const expectedOutput = 'path/to/file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that UNC format is preserved on Windows
|
||||
it('test unc format windows', () => {
|
||||
const input = '\\\\hello\\world'
|
||||
const expectedOutput = '\\\\hello\\world'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that a drive root is preserved on Windows
|
||||
it('test drive root windows', () => {
|
||||
const input = 'C:\\'
|
||||
const expectedOutput = 'C:\\'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
})
|
||||
|
||||
// Generated by CodiumAI
|
||||
|
||||
describe('getFilteredChangedFiles', () => {
|
||||
// Tests that the function returns an empty object when allDiffFiles and filePatterns are empty
|
||||
it('should return an empty object when allDiffFiles and filePatterns are empty', async () => {
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles: {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
},
|
||||
filePatterns: []
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns allDiffFiles when filePatterns is empty
|
||||
it('should return allDiffFiles when filePatterns is empty', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['file1.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: []
|
||||
})
|
||||
expect(result).toEqual(allDiffFiles)
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty object when allDiffFiles is empty
|
||||
it('should return an empty object when allDiffFiles is empty', async () => {
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles: {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
},
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns only the files that match the file patterns
|
||||
it('should return only the files that match the file patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['file1.txt', 'file2.md', 'file3.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['file1.txt', 'file3.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty object when there are no files that match the file patterns
|
||||
it('should return an empty object when there are no files that match the file patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['file1.md', 'file2.md', 'file3.md'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function can handle file names with special characters
|
||||
it('should handle file names with special characters', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file2 with spaces.txt',
|
||||
'file3$$.txt'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['file2*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['file2 with spaces.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that getFilteredChangedFiles correctly filters files using glob patterns
|
||||
it('should filter files using glob patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['test/migrations/test.sql'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const filePatterns = ['test/migrations/**']
|
||||
const filteredFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
expect(filteredFiles[ChangeTypeEnum.Added]).toEqual([
|
||||
'test/migrations/test.sql'
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -166,15 +166,15 @@ function* getChangeTypeFilesGenerator({
|
||||
}): Generator<string> {
|
||||
for (const changeType of changeTypes) {
|
||||
const files = changedFiles[changeType] || []
|
||||
for (const file of files) {
|
||||
for (const filePath of files) {
|
||||
if (inputs.dirNames) {
|
||||
yield getDirnameMaxDepth({
|
||||
pathStr: file,
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield file
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,15 +213,15 @@ function* getAllChangeTypeFilesGenerator({
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
}): Generator<string> {
|
||||
for (const file of flatten(Object.values(changedFiles))) {
|
||||
for (const filePath of flatten(Object.values(changedFiles))) {
|
||||
if (inputs.dirNames) {
|
||||
yield getDirnameMaxDepth({
|
||||
pathStr: file,
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield file
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
137
src/utils.ts
137
src/utils.ts
@@ -12,17 +12,20 @@ import {ChangedFiles, ChangeTypeEnum} from './changedFiles'
|
||||
|
||||
import {Inputs} from './inputs'
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32'
|
||||
const MINIMUM_GIT_VERSION = '2.18.0'
|
||||
|
||||
export const isWindows = (): boolean => {
|
||||
return process.platform === 'win32'
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize file path separators to '/' on Windows and Linux/macOS
|
||||
* @param p file path
|
||||
* Normalize file path separators to '/' on Linux/macOS and '\\' on Windows
|
||||
* @param p - file path
|
||||
* @returns file path with normalized separators
|
||||
*/
|
||||
const normalizeSeparators = (p: string): string => {
|
||||
export const normalizeSeparators = (p: string): string => {
|
||||
// Windows
|
||||
if (IS_WINDOWS) {
|
||||
if (isWindows()) {
|
||||
// Convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\')
|
||||
|
||||
@@ -35,9 +38,18 @@ const normalizeSeparators = (p: string): string => {
|
||||
return p.replace(/\/\/+/g, '/')
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize file path separators to '/' on all platforms
|
||||
* @param p - file path
|
||||
* @returns file path with normalized separators
|
||||
*/
|
||||
const normalizePath = (p: string): string => {
|
||||
return p.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims unnecessary trailing slash from file path
|
||||
* @param p file path
|
||||
* @param p - file path
|
||||
* @returns file path without unnecessary trailing slash
|
||||
*/
|
||||
const safeTrimTrailingSeparator = (p: string): string => {
|
||||
@@ -60,7 +72,7 @@ const safeTrimTrailingSeparator = (p: string): string => {
|
||||
}
|
||||
|
||||
// On Windows, avoid trimming the drive root, e.g. C:\ or \\hello
|
||||
if (IS_WINDOWS && /^[A-Z]:\\$/i.test(p)) {
|
||||
if (isWindows() && /^[A-Z]:\\$/i.test(p)) {
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -68,12 +80,18 @@ const safeTrimTrailingSeparator = (p: string): string => {
|
||||
return p.substring(0, p.length - 1)
|
||||
}
|
||||
|
||||
const dirname = (p: string): string => {
|
||||
/**
|
||||
* Gets the dirname of a path, similar to the Node.js path.dirname() function except that this function
|
||||
* also works for Windows UNC root paths, e.g. \\hello\world
|
||||
* @param p - file path
|
||||
* @returns dirname of path
|
||||
*/
|
||||
export const getDirname = (p: string): string => {
|
||||
// Normalize slashes and trim unnecessary trailing slash
|
||||
p = safeTrimTrailingSeparator(p)
|
||||
|
||||
// Windows UNC root, e.g. \\hello or \\hello\world
|
||||
if (IS_WINDOWS && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) {
|
||||
if (isWindows() && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) {
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -81,18 +99,31 @@ const dirname = (p: string): string => {
|
||||
let result = path.dirname(p)
|
||||
|
||||
// Trim trailing slash for Windows UNC root, e.g. \\hello\world\
|
||||
if (IS_WINDOWS && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) {
|
||||
if (isWindows() && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) {
|
||||
result = safeTrimTrailingSeparator(result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the version string to a number
|
||||
* @param version - version string
|
||||
* @returns version number
|
||||
*/
|
||||
const versionToNumber = (version: string): number => {
|
||||
const [major, minor, patch] = version.split('.').map(Number)
|
||||
return major * 1000000 + minor * 1000 + patch
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the minimum required git version
|
||||
* @returns minimum required git version
|
||||
* @throws Minimum git version requirement is not met
|
||||
* @throws Git is not installed
|
||||
* @throws Git is not found in PATH
|
||||
* @throws An unexpected error occurred
|
||||
*/
|
||||
export const verifyMinimumGitVersion = async (): Promise<void> => {
|
||||
const {exitCode, stdout, stderr} = await exec.getExecOutput(
|
||||
'git',
|
||||
@@ -113,6 +144,11 @@ export const verifyMinimumGitVersion = async (): Promise<void> => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a path exists
|
||||
* @param filePath - path to check
|
||||
* @returns path exists
|
||||
*/
|
||||
const exists = async (filePath: string): Promise<boolean> => {
|
||||
try {
|
||||
await fs.access(filePath)
|
||||
@@ -122,6 +158,11 @@ const exists = async (filePath: string): Promise<boolean> => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates lines of a file as an async iterable iterator
|
||||
* @param filePath - path of file to read
|
||||
* @param excludedFiles - whether to exclude files
|
||||
*/
|
||||
async function* lineOfFileGenerator({
|
||||
filePath,
|
||||
excludedFiles
|
||||
@@ -153,6 +194,11 @@ async function* lineOfFileGenerator({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file patterns from a source file
|
||||
* @param filePaths - paths of files to read
|
||||
* @param excludedFiles - whether to exclude the file patterns
|
||||
*/
|
||||
const getFilesFromSourceFile = async ({
|
||||
filePaths,
|
||||
excludedFiles = false
|
||||
@@ -169,6 +215,12 @@ const getFilesFromSourceFile = async ({
|
||||
return lines
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global git configs
|
||||
* @param name - name of config
|
||||
* @param value - value of config
|
||||
* @throws Couldn't update git global config
|
||||
*/
|
||||
export const updateGitGlobalConfig = async ({
|
||||
name,
|
||||
value
|
||||
@@ -191,6 +243,11 @@ export const updateGitGlobalConfig = async ({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a git repository is shallow
|
||||
* @param cwd - working directory
|
||||
* @returns repository is shallow
|
||||
*/
|
||||
export const isRepoShallow = async ({cwd}: {cwd: string}): Promise<boolean> => {
|
||||
const {stdout} = await exec.getExecOutput(
|
||||
'git',
|
||||
@@ -204,6 +261,11 @@ export const isRepoShallow = async ({cwd}: {cwd: string}): Promise<boolean> => {
|
||||
return stdout.trim() === 'true'
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a submodule exists
|
||||
* @param cwd - working directory
|
||||
* @returns submodule exists
|
||||
*/
|
||||
export const submoduleExists = async ({
|
||||
cwd
|
||||
}: {
|
||||
@@ -227,6 +289,11 @@ export const submoduleExists = async ({
|
||||
return stdout.trim() !== ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the git repository
|
||||
* @param args - arguments for fetch command
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
export const gitFetch = async ({
|
||||
args,
|
||||
cwd
|
||||
@@ -243,6 +310,11 @@ export const gitFetch = async ({
|
||||
return exitCode
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the git repository submodules
|
||||
* @param args - arguments for fetch command
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
export const gitFetchSubmodules = async ({
|
||||
args,
|
||||
cwd
|
||||
@@ -266,10 +338,10 @@ export const gitFetchSubmodules = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const normalizePath = (p: string): string => {
|
||||
return p.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the submodule paths
|
||||
* @param cwd - working directory
|
||||
*/
|
||||
export const getSubmodulePath = async ({
|
||||
cwd
|
||||
}: {
|
||||
@@ -296,6 +368,14 @@ export const getSubmodulePath = async ({
|
||||
.map((line: string) => normalizePath(line.trim().split(' ')[1]))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves commit sha of a submodule from a parent commit
|
||||
* @param cwd - working directory
|
||||
* @param parentSha1 - parent commit sha
|
||||
* @param parentSha2 - parent commit sha
|
||||
* @param submodulePath - path of submodule
|
||||
* @param diff - diff type between parent commits (`..` or `...`)
|
||||
*/
|
||||
export const gitSubmoduleDiffSHA = async ({
|
||||
cwd,
|
||||
parentSha1,
|
||||
@@ -311,7 +391,7 @@ export const gitSubmoduleDiffSHA = async ({
|
||||
}): Promise<{previousSha?: string; currentSha?: string}> => {
|
||||
const {stdout} = await exec.getExecOutput(
|
||||
'git',
|
||||
['diff', parentSha1, parentSha2, '--', submodulePath],
|
||||
['diff', `${parentSha1}${diff}${parentSha2}`, '--', submodulePath],
|
||||
{
|
||||
cwd,
|
||||
silent: !core.isDebug()
|
||||
@@ -408,6 +488,16 @@ export const gitRenamedFiles = async ({
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the changed files between two commits
|
||||
* @param cwd - working directory
|
||||
* @param sha1 - commit sha
|
||||
* @param sha2 - commit sha
|
||||
* @param diff - diff type between parent commits (`..` or `...`)
|
||||
* @param isSubmodule - is the repo a submodule
|
||||
* @param parentDir - parent directory of the submodule
|
||||
* @param outputRenamedFilesAsDeletedAndAdded - output renamed files as deleted and added
|
||||
*/
|
||||
export const getAllChangedFiles = async ({
|
||||
cwd,
|
||||
sha1,
|
||||
@@ -494,6 +584,11 @@ export const getAllChangedFiles = async ({
|
||||
return changedFiles
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the changed files by the file patterns
|
||||
* @param allDiffFiles - all the changed files
|
||||
* @param filePatterns - file patterns to filter by
|
||||
*/
|
||||
export const getFilteredChangedFiles = async ({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
@@ -518,7 +613,7 @@ export const getFilteredChangedFiles = async ({
|
||||
if (hasFilePatterns) {
|
||||
changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, {
|
||||
dot: true,
|
||||
windows: IS_WINDOWS,
|
||||
windows: isWindows(),
|
||||
noext: true
|
||||
})
|
||||
} else {
|
||||
@@ -710,15 +805,15 @@ export const canDiffCommits = async ({
|
||||
}
|
||||
|
||||
export const getDirnameMaxDepth = ({
|
||||
pathStr,
|
||||
relativePath,
|
||||
dirNamesMaxDepth,
|
||||
excludeCurrentDir
|
||||
}: {
|
||||
pathStr: string
|
||||
relativePath: string
|
||||
dirNamesMaxDepth?: number
|
||||
excludeCurrentDir?: boolean
|
||||
}): string => {
|
||||
const pathArr = dirname(pathStr).split(path.sep)
|
||||
const pathArr = getDirname(relativePath).split(path.sep)
|
||||
const maxDepth = Math.min(dirNamesMaxDepth || pathArr.length, pathArr.length)
|
||||
let output = pathArr[0]
|
||||
|
||||
@@ -815,7 +910,7 @@ export const getFilePatterns = async ({
|
||||
filePatterns = filePatterns.concat('\n', filesIgnoreFromSourceFiles)
|
||||
}
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
if (isWindows()) {
|
||||
filePatterns = filePatterns.replace(/\r\n/g, '\n')
|
||||
filePatterns = filePatterns.replace(/\r/g, '\n')
|
||||
}
|
||||
@@ -1129,7 +1224,7 @@ export const recoverDeletedFiles = async ({
|
||||
if (recoverPatterns.length > 0) {
|
||||
recoverableDeletedFiles = mm(deletedFiles, recoverPatterns, {
|
||||
dot: true,
|
||||
windows: IS_WINDOWS,
|
||||
windows: isWindows(),
|
||||
noext: true
|
||||
})
|
||||
core.debug(`filtered recoverable deleted files: ${recoverableDeletedFiles}`)
|
||||
|
||||
207
yarn.lock
207
yarn.lock
@@ -990,9 +990,9 @@
|
||||
"@types/braces" "*"
|
||||
|
||||
"@types/node@*", "@types/node@^20.3.2":
|
||||
version "20.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69"
|
||||
integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==
|
||||
version "20.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.6.tgz#b66b66c9bb5d49b199f03399e341c9d6036e9e88"
|
||||
integrity sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==
|
||||
|
||||
"@types/semver@^7.3.12", "@types/semver@^7.5.0":
|
||||
version "7.5.0"
|
||||
@@ -1022,15 +1022,15 @@
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^6.0.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz#57047c400be0632d4797ac081af8d399db3ebc3b"
|
||||
integrity sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz#41b79923fee46a745a3a50cba1c33c622aa3c79a"
|
||||
integrity sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.5.1"
|
||||
"@typescript-eslint/scope-manager" "6.2.0"
|
||||
"@typescript-eslint/type-utils" "6.2.0"
|
||||
"@typescript-eslint/utils" "6.2.0"
|
||||
"@typescript-eslint/visitor-keys" "6.2.0"
|
||||
"@typescript-eslint/scope-manager" "6.2.1"
|
||||
"@typescript-eslint/type-utils" "6.2.1"
|
||||
"@typescript-eslint/utils" "6.2.1"
|
||||
"@typescript-eslint/visitor-keys" "6.2.1"
|
||||
debug "^4.3.4"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.2.4"
|
||||
@@ -1040,14 +1040,14 @@
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
"@typescript-eslint/parser@^6.0.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.2.0.tgz#d37c30b0f459c6f39455335d8f4f085919a1c644"
|
||||
integrity sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.2.1.tgz#e18a31eea1cca8841a565f1701960c8123ed07f9"
|
||||
integrity sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "6.2.0"
|
||||
"@typescript-eslint/types" "6.2.0"
|
||||
"@typescript-eslint/typescript-estree" "6.2.0"
|
||||
"@typescript-eslint/visitor-keys" "6.2.0"
|
||||
"@typescript-eslint/scope-manager" "6.2.1"
|
||||
"@typescript-eslint/types" "6.2.1"
|
||||
"@typescript-eslint/typescript-estree" "6.2.1"
|
||||
"@typescript-eslint/visitor-keys" "6.2.1"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.62.0":
|
||||
@@ -1058,21 +1058,21 @@
|
||||
"@typescript-eslint/types" "5.62.0"
|
||||
"@typescript-eslint/visitor-keys" "5.62.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz#412a710d8fa20bc045533b3b19f423810b24f87a"
|
||||
integrity sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==
|
||||
"@typescript-eslint/scope-manager@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz#b6f43a867b84e5671fe531f2b762e0b68f7cf0c4"
|
||||
integrity sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.2.0"
|
||||
"@typescript-eslint/visitor-keys" "6.2.0"
|
||||
"@typescript-eslint/types" "6.2.1"
|
||||
"@typescript-eslint/visitor-keys" "6.2.1"
|
||||
|
||||
"@typescript-eslint/type-utils@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz#02b27a3eeb41aa5460d6275d12cce5dd72e1c9fc"
|
||||
integrity sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==
|
||||
"@typescript-eslint/type-utils@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz#8eb8a2cccdf39cd7cf93e02bd2c3782dc90b0525"
|
||||
integrity sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "6.2.0"
|
||||
"@typescript-eslint/utils" "6.2.0"
|
||||
"@typescript-eslint/typescript-estree" "6.2.1"
|
||||
"@typescript-eslint/utils" "6.2.1"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
@@ -1081,10 +1081,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
|
||||
integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
|
||||
|
||||
"@typescript-eslint/types@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.2.0.tgz#b341a4e6d5f609267306b07afc6f62bcf92b1495"
|
||||
integrity sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==
|
||||
"@typescript-eslint/types@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.2.1.tgz#7fcdeceb503aab601274bf5e210207050d88c8ab"
|
||||
integrity sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.62.0":
|
||||
version "5.62.0"
|
||||
@@ -1099,30 +1099,30 @@
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz#4969944b831b481996aa4fbd73c7164ca683b8ef"
|
||||
integrity sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==
|
||||
"@typescript-eslint/typescript-estree@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz#2af6e90c1e91cb725a5fe1682841a3f74549389e"
|
||||
integrity sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.2.0"
|
||||
"@typescript-eslint/visitor-keys" "6.2.0"
|
||||
"@typescript-eslint/types" "6.2.1"
|
||||
"@typescript-eslint/visitor-keys" "6.2.1"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.5.4"
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
"@typescript-eslint/utils@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.2.0.tgz#606a20e5c13883c2d2bd0538ddc4b96b8d410979"
|
||||
integrity sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==
|
||||
"@typescript-eslint/utils@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.2.1.tgz#2aa4279ec13053d05615bcbde2398e1e8f08c334"
|
||||
integrity sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@types/json-schema" "^7.0.12"
|
||||
"@types/semver" "^7.5.0"
|
||||
"@typescript-eslint/scope-manager" "6.2.0"
|
||||
"@typescript-eslint/types" "6.2.0"
|
||||
"@typescript-eslint/typescript-estree" "6.2.0"
|
||||
"@typescript-eslint/scope-manager" "6.2.1"
|
||||
"@typescript-eslint/types" "6.2.1"
|
||||
"@typescript-eslint/typescript-estree" "6.2.1"
|
||||
semver "^7.5.4"
|
||||
|
||||
"@typescript-eslint/utils@^5.10.0":
|
||||
@@ -1147,12 +1147,12 @@
|
||||
"@typescript-eslint/types" "5.62.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz#71943f42fdaa2ec86dc3222091f41761a49ae71a"
|
||||
integrity sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==
|
||||
"@typescript-eslint/visitor-keys@6.2.1":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz#442e7c09fe94b715a54ebe30e967987c3c41fbf4"
|
||||
integrity sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.2.0"
|
||||
"@typescript-eslint/types" "6.2.1"
|
||||
eslint-visitor-keys "^3.4.1"
|
||||
|
||||
"@vercel/ncc@^0.36.1":
|
||||
@@ -1262,6 +1262,17 @@ array-union@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
|
||||
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
|
||||
|
||||
array.prototype.findlastindex@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz#bc229aef98f6bd0533a2bc61ff95209875526c9b"
|
||||
integrity sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.20.4"
|
||||
es-shim-unscopables "^1.0.0"
|
||||
get-intrinsic "^1.1.3"
|
||||
|
||||
array.prototype.flat@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2"
|
||||
@@ -1414,13 +1425,13 @@ braces@^3.0.2:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browserslist@^4.21.0, browserslist@^4.21.9:
|
||||
version "4.21.9"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635"
|
||||
integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==
|
||||
version "4.21.10"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0"
|
||||
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001503"
|
||||
electron-to-chromium "^1.4.431"
|
||||
node-releases "^2.0.12"
|
||||
caniuse-lite "^1.0.30001517"
|
||||
electron-to-chromium "^1.4.477"
|
||||
node-releases "^2.0.13"
|
||||
update-browserslist-db "^1.0.11"
|
||||
|
||||
bs-logger@0.x:
|
||||
@@ -1472,10 +1483,10 @@ camelcase@^6.2.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
caniuse-lite@^1.0.30001503:
|
||||
version "1.0.30001517"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8"
|
||||
integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==
|
||||
caniuse-lite@^1.0.30001517:
|
||||
version "1.0.30001518"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001518.tgz#b3ca93904cb4699c01218246c4d77a71dbe97150"
|
||||
integrity sha512-rup09/e3I0BKjncL+FesTayKtPrdwKhUufQFd3riFw1hHg8JmIFoInYfB102cFcY/pPgGmdyl/iy+jgiDi2vdA==
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
@@ -1596,9 +1607,9 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
|
||||
ms "2.1.2"
|
||||
|
||||
dedent@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.3.0.tgz#15d6809eb15b581d5587a2dc208f34118e35bee3"
|
||||
integrity sha512-7glNLfvdsMzZm3FpRY1CHuI2lbYDR+71YmrhmTZjYFD5pfT0ACgnGRdrrC9Mk2uICnzkcdelCx5at787UDGOvg==
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff"
|
||||
integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
@@ -1682,10 +1693,10 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
electron-to-chromium@^1.4.431:
|
||||
version "1.4.474"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.474.tgz#ca79fe098dd802cf8fe9fb968110a28dfb1f9e56"
|
||||
integrity sha512-GsFT9gtxkFMkpHf13UeN/RFbWdLQVs4DMxA1aQv4xdUAT2qyXEoAQ0hodl2sUvWmztOlicM1UYnNPcoMdzQB5A==
|
||||
electron-to-chromium@^1.4.477:
|
||||
version "1.4.482"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.482.tgz#77c5ed37b93d4dda860e27538e0e2a01d6a19e02"
|
||||
integrity sha512-h+UqpfmEr1Qkk0zp7ej/jid7CXoq4m4QzW6wNTb0ELJ/BZCpA4wgUylBIMGCe621tnr4l5VmoHjdoSx2lbnNJA==
|
||||
|
||||
emittery@^0.13.1:
|
||||
version "0.13.1"
|
||||
@@ -1709,7 +1720,7 @@ error-ex@^1.3.1:
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.19.0, es-abstract@^1.20.4:
|
||||
es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc"
|
||||
integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==
|
||||
@@ -1813,7 +1824,7 @@ eslint-import-resolver-node@^0.3.7:
|
||||
is-core-module "^2.11.0"
|
||||
resolve "^1.22.1"
|
||||
|
||||
eslint-module-utils@^2.7.4:
|
||||
eslint-module-utils@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49"
|
||||
integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==
|
||||
@@ -1874,25 +1885,28 @@ eslint-plugin-i18n-text@^1.0.1:
|
||||
integrity sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==
|
||||
|
||||
eslint-plugin-import@^2.25.2:
|
||||
version "2.27.5"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65"
|
||||
integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==
|
||||
version "2.28.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz#8d66d6925117b06c4018d491ae84469eb3cb1005"
|
||||
integrity sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==
|
||||
dependencies:
|
||||
array-includes "^3.1.6"
|
||||
array.prototype.findlastindex "^1.2.2"
|
||||
array.prototype.flat "^1.3.1"
|
||||
array.prototype.flatmap "^1.3.1"
|
||||
debug "^3.2.7"
|
||||
doctrine "^2.1.0"
|
||||
eslint-import-resolver-node "^0.3.7"
|
||||
eslint-module-utils "^2.7.4"
|
||||
eslint-module-utils "^2.8.0"
|
||||
has "^1.0.3"
|
||||
is-core-module "^2.11.0"
|
||||
is-core-module "^2.12.1"
|
||||
is-glob "^4.0.3"
|
||||
minimatch "^3.1.2"
|
||||
object.fromentries "^2.0.6"
|
||||
object.groupby "^1.0.0"
|
||||
object.values "^1.1.6"
|
||||
resolve "^1.22.1"
|
||||
semver "^6.3.0"
|
||||
tsconfig-paths "^3.14.1"
|
||||
resolve "^1.22.3"
|
||||
semver "^6.3.1"
|
||||
tsconfig-paths "^3.14.2"
|
||||
|
||||
eslint-plugin-jest@^27.2.2:
|
||||
version "27.2.3"
|
||||
@@ -2475,7 +2489,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
||||
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
||||
|
||||
is-core-module@^2.11.0:
|
||||
is-core-module@^2.11.0, is-core-module@^2.12.0, is-core-module@^2.12.1:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd"
|
||||
integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
|
||||
@@ -3078,9 +3092,9 @@ json5@^2.2.2, json5@^2.2.3:
|
||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||
|
||||
jsx-ast-utils@^3.3.2, jsx-ast-utils@^3.3.3:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz#b896535fed5b867650acce5a9bd4135ffc7b3bf9"
|
||||
integrity sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==
|
||||
version "3.3.5"
|
||||
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a"
|
||||
integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==
|
||||
dependencies:
|
||||
array-includes "^3.1.6"
|
||||
array.prototype.flat "^1.3.1"
|
||||
@@ -3276,7 +3290,7 @@ node-int64@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
||||
integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==
|
||||
|
||||
node-releases@^2.0.12:
|
||||
node-releases@^2.0.13:
|
||||
version "2.0.13"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d"
|
||||
integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
|
||||
@@ -3338,6 +3352,16 @@ object.fromentries@^2.0.6:
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.20.4"
|
||||
|
||||
object.groupby@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.0.tgz#cb29259cf90f37e7bac6437686c1ea8c916d12a9"
|
||||
integrity sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.2.0"
|
||||
es-abstract "^1.21.2"
|
||||
get-intrinsic "^1.2.1"
|
||||
|
||||
object.values@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d"
|
||||
@@ -3505,9 +3529,9 @@ prettier-linter-helpers@^1.0.0:
|
||||
fast-diff "^1.1.2"
|
||||
|
||||
prettier@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae"
|
||||
integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.1.tgz#65271fc9320ce4913c57747a70ce635b30beaa40"
|
||||
integrity sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==
|
||||
|
||||
pretty-format@^29.0.0, pretty-format@^29.6.2:
|
||||
version "29.6.2"
|
||||
@@ -3596,6 +3620,15 @@ resolve@^1.20.0, resolve@^1.22.1:
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^1.22.3:
|
||||
version "1.22.3"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.3.tgz#4b4055349ffb962600972da1fdc33c46a4eb3283"
|
||||
integrity sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==
|
||||
dependencies:
|
||||
is-core-module "^2.12.0"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
reusify@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
@@ -3889,7 +3922,7 @@ ts-jest@^29.1.0:
|
||||
semver "^7.5.3"
|
||||
yargs-parser "^21.0.1"
|
||||
|
||||
tsconfig-paths@^3.14.1:
|
||||
tsconfig-paths@^3.14.2:
|
||||
version "3.14.2"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088"
|
||||
integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
|
||||
|
||||
Reference in New Issue
Block a user