@kontur.candy/tools 2.256.0 → 2.257.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,73 +5,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.FormGlobs = void 0;
|
|
8
|
+
var _promises = _interopRequireDefault(require("fs/promises"));
|
|
8
9
|
var _path = _interopRequireDefault(require("path"));
|
|
9
10
|
var _fsExtra = require("fs-extra");
|
|
11
|
+
var _pLimit = _interopRequireDefault(require("p-limit"));
|
|
10
12
|
var _ResolveFormInfo = require("../BuildTasks/ResolveFormInfo");
|
|
11
13
|
var _FormPathUtils = require("../../../Common/FormPathUtils");
|
|
12
14
|
var _WellKnownDirectories = require("../../../Common/WellKnownDirectories");
|
|
13
|
-
|
|
15
|
+
const GLOB_SPECIFIER_UI_TESTS = ":with-ui-tests";
|
|
16
|
+
const GLOB_SPECIFIER_CI_BUILD = ":with-ci-build";
|
|
17
|
+
const GLOB_SPECIFIERS = [GLOB_SPECIFIER_UI_TESTS, GLOB_SPECIFIER_CI_BUILD];
|
|
18
|
+
const MAX_ABSENT_GLOBS_TO_LOG = 10;
|
|
19
|
+
function buildGfvRegex(formGlob) {
|
|
20
|
+
const pattern = formGlob.replace(GLOB_SPECIFIER_UI_TESTS, "").replace(GLOB_SPECIFIER_CI_BUILD, "").replace(/\*/gi, "\\d*").replace(/\?/gi, "\\d");
|
|
21
|
+
return new RegExp(`^${pattern}$`);
|
|
22
|
+
}
|
|
14
23
|
class FormGlobs {
|
|
15
24
|
static async enumerateFormsInRepository(...repositoryRoots) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const gfv = (0, _FormPathUtils.extractGfvFromFormPath)(formPath);
|
|
23
|
-
result.push({
|
|
24
|
-
gfv: gfv,
|
|
25
|
-
formPath: _path.default.join(repositoryRoot, formPath),
|
|
26
|
-
formRelativePath: formPath
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
for (const formJsonPath of await (0, _FsUtils.globAsync)(`${_WellKnownDirectories.WellKnownDirectories.TestFarmDir}/forms/*/${_WellKnownDirectories.WellKnownDirectories.FormJsonFileName}`, {
|
|
30
|
-
cwd: repositoryRoot
|
|
31
|
-
})) {
|
|
32
|
-
const formPath = _path.default.dirname(formJsonPath);
|
|
33
|
-
const gfv = (0, _FormPathUtils.extractGfvFromFormPath)(formPath);
|
|
34
|
-
result.push({
|
|
35
|
-
gfv: gfv,
|
|
36
|
-
formPath: _path.default.join(repositoryRoot, formPath),
|
|
37
|
-
formRelativePath: formPath
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
for (const formJsonPath of await (0, _FsUtils.globAsync)(`candy.rpn.farm/forms/*/${_WellKnownDirectories.WellKnownDirectories.FormJsonFileName}`, {
|
|
41
|
-
cwd: repositoryRoot
|
|
42
|
-
})) {
|
|
43
|
-
const formPath = _path.default.dirname(formJsonPath);
|
|
44
|
-
const gfv = (0, _FormPathUtils.extractGfvFromFormPath)(formPath);
|
|
45
|
-
result.push({
|
|
46
|
-
gfv: gfv,
|
|
47
|
-
formPath: _path.default.join(repositoryRoot, formPath),
|
|
48
|
-
formRelativePath: formPath
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
for (const formJsonPath of await (0, _FsUtils.globAsync)(`candy.diadoc.farm/forms/*/${_WellKnownDirectories.WellKnownDirectories.FormJsonFileName}`, {
|
|
52
|
-
cwd: repositoryRoot
|
|
53
|
-
})) {
|
|
54
|
-
const formPath = _path.default.dirname(formJsonPath);
|
|
55
|
-
const gfv = (0, _FormPathUtils.extractGfvFromFormPath)(formPath);
|
|
56
|
-
result.push({
|
|
57
|
-
gfv: gfv,
|
|
58
|
-
formPath: _path.default.join(repositoryRoot, formPath),
|
|
59
|
-
formRelativePath: formPath
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
for (const formJsonPath of await (0, _FsUtils.globAsync)(`**/${_WellKnownDirectories.WellKnownDirectories.CandySubdirectoryName}/${_WellKnownDirectories.WellKnownDirectories.FormJsonFileName}`, {
|
|
63
|
-
cwd: _path.default.join(repositoryRoot, "forms")
|
|
64
|
-
})) {
|
|
65
|
-
const formPath = _path.default.dirname(formJsonPath);
|
|
66
|
-
const gfv = (0, _FormPathUtils.extractGfvFromFormPath)(formPath);
|
|
67
|
-
result.push({
|
|
68
|
-
gfv: gfv,
|
|
69
|
-
formPath: _path.default.join(repositoryRoot, "forms", formPath),
|
|
70
|
-
formRelativePath: formPath
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
25
|
+
const formsByRepos = await Promise.all(repositoryRoots.map(async root => {
|
|
26
|
+
const formsRoot = _path.default.join(root, "forms");
|
|
27
|
+
const formJsonPaths = await enumerateCandyForms(formsRoot);
|
|
28
|
+
return formJsonPaths.map(p => buildGfvInfo(p, formsRoot));
|
|
29
|
+
}));
|
|
30
|
+
return formsByRepos.flat();
|
|
75
31
|
}
|
|
76
32
|
static async resolveGfvGlobs(formGlobs, farmDirectory, throwErrorIfUnusedGlobFound = true) {
|
|
77
33
|
const result = new Map();
|
|
@@ -89,8 +45,7 @@ class FormGlobs {
|
|
|
89
45
|
}
|
|
90
46
|
}
|
|
91
47
|
if (throwErrorIfUnusedGlobFound) {
|
|
92
|
-
const
|
|
93
|
-
const absentGlobs = Iterator.from(formGlobs).filter(formGlob => !foundGlobs.has(formGlob)).take(maxAbsemtGlobsToLog).toArray();
|
|
48
|
+
const absentGlobs = Iterator.from(formGlobs).filter(formGlob => !foundGlobs.has(formGlob)).take(MAX_ABSENT_GLOBS_TO_LOG).toArray();
|
|
94
49
|
if (absentGlobs.length > 0) {
|
|
95
50
|
throw new Error(`Форм соответствующих ${absentGlobs.join(", ")} не найдено.`);
|
|
96
51
|
}
|
|
@@ -105,33 +60,69 @@ class FormGlobs {
|
|
|
105
60
|
return results.flat();
|
|
106
61
|
}
|
|
107
62
|
static async isFormMatchToGlob(formGlob, gfv, formPath) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
63
|
+
if (!buildGfvRegex(formGlob).test(gfv)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (formGlob.includes(GLOB_SPECIFIER_UI_TESTS)) {
|
|
67
|
+
if (!(await (0, _fsExtra.pathExists)(_path.default.join(formPath, "test")))) {
|
|
68
|
+
return false;
|
|
114
69
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
70
|
+
}
|
|
71
|
+
if (formGlob.includes(GLOB_SPECIFIER_CI_BUILD)) {
|
|
72
|
+
const formJsonPath = _path.default.join(formPath, _WellKnownDirectories.WellKnownDirectories.FormJsonFileName);
|
|
73
|
+
const formConfig = await (0, _ResolveFormInfo.readFormConfig)(formJsonPath);
|
|
74
|
+
if (formConfig.build !== "ci") {
|
|
75
|
+
return false;
|
|
121
76
|
}
|
|
122
|
-
return true;
|
|
123
77
|
}
|
|
124
|
-
return
|
|
78
|
+
return true;
|
|
125
79
|
}
|
|
126
80
|
static async resolveOnlyFormGlobSpecifiers(formGlob, farmDirectory) {
|
|
127
|
-
if (formGlob.endsWith(
|
|
128
|
-
return (await this.resolveGfvGlobs([formGlob], farmDirectory)).map(x => x.gfv);
|
|
129
|
-
}
|
|
130
|
-
if (formGlob.endsWith(":with-ci-build")) {
|
|
81
|
+
if (GLOB_SPECIFIERS.some(s => formGlob.endsWith(s))) {
|
|
131
82
|
return (await this.resolveGfvGlobs([formGlob], farmDirectory)).map(x => x.gfv);
|
|
132
83
|
}
|
|
133
84
|
return [formGlob];
|
|
134
85
|
}
|
|
135
86
|
}
|
|
136
87
|
exports.FormGlobs = FormGlobs;
|
|
88
|
+
// Глубокого исследования за этим числом нет, при необходимости, можно смело менять
|
|
89
|
+
const FORM_WALK_CONCURRENCY = 32;
|
|
90
|
+
const GFV_DIR_NAME_REGEX = /^\d{6,}$/;
|
|
91
|
+
const enumerateCandyForms = formsRoot => walkCandyForms(formsRoot, formsRoot, (0, _pLimit.default)(FORM_WALK_CONCURRENCY));
|
|
92
|
+
async function walkCandyForms(dir, baseDir, limit) {
|
|
93
|
+
const entries = await readDirSafe(dir, limit);
|
|
94
|
+
const nested = await Promise.all(entries.values().filter(isTraversableSubdirectory).map(entry => {
|
|
95
|
+
const childDir = _path.default.join(dir, entry.name);
|
|
96
|
+
return GFV_DIR_NAME_REGEX.test(entry.name) ? collectCandyFormJson(childDir, baseDir, limit) : walkCandyForms(childDir, baseDir, limit);
|
|
97
|
+
}));
|
|
98
|
+
return nested.flat();
|
|
99
|
+
}
|
|
100
|
+
async function readDirSafe(dir, limit) {
|
|
101
|
+
try {
|
|
102
|
+
return await limit(() => _promises.default.readdir(dir, {
|
|
103
|
+
withFileTypes: true
|
|
104
|
+
}));
|
|
105
|
+
} catch {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function isTraversableSubdirectory(entry) {
|
|
110
|
+
return entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules";
|
|
111
|
+
}
|
|
112
|
+
async function collectCandyFormJson(dir, baseDir, limit) {
|
|
113
|
+
const candyDir = _WellKnownDirectories.WellKnownDirectories.CandySubdirectoryName;
|
|
114
|
+
const formJsonAbsPath = _path.default.join(dir, candyDir, _WellKnownDirectories.WellKnownDirectories.FormJsonFileName);
|
|
115
|
+
if (!(await limit(() => (0, _fsExtra.pathExists)(formJsonAbsPath)))) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
return [_path.default.join(_path.default.relative(baseDir, dir), candyDir, _WellKnownDirectories.WellKnownDirectories.FormJsonFileName)];
|
|
119
|
+
}
|
|
120
|
+
const buildGfvInfo = (formJsonPath, baseDir) => {
|
|
121
|
+
const formRelativePath = _path.default.dirname(formJsonPath);
|
|
122
|
+
return {
|
|
123
|
+
gfv: (0, _FormPathUtils.extractGfvFromFormPath)(formRelativePath),
|
|
124
|
+
formPath: _path.default.join(baseDir, formRelativePath),
|
|
125
|
+
formRelativePath: formRelativePath
|
|
126
|
+
};
|
|
127
|
+
};
|
|
137
128
|
//# sourceMappingURL=FormGlobsUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormGlobsUtils.js","names":["_path","_interopRequireDefault","require","_fsExtra","_ResolveFormInfo","_FormPathUtils","_WellKnownDirectories","_FsUtils","FormGlobs","enumerateFormsInRepository","repositoryRoots","result","repositoryRoot","formJsonPath","globAsync","WellKnownDirectories","FormJsonFileName","cwd","formPath","path","dirname","gfv","extractGfvFromFormPath","push","join","formRelativePath","TestFarmDir","CandySubdirectoryName","resolveGfvGlobs","formGlobs","farmDirectory","throwErrorIfUnusedGlobFound","Map","foundGlobs","Set","forms","normalize","formGlob","isFormMatchToGlob","set","add","maxAbsemtGlobsToLog","absentGlobs","Iterator","from","filter","has","take","toArray","length","Error","entries","map","resolveSpecifiers","formGlobsWithSpecifiers","results","Promise","all","x","resolveOnlyFormGlobSpecifiers","flat","gfvRegexp","RegExp","replace","test","includes","pathExists","formConfig","readFormConfig","build","endsWith","exports"],"sources":["../../../../src/Commons/FormGlobsUtils.ts"],"sourcesContent":["import path from \"path\";\n\nimport { pathExists } from \"fs-extra\";\n\nimport { readFormConfig } from \"../BuildTasks/ResolveFormInfo\";\nimport { extractGfvFromFormPath } from \"../../../Common/FormPathUtils\";\nimport { WellKnownDirectories } from \"../../../Common/WellKnownDirectories\";\n\nimport { globAsync } from \"./FsUtils\";\nimport { FormLocationInfo } from \"./FormLocationInfo\";\n\nexport interface GfvInfo {\n gfv: string;\n formPath: string;\n formRelativePath: string;\n}\n\nexport class FormGlobs {\n public static async enumerateFormsInRepository(...repositoryRoots: string[]): Promise<GfvInfo[]> {\n const result: GfvInfo[] = [];\n\n for (const repositoryRoot of repositoryRoots) {\n for (const formJsonPath of await globAsync(`candy.farm/forms/*/${WellKnownDirectories.FormJsonFileName}`, {\n cwd: repositoryRoot,\n })) {\n const formPath = path.dirname(formJsonPath);\n const gfv = extractGfvFromFormPath(formPath);\n result.push({\n gfv: gfv,\n formPath: path.join(repositoryRoot, formPath),\n formRelativePath: formPath,\n });\n }\n for (const formJsonPath of await globAsync(\n `${WellKnownDirectories.TestFarmDir}/forms/*/${WellKnownDirectories.FormJsonFileName}`,\n {\n cwd: repositoryRoot,\n }\n )) {\n const formPath = path.dirname(formJsonPath);\n const gfv = extractGfvFromFormPath(formPath);\n result.push({\n gfv: gfv,\n formPath: path.join(repositoryRoot, formPath),\n formRelativePath: formPath,\n });\n }\n for (const formJsonPath of await globAsync(\n `candy.rpn.farm/forms/*/${WellKnownDirectories.FormJsonFileName}`,\n {\n cwd: repositoryRoot,\n }\n )) {\n const formPath = path.dirname(formJsonPath);\n const gfv = extractGfvFromFormPath(formPath);\n result.push({\n gfv: gfv,\n formPath: path.join(repositoryRoot, formPath),\n formRelativePath: formPath,\n });\n }\n for (const formJsonPath of await globAsync(\n `candy.diadoc.farm/forms/*/${WellKnownDirectories.FormJsonFileName}`,\n {\n cwd: repositoryRoot,\n }\n )) {\n const formPath = path.dirname(formJsonPath);\n const gfv = extractGfvFromFormPath(formPath);\n result.push({\n gfv: gfv,\n formPath: path.join(repositoryRoot, formPath),\n formRelativePath: formPath,\n });\n }\n for (const formJsonPath of await globAsync(\n `**/${WellKnownDirectories.CandySubdirectoryName}/${WellKnownDirectories.FormJsonFileName}`,\n { cwd: path.join(repositoryRoot, \"forms\") }\n )) {\n const formPath = path.dirname(formJsonPath);\n const gfv = extractGfvFromFormPath(formPath);\n result.push({\n gfv: gfv,\n formPath: path.join(repositoryRoot, \"forms\", formPath),\n formRelativePath: formPath,\n });\n }\n }\n return result;\n }\n\n public static async resolveGfvGlobs(\n formGlobs: string[],\n farmDirectory: string,\n throwErrorIfUnusedGlobFound: boolean = true\n ): Promise<FormLocationInfo[]> {\n const result: Map<string, string> = new Map();\n const foundGlobs = new Set<string>();\n\n const forms = await FormGlobs.enumerateFormsInRepository(path.normalize(path.join(farmDirectory, \"..\")));\n for (const { gfv, formPath } of forms) {\n for (const formGlob of formGlobs) {\n if (await FormGlobs.isFormMatchToGlob(formGlob, gfv, formPath)) {\n result.set(gfv, formPath);\n foundGlobs.add(formGlob);\n }\n }\n }\n\n if (throwErrorIfUnusedGlobFound) {\n const maxAbsemtGlobsToLog = 10;\n const absentGlobs = Iterator.from(formGlobs)\n .filter(formGlob => !foundGlobs.has(formGlob))\n .take(maxAbsemtGlobsToLog)\n .toArray();\n if (absentGlobs.length > 0) {\n throw new Error(`Форм соответствующих ${absentGlobs.join(\", \")} не найдено.`);\n }\n }\n\n return [...result.entries()].map(([gfv, formPath]) => ({ gfv: gfv, formPath: formPath }));\n }\n\n public static async resolveSpecifiers(formGlobsWithSpecifiers: string[], farmDirectory: string): Promise<string[]> {\n const results = await Promise.all(\n formGlobsWithSpecifiers.map(x => this.resolveOnlyFormGlobSpecifiers(x, farmDirectory))\n );\n\n return results.flat();\n }\n\n private static async isFormMatchToGlob(formGlob: string, gfv: string, formPath: string) {\n const gfvRegexp = new RegExp(\n \"^\" +\n formGlob\n .replace(\":with-ui-tests\", \"\")\n .replace(\":with-ci-build\", \"\")\n .replace(/\\*/gi, \"\\\\d*\")\n .replace(/\\?/gi, \"\\\\d\") +\n \"$\"\n );\n if (gfvRegexp.test(gfv)) {\n if (formGlob.includes(\":with-ui-tests\")) {\n if (!(await pathExists(path.join(formPath, \"test\")))) {\n return false;\n }\n }\n if (formGlob.includes(\":with-ci-build\")) {\n const formJsonPath = path.join(formPath, WellKnownDirectories.FormJsonFileName);\n const formConfig = await readFormConfig(formJsonPath);\n if (formConfig.build !== \"ci\") {\n return false;\n }\n }\n return true;\n }\n return false;\n }\n\n private static async resolveOnlyFormGlobSpecifiers(formGlob: string, farmDirectory: string): Promise<string[]> {\n if (formGlob.endsWith(\":with-ui-tests\")) {\n return (await this.resolveGfvGlobs([formGlob], farmDirectory)).map(x => x.gfv);\n }\n if (formGlob.endsWith(\":with-ci-build\")) {\n return (await this.resolveGfvGlobs([formGlob], farmDirectory)).map(x => x.gfv);\n }\n return [formGlob];\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"FormGlobsUtils.js","names":["_promises","_interopRequireDefault","require","_path","_fsExtra","_pLimit","_ResolveFormInfo","_FormPathUtils","_WellKnownDirectories","GLOB_SPECIFIER_UI_TESTS","GLOB_SPECIFIER_CI_BUILD","GLOB_SPECIFIERS","MAX_ABSENT_GLOBS_TO_LOG","buildGfvRegex","formGlob","pattern","replace","RegExp","FormGlobs","enumerateFormsInRepository","repositoryRoots","formsByRepos","Promise","all","map","root","formsRoot","path","join","formJsonPaths","enumerateCandyForms","p","buildGfvInfo","flat","resolveGfvGlobs","formGlobs","farmDirectory","throwErrorIfUnusedGlobFound","result","Map","foundGlobs","Set","forms","normalize","gfv","formPath","isFormMatchToGlob","set","add","absentGlobs","Iterator","from","filter","has","take","toArray","length","Error","entries","resolveSpecifiers","formGlobsWithSpecifiers","results","x","resolveOnlyFormGlobSpecifiers","test","includes","pathExists","formJsonPath","WellKnownDirectories","FormJsonFileName","formConfig","readFormConfig","build","some","s","endsWith","exports","FORM_WALK_CONCURRENCY","GFV_DIR_NAME_REGEX","walkCandyForms","pLimit","dir","baseDir","limit","readDirSafe","nested","values","isTraversableSubdirectory","entry","childDir","name","collectCandyFormJson","fs","readdir","withFileTypes","isDirectory","startsWith","candyDir","CandySubdirectoryName","formJsonAbsPath","relative","formRelativePath","dirname","extractGfvFromFormPath"],"sources":["../../../../src/Commons/FormGlobsUtils.ts"],"sourcesContent":["import fs from \"fs/promises\";\nimport { Dirent } from \"fs\";\nimport path from \"path\";\n\nimport { pathExists } from \"fs-extra\";\nimport pLimit from \"p-limit\";\n\nimport { readFormConfig } from \"../BuildTasks/ResolveFormInfo\";\nimport { extractGfvFromFormPath } from \"../../../Common/FormPathUtils\";\nimport { WellKnownDirectories } from \"../../../Common/WellKnownDirectories\";\n\nimport { FormLocationInfo } from \"./FormLocationInfo\";\n\nconst GLOB_SPECIFIER_UI_TESTS = \":with-ui-tests\";\nconst GLOB_SPECIFIER_CI_BUILD = \":with-ci-build\";\nconst GLOB_SPECIFIERS = [GLOB_SPECIFIER_UI_TESTS, GLOB_SPECIFIER_CI_BUILD] as const;\nconst MAX_ABSENT_GLOBS_TO_LOG = 10;\n\nfunction buildGfvRegex(formGlob: string): RegExp {\n const pattern = formGlob\n .replace(GLOB_SPECIFIER_UI_TESTS, \"\")\n .replace(GLOB_SPECIFIER_CI_BUILD, \"\")\n .replace(/\\*/gi, \"\\\\d*\")\n .replace(/\\?/gi, \"\\\\d\");\n return new RegExp(`^${pattern}$`);\n}\n\nexport interface GfvInfo {\n gfv: string;\n formPath: string;\n formRelativePath: string;\n}\n\nexport class FormGlobs {\n public static async enumerateFormsInRepository(...repositoryRoots: string[]): Promise<GfvInfo[]> {\n const formsByRepos = await Promise.all(\n repositoryRoots.map(async root => {\n const formsRoot = path.join(root, \"forms\");\n const formJsonPaths = await enumerateCandyForms(formsRoot);\n return formJsonPaths.map(p => buildGfvInfo(p, formsRoot));\n })\n );\n return formsByRepos.flat();\n }\n\n public static async resolveGfvGlobs(\n formGlobs: string[],\n farmDirectory: string,\n throwErrorIfUnusedGlobFound: boolean = true\n ): Promise<FormLocationInfo[]> {\n const result: Map<string, string> = new Map();\n const foundGlobs = new Set<string>();\n\n const forms = await FormGlobs.enumerateFormsInRepository(path.normalize(path.join(farmDirectory, \"..\")));\n for (const { gfv, formPath } of forms) {\n for (const formGlob of formGlobs) {\n if (await FormGlobs.isFormMatchToGlob(formGlob, gfv, formPath)) {\n result.set(gfv, formPath);\n foundGlobs.add(formGlob);\n }\n }\n }\n\n if (throwErrorIfUnusedGlobFound) {\n const absentGlobs = Iterator.from(formGlobs)\n .filter(formGlob => !foundGlobs.has(formGlob))\n .take(MAX_ABSENT_GLOBS_TO_LOG)\n .toArray();\n if (absentGlobs.length > 0) {\n throw new Error(`Форм соответствующих ${absentGlobs.join(\", \")} не найдено.`);\n }\n }\n\n return [...result.entries()].map(([gfv, formPath]) => ({ gfv: gfv, formPath: formPath }));\n }\n\n public static async resolveSpecifiers(formGlobsWithSpecifiers: string[], farmDirectory: string): Promise<string[]> {\n const results = await Promise.all(\n formGlobsWithSpecifiers.map(x => this.resolveOnlyFormGlobSpecifiers(x, farmDirectory))\n );\n\n return results.flat();\n }\n\n private static async isFormMatchToGlob(formGlob: string, gfv: string, formPath: string) {\n if (!buildGfvRegex(formGlob).test(gfv)) {\n return false;\n }\n if (formGlob.includes(GLOB_SPECIFIER_UI_TESTS)) {\n if (!(await pathExists(path.join(formPath, \"test\")))) {\n return false;\n }\n }\n if (formGlob.includes(GLOB_SPECIFIER_CI_BUILD)) {\n const formJsonPath = path.join(formPath, WellKnownDirectories.FormJsonFileName);\n const formConfig = await readFormConfig(formJsonPath);\n if (formConfig.build !== \"ci\") {\n return false;\n }\n }\n return true;\n }\n\n private static async resolveOnlyFormGlobSpecifiers(formGlob: string, farmDirectory: string): Promise<string[]> {\n if (GLOB_SPECIFIERS.some(s => formGlob.endsWith(s))) {\n return (await this.resolveGfvGlobs([formGlob], farmDirectory)).map(x => x.gfv);\n }\n return [formGlob];\n }\n}\n\ntype ConcurrencyLimit = ReturnType<typeof pLimit>;\n\n// Глубокого исследования за этим числом нет, при необходимости, можно смело менять\nconst FORM_WALK_CONCURRENCY = 32;\nconst GFV_DIR_NAME_REGEX = /^\\d{6,}$/;\n\nconst enumerateCandyForms = (formsRoot: string): Promise<string[]> =>\n walkCandyForms(formsRoot, formsRoot, pLimit(FORM_WALK_CONCURRENCY));\n\nasync function walkCandyForms(dir: string, baseDir: string, limit: ConcurrencyLimit): Promise<string[]> {\n const entries = await readDirSafe(dir, limit);\n const nested = await Promise.all(\n entries\n .values()\n .filter(isTraversableSubdirectory)\n .map(entry => {\n const childDir = path.join(dir, entry.name);\n return GFV_DIR_NAME_REGEX.test(entry.name)\n ? collectCandyFormJson(childDir, baseDir, limit)\n : walkCandyForms(childDir, baseDir, limit);\n })\n );\n return nested.flat();\n}\n\nasync function readDirSafe(dir: string, limit: ConcurrencyLimit): Promise<Dirent[]> {\n try {\n return await limit(() => fs.readdir(dir, { withFileTypes: true }));\n } catch {\n return [];\n }\n}\n\nfunction isTraversableSubdirectory(entry: Dirent): boolean {\n return entry.isDirectory() && !entry.name.startsWith(\".\") && entry.name !== \"node_modules\";\n}\n\nasync function collectCandyFormJson(dir: string, baseDir: string, limit: ConcurrencyLimit): Promise<string[]> {\n const candyDir = WellKnownDirectories.CandySubdirectoryName;\n const formJsonAbsPath = path.join(dir, candyDir, WellKnownDirectories.FormJsonFileName);\n if (!(await limit(() => pathExists(formJsonAbsPath)))) {\n return [];\n }\n return [path.join(path.relative(baseDir, dir), candyDir, WellKnownDirectories.FormJsonFileName)];\n}\n\nconst buildGfvInfo = (formJsonPath: string, baseDir: string): GfvInfo => {\n const formRelativePath = path.dirname(formJsonPath);\n return {\n gfv: extractGfvFromFormPath(formRelativePath),\n formPath: path.join(baseDir, formRelativePath),\n formRelativePath: formRelativePath,\n };\n};\n"],"mappings":"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","ignoreList":[]}
|