@nitra/cursor 1.11.3 → 1.11.6
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/CHANGELOG.md +32 -3
- package/bin/n-cursor.js +40 -6
- package/package.json +2 -1
- package/rules/abie/js/applies/check.mjs +4 -4
- package/rules/abie/js/env_dns/check.mjs +1 -1
- package/rules/abie/js/firebase_hosting/check.mjs +1 -1
- package/rules/abie/js/hc_pairing/check.mjs +3 -3
- package/rules/abie/js/ua_http_route/check.mjs +3 -3
- package/rules/abie/js/ua_node_selector/check.mjs +4 -2
- package/rules/abie/policy/base_deployment_preem/target.json +1 -5
- package/rules/abie/utils/enabled.mjs +1 -1
- package/rules/abie/utils/env-dns.mjs +4 -4
- package/rules/abie/utils/http-route.mjs +5 -5
- package/rules/abie/utils/k8s-tree.mjs +23 -15
- package/rules/abie/utils/kustomization-patches.mjs +20 -20
- package/rules/abie/utils/overlay-paths.mjs +8 -8
- package/rules/abie/utils/yaml.mjs +4 -4
- package/rules/adr/adr.mdc +2 -2
- package/rules/adr/js/hooks/check.mjs +5 -5
- package/rules/docker/docker.mdc +2 -2
- package/rules/docker/js/run.mjs +3 -2
- package/rules/docker/policy/package_json/package_json.rego +1 -1
- package/rules/ga/js/lint.mjs +3 -26
- package/rules/hasura/js/internal_urls/check.mjs +1 -1
- package/rules/js-bun-redis/js/imports/check.mjs +5 -1
- package/rules/js-run/js/runtime/check.mjs +4 -1
- package/rules/k8s/js/run.mjs +3 -2
- package/rules/k8s/k8s.mdc +2 -4
- package/rules/k8s/policy/base_manifest/target.json +1 -5
- package/rules/nginx-default-tpl/js/template/check.mjs +4 -2
- package/rules/npm-module/js/package_structure/check.mjs +8 -3
- package/rules/npm-module/npm-module.mdc +3 -3
- package/rules/rego/js/applies/check.mjs +2 -2
- package/rules/rego/js/lint.mjs +4 -1
- package/rules/rego/policy/package_json/package_json.rego +5 -3
- package/rules/rego/rego.mdc +3 -3
- package/rules/style-lint/js/tooling/check.mjs +1 -1
- package/rules/style-lint/style-lint.mdc +1 -1
- package/rules/tauri/js/tooling/check.mjs +3 -1
- package/rules/text/js/formatting/check.mjs +8 -24
- package/rules/text/js/lint.mjs +34 -0
- package/rules/text/js/run-shellcheck.mjs +2 -2
- package/rules/text/js/run-v8r.mjs +2 -2
- package/rules/text/text.mdc +5 -5
- package/schemas/v8r-catalog.json +6 -0
- package/scripts/auto-skills.mjs +3 -7
- package/scripts/utils/discover-checkable-rules.mjs +4 -3
- package/scripts/utils/resolve-target-files.mjs +1 -1
- package/scripts/utils/run-lint-step.mjs +33 -0
- package/scripts/utils/run-rule.mjs +5 -3
- package/skills/abie-clean/SKILL.md +13 -11
- package/skills/adr-normalize/SKILL.md +0 -1
- package/skills/fix/SKILL.md +3 -7
- package/rules/abie/policy/base_deployment_preem/base_deployment_preem_test.rego +0 -60
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches_test.rego +0 -48
- package/rules/abie/policy/health_check_policy/health_check_policy_test.rego +0 -99
- package/rules/abie/policy/http_route_base/http_route_base_test.rego +0 -64
- package/rules/bun/policy/package_json/package_json_test.rego +0 -109
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml_test.rego +0 -104
- package/rules/docker/policy/package_json/package_json_test.rego +0 -42
- package/rules/graphql/policy/vscode_extensions/vscode_extensions_test.rego +0 -34
- package/rules/image-avif/policy/package_json/package_json_test.rego +0 -69
- package/rules/js-lint/policy/package_json/package_json_test.rego +0 -130
- package/rules/js-run/policy/jsconfig/jsconfig_test.rego +0 -88
- package/rules/k8s/policy/base_kustomization/base_kustomization_test.rego +0 -73
- package/rules/k8s/policy/base_manifest/base_manifest_test.rego +0 -94
- package/rules/k8s/policy/gateway/gateway_test.rego +0 -122
- package/rules/k8s/policy/hasura_configmap/hasura_configmap_test.rego +0 -49
- package/rules/k8s/policy/hasura_httproute/hasura_httproute_test.rego +0 -148
- package/rules/k8s/policy/hpa_pdb/hpa_pdb_test.rego +0 -101
- package/rules/k8s/policy/kustomization/kustomization_test.rego +0 -128
- package/rules/k8s/policy/manifest/manifest_test.rego +0 -309
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml_test.rego +0 -42
- package/rules/k8s/policy/svc_yaml/svc_yaml_test.rego +0 -41
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions_test.rego +0 -30
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings_test.rego +0 -53
- package/rules/npm-module/policy/npm_package_json/npm_package_json_test.rego +0 -81
- package/rules/rego/policy/package_json/package_json_test.rego +0 -42
- package/rules/rego/policy/vscode_extensions/vscode_extensions_test.rego +0 -34
- package/rules/rego/policy/vscode_settings/vscode_settings_test.rego +0 -55
- package/rules/style-lint/policy/vscode_extensions/vscode_extensions_test.rego +0 -39
- package/rules/style-lint/policy/vscode_settings/vscode_settings_test.rego +0 -49
- package/rules/tauri/policy/vscode_extensions/vscode_extensions_test.rego +0 -44
- package/rules/text/policy/markdownlint/markdownlint_test.rego +0 -98
- package/rules/text/policy/vscode_extensions/vscode_extensions_test.rego +0 -51
- package/rules/text/policy/vscode_settings/vscode_settings_test.rego +0 -85
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Тести для `bun.package_json`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/bun/package_json
|
|
3
|
-
package bun.package_json_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.bun.package_json
|
|
8
|
-
|
|
9
|
-
valid_pkg := {
|
|
10
|
-
"name": "n-cursor",
|
|
11
|
-
"devDependencies": {"@nitra/eslint-config": "^3.9.2"},
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
test_allow_minimal if {
|
|
17
|
-
count(package_json.deny) == 0 with input as valid_pkg
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test_allow_multiple_nitra_deps if {
|
|
21
|
-
pkg := json.patch(valid_pkg, [{
|
|
22
|
-
"op": "replace",
|
|
23
|
-
"path": "/devDependencies",
|
|
24
|
-
"value": {"@nitra/eslint-config": "^3.9.2", "@nitra/cspell-dict": "^2.0.0", "@nitra/stylelint-config": "^1.0.0"},
|
|
25
|
-
}])
|
|
26
|
-
count(package_json.deny) == 0 with input as pkg
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
test_allow_no_dev_dependencies if {
|
|
30
|
-
pkg := json.patch(valid_pkg, [{"op": "remove", "path": "/devDependencies"}])
|
|
31
|
-
count(package_json.deny) == 0 with input as pkg
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
# ── deny: devDependencies лише @nitra/* ──────────────────────────────────
|
|
35
|
-
|
|
36
|
-
test_deny_non_nitra_devdep if {
|
|
37
|
-
cases := [
|
|
38
|
-
{"@cspell/dict-uk-ua": "^2.0.0"},
|
|
39
|
-
{"@cspell/cspell-lib": "^9.0.0"},
|
|
40
|
-
{"lodash": "*"},
|
|
41
|
-
{"@types/node": "^24.0.0"},
|
|
42
|
-
]
|
|
43
|
-
some bad in cases
|
|
44
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/devDependencies", "value": bad}])
|
|
45
|
-
count(package_json.deny) > 0 with input as pkg
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
test_deny_mixed_dev_deps_only_flags_non_nitra if {
|
|
49
|
-
pkg := json.patch(valid_pkg, [{
|
|
50
|
-
"op": "replace",
|
|
51
|
-
"path": "/devDependencies",
|
|
52
|
-
"value": {"@nitra/eslint-config": "^3.9.2", "lodash": "*"},
|
|
53
|
-
}])
|
|
54
|
-
some msg in package_json.deny with input as pkg
|
|
55
|
-
contains(msg, "lodash")
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
# ── deny: packageManager ─────────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
test_deny_package_manager_field if {
|
|
61
|
-
pkg := json.patch(valid_pkg, [{"op": "add", "path": "/packageManager", "value": "pnpm@9.0.0"}])
|
|
62
|
-
count(package_json.deny) > 0 with input as pkg
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# ── deny: dependencies у кореневому ──────────────────────────────────────
|
|
66
|
-
|
|
67
|
-
test_deny_root_dependencies_present if {
|
|
68
|
-
pkg := json.patch(valid_pkg, [{"op": "add", "path": "/dependencies", "value": {"lodash": "*"}}])
|
|
69
|
-
count(package_json.deny) > 0 with input as pkg
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
test_deny_empty_dependencies_object if {
|
|
73
|
-
pkg := json.patch(valid_pkg, [{"op": "add", "path": "/dependencies", "value": {}}])
|
|
74
|
-
count(package_json.deny) > 0 with input as pkg
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
# ── deny: агрегований lint ───────────────────────────────────────────────
|
|
78
|
-
|
|
79
|
-
test_deny_lint_prefixed_without_aggregate if {
|
|
80
|
-
pkg := json.patch(valid_pkg, [{"op": "add", "path": "/scripts", "value": {"lint-js": "echo"}}])
|
|
81
|
-
count(package_json.deny) > 0 with input as pkg
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
test_allow_lint_aggregate_calls_subscript_and_oxfmt if {
|
|
85
|
-
pkg := json.patch(valid_pkg, [{
|
|
86
|
-
"op": "add",
|
|
87
|
-
"path": "/scripts",
|
|
88
|
-
"value": {"lint-js": "echo", "lint": "bun run lint-js && oxfmt ."},
|
|
89
|
-
}])
|
|
90
|
-
count(package_json.deny) == 0 with input as pkg
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
test_deny_lint_aggregate_missing_oxfmt if {
|
|
94
|
-
pkg := json.patch(valid_pkg, [{
|
|
95
|
-
"op": "add",
|
|
96
|
-
"path": "/scripts",
|
|
97
|
-
"value": {"lint-js": "echo", "lint": "bun run lint-js"},
|
|
98
|
-
}])
|
|
99
|
-
count(package_json.deny) > 0 with input as pkg
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
test_deny_lint_aggregate_missing_subscript_via_bun_run if {
|
|
103
|
-
pkg := json.patch(valid_pkg, [{
|
|
104
|
-
"op": "add",
|
|
105
|
-
"path": "/scripts",
|
|
106
|
-
"value": {"lint-js": "echo", "lint-text": "echo", "lint": "bun run lint-js && oxfmt ."},
|
|
107
|
-
}])
|
|
108
|
-
count(package_json.deny) > 0 with input as pkg
|
|
109
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
# Тести для `docker.lint_docker_yml`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/docker/lint_docker_yml
|
|
3
|
-
package docker.lint_docker_yml_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.docker.lint_docker_yml
|
|
8
|
-
|
|
9
|
-
hadolint_install_run := concat("", [
|
|
10
|
-
"curl -sSL -o /tmp/hadolint",
|
|
11
|
-
" https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64",
|
|
12
|
-
])
|
|
13
|
-
|
|
14
|
-
valid_wf := {
|
|
15
|
-
"name": "Lint Docker",
|
|
16
|
-
"on": {"push": {
|
|
17
|
-
"branches": ["dev", "main"],
|
|
18
|
-
"paths": ["**/Dockerfile", "**/*.Dockerfile", "**/*.dockerfile"],
|
|
19
|
-
}},
|
|
20
|
-
"jobs": {"lint-docker": {"steps": [
|
|
21
|
-
{"uses": "actions/checkout@v6"},
|
|
22
|
-
{"name": "Install hadolint", "run": hadolint_install_run},
|
|
23
|
-
{"uses": "./.github/actions/setup-bun-deps"},
|
|
24
|
-
{"name": "Lint Docker", "run": "bun run lint-docker"},
|
|
25
|
-
]}},
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
29
|
-
|
|
30
|
-
test_allow_canonical if {
|
|
31
|
-
count(lint_docker_yml.deny) == 0 with input as valid_wf
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
# ── deny: on.push.paths ──────────────────────────────────────────────────
|
|
35
|
-
|
|
36
|
-
test_deny_missing_path_dockerfile if {
|
|
37
|
-
wf := json.patch(
|
|
38
|
-
valid_wf,
|
|
39
|
-
[{"op": "replace", "path": "/on/push/paths", "value": ["**/*.Dockerfile", "**/*.dockerfile"]}],
|
|
40
|
-
)
|
|
41
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
test_deny_missing_paths_field if {
|
|
45
|
-
wf := json.patch(valid_wf, [{"op": "remove", "path": "/on/push/paths"}])
|
|
46
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
# ── deny: hadolint version ──────────────────────────────────────────────
|
|
50
|
-
|
|
51
|
-
test_deny_wrong_hadolint_version if {
|
|
52
|
-
wrong_version_run := concat("", [
|
|
53
|
-
"curl -sSL",
|
|
54
|
-
" https://github.com/hadolint/hadolint/releases/download/v2.11.0/hadolint-Linux-x86_64",
|
|
55
|
-
])
|
|
56
|
-
wf := json.patch(valid_wf, [{
|
|
57
|
-
"op": "replace",
|
|
58
|
-
"path": "/jobs/lint-docker/steps/1/run",
|
|
59
|
-
"value": wrong_version_run,
|
|
60
|
-
}])
|
|
61
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
test_deny_no_hadolint_install if {
|
|
65
|
-
wf := json.patch(valid_wf, [{
|
|
66
|
-
"op": "replace",
|
|
67
|
-
"path": "/jobs/lint-docker/steps/1",
|
|
68
|
-
"value": {"name": "Noop", "run": "echo ok"},
|
|
69
|
-
}])
|
|
70
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
# ── deny: composite setup-bun-deps ──────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
test_deny_inline_setup_bun_instead_of_composite if {
|
|
76
|
-
# Старий канон (НЕПРАВИЛЬНО per ga.mdc): пряме `oven-sh/setup-bun` замість composite.
|
|
77
|
-
wf := json.patch(valid_wf, [{
|
|
78
|
-
"op": "replace",
|
|
79
|
-
"path": "/jobs/lint-docker/steps/2",
|
|
80
|
-
"value": {"uses": "oven-sh/setup-bun@v2"},
|
|
81
|
-
}])
|
|
82
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
test_deny_no_setup_step if {
|
|
86
|
-
wf := json.patch(valid_wf, [{"op": "remove", "path": "/jobs/lint-docker/steps/2"}])
|
|
87
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
# ── deny: bun run lint-docker ──────────────────────────────────────────
|
|
91
|
-
|
|
92
|
-
test_deny_missing_lint_docker_run if {
|
|
93
|
-
wf := json.patch(valid_wf, [{
|
|
94
|
-
"op": "replace",
|
|
95
|
-
"path": "/jobs/lint-docker/steps/3/run",
|
|
96
|
-
"value": "echo noop",
|
|
97
|
-
}])
|
|
98
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
test_deny_no_run_steps_at_all if {
|
|
102
|
-
wf := json.patch(valid_wf, [{"op": "replace", "path": "/jobs/lint-docker/steps", "value": []}])
|
|
103
|
-
count(lint_docker_yml.deny) > 0 with input as wf
|
|
104
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Тести для `docker.package_json`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/docker/package_json
|
|
3
|
-
package docker.package_json_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.docker.package_json
|
|
8
|
-
|
|
9
|
-
canonical_lint_docker := "bun ./npm/scripts/run-docker.mjs"
|
|
10
|
-
|
|
11
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
12
|
-
|
|
13
|
-
test_allow_canonical if {
|
|
14
|
-
pkg := {"scripts": {"lint-docker": canonical_lint_docker}}
|
|
15
|
-
count(package_json.deny) == 0 with input as pkg
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
test_allow_lint_docker_absent if {
|
|
19
|
-
# rego не вимагає наявність — cross-file умовно вимагає `check-bun.mjs`.
|
|
20
|
-
count(package_json.deny) == 0 with input as {"scripts": {}}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
test_allow_no_scripts_at_all if {
|
|
24
|
-
count(package_json.deny) == 0 with input as {"name": "x"}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
test_allow_with_extra_whitespace if {
|
|
28
|
-
pkg := {"scripts": {"lint-docker": concat("", [" ", canonical_lint_docker, " "])}}
|
|
29
|
-
count(package_json.deny) == 0 with input as pkg
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
# ── deny ──────────────────────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
test_deny_lint_docker_wrong_value if {
|
|
35
|
-
pkg := {"scripts": {"lint-docker": "hadolint Dockerfile"}}
|
|
36
|
-
count(package_json.deny) > 0 with input as pkg
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
test_deny_lint_docker_old_npx_form if {
|
|
40
|
-
pkg := {"scripts": {"lint-docker": "npx hadolint ."}}
|
|
41
|
-
count(package_json.deny) > 0 with input as pkg
|
|
42
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# Тести для `graphql.vscode_extensions`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/graphql/vscode_extensions
|
|
3
|
-
package graphql.vscode_extensions_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.graphql.vscode_extensions
|
|
8
|
-
|
|
9
|
-
test_allow_with_required_extension if {
|
|
10
|
-
cfg := {"recommendations": ["graphql.vscode-graphql"]}
|
|
11
|
-
count(vscode_extensions.deny) == 0 with input as cfg
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
test_allow_with_additional_extensions if {
|
|
15
|
-
cfg := {"recommendations": [
|
|
16
|
-
"dbaeumer.vscode-eslint",
|
|
17
|
-
"graphql.vscode-graphql",
|
|
18
|
-
"oxc.oxc-vscode",
|
|
19
|
-
]}
|
|
20
|
-
count(vscode_extensions.deny) == 0 with input as cfg
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
test_deny_missing_extension if {
|
|
24
|
-
cfg := {"recommendations": ["dbaeumer.vscode-eslint"]}
|
|
25
|
-
count(vscode_extensions.deny) > 0 with input as cfg
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
test_deny_empty_recommendations if {
|
|
29
|
-
count(vscode_extensions.deny) > 0 with input as {"recommendations": []}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
test_deny_no_recommendations_field if {
|
|
33
|
-
count(vscode_extensions.deny) > 0 with input as {}
|
|
34
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Тести для `image_avif.package_json`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/image_avif/package_json
|
|
3
|
-
package image_avif.package_json_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.image_avif.package_json
|
|
8
|
-
|
|
9
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
10
|
-
|
|
11
|
-
test_allow_no_field if {
|
|
12
|
-
count(package_json.deny) == 0 with input as {"name": "x"}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
test_allow_canonical_opt_out if {
|
|
16
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disable-avif": true}}
|
|
17
|
-
count(package_json.deny) == 0 with input as pkg
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test_allow_disable_avif_false if {
|
|
21
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disable-avif": false}}
|
|
22
|
-
count(package_json.deny) == 0 with input as pkg
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
test_allow_empty_config if {
|
|
26
|
-
pkg := {"name": "x", "@nitra/minify-image": {}}
|
|
27
|
-
count(package_json.deny) == 0 with input as pkg
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
test_allow_other_keys_inside if {
|
|
31
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disable-avif": true, "future-flag": "y"}}
|
|
32
|
-
count(package_json.deny) == 0 with input as pkg
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
# ── deny: тип поля ───────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
test_deny_field_is_string if {
|
|
38
|
-
pkg := {"name": "x", "@nitra/minify-image": "disable-avif"}
|
|
39
|
-
count(package_json.deny) > 0 with input as pkg
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
test_deny_field_is_array if {
|
|
43
|
-
pkg := {"name": "x", "@nitra/minify-image": ["disable-avif"]}
|
|
44
|
-
count(package_json.deny) > 0 with input as pkg
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
test_deny_field_is_boolean if {
|
|
48
|
-
pkg := {"name": "x", "@nitra/minify-image": true}
|
|
49
|
-
count(package_json.deny) > 0 with input as pkg
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# ── deny: тип disable-avif ──────────────────────────────────────────────
|
|
53
|
-
|
|
54
|
-
test_deny_disable_avif_string if {
|
|
55
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disable-avif": "yes"}}
|
|
56
|
-
count(package_json.deny) > 0 with input as pkg
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
test_deny_disable_avif_number if {
|
|
60
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disable-avif": 1}}
|
|
61
|
-
count(package_json.deny) > 0 with input as pkg
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
# ── deny: typo disabled-avif ────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
test_deny_typo_disabled_avif if {
|
|
67
|
-
pkg := {"name": "x", "@nitra/minify-image": {"disabled-avif": true}}
|
|
68
|
-
count(package_json.deny) > 0 with input as pkg
|
|
69
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
# Тести для `js_lint.package_json`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/js_lint/package_json
|
|
3
|
-
package js_lint.package_json_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.js_lint.package_json
|
|
8
|
-
|
|
9
|
-
canonical_lint_js := "bunx oxlint --fix && bunx eslint --fix . && bunx jscpd . && bunx knip --no-config-hints"
|
|
10
|
-
|
|
11
|
-
valid_pkg := {
|
|
12
|
-
"type": "module",
|
|
13
|
-
"scripts": {"lint-js": canonical_lint_js},
|
|
14
|
-
"engines": {"node": ">=24", "bun": ">=1.3"},
|
|
15
|
-
"devDependencies": {"@nitra/eslint-config": "^3.9.2"},
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
19
|
-
|
|
20
|
-
test_allow_canonical if {
|
|
21
|
-
count(package_json.deny) == 0 with input as valid_pkg
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
test_allow_workspace_eslint_config if {
|
|
25
|
-
pkg := json.patch(
|
|
26
|
-
valid_pkg,
|
|
27
|
-
[{"op": "replace", "path": "/devDependencies/@nitra~1eslint-config", "value": "workspace:*"}],
|
|
28
|
-
)
|
|
29
|
-
count(package_json.deny) == 0 with input as pkg
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
# ── lint-js ───────────────────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
test_deny_missing_lint_js if {
|
|
35
|
-
pkg := json.patch(valid_pkg, [{"op": "remove", "path": "/scripts/lint-js"}])
|
|
36
|
-
count(package_json.deny) > 0 with input as pkg
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
test_deny_lint_js_without_knip if {
|
|
40
|
-
pkg := json.patch(
|
|
41
|
-
valid_pkg,
|
|
42
|
-
[{"op": "replace", "path": "/scripts/lint-js", "value": "bunx oxlint --fix && bunx eslint --fix . && bunx jscpd ."}],
|
|
43
|
-
)
|
|
44
|
-
count(package_json.deny) > 0 with input as pkg
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
test_deny_lint_js_without_no_config_hints if {
|
|
48
|
-
without_flag := "bunx oxlint --fix && bunx eslint --fix . && bunx jscpd . && bunx knip"
|
|
49
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/scripts/lint-js", "value": without_flag}])
|
|
50
|
-
count(package_json.deny) > 0 with input as pkg
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
test_deny_lint_js_wrong_order if {
|
|
54
|
-
wrong_order := "bunx eslint --fix . && bunx oxlint --fix && bunx jscpd . && bunx knip --no-config-hints"
|
|
55
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/scripts/lint-js", "value": wrong_order}])
|
|
56
|
-
count(package_json.deny) > 0 with input as pkg
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
test_allow_lint_js_with_extra_whitespace if {
|
|
60
|
-
pkg := json.patch(
|
|
61
|
-
valid_pkg,
|
|
62
|
-
[{"op": "replace", "path": "/scripts/lint-js", "value": concat(" ", ["", canonical_lint_js, ""])}],
|
|
63
|
-
)
|
|
64
|
-
count(package_json.deny) == 0 with input as pkg
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# ── type: module ──────────────────────────────────────────────────────────
|
|
68
|
-
|
|
69
|
-
test_deny_type_not_module if {
|
|
70
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/type", "value": "commonjs"}])
|
|
71
|
-
count(package_json.deny) > 0 with input as pkg
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
test_deny_type_missing if {
|
|
75
|
-
pkg := json.patch(valid_pkg, [{"op": "remove", "path": "/type"}])
|
|
76
|
-
count(package_json.deny) > 0 with input as pkg
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
# ── engines ──────────────────────────────────────────────────────────────
|
|
80
|
-
|
|
81
|
-
test_deny_node_below_24 if {
|
|
82
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/engines/node", "value": ">=22"}])
|
|
83
|
-
count(package_json.deny) > 0 with input as pkg
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
test_allow_node_above_24 if {
|
|
87
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/engines/node", "value": ">=25"}])
|
|
88
|
-
count(package_json.deny) == 0 with input as pkg
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
test_deny_bun_below_1_3 if {
|
|
92
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/engines/bun", "value": ">=1.2"}])
|
|
93
|
-
count(package_json.deny) > 0 with input as pkg
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
test_allow_bun_2_x if {
|
|
97
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/engines/bun", "value": "^2.0.0"}])
|
|
98
|
-
count(package_json.deny) == 0 with input as pkg
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# ── @nitra/eslint-config ─────────────────────────────────────────────────
|
|
102
|
-
|
|
103
|
-
test_deny_eslint_config_below_3_9_2 if {
|
|
104
|
-
cases := [
|
|
105
|
-
"^3.9.1",
|
|
106
|
-
"^3.8.0",
|
|
107
|
-
"^3.6.12",
|
|
108
|
-
"^3.4.3",
|
|
109
|
-
]
|
|
110
|
-
some bad in cases
|
|
111
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/devDependencies/@nitra~1eslint-config", "value": bad}])
|
|
112
|
-
count(package_json.deny) > 0 with input as pkg
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
test_allow_eslint_config_above_3_9_2 if {
|
|
116
|
-
cases := [
|
|
117
|
-
"^3.9.2",
|
|
118
|
-
"^3.9.10",
|
|
119
|
-
"^3.10.0",
|
|
120
|
-
"^4.0.0",
|
|
121
|
-
]
|
|
122
|
-
some good in cases
|
|
123
|
-
pkg := json.patch(valid_pkg, [{"op": "replace", "path": "/devDependencies/@nitra~1eslint-config", "value": good}])
|
|
124
|
-
count(package_json.deny) == 0 with input as pkg
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
test_deny_missing_eslint_config if {
|
|
128
|
-
pkg := json.patch(valid_pkg, [{"op": "remove", "path": "/devDependencies/@nitra~1eslint-config"}])
|
|
129
|
-
count(package_json.deny) > 0 with input as pkg
|
|
130
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Тести для `js_run.jsconfig`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/js_run/jsconfig
|
|
3
|
-
package js_run.jsconfig_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.js_run.jsconfig
|
|
8
|
-
|
|
9
|
-
valid_cfg := {
|
|
10
|
-
"compilerOptions": {
|
|
11
|
-
"lib": ["esnext"],
|
|
12
|
-
"module": "NodeNext",
|
|
13
|
-
"moduleResolution": "NodeNext",
|
|
14
|
-
"target": "esnext",
|
|
15
|
-
"checkJs": false,
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*"],
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
# ── happy path ────────────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
test_allow_canonical if {
|
|
23
|
-
count(jsconfig.deny) == 0 with input as valid_cfg
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
# ── compilerOptions.lib ───────────────────────────────────────────────────
|
|
27
|
-
|
|
28
|
-
test_deny_lib_not_array if {
|
|
29
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/compilerOptions/lib", "value": "esnext"}])
|
|
30
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
test_deny_lib_wrong_value if {
|
|
34
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/compilerOptions/lib", "value": ["es2022"]}])
|
|
35
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
test_deny_lib_missing if {
|
|
39
|
-
cfg := json.patch(valid_cfg, [{"op": "remove", "path": "/compilerOptions/lib"}])
|
|
40
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
# ── compilerOptions.module / moduleResolution / target / checkJs ──────────
|
|
44
|
-
|
|
45
|
-
test_deny_module_not_nodenext if {
|
|
46
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/compilerOptions/module", "value": "esnext"}])
|
|
47
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
test_deny_module_resolution_not_nodenext if {
|
|
51
|
-
cfg := json.patch(
|
|
52
|
-
valid_cfg,
|
|
53
|
-
[{"op": "replace", "path": "/compilerOptions/moduleResolution", "value": "node"}],
|
|
54
|
-
)
|
|
55
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
test_deny_target_not_esnext if {
|
|
59
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/compilerOptions/target", "value": "es2022"}])
|
|
60
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
test_deny_check_js_true if {
|
|
64
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/compilerOptions/checkJs", "value": true}])
|
|
65
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
test_deny_check_js_missing if {
|
|
69
|
-
cfg := json.patch(valid_cfg, [{"op": "remove", "path": "/compilerOptions/checkJs"}])
|
|
70
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
# ── include ──────────────────────────────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
test_deny_include_not_array if {
|
|
76
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/include", "value": "src/**/*"}])
|
|
77
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
test_deny_include_wrong_value if {
|
|
81
|
-
cfg := json.patch(valid_cfg, [{"op": "replace", "path": "/include", "value": ["lib/**/*"]}])
|
|
82
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
test_deny_include_missing if {
|
|
86
|
-
cfg := json.patch(valid_cfg, [{"op": "remove", "path": "/include"}])
|
|
87
|
-
count(jsconfig.deny) > 0 with input as cfg
|
|
88
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# Тести для `k8s.base_kustomization`. Запуск:
|
|
2
|
-
# conftest verify -p npm/policy/k8s/base_kustomization --namespace k8s.base_kustomization
|
|
3
|
-
package k8s.base_kustomization_test
|
|
4
|
-
|
|
5
|
-
import rego.v1
|
|
6
|
-
|
|
7
|
-
import data.k8s.base_kustomization
|
|
8
|
-
|
|
9
|
-
base_kust := {
|
|
10
|
-
"apiVersion": "kustomize.config.k8s.io/v1beta1",
|
|
11
|
-
"kind": "Kustomization",
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
test_deny_missing_namespace if {
|
|
15
|
-
count(base_kustomization.deny) > 0 with input as base_kust
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
test_deny_empty_namespace if {
|
|
19
|
-
count(base_kustomization.deny) > 0 with input as object.union(base_kust, {"namespace": ""})
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
test_deny_whitespace_namespace if {
|
|
23
|
-
count(base_kustomization.deny) > 0 with input as object.union(base_kust, {"namespace": " "})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
test_allow_with_namespace if {
|
|
27
|
-
count(base_kustomization.deny) == 0 with input as object.union(base_kust, {"namespace": "dev"})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
test_allow_non_kustomization if {
|
|
31
|
-
count(base_kustomization.deny) == 0 with input as {
|
|
32
|
-
"apiVersion": "v1",
|
|
33
|
-
"kind": "ConfigMap",
|
|
34
|
-
"metadata": {"name": "cm"},
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
base_kust_ok := object.union(base_kust, {"namespace": "dev"})
|
|
39
|
-
|
|
40
|
-
test_deny_hpa_yaml_in_resources if {
|
|
41
|
-
count(base_kustomization.deny) > 0 with input as object.union(
|
|
42
|
-
base_kust_ok,
|
|
43
|
-
{"resources": ["deployment.yaml", "hpa.yaml"]},
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
test_deny_pdb_yaml_in_resources if {
|
|
48
|
-
count(base_kustomization.deny) > 0 with input as object.union(
|
|
49
|
-
base_kust_ok,
|
|
50
|
-
{"resources": ["pdb.yaml"]},
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
test_deny_hpa_yml_in_subdir if {
|
|
55
|
-
count(base_kustomization.deny) > 0 with input as object.union(
|
|
56
|
-
base_kust_ok,
|
|
57
|
-
{"resources": ["nested/dir/hpa.yml"]},
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
test_allow_resources_without_hpa_pdb if {
|
|
62
|
-
count(base_kustomization.deny) == 0 with input as object.union(
|
|
63
|
-
base_kust_ok,
|
|
64
|
-
{"resources": ["deployment.yaml", "service.yaml", "configmap.yaml"]},
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
test_allow_lookalike_basename if {
|
|
69
|
-
count(base_kustomization.deny) == 0 with input as object.union(
|
|
70
|
-
base_kust_ok,
|
|
71
|
-
{"resources": ["myhpa.yaml", "pdb-extra.yaml"]},
|
|
72
|
-
)
|
|
73
|
-
}
|