@aspruyt/xfg 4.0.0 → 4.0.2
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.
- package/README.md +1 -2
- package/dist/cli/index.d.ts +1 -2
- package/dist/cli/index.js +0 -1
- package/dist/cli/program.js +7 -2
- package/dist/cli/{settings/results-collector.d.ts → results-collector.d.ts} +1 -1
- package/dist/cli/{settings/results-collector.js → results-collector.js} +2 -1
- package/dist/cli/settings-report-builder.d.ts +1 -3
- package/dist/cli/sync-command.d.ts +2 -24
- package/dist/cli/sync-command.js +295 -301
- package/dist/cli/types.d.ts +60 -40
- package/dist/cli/types.js +1 -12
- package/dist/config/errors.d.ts +9 -0
- package/dist/config/errors.js +11 -0
- package/dist/config/file-reference-resolver.d.ts +2 -1
- package/dist/config/file-reference-resolver.js +10 -8
- package/dist/config/formatter.d.ts +3 -2
- package/dist/config/index.d.ts +4 -6
- package/dist/config/index.js +4 -8
- package/dist/config/loader.js +4 -2
- package/dist/config/merge.d.ts +0 -9
- package/dist/config/merge.js +2 -7
- package/dist/config/normalizer.d.ts +4 -0
- package/dist/config/normalizer.js +61 -110
- package/dist/config/types.d.ts +15 -19
- package/dist/config/types.js +1 -1
- package/dist/config/validator.d.ts +0 -4
- package/dist/config/validator.js +286 -363
- package/dist/config/validators/file-validator.d.ts +2 -8
- package/dist/config/validators/file-validator.js +6 -17
- package/dist/config/validators/index.d.ts +3 -3
- package/dist/config/validators/index.js +3 -3
- package/dist/config/validators/repo-settings-validator.d.ts +0 -6
- package/dist/config/validators/repo-settings-validator.js +9 -9
- package/dist/config/validators/ruleset-validator.d.ts +0 -14
- package/dist/config/validators/ruleset-validator.js +28 -28
- package/dist/lifecycle/ado-migration-source.js +2 -1
- package/dist/lifecycle/github-lifecycle-provider.d.ts +6 -5
- package/dist/lifecycle/github-lifecycle-provider.js +79 -90
- package/dist/lifecycle/index.d.ts +2 -6
- package/dist/lifecycle/index.js +0 -4
- package/dist/lifecycle/lifecycle-formatter.d.ts +2 -1
- package/dist/lifecycle/lifecycle-formatter.js +4 -0
- package/dist/lifecycle/lifecycle-helpers.d.ts +3 -2
- package/dist/lifecycle/repo-lifecycle-manager.js +4 -11
- package/dist/lifecycle/types.d.ts +0 -8
- package/dist/output/github-summary.d.ts +5 -0
- package/dist/output/github-summary.js +9 -2
- package/dist/output/index.d.ts +2 -2
- package/dist/output/index.js +1 -1
- package/dist/output/lifecycle-report.js +5 -23
- package/dist/output/settings-report.d.ts +14 -3
- package/dist/output/settings-report.js +137 -197
- package/dist/output/summary-utils.d.ts +1 -1
- package/dist/output/summary-utils.js +2 -1
- package/dist/output/sync-report.js +5 -8
- package/dist/output/unified-summary.d.ts +2 -1
- package/dist/output/unified-summary.js +71 -133
- package/dist/settings/base-processor.d.ts +67 -0
- package/dist/settings/base-processor.js +91 -0
- package/dist/settings/index.d.ts +4 -3
- package/dist/settings/index.js +3 -3
- package/dist/settings/labels/converter.d.ts +2 -1
- package/dist/settings/labels/github-labels-strategy.d.ts +9 -18
- package/dist/settings/labels/github-labels-strategy.js +17 -73
- package/dist/settings/labels/index.d.ts +2 -6
- package/dist/settings/labels/index.js +1 -9
- package/dist/settings/labels/processor.d.ts +6 -30
- package/dist/settings/labels/processor.js +62 -152
- package/dist/settings/labels/types.d.ts +5 -8
- package/dist/settings/repo-settings/formatter.d.ts +2 -2
- package/dist/settings/repo-settings/formatter.js +6 -6
- package/dist/settings/repo-settings/github-repo-settings-strategy.d.ts +11 -12
- package/dist/settings/repo-settings/github-repo-settings-strategy.js +32 -79
- package/dist/settings/repo-settings/index.d.ts +2 -5
- package/dist/settings/repo-settings/index.js +1 -9
- package/dist/settings/repo-settings/processor.d.ts +6 -27
- package/dist/settings/repo-settings/processor.js +51 -104
- package/dist/settings/repo-settings/types.d.ts +7 -9
- package/dist/settings/rulesets/diff-algorithm.d.ts +0 -4
- package/dist/settings/rulesets/diff-algorithm.js +1 -10
- package/dist/settings/rulesets/diff.d.ts +1 -1
- package/dist/settings/rulesets/diff.js +2 -21
- package/dist/settings/rulesets/formatter.d.ts +1 -3
- package/dist/settings/rulesets/formatter.js +1 -8
- package/dist/settings/rulesets/github-ruleset-strategy.d.ts +11 -51
- package/dist/settings/rulesets/github-ruleset-strategy.js +24 -85
- package/dist/settings/rulesets/index.d.ts +3 -6
- package/dist/settings/rulesets/index.js +5 -9
- package/dist/settings/rulesets/processor.d.ts +8 -33
- package/dist/settings/rulesets/processor.js +58 -151
- package/dist/settings/rulesets/types.d.ts +35 -6
- package/dist/shared/command-executor.d.ts +2 -22
- package/dist/shared/command-executor.js +8 -7
- package/dist/shared/env.d.ts +0 -8
- package/dist/shared/env.js +14 -70
- package/dist/shared/file-status.d.ts +2 -0
- package/dist/shared/file-status.js +13 -0
- package/dist/shared/gh-api-utils.d.ts +46 -0
- package/dist/shared/gh-api-utils.js +107 -0
- package/dist/shared/index.d.ts +5 -5
- package/dist/shared/index.js +3 -3
- package/dist/shared/interpolation-engine.d.ts +31 -0
- package/dist/shared/interpolation-engine.js +50 -0
- package/dist/shared/logger.d.ts +3 -7
- package/dist/shared/logger.js +4 -1
- package/dist/shared/repo-detector.d.ts +17 -2
- package/dist/shared/repo-detector.js +27 -0
- package/dist/shared/retry-utils.d.ts +9 -17
- package/dist/shared/retry-utils.js +22 -28
- package/dist/shared/sanitize-utils.d.ts +0 -7
- package/dist/shared/sanitize-utils.js +0 -7
- package/dist/shared/shell-utils.d.ts +1 -0
- package/dist/shared/shell-utils.js +3 -0
- package/dist/shared/string-utils.d.ts +4 -0
- package/dist/shared/string-utils.js +6 -0
- package/dist/shared/type-guards.d.ts +17 -0
- package/dist/shared/type-guards.js +26 -0
- package/dist/shared/workspace-utils.d.ts +0 -4
- package/dist/shared/workspace-utils.js +0 -4
- package/dist/{sync → shared}/xfg-template.d.ts +3 -2
- package/dist/{sync → shared}/xfg-template.js +13 -54
- package/dist/sync/auth-options-builder.d.ts +4 -5
- package/dist/sync/auth-options-builder.js +15 -26
- package/dist/sync/branch-manager.d.ts +5 -0
- package/dist/sync/branch-manager.js +12 -10
- package/dist/sync/commit-push-manager.d.ts +1 -1
- package/dist/sync/commit-push-manager.js +22 -18
- package/dist/sync/diff-utils.d.ts +4 -9
- package/dist/sync/diff-utils.js +2 -19
- package/dist/sync/file-sync-orchestrator.js +9 -8
- package/dist/sync/file-writer.d.ts +2 -1
- package/dist/sync/file-writer.js +3 -6
- package/dist/sync/index.d.ts +2 -15
- package/dist/sync/index.js +0 -19
- package/dist/sync/manifest-manager.d.ts +4 -0
- package/dist/sync/manifest-manager.js +5 -1
- package/dist/sync/manifest.d.ts +10 -41
- package/dist/sync/manifest.js +11 -56
- package/dist/sync/pr-merge-handler.d.ts +2 -6
- package/dist/sync/pr-merge-handler.js +6 -3
- package/dist/sync/repository-processor.d.ts +1 -2
- package/dist/sync/repository-processor.js +20 -12
- package/dist/sync/repository-session.js +5 -14
- package/dist/sync/sync-workflow.js +31 -38
- package/dist/sync/types.d.ts +43 -178
- package/dist/vcs/authenticated-git-ops.d.ts +27 -70
- package/dist/vcs/authenticated-git-ops.js +70 -96
- package/dist/vcs/azure-pr-strategy.d.ts +6 -4
- package/dist/vcs/azure-pr-strategy.js +34 -82
- package/dist/vcs/branch-utils.d.ts +6 -0
- package/dist/vcs/branch-utils.js +29 -0
- package/dist/vcs/commit-strategy-selector.d.ts +5 -0
- package/dist/vcs/commit-strategy-selector.js +10 -0
- package/dist/vcs/git-commit-strategy.js +1 -2
- package/dist/vcs/git-ops.d.ts +15 -59
- package/dist/vcs/git-ops.js +46 -110
- package/dist/vcs/github-app-token-manager.d.ts +0 -6
- package/dist/vcs/github-app-token-manager.js +5 -12
- package/dist/vcs/github-pr-strategy.d.ts +5 -5
- package/dist/vcs/github-pr-strategy.js +44 -122
- package/dist/vcs/gitlab-pr-strategy.d.ts +6 -4
- package/dist/vcs/gitlab-pr-strategy.js +39 -87
- package/dist/vcs/graphql-commit-strategy.d.ts +3 -4
- package/dist/vcs/graphql-commit-strategy.js +31 -63
- package/dist/vcs/index.d.ts +3 -16
- package/dist/vcs/index.js +2 -33
- package/dist/vcs/pr-creator.d.ts +9 -9
- package/dist/vcs/pr-creator.js +11 -10
- package/dist/vcs/pr-strategy-factory.d.ts +5 -0
- package/dist/vcs/pr-strategy-factory.js +17 -0
- package/dist/vcs/pr-strategy.d.ts +13 -26
- package/dist/vcs/pr-strategy.js +20 -25
- package/dist/vcs/types.d.ts +87 -21
- package/package.json +2 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
|
+
import { isTextContent } from "../merge.js";
|
|
2
|
+
export { isTextContent };
|
|
1
3
|
declare const VALID_STRATEGIES: string[];
|
|
2
|
-
/**
|
|
3
|
-
* Check if content is text type (string or string[]).
|
|
4
|
-
*/
|
|
5
|
-
export declare function isTextContent(content: unknown): boolean;
|
|
6
4
|
/**
|
|
7
5
|
* Check if content is object type (for JSON/YAML output).
|
|
8
6
|
*/
|
|
@@ -15,8 +13,4 @@ export declare function isStructuredFileExtension(fileName: string): boolean;
|
|
|
15
13
|
* Validates a file name for security issues
|
|
16
14
|
*/
|
|
17
15
|
export declare function validateFileName(fileName: string): void;
|
|
18
|
-
/**
|
|
19
|
-
* Validates that merge strategy is valid
|
|
20
|
-
*/
|
|
21
|
-
export declare function isValidMergeStrategy(strategy: string): boolean;
|
|
22
16
|
export { VALID_STRATEGIES };
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { extname, isAbsolute } from "node:path";
|
|
2
|
+
import { isTextContent } from "../merge.js";
|
|
3
|
+
import { ValidationError } from "../errors.js";
|
|
4
|
+
export { isTextContent };
|
|
2
5
|
const VALID_STRATEGIES = ["replace", "append", "prepend"];
|
|
3
|
-
/**
|
|
4
|
-
* Check if content is text type (string or string[]).
|
|
5
|
-
*/
|
|
6
|
-
export function isTextContent(content) {
|
|
7
|
-
return (typeof content === "string" ||
|
|
8
|
-
(Array.isArray(content) &&
|
|
9
|
-
content.every((item) => typeof item === "string")));
|
|
10
|
-
}
|
|
11
6
|
/**
|
|
12
7
|
* Check if content is object type (for JSON/YAML output).
|
|
13
8
|
*/
|
|
@@ -26,21 +21,15 @@ export function isStructuredFileExtension(fileName) {
|
|
|
26
21
|
*/
|
|
27
22
|
export function validateFileName(fileName) {
|
|
28
23
|
if (!fileName || typeof fileName !== "string") {
|
|
29
|
-
throw new
|
|
24
|
+
throw new ValidationError("File name must be a non-empty string");
|
|
30
25
|
}
|
|
31
26
|
// Validate fileName doesn't allow path traversal
|
|
32
27
|
if (fileName.includes("..") || isAbsolute(fileName)) {
|
|
33
|
-
throw new
|
|
28
|
+
throw new ValidationError(`Invalid fileName '${fileName}': must be a relative path without '..' components`);
|
|
34
29
|
}
|
|
35
30
|
// Validate fileName doesn't contain control characters that could bypass shell escaping
|
|
36
31
|
if (/[\n\r\0]/.test(fileName)) {
|
|
37
|
-
throw new
|
|
32
|
+
throw new ValidationError(`Invalid fileName '${fileName}': cannot contain newlines or null bytes`);
|
|
38
33
|
}
|
|
39
34
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Validates that merge strategy is valid
|
|
42
|
-
*/
|
|
43
|
-
export function isValidMergeStrategy(strategy) {
|
|
44
|
-
return VALID_STRATEGIES.includes(strategy);
|
|
45
|
-
}
|
|
46
35
|
export { VALID_STRATEGIES };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { isTextContent, isObjectContent, isStructuredFileExtension, validateFileName,
|
|
2
|
-
export { validateRepoSettings
|
|
3
|
-
export {
|
|
1
|
+
export { isTextContent, isObjectContent, isStructuredFileExtension, validateFileName, VALID_STRATEGIES, } from "./file-validator.js";
|
|
2
|
+
export { validateRepoSettings } from "./repo-settings-validator.js";
|
|
3
|
+
export { validateRuleset } from "./ruleset-validator.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// File validation
|
|
2
|
-
export { isTextContent, isObjectContent, isStructuredFileExtension, validateFileName,
|
|
2
|
+
export { isTextContent, isObjectContent, isStructuredFileExtension, validateFileName, VALID_STRATEGIES, } from "./file-validator.js";
|
|
3
3
|
// Repo settings validation
|
|
4
|
-
export { validateRepoSettings
|
|
4
|
+
export { validateRepoSettings } from "./repo-settings-validator.js";
|
|
5
5
|
// Ruleset validation
|
|
6
|
-
export {
|
|
6
|
+
export { validateRuleset } from "./ruleset-validator.js";
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
declare const VALID_VISIBILITY: string[];
|
|
2
|
-
declare const VALID_SQUASH_MERGE_COMMIT_TITLE: string[];
|
|
3
|
-
declare const VALID_SQUASH_MERGE_COMMIT_MESSAGE: string[];
|
|
4
|
-
declare const VALID_MERGE_COMMIT_TITLE: string[];
|
|
5
|
-
declare const VALID_MERGE_COMMIT_MESSAGE: string[];
|
|
6
1
|
/**
|
|
7
2
|
* Validates GitHub repository settings.
|
|
8
3
|
*/
|
|
9
4
|
export declare function validateRepoSettings(repo: unknown, context: string): void;
|
|
10
|
-
export { VALID_VISIBILITY, VALID_SQUASH_MERGE_COMMIT_TITLE, VALID_SQUASH_MERGE_COMMIT_MESSAGE, VALID_MERGE_COMMIT_TITLE, VALID_MERGE_COMMIT_MESSAGE, };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ValidationError } from "../errors.js";
|
|
1
2
|
const VALID_VISIBILITY = ["public", "private", "internal"];
|
|
2
3
|
const VALID_SQUASH_MERGE_COMMIT_TITLE = ["PR_TITLE", "COMMIT_OR_PR_TITLE"];
|
|
3
4
|
const VALID_SQUASH_MERGE_COMMIT_MESSAGE = [
|
|
@@ -12,7 +13,7 @@ const VALID_MERGE_COMMIT_MESSAGE = ["PR_BODY", "PR_TITLE", "BLANK"];
|
|
|
12
13
|
*/
|
|
13
14
|
export function validateRepoSettings(repo, context) {
|
|
14
15
|
if (typeof repo !== "object" || repo === null || Array.isArray(repo)) {
|
|
15
|
-
throw new
|
|
16
|
+
throw new ValidationError(`${context}: repo must be an object`);
|
|
16
17
|
}
|
|
17
18
|
const r = repo;
|
|
18
19
|
// Validate boolean fields
|
|
@@ -39,33 +40,32 @@ export function validateRepoSettings(repo, context) {
|
|
|
39
40
|
];
|
|
40
41
|
for (const field of booleanFields) {
|
|
41
42
|
if (r[field] !== undefined && typeof r[field] !== "boolean") {
|
|
42
|
-
throw new
|
|
43
|
+
throw new ValidationError(`${context}: ${field} must be a boolean`);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
// Validate string fields
|
|
46
47
|
if (r.defaultBranch !== undefined && typeof r.defaultBranch !== "string") {
|
|
47
|
-
throw new
|
|
48
|
+
throw new ValidationError(`${context}: defaultBranch must be a string`);
|
|
48
49
|
}
|
|
49
50
|
// Validate enum fields
|
|
50
51
|
if (r.visibility !== undefined &&
|
|
51
52
|
!VALID_VISIBILITY.includes(r.visibility)) {
|
|
52
|
-
throw new
|
|
53
|
+
throw new ValidationError(`${context}: visibility must be one of: ${VALID_VISIBILITY.join(", ")}`);
|
|
53
54
|
}
|
|
54
55
|
if (r.squashMergeCommitTitle !== undefined &&
|
|
55
56
|
!VALID_SQUASH_MERGE_COMMIT_TITLE.includes(r.squashMergeCommitTitle)) {
|
|
56
|
-
throw new
|
|
57
|
+
throw new ValidationError(`${context}: squashMergeCommitTitle must be one of: ${VALID_SQUASH_MERGE_COMMIT_TITLE.join(", ")}`);
|
|
57
58
|
}
|
|
58
59
|
if (r.squashMergeCommitMessage !== undefined &&
|
|
59
60
|
!VALID_SQUASH_MERGE_COMMIT_MESSAGE.includes(r.squashMergeCommitMessage)) {
|
|
60
|
-
throw new
|
|
61
|
+
throw new ValidationError(`${context}: squashMergeCommitMessage must be one of: ${VALID_SQUASH_MERGE_COMMIT_MESSAGE.join(", ")}`);
|
|
61
62
|
}
|
|
62
63
|
if (r.mergeCommitTitle !== undefined &&
|
|
63
64
|
!VALID_MERGE_COMMIT_TITLE.includes(r.mergeCommitTitle)) {
|
|
64
|
-
throw new
|
|
65
|
+
throw new ValidationError(`${context}: mergeCommitTitle must be one of: ${VALID_MERGE_COMMIT_TITLE.join(", ")}`);
|
|
65
66
|
}
|
|
66
67
|
if (r.mergeCommitMessage !== undefined &&
|
|
67
68
|
!VALID_MERGE_COMMIT_MESSAGE.includes(r.mergeCommitMessage)) {
|
|
68
|
-
throw new
|
|
69
|
+
throw new ValidationError(`${context}: mergeCommitMessage must be one of: ${VALID_MERGE_COMMIT_MESSAGE.join(", ")}`);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
export { VALID_VISIBILITY, VALID_SQUASH_MERGE_COMMIT_TITLE, VALID_SQUASH_MERGE_COMMIT_MESSAGE, VALID_MERGE_COMMIT_TITLE, VALID_MERGE_COMMIT_MESSAGE, };
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
declare const VALID_RULESET_TARGETS: string[];
|
|
2
|
-
declare const VALID_ENFORCEMENT_LEVELS: string[];
|
|
3
|
-
declare const VALID_ACTOR_TYPES: string[];
|
|
4
|
-
declare const VALID_BYPASS_MODES: string[];
|
|
5
|
-
declare const VALID_PATTERN_OPERATORS: string[];
|
|
6
|
-
declare const VALID_MERGE_METHODS: string[];
|
|
7
|
-
declare const VALID_ALERTS_THRESHOLDS: string[];
|
|
8
|
-
declare const VALID_SECURITY_THRESHOLDS: string[];
|
|
9
|
-
declare const VALID_RULE_TYPES: string[];
|
|
10
|
-
/**
|
|
11
|
-
* Validates a single ruleset rule.
|
|
12
|
-
*/
|
|
13
|
-
export declare function validateRule(rule: unknown, context: string): void;
|
|
14
1
|
/**
|
|
15
2
|
* Validates a single ruleset.
|
|
16
3
|
*/
|
|
17
4
|
export declare function validateRuleset(ruleset: unknown, name: string, context: string): void;
|
|
18
|
-
export { VALID_RULESET_TARGETS, VALID_ENFORCEMENT_LEVELS, VALID_ACTOR_TYPES, VALID_BYPASS_MODES, VALID_PATTERN_OPERATORS, VALID_MERGE_METHODS, VALID_ALERTS_THRESHOLDS, VALID_SECURITY_THRESHOLDS, VALID_RULE_TYPES, };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ValidationError } from "../errors.js";
|
|
1
2
|
const VALID_RULESET_TARGETS = ["branch", "tag"];
|
|
2
3
|
const VALID_ENFORCEMENT_LEVELS = ["active", "disabled", "evaluate"];
|
|
3
4
|
const VALID_ACTOR_TYPES = ["Team", "User", "Integration"];
|
|
@@ -48,33 +49,33 @@ const VALID_RULE_TYPES = [
|
|
|
48
49
|
/**
|
|
49
50
|
* Validates a single ruleset rule.
|
|
50
51
|
*/
|
|
51
|
-
|
|
52
|
+
function validateRule(rule, context) {
|
|
52
53
|
if (typeof rule !== "object" || rule === null || Array.isArray(rule)) {
|
|
53
|
-
throw new
|
|
54
|
+
throw new ValidationError(`${context}: rule must be an object`);
|
|
54
55
|
}
|
|
55
56
|
const r = rule;
|
|
56
57
|
if (!r.type || typeof r.type !== "string") {
|
|
57
|
-
throw new
|
|
58
|
+
throw new ValidationError(`${context}: rule must have a 'type' string field`);
|
|
58
59
|
}
|
|
59
60
|
if (!VALID_RULE_TYPES.includes(r.type)) {
|
|
60
|
-
throw new
|
|
61
|
+
throw new ValidationError(`${context}: invalid rule type '${r.type}'. Must be one of: ${VALID_RULE_TYPES.join(", ")}`);
|
|
61
62
|
}
|
|
62
63
|
// Validate parameters based on rule type
|
|
63
64
|
if (r.parameters !== undefined) {
|
|
64
65
|
if (typeof r.parameters !== "object" ||
|
|
65
66
|
r.parameters === null ||
|
|
66
67
|
Array.isArray(r.parameters)) {
|
|
67
|
-
throw new
|
|
68
|
+
throw new ValidationError(`${context}: rule parameters must be an object`);
|
|
68
69
|
}
|
|
69
70
|
const params = r.parameters;
|
|
70
71
|
// Validate pattern rule parameters
|
|
71
72
|
if (r.type.toString().endsWith("_pattern")) {
|
|
72
73
|
if (params.operator !== undefined &&
|
|
73
74
|
!VALID_PATTERN_OPERATORS.includes(params.operator)) {
|
|
74
|
-
throw new
|
|
75
|
+
throw new ValidationError(`${context}: pattern rule operator must be one of: ${VALID_PATTERN_OPERATORS.join(", ")}`);
|
|
75
76
|
}
|
|
76
77
|
if (params.pattern !== undefined && typeof params.pattern !== "string") {
|
|
77
|
-
throw new
|
|
78
|
+
throw new ValidationError(`${context}: pattern rule pattern must be a string`);
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
// Validate pull_request parameters
|
|
@@ -85,16 +86,16 @@ export function validateRule(rule, context) {
|
|
|
85
86
|
!Number.isInteger(count) ||
|
|
86
87
|
count < 0 ||
|
|
87
88
|
count > 10) {
|
|
88
|
-
throw new
|
|
89
|
+
throw new ValidationError(`${context}: requiredApprovingReviewCount must be an integer between 0 and 10`);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
if (params.allowedMergeMethods !== undefined) {
|
|
92
93
|
if (!Array.isArray(params.allowedMergeMethods)) {
|
|
93
|
-
throw new
|
|
94
|
+
throw new ValidationError(`${context}: allowedMergeMethods must be an array`);
|
|
94
95
|
}
|
|
95
96
|
for (const method of params.allowedMergeMethods) {
|
|
96
97
|
if (!VALID_MERGE_METHODS.includes(method)) {
|
|
97
|
-
throw new
|
|
98
|
+
throw new ValidationError(`${context}: allowedMergeMethods values must be one of: ${VALID_MERGE_METHODS.join(", ")}`);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
}
|
|
@@ -102,20 +103,20 @@ export function validateRule(rule, context) {
|
|
|
102
103
|
// Validate code_scanning parameters
|
|
103
104
|
if (r.type === "code_scanning" && params.codeScanningTools !== undefined) {
|
|
104
105
|
if (!Array.isArray(params.codeScanningTools)) {
|
|
105
|
-
throw new
|
|
106
|
+
throw new ValidationError(`${context}: codeScanningTools must be an array`);
|
|
106
107
|
}
|
|
107
108
|
for (const tool of params.codeScanningTools) {
|
|
108
109
|
if (typeof tool !== "object" || tool === null) {
|
|
109
|
-
throw new
|
|
110
|
+
throw new ValidationError(`${context}: each codeScanningTool must be an object`);
|
|
110
111
|
}
|
|
111
112
|
const t = tool;
|
|
112
113
|
if (t.alertsThreshold !== undefined &&
|
|
113
114
|
!VALID_ALERTS_THRESHOLDS.includes(t.alertsThreshold)) {
|
|
114
|
-
throw new
|
|
115
|
+
throw new ValidationError(`${context}: alertsThreshold must be one of: ${VALID_ALERTS_THRESHOLDS.join(", ")}`);
|
|
115
116
|
}
|
|
116
117
|
if (t.securityAlertsThreshold !== undefined &&
|
|
117
118
|
!VALID_SECURITY_THRESHOLDS.includes(t.securityAlertsThreshold)) {
|
|
118
|
-
throw new
|
|
119
|
+
throw new ValidationError(`${context}: securityAlertsThreshold must be one of: ${VALID_SECURITY_THRESHOLDS.join(", ")}`);
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
}
|
|
@@ -128,36 +129,36 @@ export function validateRuleset(ruleset, name, context) {
|
|
|
128
129
|
if (typeof ruleset !== "object" ||
|
|
129
130
|
ruleset === null ||
|
|
130
131
|
Array.isArray(ruleset)) {
|
|
131
|
-
throw new
|
|
132
|
+
throw new ValidationError(`${context}: ruleset '${name}' must be an object`);
|
|
132
133
|
}
|
|
133
134
|
const rs = ruleset;
|
|
134
135
|
if (rs.target !== undefined &&
|
|
135
136
|
!VALID_RULESET_TARGETS.includes(rs.target)) {
|
|
136
|
-
throw new
|
|
137
|
+
throw new ValidationError(`${context}: ruleset '${name}' target must be one of: ${VALID_RULESET_TARGETS.join(", ")}`);
|
|
137
138
|
}
|
|
138
139
|
if (rs.enforcement !== undefined &&
|
|
139
140
|
!VALID_ENFORCEMENT_LEVELS.includes(rs.enforcement)) {
|
|
140
|
-
throw new
|
|
141
|
+
throw new ValidationError(`${context}: ruleset '${name}' enforcement must be one of: ${VALID_ENFORCEMENT_LEVELS.join(", ")}`);
|
|
141
142
|
}
|
|
142
143
|
// Validate bypassActors
|
|
143
144
|
if (rs.bypassActors !== undefined) {
|
|
144
145
|
if (!Array.isArray(rs.bypassActors)) {
|
|
145
|
-
throw new
|
|
146
|
+
throw new ValidationError(`${context}: ruleset '${name}' bypassActors must be an array`);
|
|
146
147
|
}
|
|
147
148
|
for (let i = 0; i < rs.bypassActors.length; i++) {
|
|
148
149
|
const actor = rs.bypassActors[i];
|
|
149
150
|
if (typeof actor !== "object" || actor === null) {
|
|
150
|
-
throw new
|
|
151
|
+
throw new ValidationError(`${context}: ruleset '${name}' bypassActors[${i}] must be an object`);
|
|
151
152
|
}
|
|
152
153
|
if (typeof actor.actorId !== "number") {
|
|
153
|
-
throw new
|
|
154
|
+
throw new ValidationError(`${context}: ruleset '${name}' bypassActors[${i}].actorId must be a number`);
|
|
154
155
|
}
|
|
155
156
|
if (!VALID_ACTOR_TYPES.includes(actor.actorType)) {
|
|
156
|
-
throw new
|
|
157
|
+
throw new ValidationError(`${context}: ruleset '${name}' bypassActors[${i}].actorType must be one of: ${VALID_ACTOR_TYPES.join(", ")}`);
|
|
157
158
|
}
|
|
158
159
|
if (actor.bypassMode !== undefined &&
|
|
159
160
|
!VALID_BYPASS_MODES.includes(actor.bypassMode)) {
|
|
160
|
-
throw new
|
|
161
|
+
throw new ValidationError(`${context}: ruleset '${name}' bypassActors[${i}].bypassMode must be one of: ${VALID_BYPASS_MODES.join(", ")}`);
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
}
|
|
@@ -166,7 +167,7 @@ export function validateRuleset(ruleset, name, context) {
|
|
|
166
167
|
if (typeof rs.conditions !== "object" ||
|
|
167
168
|
rs.conditions === null ||
|
|
168
169
|
Array.isArray(rs.conditions)) {
|
|
169
|
-
throw new
|
|
170
|
+
throw new ValidationError(`${context}: ruleset '${name}' conditions must be an object`);
|
|
170
171
|
}
|
|
171
172
|
const conditions = rs.conditions;
|
|
172
173
|
if (conditions.refName !== undefined) {
|
|
@@ -174,28 +175,27 @@ export function validateRuleset(ruleset, name, context) {
|
|
|
174
175
|
if (typeof refName !== "object" ||
|
|
175
176
|
refName === null ||
|
|
176
177
|
Array.isArray(refName)) {
|
|
177
|
-
throw new
|
|
178
|
+
throw new ValidationError(`${context}: ruleset '${name}' conditions.refName must be an object`);
|
|
178
179
|
}
|
|
179
180
|
if (refName.include !== undefined &&
|
|
180
181
|
(!Array.isArray(refName.include) ||
|
|
181
182
|
!refName.include.every((s) => typeof s === "string"))) {
|
|
182
|
-
throw new
|
|
183
|
+
throw new ValidationError(`${context}: ruleset '${name}' conditions.refName.include must be an array of strings`);
|
|
183
184
|
}
|
|
184
185
|
if (refName.exclude !== undefined &&
|
|
185
186
|
(!Array.isArray(refName.exclude) ||
|
|
186
187
|
!refName.exclude.every((s) => typeof s === "string"))) {
|
|
187
|
-
throw new
|
|
188
|
+
throw new ValidationError(`${context}: ruleset '${name}' conditions.refName.exclude must be an array of strings`);
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
// Validate rules array
|
|
192
193
|
if (rs.rules !== undefined) {
|
|
193
194
|
if (!Array.isArray(rs.rules)) {
|
|
194
|
-
throw new
|
|
195
|
+
throw new ValidationError(`${context}: ruleset '${name}' rules must be an array`);
|
|
195
196
|
}
|
|
196
197
|
for (let i = 0; i < rs.rules.length; i++) {
|
|
197
198
|
validateRule(rs.rules[i], `${context}: ruleset '${name}' rules[${i}]`);
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
|
-
export { VALID_RULESET_TARGETS, VALID_ENFORCEMENT_LEVELS, VALID_ACTOR_TYPES, VALID_BYPASS_MODES, VALID_PATTERN_OPERATORS, VALID_MERGE_METHODS, VALID_ALERTS_THRESHOLDS, VALID_SECURITY_THRESHOLDS, VALID_RULE_TYPES, };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { escapeShellArg } from "../shared/shell-utils.js";
|
|
2
2
|
import { defaultExecutor, } from "../shared/command-executor.js";
|
|
3
3
|
import { withRetry } from "../shared/retry-utils.js";
|
|
4
|
+
import { toErrorMessage } from "../shared/type-guards.js";
|
|
4
5
|
import { isAzureDevOpsRepo, } from "../shared/repo-detector.js";
|
|
5
6
|
/**
|
|
6
7
|
* Azure DevOps implementation of IMigrationSource.
|
|
@@ -28,7 +29,7 @@ export class AdoMigrationSource {
|
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
|
-
const msg =
|
|
32
|
+
const msg = toErrorMessage(error);
|
|
32
33
|
throw new Error(`Failed to clone migration source ${repoInfo.gitUrl}: ${msg}. ` +
|
|
33
34
|
`Ensure you have authentication configured for Azure DevOps ` +
|
|
34
35
|
`(e.g., AZURE_DEVOPS_EXT_PAT or git credential helper).`);
|
|
@@ -5,7 +5,7 @@ import type { IRepoLifecycleProvider, LifecyclePlatform, CreateRepoSettings } fr
|
|
|
5
5
|
* GitHub implementation of IRepoLifecycleProvider.
|
|
6
6
|
* Uses gh CLI for all operations.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
interface GitHubLifecycleProviderOptions {
|
|
9
9
|
executor?: ICommandExecutor;
|
|
10
10
|
retries?: number;
|
|
11
11
|
cwd?: string;
|
|
@@ -29,11 +29,11 @@ export declare class GitHubLifecycleProvider implements IRepoLifecycleProvider {
|
|
|
29
29
|
private isOrganization;
|
|
30
30
|
private assertGitHub;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
* Returns
|
|
34
|
-
*
|
|
32
|
+
* Builds the common gh API command prefix parts for a given repo.
|
|
33
|
+
* Returns tokenEnv for exec options, and the command prefix string
|
|
34
|
+
* (e.g., "gh api --hostname host repos/owner/repo").
|
|
35
35
|
*/
|
|
36
|
-
private
|
|
36
|
+
private buildGhApiPrefix;
|
|
37
37
|
exists(repoInfo: RepoInfo, token?: string): Promise<boolean>;
|
|
38
38
|
create(repoInfo: RepoInfo, settings?: CreateRepoSettings, token?: string): Promise<void>;
|
|
39
39
|
fork(upstream: RepoInfo, target: RepoInfo, settings?: CreateRepoSettings, token?: string): Promise<void>;
|
|
@@ -68,3 +68,4 @@ export declare class GitHubLifecycleProvider implements IRepoLifecycleProvider {
|
|
|
68
68
|
*/
|
|
69
69
|
private deleteReadme;
|
|
70
70
|
}
|
|
71
|
+
export {};
|