@cldmv/slothlet 3.2.1 → 3.3.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.
Files changed (38) hide show
  1. package/README.md +24 -10
  2. package/dist/lib/builders/api_builder.mjs +233 -3
  3. package/dist/lib/handlers/api-manager.mjs +23 -0
  4. package/dist/lib/handlers/context-async.mjs +4 -0
  5. package/dist/lib/handlers/context-live.mjs +5 -0
  6. package/dist/lib/handlers/hook-manager.mjs +5 -111
  7. package/dist/lib/handlers/permission-manager.mjs +408 -0
  8. package/dist/lib/handlers/unified-wrapper.mjs +90 -22
  9. package/dist/lib/handlers/version-manager.mjs +77 -4
  10. package/dist/lib/helpers/config.mjs +91 -7
  11. package/dist/lib/helpers/pattern-matcher.mjs +141 -0
  12. package/dist/lib/i18n/languages/de-de.json +21 -1
  13. package/dist/lib/i18n/languages/en-gb.json +21 -1
  14. package/dist/lib/i18n/languages/en-us.json +21 -1
  15. package/dist/lib/i18n/languages/es-mx.json +21 -1
  16. package/dist/lib/i18n/languages/fr-fr.json +21 -1
  17. package/dist/lib/i18n/languages/hi-in.json +21 -1
  18. package/dist/lib/i18n/languages/ja-jp.json +21 -1
  19. package/dist/lib/i18n/languages/ko-kr.json +21 -1
  20. package/dist/lib/i18n/languages/pt-br.json +21 -1
  21. package/dist/lib/i18n/languages/ru-ru.json +21 -1
  22. package/dist/lib/i18n/languages/zh-cn.json +21 -1
  23. package/dist/slothlet.mjs +11 -2
  24. package/package.json +4 -1
  25. package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
  26. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
  27. package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
  28. package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
  29. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
  30. package/types/dist/lib/handlers/permission-manager.d.mts +151 -0
  31. package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -0
  32. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
  33. package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
  34. package/types/dist/lib/helpers/config.d.mts +16 -0
  35. package/types/dist/lib/helpers/config.d.mts.map +1 -1
  36. package/types/dist/lib/helpers/pattern-matcher.d.mts +44 -0
  37. package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -0
  38. package/types/dist/slothlet.d.mts.map +1 -1
@@ -18,6 +18,7 @@
18
18
 
19
19
 
20
20
  import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
21
+ import { SlothletError } from "@cldmv/slothlet/errors";
21
22
 
22
23
 
23
24
  export class Config extends ComponentBase {
@@ -98,7 +99,7 @@ export class Config extends ComponentBase {
98
99
 
99
100
 
100
101
  normalizeMutations(mutations) {
101
- const defaults = { add: true, remove: true, reload: true };
102
+ const defaults = { add: true, remove: true, reload: true, permissions: true };
102
103
 
103
104
 
104
105
  if (!mutations || typeof mutations !== "object") {
@@ -109,7 +110,8 @@ export class Config extends ComponentBase {
109
110
  return {
110
111
  add: mutations.add === false ? false : true,
111
112
  remove: mutations.remove === false ? false : true,
112
- reload: mutations.reload === false ? false : true
113
+ reload: mutations.reload === false ? false : true,
114
+ permissions: mutations.permissions === false ? false : true
113
115
  };
114
116
  }
115
117
 
@@ -126,7 +128,8 @@ export class Config extends ComponentBase {
126
128
  context: false,
127
129
  initialization: false,
128
130
  materialize: false,
129
- versioning: false
131
+ versioning: false,
132
+ permissions: false
130
133
  };
131
134
  }
132
135
 
@@ -142,7 +145,8 @@ export class Config extends ComponentBase {
142
145
  context: true,
143
146
  initialization: true,
144
147
  materialize: true,
145
- versioning: true
148
+ versioning: true,
149
+ permissions: true
146
150
  };
147
151
  }
148
152
 
@@ -158,7 +162,8 @@ export class Config extends ComponentBase {
158
162
  context: debug.context || false,
159
163
  initialization: debug.initialization || false,
160
164
  materialize: debug.materialize || false,
161
- versioning: debug.versioning || false
165
+ versioning: debug.versioning || false,
166
+ permissions: debug.permissions || false
162
167
  };
163
168
  }
164
169
 
@@ -173,7 +178,8 @@ export class Config extends ComponentBase {
173
178
  context: false,
174
179
  initialization: false,
175
180
  materialize: false,
176
- versioning: false
181
+ versioning: false,
182
+ permissions: false
177
183
  };
178
184
  }
179
185
 
@@ -284,6 +290,9 @@ export class Config extends ComponentBase {
284
290
  }
285
291
 
286
292
 
293
+ const permissionsConfig = this.normalizePermissions(config.permissions);
294
+
295
+
287
296
  let i18nConfig = null;
288
297
  if (config.i18n && typeof config.i18n === "object") {
289
298
  i18nConfig = {
@@ -315,7 +324,8 @@ export class Config extends ComponentBase {
315
324
  silent: config.silent === true,
316
325
  typescript: this.normalizeTypeScript(config.typescript),
317
326
  env: this.normalizeEnv(config.env),
318
- versionDispatcher: config.versionDispatcher ?? null
327
+ versionDispatcher: config.versionDispatcher ?? null,
328
+ permissions: permissionsConfig
319
329
  };
320
330
  }
321
331
 
@@ -368,4 +378,78 @@ export class Config extends ComponentBase {
368
378
  }
369
379
  return null;
370
380
  }
381
+
382
+
383
+ normalizePermissions(permissions) {
384
+ if (!permissions || typeof permissions !== "object") {
385
+ return null;
386
+ }
387
+
388
+
389
+ let defaultPolicy;
390
+ if (permissions.defaultPolicy === "deny") {
391
+ defaultPolicy = "deny";
392
+ } else if (permissions.defaultPolicy === "allow" || permissions.defaultPolicy === undefined) {
393
+ defaultPolicy = "allow";
394
+ } else {
395
+ throw new SlothletError(
396
+ "INVALID_CONFIG",
397
+ {
398
+ option: "permissions.defaultPolicy",
399
+ value: permissions.defaultPolicy,
400
+ expected: '"allow" or "deny"',
401
+ hint: "HINT_INVALID_CONFIG"
402
+ },
403
+ null,
404
+ { validationError: true }
405
+ );
406
+ }
407
+
408
+ const enabled = permissions.enabled !== false;
409
+
410
+
411
+ let audit;
412
+ if (permissions.audit === "verbose") {
413
+ audit = "verbose";
414
+ } else if (permissions.audit === "default" || permissions.audit === undefined) {
415
+ audit = "default";
416
+ } else if (permissions.audit === true) {
417
+
418
+ audit = "default";
419
+ } else if (permissions.audit === false) {
420
+
421
+ audit = "default";
422
+ } else {
423
+ throw new SlothletError(
424
+ "INVALID_CONFIG",
425
+ {
426
+ option: "permissions.audit",
427
+ value: permissions.audit,
428
+ expected: '"default" or "verbose"',
429
+ hint: "HINT_INVALID_CONFIG"
430
+ },
431
+ null,
432
+ { validationError: true }
433
+ );
434
+ }
435
+
436
+
437
+ if (permissions.rules !== undefined && !Array.isArray(permissions.rules)) {
438
+ throw new SlothletError(
439
+ "INVALID_CONFIG",
440
+ {
441
+ option: "permissions.rules",
442
+ value: permissions.rules,
443
+ expected: "array",
444
+ hint: "HINT_INVALID_CONFIG"
445
+ },
446
+ null,
447
+ { validationError: true }
448
+ );
449
+ }
450
+
451
+ const rules = Array.isArray(permissions.rules) ? permissions.rules : [];
452
+
453
+ return { defaultPolicy, enabled, audit, rules };
454
+ }
371
455
  }
@@ -0,0 +1,141 @@
1
+ /*
2
+ Copyright 2026 CLDMV/Shinrai
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+
19
+
20
+
21
+ import { SlothletError } from "@cldmv/slothlet/errors";
22
+
23
+
24
+ export function compilePattern(pattern, options = {}) {
25
+
26
+ const isNegation = pattern.startsWith("!");
27
+ if (isNegation) {
28
+ pattern = pattern.slice(1);
29
+ const matcher = compilePattern(pattern, options);
30
+ return (path) => !matcher(path);
31
+ }
32
+
33
+
34
+ const expanded = expandBraces(pattern, 0, 10, options);
35
+ if (expanded.length > 1) {
36
+
37
+ const matchers = expanded.map((p) => compilePattern(p, options));
38
+ return (path) => matchers.some((m) => m(path));
39
+ }
40
+
41
+
42
+ pattern = expanded[0];
43
+
44
+
45
+ let regexPattern = pattern
46
+ .replace(/[.+^$()|[\]\\]/g, "\\$&")
47
+ .replace(/\*\*/g, "__DOUBLESTAR__")
48
+ .replace(/\*/g, "[^.]*")
49
+ .replace(/__DOUBLESTAR__/g, ".*")
50
+ .replace(/\?/g, ".");
51
+
52
+ regexPattern = `^${regexPattern}$`;
53
+ const regex = new RegExp(regexPattern);
54
+
55
+ return (path) => regex.test(path);
56
+ }
57
+
58
+
59
+ export function expandBraces(pattern, depth = 0, maxDepth = 10, options = {}) {
60
+
61
+ if (depth >= maxDepth) {
62
+ if (options.onMaxDepth) {
63
+ options.onMaxDepth(maxDepth);
64
+ }
65
+
66
+ throw new SlothletError("BRACE_EXPANSION_MAX_DEPTH", { maxDepth, validationError: true });
67
+ }
68
+
69
+
70
+ const braceStart = pattern.indexOf("{");
71
+ if (braceStart === -1) {
72
+ return [pattern];
73
+ }
74
+
75
+
76
+ let braceEnd = -1;
77
+ let depthCount = 1;
78
+ for (let i = braceStart + 1; i < pattern.length; i++) {
79
+ if (pattern[i] === "{") depthCount++;
80
+ if (pattern[i] === "}") {
81
+ depthCount--;
82
+ if (depthCount === 0) {
83
+ braceEnd = i;
84
+ break;
85
+ }
86
+ }
87
+ }
88
+
89
+ if (braceEnd === -1) {
90
+ return [pattern];
91
+ }
92
+
93
+
94
+ const prefix = pattern.slice(0, braceStart);
95
+ const braceContent = pattern.slice(braceStart + 1, braceEnd);
96
+ const suffix = pattern.slice(braceEnd + 1);
97
+
98
+
99
+ const alternatives = splitBraceAlternatives(braceContent);
100
+
101
+
102
+ const expanded = [];
103
+ for (const alt of alternatives) {
104
+ const combined = prefix + alt + suffix;
105
+
106
+ const recursiveExpanded = expandBraces(combined, depth + 1, maxDepth, options);
107
+ expanded.push(...recursiveExpanded);
108
+ }
109
+
110
+ return expanded;
111
+ }
112
+
113
+
114
+ export function splitBraceAlternatives(content) {
115
+ const alternatives = [];
116
+ let current = "";
117
+ let depth = 0;
118
+
119
+ for (let i = 0; i < content.length; i++) {
120
+ const char = content[i];
121
+
122
+ if (char === "{") {
123
+ depth++;
124
+ current += char;
125
+ } else if (char === "}") {
126
+ depth--;
127
+ current += char;
128
+ } else if (char === "," && depth === 0) {
129
+ alternatives.push(current);
130
+ current = "";
131
+ } else {
132
+ current += char;
133
+ }
134
+ }
135
+
136
+ if (current) {
137
+ alternatives.push(current);
138
+ }
139
+
140
+ return alternatives;
141
+ }
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Version aufgelöst: {version} für Pfad {apiPath} (Aufrufer: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "Keine Discriminator-Übereinstimmung für Pfad {apiPath}; Standardversion {version} wird verwendet.",
383
383
  "DEBUG_VERSION_REGISTERED": "Version {version} unter {logicalPath} registriert (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Version {version} von {logicalPath} abgemeldet"
384
+ "DEBUG_VERSION_UNREGISTERED": "Version {version} von {logicalPath} abgemeldet",
385
+
386
+ "PERMISSION_DENIED": "Zugriff verweigert: Aufrufer '{caller}' darf nicht auf '{target}' zugreifen",
387
+ "HINT_PERMISSION_DENIED": "Prüfen Sie die Berechtigungsregeln für dieses Aufrufer/Ziel-Paar. Verwenden Sie api.slothlet.permissions.global.rulesForPath('{target}'), um die aktiven Regeln einzusehen.",
388
+ "PERMISSION_SELF_MODIFY": "Modul '{moduleID}' kann seine eigene Berechtigungsregel '{ruleId}' nicht entfernen",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Berechtigungsregeln sind für das besitzende Modul unveränderlich. Ein anderes Modul muss diese Regel entfernen.",
390
+ "INVALID_PERMISSION_RULE": "Ungültige Berechtigungsregel: {reason} (erhalten: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Berechtigungsregeln erfordern: caller (String-Glob), target (String-Glob) und effect ('allow' oder 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Berechtigung verweigert: Aufrufer '{caller}' -> Ziel '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Berechtigung erteilt: Aufrufer '{caller}' -> Ziel '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Berechtigungs-Self-Bypass: Aufrufer und Ziel teilen sich moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Standard-Berechtigungsrichtlinie angewendet: Aufrufer '{caller}' -> Ziel '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Berechtigungsregel hinzugefügt: {ruleId} ({caller} -> {target}: {effect}, Besitzer: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Berechtigungsregel entfernt: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "Regel muss ein nicht-leeres Objekt sein",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller muss eine nicht-leere Zeichenkette sein",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target muss eine nicht-leere Zeichenkette sein",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect muss 'allow' oder 'deny' sein",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "Klammerauflösung hat die maximale Tiefe von {maxDepth} überschritten",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Verringern Sie die Verschachtelung in Ihren Klammermustern oder erhöhen Sie die maxDepth-Option.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Berechtigungsmanager ist nicht in dieser Slothlet-Instanz verfügbar"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "de-de",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Version resolved: {version} for path {apiPath} (caller: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "No discriminator match for path {apiPath}; using default version {version}",
383
383
  "DEBUG_VERSION_REGISTERED": "Version {version} registered at {logicalPath} (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Version {version} unregistered from {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Version {version} unregistered from {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Access denied: caller '{caller}' is not permitted to access '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Check permission rules for this caller/target pair. Use api.slothlet.permissions.global.rulesForPath('{target}') to inspect active rules.",
388
+ "PERMISSION_SELF_MODIFY": "Module '{moduleID}' cannot remove its own permission rule '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Permission rules are immutable for the owning module. Another module must remove this rule.",
390
+ "INVALID_PERMISSION_RULE": "Invalid permission rule: {reason} (received: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Permission rules require: caller (string glob), target (string glob), and effect ('allow' or 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Permission denied: caller '{caller}' -> target '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Permission allowed: caller '{caller}' -> target '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Permission self-bypass: caller and target share moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Permission default policy applied: caller '{caller}' -> target '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Permission rule added: {ruleId} ({caller} -> {target}: {effect}, owner: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Permission rule removed: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "rule must be a non-null object",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller must be a non-empty string",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target must be a non-empty string",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect must be 'allow' or 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "Brace expansion exceeded maximum depth of {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Reduce nesting in your brace patterns or increase the maxDepth option.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Permission manager is not available in this Slothlet instance"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "en-gb",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Version resolved: {version} for path {apiPath} (caller: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "No discriminator match for path {apiPath}; using default version {version}",
383
383
  "DEBUG_VERSION_REGISTERED": "Version {version} registered at {logicalPath} (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Version {version} unregistered from {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Version {version} unregistered from {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Access denied: caller '{caller}' is not permitted to access '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Check permission rules for this caller/target pair. Use api.slothlet.permissions.global.rulesForPath('{target}') to inspect active rules.",
388
+ "PERMISSION_SELF_MODIFY": "Module '{moduleID}' cannot remove its own permission rule '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Permission rules are immutable for the owning module. Another module must remove this rule.",
390
+ "INVALID_PERMISSION_RULE": "Invalid permission rule: {reason} (received: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Permission rules require: caller (string glob), target (string glob), and effect ('allow' or 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Permission denied: caller '{caller}' -> target '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Permission allowed: caller '{caller}' -> target '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Permission self-bypass: caller and target share moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Permission default policy applied: caller '{caller}' -> target '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Permission rule added: {ruleId} ({caller} -> {target}: {effect}, owner: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Permission rule removed: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "rule must be a non-null object",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller must be a non-empty string",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target must be a non-empty string",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect must be 'allow' or 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "Brace expansion exceeded maximum depth of {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Reduce nesting in your brace patterns or increase the maxDepth option.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Permission manager is not available in this Slothlet instance"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "en-us",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Versión resuelta: {version} para la ruta {apiPath} (llamador: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "Sin coincidencia del discriminador para la ruta {apiPath}; se usa la versión predeterminada {version}.",
383
383
  "DEBUG_VERSION_REGISTERED": "Versión {version} registrada en {logicalPath} (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Versión {version} dada de baja de {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Versión {version} dada de baja de {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Acceso denegado: el llamador '{caller}' no tiene permiso para acceder a '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Verifique las reglas de permisos para este par llamador/objetivo. Use api.slothlet.permissions.global.rulesForPath('{target}') para inspeccionar las reglas activas.",
388
+ "PERMISSION_SELF_MODIFY": "El módulo '{moduleID}' no puede eliminar su propia regla de permiso '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Las reglas de permisos son inmutables para el módulo propietario. Otro módulo debe eliminar esta regla.",
390
+ "INVALID_PERMISSION_RULE": "Regla de permiso inválida: {reason} (recibido: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Las reglas de permisos requieren: caller (string glob), target (string glob) y effect ('allow' o 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Permiso denegado: llamador '{caller}' -> objetivo '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Permiso concedido: llamador '{caller}' -> objetivo '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Auto-bypass de permisos: llamador y objetivo comparten moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Política de permisos predeterminada aplicada: llamador '{caller}' -> objetivo '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Regla de permiso agregada: {ruleId} ({caller} -> {target}: {effect}, propietario: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Regla de permiso eliminada: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "la regla debe ser un objeto no nulo",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller debe ser una cadena no vacía",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target debe ser una cadena no vacía",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect debe ser 'allow' o 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "La expansión de llaves superó la profundidad máxima de {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Reduce el anidamiento en tus patrones de llaves o aumenta la opción maxDepth.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "El administrador de permisos no está disponible en esta instancia de Slothlet"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "es-mx",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Version résolue : {version} pour le chemin {apiPath} (appelant : {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "Aucune correspondance de discriminateur pour le chemin {apiPath} ; utilisation de la version par défaut {version}.",
383
383
  "DEBUG_VERSION_REGISTERED": "Version {version} enregistrée à {logicalPath} (moduleID : {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Version {version} désinscrite de {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Version {version} désinscrite de {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Accès refusé : l'appelant '{caller}' n'est pas autorisé à accéder à '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Vérifiez les règles d'autorisation pour ce couple appelant/cible. Utilisez api.slothlet.permissions.global.rulesForPath('{target}') pour inspecter les règles actives.",
388
+ "PERMISSION_SELF_MODIFY": "Le module '{moduleID}' ne peut pas supprimer sa propre règle d'autorisation '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Les règles d'autorisation sont immuables pour le module propriétaire. Un autre module doit supprimer cette règle.",
390
+ "INVALID_PERMISSION_RULE": "Règle d'autorisation invalide : {reason} (reçu : {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Les règles d'autorisation nécessitent : caller (string glob), target (string glob) et effect ('allow' ou 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Autorisation refusée : appelant '{caller}' -> cible '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Autorisation accordée : appelant '{caller}' -> cible '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Auto-bypass d'autorisation : l'appelant et la cible partagent le moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Politique d'autorisation par défaut appliquée : appelant '{caller}' -> cible '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Règle d'autorisation ajoutée : {ruleId} ({caller} -> {target} : {effect}, propriétaire : {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Règle d'autorisation supprimée : {ruleId} ({caller} -> {target} : {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "la règle doit être un objet non nul",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller doit être une chaîne non vide",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target doit être une chaîne non vide",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect doit être 'allow' ou 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "L'expansion des accolades a dépassé la profondeur maximale de {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Réduisez le niveau d'imbrication dans vos motifs d'accolades ou augmentez l'option maxDepth.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Le gestionnaire de permissions n'est pas disponible dans cette instance Slothlet"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "fr-fr",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "संस्करण हल किया गया: {version}, पथ: {apiPath} (कॉलर: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "पथ {apiPath} के लिए कोई Discriminator मिलान नहीं; डिफ़ॉल्ट संस्करण {version} का उपयोग किया जा रहा है।",
383
383
  "DEBUG_VERSION_REGISTERED": "संस्करण {version} को {logicalPath} पर पंजीकृत किया गया (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "संस्करण {version} को {logicalPath} से हटाया गया"
384
+ "DEBUG_VERSION_UNREGISTERED": "संस्करण {version} को {logicalPath} से हटाया गया",
385
+
386
+ "PERMISSION_DENIED": "पहुँच अस्वीकृत: कॉलर '{caller}' को '{target}' तक पहुँचने की अनुमति नहीं है",
387
+ "HINT_PERMISSION_DENIED": "इस कॉलर/लक्ष्य जोड़ी के लिए अनुमति नियम जाँचें। सक्रिय नियमों का निरीक्षण करने के लिए api.slothlet.permissions.global.rulesForPath('{target}') का उपयोग करें।",
388
+ "PERMISSION_SELF_MODIFY": "मॉड्यूल '{moduleID}' अपना स्वयं का अनुमति नियम '{ruleId}' नहीं हटा सकता",
389
+ "HINT_PERMISSION_SELF_MODIFY": "अनुमति नियम स्वामी मॉड्यूल के लिए अपरिवर्तनीय हैं। किसी अन्य मॉड्यूल को यह नियम हटाना होगा।",
390
+ "INVALID_PERMISSION_RULE": "अमान्य अनुमति नियम: {reason} (प्राप्त: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "अनुमति नियमों के लिए आवश्यक: caller (string glob), target (string glob) और effect ('allow' या 'deny')।",
392
+ "DEBUG_PERMISSION_DENIED": "अनुमति अस्वीकृत: कॉलर '{caller}' -> लक्ष्य '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "अनुमति स्वीकृत: कॉलर '{caller}' -> लक्ष्य '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "अनुमति सेल्फ-बाइपास: कॉलर और लक्ष्य moduleID '{moduleID}' साझा करते हैं",
395
+ "DEBUG_PERMISSION_DEFAULT": "डिफ़ॉल्ट अनुमति नीति लागू: कॉलर '{caller}' -> लक्ष्य '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "अनुमति नियम जोड़ा गया: {ruleId} ({caller} -> {target}: {effect}, स्वामी: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "अनुमति नियम हटाया गया: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "नियम एक गैर-शून्य ऑब्जेक्ट होना चाहिए",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller एक गैर-रिक्त स्ट्रिंग होना चाहिए",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target एक गैर-रिक्त स्ट्रिंग होना चाहिए",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect 'allow' या 'deny' होना चाहिए",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "ब्रेस विस्तार ने {maxDepth} की अधिकतम गहराई पार कर दी",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "अपने ब्रेस पैटर्न में नेस्टिंग कम करें या maxDepth विकल्प बढ़ाएं।",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "अनुमति प्रबंधक इस Slothlet इंस्टेंस में उपलब्ध नहीं है"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "hi-in",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "バージョン解決済み: {version}、パス: {apiPath}(呼び出し元: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "パス {apiPath} の Discriminator に一致なし。デフォルトバージョン {version} を使用します。",
383
383
  "DEBUG_VERSION_REGISTERED": "バージョン {version} が {logicalPath} に登録されました(moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "バージョン {version} が {logicalPath} から登録解除されました"
384
+ "DEBUG_VERSION_UNREGISTERED": "バージョン {version} が {logicalPath} から登録解除されました",
385
+
386
+ "PERMISSION_DENIED": "アクセス拒否: 呼び出し元 '{caller}' は '{target}' へのアクセスが許可されていません",
387
+ "HINT_PERMISSION_DENIED": "この呼び出し元/ターゲットのペアのパーミッションルールを確認してください。api.slothlet.permissions.global.rulesForPath('{target}') を使用してアクティブなルールを検査できます。",
388
+ "PERMISSION_SELF_MODIFY": "モジュール '{moduleID}' は自身のパーミッションルール '{ruleId}' を削除できません",
389
+ "HINT_PERMISSION_SELF_MODIFY": "パーミッションルールは所有モジュールに対して不変です。別のモジュールがこのルールを削除する必要があります。",
390
+ "INVALID_PERMISSION_RULE": "無効なパーミッションルール: {reason}(受信値: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "パーミッションルールには caller(string glob)、target(string glob)、および effect('allow' または 'deny')が必要です。",
392
+ "DEBUG_PERMISSION_DENIED": "パーミッション拒否: 呼び出し元 '{caller}' -> ターゲット '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "パーミッション許可: 呼び出し元 '{caller}' -> ターゲット '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "パーミッション・セルフバイパス: 呼び出し元とターゲットが moduleID '{moduleID}' を共有しています",
395
+ "DEBUG_PERMISSION_DEFAULT": "デフォルトパーミッションポリシー適用: 呼び出し元 '{caller}' -> ターゲット '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "パーミッションルール追加: {ruleId}({caller} -> {target}: {effect}、所有者: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "パーミッションルール削除: {ruleId}({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "ルールは非ヌルのオブジェクトである必要があります",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.callerは空でない文字列である必要があります",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.targetは空でない文字列である必要があります",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effectは'allow'または'deny'である必要があります",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "ブレース展開が最大深度 {maxDepth} を超えました",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "波括弧パターンのネストを減らすか、maxDepthオプションを増やしてください。",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "権限マネージャーはこのSlothletインスタンスで利用できません"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "ja-jp",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "버전 해석됨: {version}, 경로: {apiPath} (호출자: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "경로 {apiPath}에 대한 Discriminator 일치 없음; 기본 버전 {version}을(를) 사용합니다.",
383
383
  "DEBUG_VERSION_REGISTERED": "버전 {version}이(가) {logicalPath}에 등록됨 (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "버전 {version}이(가) {logicalPath}에서 등록 취소됨"
384
+ "DEBUG_VERSION_UNREGISTERED": "버전 {version}이(가) {logicalPath}에서 등록 취소됨",
385
+
386
+ "PERMISSION_DENIED": "접근 거부: 호출자 '{caller}'은(는) '{target}'에 접근할 권한이 없습니다",
387
+ "HINT_PERMISSION_DENIED": "이 호출자/대상 쌍의 권한 규칙을 확인하세요. api.slothlet.permissions.global.rulesForPath('{target}')를 사용하여 활성 규칙을 검사할 수 있습니다.",
388
+ "PERMISSION_SELF_MODIFY": "모듈 '{moduleID}'은(는) 자신의 권한 규칙 '{ruleId}'을(를) 제거할 수 없습니다",
389
+ "HINT_PERMISSION_SELF_MODIFY": "권한 규칙은 소유 모듈에 대해 불변입니다. 다른 모듈이 이 규칙을 제거해야 합니다.",
390
+ "INVALID_PERMISSION_RULE": "잘못된 권한 규칙: {reason} (수신됨: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "권한 규칙에는 caller (string glob), target (string glob), effect ('allow' 또는 'deny')가 필요합니다.",
392
+ "DEBUG_PERMISSION_DENIED": "권한 거부: 호출자 '{caller}' -> 대상 '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "권한 허용: 호출자 '{caller}' -> 대상 '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "권한 셀프 바이패스: 호출자와 대상이 moduleID '{moduleID}'을(를) 공유합니다",
395
+ "DEBUG_PERMISSION_DEFAULT": "기본 권한 정책 적용: 호출자 '{caller}' -> 대상 '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "권한 규칙 추가됨: {ruleId} ({caller} -> {target}: {effect}, 소유자: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "권한 규칙 제거됨: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "규칙은 널이 아닌 객체여야 합니다",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller는 비어 있지 않은 문자열이어야 합니다",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target은 비어 있지 않은 문자열이어야 합니다",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect는 'allow' 또는 'deny'여야 합니다",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "중괄호 확장이 최대 깊이 {maxDepth}을(를) 초과했습니다",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "중괄호 패턴의 중첩을 줄이거나 maxDepth 옵션을 늘리세요.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "권한 관리자가 이 Slothlet 인스턴스에서 사용할 수 없습니다"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "ko-kr",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Versão resolvida: {version} para o caminho {apiPath} (chamador: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "Nenhuma correspondência de discriminador para o caminho {apiPath}; usando versão padrão {version}.",
383
383
  "DEBUG_VERSION_REGISTERED": "Versão {version} registrada em {logicalPath} (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Versão {version} removida de {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Versão {version} removida de {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Acesso negado: o chamador '{caller}' não tem permissão para acessar '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Verifique as regras de permissão para este par chamador/alvo. Use api.slothlet.permissions.global.rulesForPath('{target}') para inspecionar as regras ativas.",
388
+ "PERMISSION_SELF_MODIFY": "O módulo '{moduleID}' não pode remover sua própria regra de permissão '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Regras de permissão são imutáveis para o módulo proprietário. Outro módulo deve remover esta regra.",
390
+ "INVALID_PERMISSION_RULE": "Regra de permissão inválida: {reason} (recebido: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Regras de permissão requerem: caller (string glob), target (string glob) e effect ('allow' ou 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Permissão negada: chamador '{caller}' -> alvo '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Permissão concedida: chamador '{caller}' -> alvo '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Auto-bypass de permissão: chamador e alvo compartilham moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Política de permissão padrão aplicada: chamador '{caller}' -> alvo '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Regra de permissão adicionada: {ruleId} ({caller} -> {target}: {effect}, proprietário: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Regra de permissão removida: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "a regra deve ser um objeto não nulo",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller deve ser uma string não vazia",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target deve ser uma string não vazia",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect deve ser 'allow' ou 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "Expansão de chaves excedeu a profundidade máxima de {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Reduza o aninhamento em seus padrões de chaves ou aumente a opção maxDepth.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Gerenciador de permissões não está disponível nesta instância do Slothlet"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "pt-br",
@@ -381,7 +381,27 @@
381
381
  "DEBUG_VERSION_RESOLVED": "Версия определена: {version} для пути {apiPath} (вызывающий: {callerModule})",
382
382
  "DEBUG_VERSION_DEFAULT_USED": "Нет совпадения дискриминатора для пути {apiPath}; используется версия по умолчанию {version}.",
383
383
  "DEBUG_VERSION_REGISTERED": "Версия {version} зарегистрирована в {logicalPath} (moduleID: {moduleID})",
384
- "DEBUG_VERSION_UNREGISTERED": "Версия {version} удалена из {logicalPath}"
384
+ "DEBUG_VERSION_UNREGISTERED": "Версия {version} удалена из {logicalPath}",
385
+
386
+ "PERMISSION_DENIED": "Доступ запрещён: вызывающий '{caller}' не имеет права доступа к '{target}'",
387
+ "HINT_PERMISSION_DENIED": "Проверьте правила разрешений для этой пары вызывающий/цель. Используйте api.slothlet.permissions.global.rulesForPath('{target}') для просмотра активных правил.",
388
+ "PERMISSION_SELF_MODIFY": "Модуль '{moduleID}' не может удалить собственное правило разрешений '{ruleId}'",
389
+ "HINT_PERMISSION_SELF_MODIFY": "Правила разрешений неизменяемы для модуля-владельца. Другой модуль должен удалить это правило.",
390
+ "INVALID_PERMISSION_RULE": "Недопустимое правило разрешений: {reason} (получено: {received})",
391
+ "HINT_INVALID_PERMISSION_RULE": "Правила разрешений требуют: caller (string glob), target (string glob) и effect ('allow' или 'deny').",
392
+ "DEBUG_PERMISSION_DENIED": "Разрешение отклонено: вызывающий '{caller}' -> цель '{target}'",
393
+ "DEBUG_PERMISSION_ALLOWED": "Разрешение предоставлено: вызывающий '{caller}' -> цель '{target}'",
394
+ "DEBUG_PERMISSION_SELF_BYPASS": "Самообход разрешений: вызывающий и цель имеют общий moduleID '{moduleID}'",
395
+ "DEBUG_PERMISSION_DEFAULT": "Применена политика разрешений по умолчанию: вызывающий '{caller}' -> цель '{target}' -> {effect}",
396
+ "DEBUG_PERMISSION_RULE_ADDED": "Правило разрешений добавлено: {ruleId} ({caller} -> {target}: {effect}, владелец: {ownerModuleID})",
397
+ "DEBUG_PERMISSION_RULE_REMOVED": "Правило разрешений удалено: {ruleId} ({caller} -> {target}: {effect})",
398
+ "PERM_RULE_NOT_OBJECT": "правило должно быть ненулевым объектом",
399
+ "PERM_RULE_CALLER_REQUIRED": "rule.caller должно быть непустой строкой",
400
+ "PERM_RULE_TARGET_REQUIRED": "rule.target должно быть непустой строкой",
401
+ "PERM_RULE_EFFECT_INVALID": "rule.effect должно быть 'allow' или 'deny'",
402
+ "BRACE_EXPANSION_MAX_DEPTH": "Расширение фигурных скобок превысило максимальную глубину {maxDepth}",
403
+ "HINT_BRACE_EXPANSION_MAX_DEPTH": "Уменьшите вложенность в ваших шаблонах скобок или увеличьте параметр maxDepth.",
404
+ "PERMISSION_MANAGER_NOT_AVAILABLE": "Менеджер разрешений недоступен в этом экземпляре Slothlet"
385
405
  },
386
406
  "metadata": {
387
407
  "code": "ru-ru",