@cosmicdrift/kumiko-guards 0.371.1 → 0.372.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-guards",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.372.0",
|
|
4
4
|
"description": "AST-based security guards for Kumiko repos: direct-fs/fetch, tenant escalation, admin-API, escape hatches and related checks, run over a shared ts-morph project.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"kumiko-pre-push": "./src/pre-push.sh"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@cosmicdrift/kumiko-repo-manifest": "0.
|
|
31
|
+
"@cosmicdrift/kumiko-repo-manifest": "0.372.0",
|
|
32
32
|
"ts-morph": "^28.0.0"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Guard: locale bundle values must follow Mandant/Organización terminology (#2200, fw#2355).
|
|
4
4
|
*
|
|
5
|
-
* German UI copy always says "Mandant" (never "Tenant"/"Organisation"); Spanish
|
|
6
|
-
*
|
|
5
|
+
* German UI copy always says "Mandant" (never "Tenant"/"Organisation"); Spanish, French
|
|
6
|
+
* and Italian always say "Organización"/"organisation"/"organizzazione" (never the
|
|
7
|
+
* "tenant" loanword). Only translation *values* are
|
|
7
8
|
* checked — JSON key names like `tenant.members.*` are ignored. Role identifiers
|
|
8
9
|
* such as TenantAdmin/SystemAdmin in prose are allowed.
|
|
9
10
|
*
|
|
@@ -29,7 +30,12 @@ const SCAN: ScanSpec = {
|
|
|
29
30
|
scope: "source",
|
|
30
31
|
extensions: ["ts"],
|
|
31
32
|
kinds: ["framework"],
|
|
32
|
-
frameworkWithin: [
|
|
33
|
+
frameworkWithin: [
|
|
34
|
+
"packages/locale-de/src/strings.ts",
|
|
35
|
+
"packages/locale-es/src/strings.ts",
|
|
36
|
+
"packages/locale-fr/src/strings.ts",
|
|
37
|
+
"packages/locale-it/src/strings.ts",
|
|
38
|
+
],
|
|
33
39
|
};
|
|
34
40
|
const IGNORE_TAG = "kumiko-lint-ignore i18n-locale-terminology";
|
|
35
41
|
|
|
@@ -38,7 +44,9 @@ type LocaleRule = {
|
|
|
38
44
|
readonly forbidden: readonly RegExp[];
|
|
39
45
|
};
|
|
40
46
|
|
|
41
|
-
|
|
47
|
+
type TerminologyLocale = "de" | "es" | "fr" | "it";
|
|
48
|
+
|
|
49
|
+
const RULES: Record<TerminologyLocale, LocaleRule> = {
|
|
42
50
|
de: {
|
|
43
51
|
preferred: "Mandant",
|
|
44
52
|
// Tenants? covers plural; Organisation(en|s)? without trailing \b so
|
|
@@ -50,11 +58,21 @@ const RULES: Record<"de" | "es", LocaleRule> = {
|
|
|
50
58
|
preferred: "Organización",
|
|
51
59
|
forbidden: [/\btenants?\b/i],
|
|
52
60
|
},
|
|
61
|
+
fr: {
|
|
62
|
+
preferred: "organisation",
|
|
63
|
+
forbidden: [/\btenants?\b/i],
|
|
64
|
+
},
|
|
65
|
+
it: {
|
|
66
|
+
preferred: "organizzazione",
|
|
67
|
+
forbidden: [/\btenants?\b/i],
|
|
68
|
+
},
|
|
53
69
|
};
|
|
54
70
|
|
|
55
|
-
function localeFromPath(filePath: string):
|
|
71
|
+
function localeFromPath(filePath: string): TerminologyLocale | undefined {
|
|
56
72
|
if (filePath.includes("locale-de/src/strings.ts")) return "de";
|
|
57
73
|
if (filePath.includes("locale-es/src/strings.ts")) return "es";
|
|
74
|
+
if (filePath.includes("locale-fr/src/strings.ts")) return "fr";
|
|
75
|
+
if (filePath.includes("locale-it/src/strings.ts")) return "it";
|
|
58
76
|
return undefined;
|
|
59
77
|
}
|
|
60
78
|
|
|
@@ -104,7 +122,7 @@ export function findViolations(files: readonly SourceFile[]): GuardViolation[] {
|
|
|
104
122
|
export const guard: AstGuard = {
|
|
105
123
|
name: "i18n-Locale-Terminology Guard",
|
|
106
124
|
scan: SCAN,
|
|
107
|
-
hint: "DE: Mandant instead of Tenant/Organisation; ES: Organización instead of the tenant loanword. Roles like TenantAdmin are fine.",
|
|
125
|
+
hint: "DE: Mandant instead of Tenant/Organisation; ES/FR/IT: Organización/organisation/organizzazione instead of the tenant loanword. Roles like TenantAdmin are fine.",
|
|
108
126
|
run(files, roots: readonly RepoRoot[] = resolveRepoRoots()) {
|
|
109
127
|
const violations = findViolations(files)
|
|
110
128
|
.map((v) => ({ ...v, file: relFromRepoRoot(v.file, roots) }))
|
|
@@ -60,7 +60,7 @@ const PATH_RULES: readonly (readonly [RegExp, Runtime])[] = [
|
|
|
60
60
|
[/(?:^|\/)ui-types\//, "client"],
|
|
61
61
|
|
|
62
62
|
// Same reasoning, two more shapes: a `web.ts`/`web/` subpath is the
|
|
63
|
-
// established convention (locale-de, locale-es, bundled-features) for the
|
|
63
|
+
// established convention (locale-de, locale-es, locale-fr, locale-it, bundled-features) for the
|
|
64
64
|
// client-safe slice of an otherwise `"runtime"`-marked package — the
|
|
65
65
|
// package.json marker classifies the whole package, this carves the
|
|
66
66
|
// deliberately-named exception back out. Deliberately workspace-wide (any
|
|
@@ -79,10 +79,10 @@ const PATH_RULES: readonly (readonly [RegExp, Runtime])[] = [
|
|
|
79
79
|
// More single-file carve-outs, same "package marker is coarser than the
|
|
80
80
|
// file" shape, verified case by case rather than by a directory
|
|
81
81
|
// convention:
|
|
82
|
-
// - locale-{de,es}/src/strings.ts: pure string-constant data (zero
|
|
82
|
+
// - locale-{de,es,fr,it}/src/strings.ts: pure string-constant data (zero
|
|
83
83
|
// imports), re-exported by the already-client `web.ts` sibling in the
|
|
84
84
|
// same package but shadowed by the package's own `"runtime"` marker.
|
|
85
|
-
[/^packages\/locale-(?:de|es)\/src\/strings\.ts$/, "client"],
|
|
85
|
+
[/^packages\/locale-(?:de|es|fr|it)\/src\/strings\.ts$/, "client"],
|
|
86
86
|
// - dev-server/src/env-schema.ts: a zod-only schema, no dev-server-
|
|
87
87
|
// internal imports — safe to carve out on its own.
|
|
88
88
|
[/^packages\/dev-server\/src\/env-schema\.ts$/, "client"],
|