@happyvertical/smrt-languages 0.51.32 → 0.51.33

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/types.d.ts CHANGED
@@ -1,111 +1,96 @@
1
- import { SmrtClassOptions } from '@happyvertical/smrt-core';
2
-
3
- export declare interface LanguageCacheValue {
4
- key: string;
5
- locale: string;
6
- template: string;
7
- source: ResolvedLanguageString['source'];
8
- resolvedFromLocale: string;
9
- }
10
-
11
- export declare interface LanguageOverrideOptions {
12
- key?: string;
13
- locale?: string;
14
- tenantId?: string | null;
15
- template?: string;
16
- auto_generated?: boolean;
17
- source_hash?: string | null;
18
- ai_model?: string | null;
19
- reviewed_at?: string | null;
20
- reviewed_by?: string | null;
21
- }
22
-
23
- /**
24
- * Per-package config bag, read via `getPackageConfig('languages', ...)`.
25
- *
26
- * `overrides[key][locale]` is a plain string template that takes precedence over
27
- * code defaults for that (key, locale) pair. It is the file-config layer in the
28
- * 5-layer resolution chain.
29
- */
30
- export declare interface LanguagesPackageConfig {
31
- /** Default locale used when none is supplied at resolve-time. Defaults to 'en'. */
32
- defaultLocale?: string;
33
- /** When set, AI auto-translation jobs are only enqueued for these locales. */
34
- supportedLocales?: string[];
35
- /** Daily cap on AI translation jobs per tenant (null = no cap). */
36
- translationBudgetPerTenantPerDay?: number | null;
37
- /** File-config overrides, keyed by (key)(locale). */
38
- overrides?: Record<string, Record<string, string>>;
39
- [key: string]: unknown;
40
- }
41
-
42
- export declare interface LanguageStringDefinition {
43
- key: string;
44
- locale: string;
45
- template: string;
46
- /** sha256 of the template at registration time, used for re-translation gating */
47
- sourceHash: string;
48
- }
49
-
50
- /** A registered code default for a single (key, locale) pair. */
51
- export declare interface LanguageStringDefinitionInput {
52
- key: string;
53
- locale: string;
54
- template: string;
55
- }
56
-
57
- export declare type LanguageVariables = Record<string, unknown>;
58
-
59
- export declare interface ResolvedLanguageString {
60
- key: string;
61
- locale: string;
62
- /** The fully-rendered string with variables substituted. */
63
- text: string;
64
- /** The raw template that produced `text`. */
65
- template: string;
66
- /** Locale that actually produced the template (may differ from `locale` after fallback). */
67
- resolvedFromLocale: string;
68
- /**
69
- * `'code' | 'config' | 'app' | 'tenant' | 'runtime'`. `'fallback'` indicates
70
- * no exact match was found and a fallback locale was used.
71
- */
72
- source: 'code' | 'config' | 'app' | 'tenant' | 'runtime' | 'fallback' | 'missing';
73
- }
74
-
75
- export declare interface ResolveLanguageStringOptions {
76
- db?: SmrtClassOptions['db'];
77
- tenantId?: string | null;
78
- locale?: string;
79
- /** Variables substituted into `{var}` placeholders. */
80
- vars?: LanguageVariables;
81
- /** Optional per-call override for the rendered template (highest precedence). */
82
- overrides?: {
83
- template?: string;
84
- };
85
- /**
86
- * When `true`, throw if the resolution chain finishes without producing a
87
- * template. When `false` (default), return the key as the rendered string and
88
- * enqueue an AI translation job for the missing (key, locale).
89
- */
90
- strict?: boolean;
91
- }
92
-
93
- /** Payload pushed to the smrt-jobs translation handler. */
94
- export declare interface TranslationJobPayload {
95
- key: string;
96
- sourceLocale: string;
97
- sourceTemplate: string;
98
- sourceHash: string;
99
- targetLocale: string;
100
- tenantId?: string | null;
101
- /** Optional model override; defaults to config / @happyvertical/ai default. */
102
- model?: string;
103
- [key: string]: unknown;
104
- }
105
-
106
- export { }
107
-
108
-
109
- declare global {
110
- var __smrtLanguageRegistry: Map<string, Map<string, LanguageStringDefinition>> | undefined;
1
+ import type { SmrtClassOptions } from '@happyvertical/smrt-core';
2
+ /** A registered code default for a single (key, locale) pair. */
3
+ export interface LanguageStringDefinitionInput {
4
+ key: string;
5
+ locale: string;
6
+ template: string;
111
7
  }
8
+ export interface LanguageStringDefinition {
9
+ key: string;
10
+ locale: string;
11
+ template: string;
12
+ /** sha256 of the template at registration time, used for re-translation gating */
13
+ sourceHash: string;
14
+ }
15
+ /**
16
+ * Per-package config bag, read via `getPackageConfig('languages', ...)`.
17
+ *
18
+ * `overrides[key][locale]` is a plain string template that takes precedence over
19
+ * code defaults for that (key, locale) pair. It is the file-config layer in the
20
+ * 5-layer resolution chain.
21
+ */
22
+ export interface LanguagesPackageConfig {
23
+ /** Default locale used when none is supplied at resolve-time. Defaults to 'en'. */
24
+ defaultLocale?: string;
25
+ /** When set, AI auto-translation jobs are only enqueued for these locales. */
26
+ supportedLocales?: string[];
27
+ /** Daily cap on AI translation jobs per tenant (null = no cap). */
28
+ translationBudgetPerTenantPerDay?: number | null;
29
+ /** File-config overrides, keyed by (key)(locale). */
30
+ overrides?: Record<string, Record<string, string>>;
31
+ [key: string]: unknown;
32
+ }
33
+ export type LanguageVariables = Record<string, unknown>;
34
+ export interface ResolveLanguageStringOptions {
35
+ db?: SmrtClassOptions['db'];
36
+ tenantId?: string | null;
37
+ locale?: string;
38
+ /** Variables substituted into `{var}` placeholders. */
39
+ vars?: LanguageVariables;
40
+ /** Optional per-call override for the rendered template (highest precedence). */
41
+ overrides?: {
42
+ template?: string;
43
+ };
44
+ /**
45
+ * When `true`, throw if the resolution chain finishes without producing a
46
+ * template. When `false` (default), return the key as the rendered string and
47
+ * enqueue an AI translation job for the missing (key, locale).
48
+ */
49
+ strict?: boolean;
50
+ }
51
+ export interface ResolvedLanguageString {
52
+ key: string;
53
+ locale: string;
54
+ /** The fully-rendered string with variables substituted. */
55
+ text: string;
56
+ /** The raw template that produced `text`. */
57
+ template: string;
58
+ /** Locale that actually produced the template (may differ from `locale` after fallback). */
59
+ resolvedFromLocale: string;
60
+ /**
61
+ * `'code' | 'config' | 'app' | 'tenant' | 'runtime'`. `'fallback'` indicates
62
+ * no exact match was found and a fallback locale was used.
63
+ */
64
+ source: 'code' | 'config' | 'app' | 'tenant' | 'runtime' | 'fallback' | 'missing';
65
+ }
66
+ export interface LanguageCacheValue {
67
+ key: string;
68
+ locale: string;
69
+ template: string;
70
+ source: ResolvedLanguageString['source'];
71
+ resolvedFromLocale: string;
72
+ }
73
+ export interface LanguageOverrideOptions {
74
+ key?: string;
75
+ locale?: string;
76
+ tenantId?: string | null;
77
+ template?: string;
78
+ auto_generated?: boolean;
79
+ source_hash?: string | null;
80
+ ai_model?: string | null;
81
+ reviewed_at?: string | null;
82
+ reviewed_by?: string | null;
83
+ }
84
+ /** Payload pushed to the smrt-jobs translation handler. */
85
+ export interface TranslationJobPayload {
86
+ key: string;
87
+ sourceLocale: string;
88
+ sourceTemplate: string;
89
+ sourceHash: string;
90
+ targetLocale: string;
91
+ tenantId?: string | null;
92
+ /** Optional model override; defaults to config / @happyvertical/ai default. */
93
+ model?: string;
94
+ [key: string]: unknown;
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { LanguageVariables } from './types.js';
2
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
3
+ /** Stable hash used to gate auto-translation re-runs against a specific source. */
4
+ export declare function computeSourceHash(template: string): string;
5
+ /**
6
+ * Normalize a BCP-47-ish locale tag for consistent matching across the
7
+ * registry, the cache, and DB lookups.
8
+ *
9
+ * Lowercases the language subtag and uppercases everything after it so
10
+ * `fr-ca`, `fr-CA`, and `Fr-Ca` collapse to the same key. This is **not**
11
+ * canonical BCP-47 casing (proper BCP-47 lower-cases variants and uses
12
+ * Title-case for script subtags like `Hans`); it is an internal
13
+ * normalization shared by every layer in this package and intentionally
14
+ * stricter than what BCP-47 mandates.
15
+ */
16
+ export declare function normalizeLocale(locale: string): string;
17
+ /**
18
+ * Build the locale fallback chain for a requested locale.
19
+ *
20
+ * Example: `fr-CA` with default `en` → `['fr-CA', 'fr', 'en']`.
21
+ * Duplicates and empty segments are removed.
22
+ */
23
+ export declare function buildLocaleFallbackChain(requested: string, defaultLocale: string): string[];
24
+ /**
25
+ * Render `{var}` placeholders against the supplied variables.
26
+ *
27
+ * When at least one variable is provided, every `{...}` placeholder in the
28
+ * template is replaced; missing or `undefined`/`null` variables collapse to
29
+ * empty strings (callers that pass `name` but not `title` get the `{title}`
30
+ * placeholder removed).
31
+ *
32
+ * When `variables` is `undefined` or `{}` the template is returned unchanged
33
+ * — that fast path avoids the regex pass for the common "no interpolation
34
+ * needed" case. If you need every placeholder collapsed regardless, pass at
35
+ * least one variable (e.g. `{ __forceRender: true }`).
36
+ */
37
+ export declare function renderTemplate(template: string, variables?: LanguageVariables): string;
38
+ /** Deterministic translation-job ID — used for stampede protection. */
39
+ export declare function buildTranslationJobId(key: string, targetLocale: string): string;
40
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAElC;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYtD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,MAAM,EAAE,CAwBV;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,iBAAiB,GAC5B,MAAM,CA2BR;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,MAAM,CAER"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-languages",
3
- "version": "0.51.32",
3
+ "version": "0.51.33",
4
4
  "description": "Code-first language strings with config + tenant overrides and AI auto-translation for SMRT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,19 +29,19 @@
29
29
  "dependencies": {
30
30
  "@happyvertical/ai": "^0.94.1",
31
31
  "@happyvertical/logger": "^0.94.1",
32
- "@happyvertical/smrt-config": "0.51.32",
33
- "@happyvertical/smrt-core": "0.51.32",
34
- "@happyvertical/smrt-features": "0.51.32",
35
- "@happyvertical/smrt-jobs": "0.51.32",
36
- "@happyvertical/smrt-prompts": "0.51.32",
37
- "@happyvertical/smrt-tenancy": "0.51.32",
32
+ "@happyvertical/smrt-config": "0.51.33",
33
+ "@happyvertical/smrt-core": "0.51.33",
34
+ "@happyvertical/smrt-features": "0.51.33",
35
+ "@happyvertical/smrt-jobs": "0.51.33",
36
+ "@happyvertical/smrt-prompts": "0.51.33",
37
+ "@happyvertical/smrt-tenancy": "0.51.33",
38
38
  "@happyvertical/sql": "^0.94.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@happyvertical/smrt-cli": "0.51.32",
42
- "@happyvertical/smrt-vitest": "0.51.32",
41
+ "@happyvertical/smrt-cli": "0.51.33",
42
+ "@happyvertical/smrt-vitest": "0.51.33",
43
43
  "@types/node": "24.13.6",
44
- "typescript": "5.9.3",
44
+ "typescript": "6.0.3",
45
45
  "vite": "8.1.4",
46
46
  "vitest": "4.1.10"
47
47
  },