@figulus/validator-core 0.5.0-alpha-dev-01 → 0.5.0-alpha-dev-03
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/dist/changed-file.d.ts +30 -0
- package/dist/changed-file.d.ts.map +1 -0
- package/dist/changed-file.js +131 -0
- package/dist/changed-file.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/check-push-limit.d.ts +5 -0
- package/dist/lib/check-push-limit.d.ts.map +1 -0
- package/dist/lib/check-push-limit.js +61 -0
- package/dist/lib/check-push-limit.js.map +1 -0
- package/dist/lib/git-head.d.ts +5 -0
- package/dist/lib/git-head.d.ts.map +1 -0
- package/dist/lib/git-head.js +20 -0
- package/dist/lib/git-head.js.map +1 -0
- package/dist/lib/namespace.d.ts +5 -0
- package/dist/lib/namespace.d.ts.map +1 -0
- package/dist/lib/namespace.js +10 -0
- package/dist/lib/namespace.js.map +1 -0
- package/dist/lib/parse.d.ts +7 -0
- package/dist/lib/parse.d.ts.map +1 -0
- package/dist/lib/parse.js +29 -0
- package/dist/lib/parse.js.map +1 -0
- package/dist/lib/permissions.d.ts +4 -0
- package/dist/lib/permissions.d.ts.map +1 -0
- package/dist/lib/permissions.js +9 -0
- package/dist/lib/permissions.js.map +1 -0
- package/dist/lib/validate-blob-references.d.ts +5 -0
- package/dist/lib/validate-blob-references.d.ts.map +1 -0
- package/dist/lib/validate-blob-references.js +21 -0
- package/dist/lib/validate-blob-references.js.map +1 -0
- package/dist/lib/validate-file/blob.d.ts +4 -0
- package/dist/lib/validate-file/blob.d.ts.map +1 -0
- package/dist/lib/validate-file/blob.js +57 -0
- package/dist/lib/validate-file/blob.js.map +1 -0
- package/dist/lib/validate-file/entity.d.ts +4 -0
- package/dist/lib/validate-file/entity.d.ts.map +1 -0
- package/dist/lib/validate-file/entity.js +74 -0
- package/dist/lib/validate-file/entity.js.map +1 -0
- package/dist/lib/validate-file/namespace-metadata.d.ts +4 -0
- package/dist/lib/validate-file/namespace-metadata.d.ts.map +1 -0
- package/dist/lib/validate-file/namespace-metadata.js +128 -0
- package/dist/lib/validate-file/namespace-metadata.js.map +1 -0
- package/dist/lib/validate-file/namespace-overrides.d.ts +4 -0
- package/dist/lib/validate-file/namespace-overrides.d.ts.map +1 -0
- package/dist/lib/validate-file/namespace-overrides.js +47 -0
- package/dist/lib/validate-file/namespace-overrides.js.map +1 -0
- package/dist/lib/validate-ownership-transfer.d.ts +3 -0
- package/dist/lib/validate-ownership-transfer.d.ts.map +1 -0
- package/dist/lib/validate-ownership-transfer.js +13 -0
- package/dist/lib/validate-ownership-transfer.js.map +1 -0
- package/dist/lib/validate-push-limit-constraints.d.ts +19 -0
- package/dist/lib/validate-push-limit-constraints.d.ts.map +1 -0
- package/dist/lib/validate-push-limit-constraints.js +14 -0
- package/dist/lib/validate-push-limit-constraints.js.map +1 -0
- package/dist/pr.d.ts +13 -0
- package/dist/pr.d.ts.map +1 -0
- package/dist/pr.js +80 -0
- package/dist/pr.js.map +1 -0
- package/dist/registry-validator.d.ts +39 -0
- package/dist/registry-validator.d.ts.map +1 -0
- package/dist/registry-validator.js +19 -0
- package/dist/registry-validator.js.map +1 -0
- package/dist/settings.d.ts +39 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +56 -0
- package/dist/settings.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation-result.d.ts +39 -0
- package/dist/validation-result.d.ts.map +1 -0
- package/dist/validation-result.js +44 -0
- package/dist/validation-result.js.map +1 -0
- package/package.json +2 -2
- package/src/changed-file.ts +3 -3
- package/src/lib/check-push-limit.ts +7 -7
- package/src/lib/git-head.ts +5 -5
- package/src/lib/validate-file/entity.ts +6 -6
- package/src/lib/validate-file/namespace-metadata.ts +2 -2
- package/src/pr.ts +2 -2
- package/src/registry-validator.ts +7 -7
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { namespaceMetadataSchema } from "@figulus/schema";
|
|
2
|
+
import { parseJSON, parseSchema } from "../parse.js";
|
|
3
|
+
import { validateOwnershipTransfer } from "../validate-ownership-transfer.js";
|
|
4
|
+
import { ERROR_CODES, createError, success, } from "../../validation-result.js";
|
|
5
|
+
import { validatePushLimitConstraints, getPushLimitConstraintsForEditor, } from "../validate-push-limit-constraints.js";
|
|
6
|
+
export async function validateNamespaceMetadata(file) {
|
|
7
|
+
const { registry, prInfo } = file.pr;
|
|
8
|
+
const { git } = registry.helpers;
|
|
9
|
+
const namespace = file.getNamespace("namespace");
|
|
10
|
+
if (registry.isNamespaceRestricted(namespace)) {
|
|
11
|
+
if (!registry.isMaintainer(prInfo.author))
|
|
12
|
+
return {
|
|
13
|
+
success: false,
|
|
14
|
+
errors: [
|
|
15
|
+
createError(`Cannot create namespace "${namespace}": this name is reserved. You must be a registry maintainer to claim this namespace.`, ERROR_CODES.NAMESPACE_RESERVED),
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const prAuthor = file.pr.prInfo.author;
|
|
20
|
+
const validatePushLimitsInMetadata = (data) => {
|
|
21
|
+
const errors = [];
|
|
22
|
+
const editors = data.editors || [];
|
|
23
|
+
for (const editor of editors) {
|
|
24
|
+
if (editor.pushLimit) {
|
|
25
|
+
const constraints = getPushLimitConstraintsForEditor(registry.settings, editor.pushLimit.unit);
|
|
26
|
+
const error = validatePushLimitConstraints(editor.pushLimit, constraints, `Editor ${editor.username}`);
|
|
27
|
+
if (error)
|
|
28
|
+
errors.push(error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return errors;
|
|
32
|
+
};
|
|
33
|
+
if (namespace) {
|
|
34
|
+
try {
|
|
35
|
+
try {
|
|
36
|
+
const headContent = await git.showHead(file.path);
|
|
37
|
+
const headData = parseJSON(headContent);
|
|
38
|
+
const headEditors = headData.editors || [];
|
|
39
|
+
const isEditorInHead = headEditors.some((e) => e.username === prAuthor);
|
|
40
|
+
if (!isEditorInHead)
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
errors: [
|
|
44
|
+
createError(`PR author "${prAuthor}" is not listed as an editor in the existing namespace metadata`, ERROR_CODES.NAMESPACE_NOT_EDITOR),
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
try {
|
|
48
|
+
const submittedData = file.parseJson();
|
|
49
|
+
const headOwner = headData.owner?.username;
|
|
50
|
+
const submittedOwner = submittedData.owner?.username;
|
|
51
|
+
const ownershipResult = validateOwnershipTransfer(headOwner, submittedOwner, prAuthor);
|
|
52
|
+
if (!ownershipResult.success) {
|
|
53
|
+
return ownershipResult;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Continue - this error will be caught again during full validation
|
|
58
|
+
}
|
|
59
|
+
// Namespace exists in HEAD and author is a valid editor with no ownership violations
|
|
60
|
+
// Validate the submitted file against the schema
|
|
61
|
+
try {
|
|
62
|
+
const data = file.parseJson();
|
|
63
|
+
const schemaResult = parseSchema(data, namespaceMetadataSchema);
|
|
64
|
+
if (!schemaResult.success)
|
|
65
|
+
return schemaResult;
|
|
66
|
+
const pushLimitErrors = validatePushLimitsInMetadata(data);
|
|
67
|
+
if (pushLimitErrors.length > 0) {
|
|
68
|
+
return { success: false, errors: pushLimitErrors };
|
|
69
|
+
}
|
|
70
|
+
return success();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
errors: [
|
|
76
|
+
createError(`Failed to parse namespace metadata: ${error instanceof Error ? error.message : String(error)}`, ERROR_CODES.NAMESPACE_PARSE_ERROR),
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (parseError) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
errors: [
|
|
85
|
+
createError(`Failed to parse HEAD version of namespace metadata: ${parseError instanceof Error ? parseError.message : String(parseError)}`, ERROR_CODES.NAMESPACE_PARSE_ERROR),
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// File doesn't exist in HEAD - this is a new namespace claim
|
|
92
|
+
// Fall through to validate the new submission
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// If we reach here, the namespace doesn't exist in HEAD (new namespace claim)
|
|
96
|
+
try {
|
|
97
|
+
const data = file.parseJson();
|
|
98
|
+
const schemaResult = parseSchema(data, namespaceMetadataSchema);
|
|
99
|
+
if (!schemaResult.success)
|
|
100
|
+
return schemaResult;
|
|
101
|
+
// Check push limit constraints
|
|
102
|
+
const pushLimitErrors = validatePushLimitsInMetadata(data);
|
|
103
|
+
if (pushLimitErrors.length > 0) {
|
|
104
|
+
return { success: false, errors: pushLimitErrors };
|
|
105
|
+
}
|
|
106
|
+
// For new namespaces, check that PR author is in editors
|
|
107
|
+
const editors = data.editors || [];
|
|
108
|
+
const isEditor = editors.some((e) => e.username === prAuthor);
|
|
109
|
+
if (!isEditor) {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
errors: [
|
|
113
|
+
createError(`PR author "${prAuthor}" is not listed as an editor in the namespace`, ERROR_CODES.NAMESPACE_NOT_EDITOR),
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return success();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
errors: [
|
|
123
|
+
createError(`Failed to parse namespace metadata: ${error instanceof Error ? error.message : String(error)}`, ERROR_CODES.NAMESPACE_PARSE_ERROR),
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=namespace-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-metadata.js","sourceRoot":"","sources":["../../../src/lib/validate-file/namespace-metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ChangedFile, FileTypeNamespaceOverrides } from "../../changed-file.js";
|
|
2
|
+
import { ValidationResult } from "../../validation-result.js";
|
|
3
|
+
export declare function validateNamespaceOverrides(file: ChangedFile, fileType: FileTypeNamespaceOverrides): ValidationResult;
|
|
4
|
+
//# sourceMappingURL=namespace-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-overrides.d.ts","sourceRoot":"","sources":["../../../src/lib/validate-file/namespace-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,0BAA0B,EAE3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,gBAAgB,EAGjB,MAAM,4BAA4B,CAAC;AAMpC,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,0BAA0B,GACnC,gBAAgB,CA4DlB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getSchemaFromFileTypeNamespaceOverrides, } from "../../changed-file.js";
|
|
2
|
+
import { parseSchema } from "../parse.js";
|
|
3
|
+
import { ERROR_CODES, createError, } from "../../validation-result.js";
|
|
4
|
+
import { validatePushLimitConstraints, getPushLimitConstraintsForMaintainer, } from "../validate-push-limit-constraints.js";
|
|
5
|
+
export function validateNamespaceOverrides(file, fileType) {
|
|
6
|
+
const { registry, prInfo } = file.pr;
|
|
7
|
+
if (!registry.isMaintainer(prInfo.author)) {
|
|
8
|
+
return {
|
|
9
|
+
success: false,
|
|
10
|
+
errors: [
|
|
11
|
+
createError(`Only registry maintainers can modify ${file.path}`, ERROR_CODES.PERMISSION_DENIED_MAINTAINER_ONLY),
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const data = file.parseJson();
|
|
17
|
+
const schemaResult = parseSchema(data, getSchemaFromFileTypeNamespaceOverrides(fileType));
|
|
18
|
+
if (!schemaResult.success)
|
|
19
|
+
return schemaResult;
|
|
20
|
+
// For limits overrides, validate push limit constraints
|
|
21
|
+
if (fileType === "limits") {
|
|
22
|
+
const errors = [];
|
|
23
|
+
const overrides = data || [];
|
|
24
|
+
for (const override of overrides) {
|
|
25
|
+
if (override.pushLimit) {
|
|
26
|
+
const constraints = getPushLimitConstraintsForMaintainer(registry.settings, override.pushLimit.unit);
|
|
27
|
+
const error = validatePushLimitConstraints(override.pushLimit, constraints, `Namespace ${override.namespace}`);
|
|
28
|
+
if (error)
|
|
29
|
+
errors.push(error);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (errors.length > 0) {
|
|
33
|
+
return { success: false, errors };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return schemaResult;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return {
|
|
40
|
+
success: false,
|
|
41
|
+
errors: [
|
|
42
|
+
createError(`Failed to parse ${file.path}: ${error instanceof Error ? error.message : String(error)}`, ERROR_CODES.NAMESPACE_PARSE_ERROR),
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=namespace-overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-overrides.js","sourceRoot":"","sources":["../../../src/lib/validate-file/namespace-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,uCAAuC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAEL,WAAW,EACX,WAAW,GACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,uCAAuC,CAAC;AAE/C,MAAM,UAAU,0BAA0B,CACxC,IAAiB,EACjB,QAAoC;IAEpC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE;gBACN,WAAW,CACT,wCAAwC,IAAI,CAAC,IAAI,EAAE,EACnD,WAAW,CAAC,iCAAiC,CAC9C;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,WAAW,CAC9B,IAAI,EACJ,uCAAuC,CAAC,QAAQ,CAAC,CAClD,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,OAAO;YAAE,OAAO,YAAY,CAAC;QAE/C,wDAAwD;QACxD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;YAE7B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACvB,MAAM,WAAW,GAAG,oCAAoC,CACtD,QAAQ,CAAC,QAAQ,EACjB,QAAQ,CAAC,SAAS,CAAC,IAAI,CACxB,CAAC;oBACF,MAAM,KAAK,GAAG,4BAA4B,CACxC,QAAQ,CAAC,SAAS,EAClB,WAAW,EACX,aAAa,QAAQ,CAAC,SAAS,EAAE,CAClC,CAAC;oBACF,IAAI,KAAK;wBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE;gBACN,WAAW,CACT,mBAAmB,IAAI,CAAC,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACzF,WAAW,CAAC,qBAAqB,CAClC;aACF;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-ownership-transfer.d.ts","sourceRoot":"","sources":["../../src/lib/validate-ownership-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAclB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ERROR_CODES, createError, success, } from "../validation-result.js";
|
|
2
|
+
export function validateOwnershipTransfer(headOwner, submittedOwner, prAuthor) {
|
|
3
|
+
if (submittedOwner !== headOwner && prAuthor !== headOwner) {
|
|
4
|
+
return {
|
|
5
|
+
success: false,
|
|
6
|
+
errors: [
|
|
7
|
+
createError(`Only the namespace owner ("${headOwner}") can transfer ownership`, ERROR_CODES.NAMESPACE_OWNERSHIP_TRANSFER_DENIED),
|
|
8
|
+
],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return success();
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=validate-ownership-transfer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-ownership-transfer.js","sourceRoot":"","sources":["../../src/lib/validate-ownership-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,WAAW,EACX,OAAO,GACR,MAAM,yBAAyB,CAAC;AAEjC,MAAM,UAAU,yBAAyB,CACvC,SAA6B,EAC7B,cAAkC,EAClC,QAAgB;IAEhB,IAAI,cAAc,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE;gBACN,WAAW,CACT,8BAA8B,SAAS,2BAA2B,EAClE,WAAW,CAAC,mCAAmC,CAChD;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Settings } from "../settings.js";
|
|
2
|
+
import { ValidationError } from "../validation-result.js";
|
|
3
|
+
export interface PushLimitValue {
|
|
4
|
+
unit: "daily" | "weekly";
|
|
5
|
+
value: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function validatePushLimitConstraints(pushLimit: PushLimitValue, constraints: {
|
|
8
|
+
min: number;
|
|
9
|
+
max: number;
|
|
10
|
+
}, context: string): ValidationError | null;
|
|
11
|
+
export declare function getPushLimitConstraintsForEditor(settings: Settings, unit: "daily" | "weekly"): {
|
|
12
|
+
min: number;
|
|
13
|
+
max: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function getPushLimitConstraintsForMaintainer(settings: Settings, unit: "daily" | "weekly"): {
|
|
16
|
+
min: number;
|
|
17
|
+
max: number;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=validate-push-limit-constraints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-push-limit-constraints.d.ts","sourceRoot":"","sources":["../../src/lib/validate-push-limit-constraints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,eAAe,EAGhB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,cAAc,EACzB,WAAW,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACzC,OAAO,EAAE,MAAM,GACd,eAAe,GAAG,IAAI,CAQxB;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,OAAO,GAAG,QAAQ,GACvB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAE9B;AAED,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,OAAO,GAAG,QAAQ,GACvB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAE9B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ERROR_CODES, createError, } from "../validation-result.js";
|
|
2
|
+
export function validatePushLimitConstraints(pushLimit, constraints, context) {
|
|
3
|
+
if (pushLimit.value < constraints.min || pushLimit.value > constraints.max) {
|
|
4
|
+
return createError(`${context} push limit ${pushLimit.value}/${pushLimit.unit} is outside allowed range: ${constraints.min}-${constraints.max}`, ERROR_CODES.PUSH_LIMIT_EXCEEDED);
|
|
5
|
+
}
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
export function getPushLimitConstraintsForEditor(settings, unit) {
|
|
9
|
+
return settings.pushLimits.overridesSetBy.namespaceOwners[unit];
|
|
10
|
+
}
|
|
11
|
+
export function getPushLimitConstraintsForMaintainer(settings, unit) {
|
|
12
|
+
return settings.pushLimits.overridesSetBy.registryMaintainers[unit];
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=validate-push-limit-constraints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-push-limit-constraints.js","sourceRoot":"","sources":["../../src/lib/validate-push-limit-constraints.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EACX,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAOjC,MAAM,UAAU,4BAA4B,CAC1C,SAAyB,EACzB,WAAyC,EACzC,OAAe;IAEf,IAAI,SAAS,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,IAAI,SAAS,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC3E,OAAO,WAAW,CAChB,GAAG,OAAO,eAAe,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,IAAI,8BAA8B,WAAW,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,EAAE,EAC5H,WAAW,CAAC,mBAAmB,CAChC,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,QAAkB,EAClB,IAAwB;IAExB,OAAO,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,QAAkB,EAClB,IAAwB;IAExB,OAAO,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/pr.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RegistryValidator, Helpers } from "./registry-validator";
|
|
2
|
+
import { PullRequestInfo, ValidationSummary } from "./types.js";
|
|
3
|
+
import { Settings } from "./settings.js";
|
|
4
|
+
export declare class PR {
|
|
5
|
+
prInfo: PullRequestInfo;
|
|
6
|
+
registry: RegistryValidator;
|
|
7
|
+
constructor(prInfo: PullRequestInfo, registry: RegistryValidator);
|
|
8
|
+
getAuthor(): string;
|
|
9
|
+
getSettings(): Settings;
|
|
10
|
+
getHelpers(): Helpers;
|
|
11
|
+
validate(): Promise<ValidationSummary>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=pr.d.ts.map
|
package/dist/pr.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../src/pr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAa,EAAE;IAEJ,MAAM,EAAE,eAAe;IACvB,QAAQ,EAAE,iBAAiB;gBAD3B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,iBAAiB;IAG7B,SAAS,IAAI,MAAM;IAInB,WAAW,IAAI,QAAQ;IAIvB,UAAU,IAAI,OAAO;IAIf,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAoEpD"}
|
package/dist/pr.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ChangedFile } from "./changed-file.js";
|
|
2
|
+
export class PR {
|
|
3
|
+
prInfo;
|
|
4
|
+
registry;
|
|
5
|
+
constructor(prInfo, registry) {
|
|
6
|
+
this.prInfo = prInfo;
|
|
7
|
+
this.registry = registry;
|
|
8
|
+
}
|
|
9
|
+
getAuthor() {
|
|
10
|
+
return this.prInfo.author;
|
|
11
|
+
}
|
|
12
|
+
getSettings() {
|
|
13
|
+
return this.registry.settings;
|
|
14
|
+
}
|
|
15
|
+
getHelpers() {
|
|
16
|
+
return this.registry.helpers;
|
|
17
|
+
}
|
|
18
|
+
async validate() {
|
|
19
|
+
const { prInfo, registry } = this;
|
|
20
|
+
const { helpers } = registry;
|
|
21
|
+
const results = [];
|
|
22
|
+
let filesWithErrors = 0;
|
|
23
|
+
let filesWithWarnings = 0;
|
|
24
|
+
if (prInfo.changedFiles.length === 0) {
|
|
25
|
+
helpers.console.log("No changed files to validate");
|
|
26
|
+
return {
|
|
27
|
+
success: true,
|
|
28
|
+
totalFiles: 0,
|
|
29
|
+
filesWithErrors: 0,
|
|
30
|
+
filesWithWarnings: 0,
|
|
31
|
+
results: [],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
for (const file of prInfo.changedFiles) {
|
|
35
|
+
const result = await new ChangedFile(file, this).validate();
|
|
36
|
+
results.push(result);
|
|
37
|
+
if (!result.result.success) {
|
|
38
|
+
filesWithErrors++;
|
|
39
|
+
}
|
|
40
|
+
else if (result.result.warnings?.length) {
|
|
41
|
+
filesWithWarnings++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Output results
|
|
45
|
+
const hasErrors = filesWithErrors > 0;
|
|
46
|
+
if (hasErrors) {
|
|
47
|
+
helpers.console.error("\n❌ Validation failed:\n");
|
|
48
|
+
for (const result of results) {
|
|
49
|
+
if (!result.result.success) {
|
|
50
|
+
helpers.console.error(`📄 ${result.file}:`);
|
|
51
|
+
result.result.errors.forEach((err) => {
|
|
52
|
+
helpers.console.error(` • [${err.code}] ${err.message}`);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
helpers.console.log("✅ All validations passed!");
|
|
59
|
+
}
|
|
60
|
+
if (filesWithWarnings > 0) {
|
|
61
|
+
helpers.console.log(`\n⚠️ ${filesWithWarnings} file(s) with warnings:\n`);
|
|
62
|
+
for (const result of results) {
|
|
63
|
+
if (result.result.success && result.result.warnings?.length) {
|
|
64
|
+
helpers.console.log(`📄 ${result.file}:`);
|
|
65
|
+
result.result.warnings.forEach((warn) => {
|
|
66
|
+
helpers.console.log(` • [${warn.code}] ${warn.message}`);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
success: !hasErrors,
|
|
73
|
+
totalFiles: prInfo.changedFiles.length,
|
|
74
|
+
filesWithErrors,
|
|
75
|
+
filesWithWarnings,
|
|
76
|
+
results,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=pr.js.map
|
package/dist/pr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../src/pr.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,OAAO,EAAE;IAEJ;IACA;IAFT,YACS,MAAuB,EACvB,QAA2B;QAD3B,WAAM,GAAN,MAAM,CAAiB;QACvB,aAAQ,GAAR,QAAQ,CAAmB;IACjC,CAAC;IAEG,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;IAC/B,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAE7B,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAE1B,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,CAAC;gBACb,eAAe,EAAE,CAAC;gBAClB,iBAAiB,EAAE,CAAC;gBACpB,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAErB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC3B,eAAe,EAAE,CAAC;YACpB,CAAC;iBAAM,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAC1C,iBAAiB,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAG,eAAe,GAAG,CAAC,CAAC;QACtC,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAClD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC3B,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;wBACnC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC7D,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,SAAS,iBAAiB,2BAA2B,CACtD,CAAC;YACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;oBAC5D,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC1C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;wBACtC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC7D,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,SAAS;YACnB,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;YACtC,eAAe;YACf,iBAAiB;YACjB,OAAO;SACR,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Settings } from "./settings.js";
|
|
2
|
+
import { PullRequestInfo } from "./types.js";
|
|
3
|
+
export interface Helpers {
|
|
4
|
+
console: {
|
|
5
|
+
log: (...data: any[]) => void;
|
|
6
|
+
error: (...data: any[]) => void;
|
|
7
|
+
};
|
|
8
|
+
crypto: {
|
|
9
|
+
createSha256HexHash: (data: string) => string;
|
|
10
|
+
};
|
|
11
|
+
fs: {
|
|
12
|
+
resolvePath: (...paths: string[]) => string;
|
|
13
|
+
splitPath: (path: string) => string[];
|
|
14
|
+
fileOrDirExists: (path: string) => boolean;
|
|
15
|
+
readFileAsUtf8: (path: string) => string;
|
|
16
|
+
};
|
|
17
|
+
git: {
|
|
18
|
+
showHead: (filePath: string, branch?: string) => Promise<string>;
|
|
19
|
+
getAllPRs: () => Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
user: {
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
}[]>;
|
|
26
|
+
getPRFiles: (prUrl: string) => Promise<{
|
|
27
|
+
filename: string;
|
|
28
|
+
}[]>;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export declare class RegistryValidator {
|
|
32
|
+
helpers: Helpers;
|
|
33
|
+
settings: Settings;
|
|
34
|
+
constructor(helpers: Helpers, settings: Settings);
|
|
35
|
+
validatePr(prInfo: PullRequestInfo): Promise<import("./types.js").ValidationSummary>;
|
|
36
|
+
isMaintainer(user: string): boolean;
|
|
37
|
+
isNamespaceRestricted(namespace: string): boolean;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=registry-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-validator.d.ts","sourceRoot":"","sources":["../src/registry-validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE;QACP,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAC9B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;KACjC,CAAC;IACF,MAAM,EAAE;QACN,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;KAC/C,CAAC;IACF,EAAE,EAAE;QACF,WAAW,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;QAC5C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;QACtC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAC3C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;KAC1C,CAAC;IACF,GAAG,EAAE;QACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACjE,SAAS,EAAE,MAAM,OAAO,CAAC;YACvB,GAAG,EAAE,MAAM,CAAC;YACZ,SAAS,EAAE,MAAM,CAAC;YAClB,IAAI,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC;SACtB,EAAE,CAAC,CAAC;QACL,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;YACrC,QAAQ,EAAE,MAAM,CAAC;SAClB,EAAE,CAAC,CAAC;KACN,CAAC;CACH;AAED,qBAAa,iBAAiB;IAEnB,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,QAAQ;gBADlB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ;IAGd,UAAU,CAAC,MAAM,EAAE,eAAe;IAIxC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAGzD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PR } from "./pr.js";
|
|
2
|
+
export class RegistryValidator {
|
|
3
|
+
helpers;
|
|
4
|
+
settings;
|
|
5
|
+
constructor(helpers, settings) {
|
|
6
|
+
this.helpers = helpers;
|
|
7
|
+
this.settings = settings;
|
|
8
|
+
}
|
|
9
|
+
async validatePr(prInfo) {
|
|
10
|
+
return await new PR(prInfo, this).validate();
|
|
11
|
+
}
|
|
12
|
+
isMaintainer(user) {
|
|
13
|
+
return this.settings.registryMaintainers.includes(user);
|
|
14
|
+
}
|
|
15
|
+
isNamespaceRestricted(namespace) {
|
|
16
|
+
return this.settings.restrictedNamespaces.includes(namespace);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=registry-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-validator.js","sourceRoot":"","sources":["../src/registry-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AA+B7B,MAAM,OAAO,iBAAiB;IAEnB;IACA;IAFT,YACS,OAAgB,EAChB,QAAkB;QADlB,YAAO,GAAP,OAAO,CAAS;QAChB,aAAQ,GAAR,QAAQ,CAAU;IACxB,CAAC;IAEG,KAAK,CAAC,UAAU,CAAC,MAAuB;QAC7C,OAAO,MAAM,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/C,CAAC;IAEM,YAAY,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IAEM,qBAAqB,CAAC,SAAiB;QAC5C,OAAO,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export declare const settingsSchema: z.ZodObject<{
|
|
3
|
+
repoRoot: z.ZodString;
|
|
4
|
+
registryMaintainers: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
5
|
+
restrictedNamespaces: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
6
|
+
pushLimits: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
7
|
+
default: z.ZodObject<{
|
|
8
|
+
unit: z.ZodEnum<{
|
|
9
|
+
daily: "daily";
|
|
10
|
+
weekly: "weekly";
|
|
11
|
+
}>;
|
|
12
|
+
pushes: z.ZodInt;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
overridesSetBy: z.ZodObject<{
|
|
15
|
+
namespaceOwners: z.ZodObject<{
|
|
16
|
+
daily: z.ZodObject<{
|
|
17
|
+
max: z.ZodInt;
|
|
18
|
+
min: z.ZodInt;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
weekly: z.ZodObject<{
|
|
21
|
+
max: z.ZodInt;
|
|
22
|
+
min: z.ZodInt;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
registryMaintainers: z.ZodObject<{
|
|
26
|
+
daily: z.ZodObject<{
|
|
27
|
+
max: z.ZodInt;
|
|
28
|
+
min: z.ZodInt;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
weekly: z.ZodObject<{
|
|
31
|
+
max: z.ZodInt;
|
|
32
|
+
min: z.ZodInt;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
}, z.core.$strip>>>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export type Settings = z.infer<typeof settingsSchema>;
|
|
39
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAapB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
const pushLimitOverridesSetBySchema = z.object({
|
|
3
|
+
daily: z.object({
|
|
4
|
+
max: z.int(),
|
|
5
|
+
min: z.int(),
|
|
6
|
+
}),
|
|
7
|
+
weekly: z.object({
|
|
8
|
+
max: z.int(),
|
|
9
|
+
min: z.int(),
|
|
10
|
+
}),
|
|
11
|
+
});
|
|
12
|
+
export const settingsSchema = z.object({
|
|
13
|
+
repoRoot: z.string(),
|
|
14
|
+
registryMaintainers: z
|
|
15
|
+
.string()
|
|
16
|
+
.array()
|
|
17
|
+
.optional()
|
|
18
|
+
.default(["figulusproject"]),
|
|
19
|
+
restrictedNamespaces: z
|
|
20
|
+
.string()
|
|
21
|
+
.array()
|
|
22
|
+
.optional()
|
|
23
|
+
.default([
|
|
24
|
+
"examples",
|
|
25
|
+
"figulus",
|
|
26
|
+
"official",
|
|
27
|
+
"push-limit-overrides",
|
|
28
|
+
"verified",
|
|
29
|
+
]),
|
|
30
|
+
pushLimits: z
|
|
31
|
+
.object({
|
|
32
|
+
default: z.object({
|
|
33
|
+
unit: z.enum(["daily", "weekly"]),
|
|
34
|
+
pushes: z.int(),
|
|
35
|
+
}),
|
|
36
|
+
overridesSetBy: z.object({
|
|
37
|
+
namespaceOwners: pushLimitOverridesSetBySchema,
|
|
38
|
+
registryMaintainers: pushLimitOverridesSetBySchema,
|
|
39
|
+
}),
|
|
40
|
+
})
|
|
41
|
+
.optional()
|
|
42
|
+
.default({
|
|
43
|
+
default: { unit: "daily", pushes: 10 },
|
|
44
|
+
overridesSetBy: {
|
|
45
|
+
namespaceOwners: {
|
|
46
|
+
daily: { min: 1, max: 10 },
|
|
47
|
+
weekly: { min: 1, max: 10 * 7 },
|
|
48
|
+
},
|
|
49
|
+
registryMaintainers: {
|
|
50
|
+
daily: { min: 0, max: 30 },
|
|
51
|
+
weekly: { min: 0, max: 30 * 7 },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;KACb,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;KACb,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,mBAAmB,EAAE,CAAC;SACnB,MAAM,EAAE;SACR,KAAK,EAAE;SACP,QAAQ,EAAE;SACV,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC9B,oBAAoB,EAAE,CAAC;SACpB,MAAM,EAAE;SACR,KAAK,EAAE;SACP,QAAQ,EAAE;SACV,OAAO,CAAC;QACP,UAAU;QACV,SAAS;QACT,UAAU;QACV,sBAAsB;QACtB,UAAU;KACX,CAAC;IACJ,UAAU,EAAE,CAAC;SACV,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE;SAChB,CAAC;QACF,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,eAAe,EAAE,6BAA6B;YAC9C,mBAAmB,EAAE,6BAA6B;SACnD,CAAC;KACH,CAAC;SACD,QAAQ,EAAE;SACV,OAAO,CAAC;QACP,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACtC,cAAc,EAAE;YACd,eAAe,EAAE;gBACf,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC1B,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE;aAChC;YACD,mBAAmB,EAAE;gBACnB,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC1B,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE;aAChC;SACF;KACF,CAAC;CACL,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ZodArray, ZodObject } from "zod";
|
|
2
|
+
import { ValidationResult } from "./validation-result.js";
|
|
3
|
+
export type SchemaObject = ZodObject | ZodArray;
|
|
4
|
+
export interface PullRequestInfo {
|
|
5
|
+
changedFiles: string[];
|
|
6
|
+
author: string;
|
|
7
|
+
}
|
|
8
|
+
export interface FileValidationResult {
|
|
9
|
+
file: string;
|
|
10
|
+
type: string;
|
|
11
|
+
result: ValidationResult;
|
|
12
|
+
}
|
|
13
|
+
export interface ValidationSummary {
|
|
14
|
+
success: boolean;
|
|
15
|
+
totalFiles: number;
|
|
16
|
+
filesWithErrors: number;
|
|
17
|
+
filesWithWarnings: number;
|
|
18
|
+
results: FileValidationResult[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const ERROR_CODES: {
|
|
2
|
+
readonly FILE_TYPE_UNKNOWN: "FILE_TYPE_UNKNOWN";
|
|
3
|
+
readonly BLOB_INVALID_FILENAME: "BLOB_INVALID_FILENAME";
|
|
4
|
+
readonly BLOB_MISSING_EXTENSION: "BLOB_MISSING_EXTENSION";
|
|
5
|
+
readonly BLOB_INVALID_EXTENSION: "BLOB_INVALID_EXTENSION";
|
|
6
|
+
readonly BLOB_HASH_MISMATCH: "BLOB_HASH_MISMATCH";
|
|
7
|
+
readonly BLOB_VERIFICATION_FAILED: "BLOB_VERIFICATION_FAILED";
|
|
8
|
+
readonly BLOB_REFERENCE_NOT_FOUND: "BLOB_REFERENCE_NOT_FOUND";
|
|
9
|
+
readonly ENTITY_PARSE_ERROR: "ENTITY_PARSE_ERROR";
|
|
10
|
+
readonly ENTITY_SCHEMA_INVALID: "ENTITY_SCHEMA_INVALID";
|
|
11
|
+
readonly NAMESPACE_RESERVED: "NAMESPACE_RESERVED";
|
|
12
|
+
readonly NAMESPACE_NOT_FOUND: "NAMESPACE_NOT_FOUND";
|
|
13
|
+
readonly NAMESPACE_NOT_EDITOR: "NAMESPACE_NOT_EDITOR";
|
|
14
|
+
readonly NAMESPACE_PARSE_ERROR: "NAMESPACE_PARSE_ERROR";
|
|
15
|
+
readonly NAMESPACE_SCHEMA_INVALID: "NAMESPACE_SCHEMA_INVALID";
|
|
16
|
+
readonly NAMESPACE_OWNERSHIP_TRANSFER_DENIED: "NAMESPACE_OWNERSHIP_TRANSFER_DENIED";
|
|
17
|
+
readonly PERMISSION_DENIED_MAINTAINER_ONLY: "PERMISSION_DENIED_MAINTAINER_ONLY";
|
|
18
|
+
readonly PUSH_LIMIT_EXCEEDED: "PUSH_LIMIT_EXCEEDED";
|
|
19
|
+
};
|
|
20
|
+
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
21
|
+
export interface ValidationError {
|
|
22
|
+
message: string;
|
|
23
|
+
code: ErrorCode;
|
|
24
|
+
}
|
|
25
|
+
export interface SuccessResult {
|
|
26
|
+
success: true;
|
|
27
|
+
warnings?: ValidationError[];
|
|
28
|
+
}
|
|
29
|
+
export interface FailureResult {
|
|
30
|
+
success: false;
|
|
31
|
+
errors: ValidationError[];
|
|
32
|
+
}
|
|
33
|
+
export type ValidationResult = SuccessResult | FailureResult;
|
|
34
|
+
export declare function createError(message: string, code: ErrorCode): ValidationError;
|
|
35
|
+
export declare function createWarning(message: string, code: ErrorCode): ValidationError;
|
|
36
|
+
export declare function success(warnings?: ValidationError[]): SuccessResult;
|
|
37
|
+
export declare function failure(errors: ValidationError[]): FailureResult;
|
|
38
|
+
export declare function failureFromStrings(messages: string[], code: ErrorCode): FailureResult;
|
|
39
|
+
//# sourceMappingURL=validation-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-result.d.ts","sourceRoot":"","sources":["../src/validation-result.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;CA6Bd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAEvE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,aAAa,CAAC;AAE7D,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,eAAe,CAE7E;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,GACd,eAAe,CAEjB;AAED,wBAAgB,OAAO,CAAC,QAAQ,GAAE,eAAe,EAAO,GAAG,aAAa,CAEvE;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,CAEhE;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,EAAE,SAAS,GACd,aAAa,CAKf"}
|